diff --git a/epd-waveshare/src/epd3in7/mod.rs b/epd-waveshare/src/epd3in7/mod.rs index e847214..e8ed9a7 100644 --- a/epd-waveshare/src/epd3in7/mod.rs +++ b/epd-waveshare/src/epd3in7/mod.rs @@ -29,6 +29,7 @@ pub const HEIGHT: u32 = 480; pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; const IS_BUSY_LOW: bool = false; +const IS_BUSY_HIGH: bool = true; const SINGLE_BYTE_WRITE: bool = true; @@ -259,21 +260,30 @@ where width: u32, height: u32, ) -> Result<(), SPI::Error> { - self.interface - .cmd(spi, Command::SetRamXAddressStartEndPosition); + let i = &mut self.interface; + i.cmd(spi, Command::SetRamXAddressStartEndPosition); + i.data(spi, &[(x >> 8) as u8])?; + let tmp = x & 0xf8; + i.data(spi, &[tmp as u8])?; // x should be the multiple of 8, the last 3 bit will always be ignored + let tmp = tmp + width - 1; + i.data(spi, &[(tmp >> 8) as u8])?; + i.data(spi, &[(tmp | 0x07) as u8])?; - self.interface.data(spi, &[x as u8 & 0xff]); - self.interface.data(spi, &[(x >> 8) as u8 & 0x03]); - self.interface.data(spi, &[(width - x) as u8 & 0xff]); - self.interface.data(spi, &[((width - x) as u8 >> 8) & 0x03]); + i.cmd(spi, Command::SetRamYAddressStartEndPosition); + i.data(spi, &[(y >> 8) as u8])?; + i.data(spi, &[y as u8])?; + i.data(spi, &[((y + height - 1) >> 8) as u8])?; + i.data(spi, &[(y + height - 1) as u8])?; - self.interface - .cmd(spi, Command::SetRamYAddressStartEndPosition); - self.interface.data(spi, y as u8 & 0xff); - self.interface.data(spi, (y as u8 >> 8) & 0x03); - self.interface.data(spi, (height - y) as u8 & 0xff); - self.interface.data(spi, ((height - y) as u8 >> 8) & 0x03); - todo!() + i.cmd_with_data(spi, Command::WriteRam, buffer); + + //load lut 2 + i.cmd_with_data(spi, Command::WriteLutRegister, &LUT_1GRAY_DU); + + i.cmd(spi, Command::DisplayUpdateSequence); + i.wait_until_idle(delay, IS_BUSY_LOW); + + Ok(()) } fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> { diff --git a/maze/src/lib.rs b/maze/src/lib.rs index 19e93cc..00ab166 100644 --- a/maze/src/lib.rs +++ b/maze/src/lib.rs @@ -409,7 +409,7 @@ impl AsciiBroad { // const LINE_SIZE: usize = X * Self::CELL_SIZE + 1; // const BUFFER_SIZE: usize = Y + Self::CELL_SIZE * Self::LINE_SIZE; - fn format(&self, grid: &Grid, output: &mut impl Write) { + pub fn format(&self, grid: &Grid, output: &mut impl Write) { write!(output, "#").unwrap(); (0..X).into_iter().for_each(|_| { write!(output, "##").unwrap(); @@ -456,10 +456,12 @@ impl<'s> BufWriter<'s> { pub fn new(b: &'s mut [MazePart]) -> Self { Self(b, 0) } + pub fn push(&mut self, part: MazePart) { self.0[self.1] = part; self.1 += 1; } + pub fn copy(&mut self, src: &[MazePart]) { src.iter() .take_while(|p| **p != MazePart::Noop) @@ -678,6 +680,87 @@ mod print_tests { let mut map = BinaryMap::<122, 122, 14884>::new(); BinaryMapVisitor.format(&mut grid, &mut map.0); } + + #[test] + fn binary_map() { + let mut g = Grid::<5, 5, 25>::new(); + g.cells[0] = Cell::EAST; + g.cells[1] = Cell::default(); + g.cells[2] = Cell::EAST; + g.cells[3] = Cell::WEST; + g.cells[4] = Cell::default(); + + g.cells[5] = Cell::EAST | Cell::WEST; + g.cells[6] = Cell::EAST | Cell::WEST; + g.cells[7] = Cell::EAST | Cell::WEST; + g.cells[8] = Cell::EAST | Cell::WEST; + g.cells[9] = Cell::EAST | Cell::WEST; + + g.cells[10] = Cell::EAST | Cell::WEST; + g.cells[11] = Cell::SOUTH; + g.cells[12] = Cell::NORTH; + g.cells[13] = Cell::WEST | Cell::SOUTH; + g.cells[14] = Cell::EAST | Cell::WEST; + + g.cells[15] = Cell::WEST; + g.cells[16] = Cell::WEST | Cell::NORTH | Cell::SOUTH; + g.cells[17] = Cell::WEST | Cell::SOUTH; + g.cells[18] = Cell::EAST | Cell::NORTH; + g.cells[19] = Cell::EAST | Cell::WEST; + + g.cells[20] = Cell::WEST | Cell::SOUTH; + g.cells[21] = Cell::SOUTH | Cell::NORTH; + g.cells[22] = Cell::SOUTH | Cell::NORTH; + g.cells[23] = Cell::SOUTH | Cell::EAST; + g.cells[24] = Cell::WEST | Cell::SOUTH; + + let mut map = BinaryMap::<12, 12, 144>::new(); + BinaryMapVisitor.format(&mut g, &mut map.0); + + use MazePart::Passage as P; + use MazePart::Wall as W; + use MazePart::*; + + #[derive(PartialEq)] + struct MB([MazePart; 144]); + + impl std::fmt::Debug for MB { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "\n"); + for x in 0..12 { + for y in 0..12 { + let c = match self.0[y * 12 + x] { + P => ' ', + W => '#', + Noop => '?', + Player => 'O', + }; + write!(f, "{c} "); + } + write!(f, "\n"); + } + Ok(()) + } + } + + assert_eq!( + MB(map.0), + MB([ + W, W, W, W, W, W, W, W, W, W, W, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, P, P, P, P, P, P, P, P, P, P, W, // + W, W, W, W, W, W, W, W, W, W, W, W, + ]) + ); + } } #[cfg(test)] diff --git a/src/apps/maze_game.rs b/src/apps/maze_game.rs index 13af8bf..bb013ab 100644 --- a/src/apps/maze_game.rs +++ b/src/apps/maze_game.rs @@ -1,12 +1,15 @@ use epd_waveshare::color::Color; -use maze::{BinaryMapVisitor, Direction}; +use maze::{AsciiBroad, BinaryMapVisitor, Direction}; use crate::Button; use super::*; +pub const MAZE_WIDTH: usize = 42; +pub const MAZE_HEIGHT: usize = 42; + pub struct MazeGame { - map: maze::BinaryMap<122, 122, 14884>, + map: maze::BinaryMap, player: Point, old_player: Option, } @@ -22,8 +25,8 @@ impl MazeGame { } impl MazeGame { - const X_OFFSET: i32 = 2; - const Y_OFFSET: i32 = 2; + const X_OFFSET: i32 = 4; + const Y_OFFSET: i32 = 4; fn player_pos(&self) -> (u16, u16) { (self.player.x as u16, self.player.y as u16) @@ -36,14 +39,15 @@ impl MazeGame { .fill_color(Color::Black) .build(); - for x in 0..122 { - for y in 0..122 { - if self.map.at(x, y) == maze::MazePart::Wall { - let p = Rectangle::new( - Point::new(x as i32 + Self::X_OFFSET, y as i32 + Self::Y_OFFSET), - Size::new(1, 1), - ); - p.draw_styled(&wall_style, &mut ctx.epaper.display).unwrap(); + for x in 0..MAZE_WIDTH { + for y in 0..MAZE_HEIGHT { + if self.map.at(x as u16, y as u16) == maze::MazePart::Wall { + Rectangle::new( + Point::new(x as i32 * Self::X_OFFSET, y as i32 * Self::Y_OFFSET), + Size::new(3, 3), + ) + .draw_styled(&wall_style, &mut ctx.epaper.display) + .unwrap(); } } } @@ -56,23 +60,27 @@ impl MazeGame { .fill_color(Color::Black) .build(); - let p = Rectangle::new( + Rectangle::new( Point::new( - self.player.x + Self::X_OFFSET, - self.player.y + Self::Y_OFFSET, + self.player.x * Self::X_OFFSET, + self.player.y * Self::Y_OFFSET, ), Size::new(1, 1), - ); - p.draw_styled(&player_style, &mut ctx.epaper.display) - .unwrap(); + ) + .draw_styled(&player_style, &mut ctx.epaper.display) + .unwrap(); } } impl App for MazeGame { fn start(&mut self, trng: &mut Trng) { - let mut grid = maze::Grid::<60, 60, 3600>::new(); + let mut grid = maze::Grid::<20, 20, 400>::new(); maze::RecursiveDivision.generate(&mut grid, trng); BinaryMapVisitor.format(&mut grid, &mut self.map.0); + + let mut result = heapless::String::<500>::new(); + AsciiBroad.format(&grid, &mut result); + println!("{result}"); } fn draw(&self, ctx: &mut Context) { diff --git a/src/main.rs b/src/main.rs index b3b1f1b..d47f79f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,8 @@ use esp_hal::{ clock::ClockControl, delay::Delay, gpio::{ - Gpio0, Gpio1, Gpio10, Gpio20, Gpio21, Gpio22, Gpio23, Gpio4, Gpio5, - Gpio6, Gpio7, Gpio8, Input, Io, Level, Output, OutputOpenDrain, Pull, + Gpio0, Gpio1, Gpio10, Gpio20, Gpio21, Gpio22, Gpio23, Gpio4, Gpio5, Gpio6, Gpio7, Gpio8, + Input, Io, Level, Output, OutputOpenDrain, Pull, }, peripherals::Peripherals, prelude::*, @@ -152,10 +152,10 @@ impl Button { 10 => Button::D, 11 => Button::Z, // - 12 => Button::A, - 13 => Button::A, - 14 => Button::A, - 15 => Button::A, + 12 => Button::M1, + 13 => Button::M2, + 14 => Button::M3, + 15 => Button::Back, _ => return None, }) } @@ -203,7 +203,9 @@ impl<'d> Keypad<'d> { .find(|(_idx, b)| *b) .and_then(|(idx, _)| Button::from_idx(idx)); - println!("Button: {c:?}"); + if c.is_some() { + println!("Button: {c:?}"); + } c }