diff --git a/.vscode/settings.json b/.vscode/settings.json index aa6e6ab..7ec9b61 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,4 +4,5 @@ "workbench.editor.customLabels.patterns": { "**/mod.rs": "mod | ${dirname}" }, + "rust-analyzer.cargo.target": "thumbv6m-none-eabi" } \ No newline at end of file diff --git a/src/graphics.rs b/src/graphics.rs index 1e73363..489bfce 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,4 +1,6 @@ -use crate::sprite::{Sprite, SpriteAtlas}; +mod sprite; + +use sprite::*; pub struct GraphicsBuf { buffer: [u8; 8192], diff --git a/src/sprite.rs b/src/graphics/sprite.rs similarity index 72% rename from src/sprite.rs rename to src/graphics/sprite.rs index 383c077..3480468 100644 --- a/src/sprite.rs +++ b/src/graphics/sprite.rs @@ -1,6 +1,6 @@ -static SPRITES_COMPRESSED:[u8;16384] = *include_bytes!("../sprites/sprites_tex.bin"); +static SPRITES_COMPRESSED: [u8; 16384] = *include_bytes!("../../sprites/sprites_tex.bin"); -const ATLAS_WIDTH:usize = 256; +const ATLAS_WIDTH: usize = 256; #[derive(Copy, Clone)] pub struct Sprite { @@ -47,9 +47,8 @@ pub struct SpriteAtlas { } impl SpriteAtlas { - pub fn new(from_bin:&[u8]) -> SpriteAtlas { - - if from_bin.len() > 256*4 { + pub fn new(from_bin: &[u8]) -> SpriteAtlas { + if from_bin.len() > 256 * 4 { panic!("SpriteAtlas::new() - from_bin is too large"); } @@ -67,14 +66,15 @@ impl SpriteAtlas { entries[i].height = chunk[3]; }); - SpriteAtlas { - entries: entries, - } + SpriteAtlas { entries: entries } } - pub fn draw_textfield(&self, - x: u8, y: u8, - width: u8, height: u8, + pub fn draw_textfield( + &self, + x: u8, + y: u8, + width: u8, + height: u8, string: &str, gfx_buf: &mut [u8; 8192], ) { @@ -89,32 +89,28 @@ impl SpriteAtlas { cur_x = x; cur_y += 8; } - + self.draw_string(cur_x, cur_y, word, gfx_buf); cur_x += word_width as u8 + 4; } } - pub fn draw_string(&self, - x: u8, y: u8, - string: &str, - gfx_buf: &mut [u8; 8192], - ) { + pub fn draw_string(&self, x: u8, y: u8, string: &str, gfx_buf: &mut [u8; 8192]) { let mut x = x; - + for c in string.chars() { if c == ' ' { x += 4; continue; } - + let sprite_index = c as usize - 33; self.draw_sprite(sprite_index, x, y, SpriteFlip::None, gfx_buf); x += self.entries[sprite_index].width + 1; } } - fn get_str_pixel_width(&self, str:&str) -> usize { + fn get_str_pixel_width(&self, str: &str) -> usize { let mut width = 0; for c in str.chars() { @@ -130,12 +126,14 @@ impl SpriteAtlas { width } - pub fn draw_sprite(&self, + pub fn draw_sprite( + &self, sprite_index: usize, - x: u8, y:u8, + x: u8, + y: u8, flip: SpriteFlip, - gfx_buf: &mut [u8; 8192]) { - + gfx_buf: &mut [u8; 8192], + ) { let entry = self.entries[sprite_index]; for sprite_y in 0..entry.height { @@ -152,23 +150,30 @@ impl SpriteAtlas { let px = match flip { SpriteFlip::None => self.px_for_entry(sprite_index, sprite_x, sprite_y), - SpriteFlip::Horizontal => self.px_for_entry(sprite_index, entry.width - sprite_x - 1, sprite_y), - SpriteFlip::Vertical => self.px_for_entry(sprite_index, sprite_x, entry.height - sprite_y - 1), - SpriteFlip::Both => self.px_for_entry(sprite_index, entry.width - sprite_x - 1, entry.height - sprite_y - 1), + SpriteFlip::Horizontal => { + self.px_for_entry(sprite_index, entry.width - sprite_x - 1, sprite_y) + } + SpriteFlip::Vertical => { + self.px_for_entry(sprite_index, sprite_x, entry.height - sprite_y - 1) + } + SpriteFlip::Both => self.px_for_entry( + sprite_index, + entry.width - sprite_x - 1, + entry.height - sprite_y - 1, + ), }; if px == 3 { continue; } - let target_index = (tgt_y as usize)*128 + tgt_x as usize; + let target_index = (tgt_y as usize) * 128 + tgt_x as usize; gfx_buf[target_index] = px; } } - } - pub fn px_for_entry(&self, entry_index:usize, x:u8, y:u8) -> u8 { + pub fn px_for_entry(&self, entry_index: usize, x: u8, y: u8) -> u8 { let entry = self.entries[entry_index]; // input is uncompressed coordinate system @@ -181,7 +186,7 @@ impl SpriteAtlas { // however as the compressed tiles are 2bpp (4px per byte) // we need to find the byte that contains the pixel we're looking for - let sprite_row_byte_index = (y as usize)*ATLAS_WIDTH/4 + (x as usize)/4; + let sprite_row_byte_index = (y as usize) * ATLAS_WIDTH / 4 + (x as usize) / 4; let sprite_row_byte = SPRITES_COMPRESSED[sprite_row_byte_index]; let x_remain = x % 4; @@ -196,9 +201,8 @@ impl SpriteAtlas { // (sprite_row_byte & (0b1100_0000 >> 4)) >> 2 // etc - let px_byte = (sprite_row_byte & (0b1100_0000 >> (x_remain*2))) >> (6 - x_remain*2); + let px_byte = (sprite_row_byte & (0b1100_0000 >> (x_remain * 2))) >> (6 - x_remain * 2); px_byte - } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d667ba1 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +#![no_std] + +pub mod graphics; +pub mod ssh1106; diff --git a/src/main.rs b/src/main.rs index c691392..7c686e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,13 +12,6 @@ use rp2040_hal as hal; use defmt_rtt as _; use panic_probe as _; -mod graphics; -mod sprite; -mod ssh1106; - -use crate::graphics::*; -use crate::ssh1106::*; - #[link_section = ".boot_loader"] #[used] pub static BOOT_LOADER: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080; @@ -72,10 +65,10 @@ fn main() -> ! { let mut led_pin = pins.gpio25.into_push_pull_output(); led_pin.set_high().unwrap(); - let ssh1106_dev = SSH1106Dev::new(&mut delay, &mut i2c); + let ssh1106_dev = sh1106_pico_rs::ssh1106::SSH1106Dev::new(&mut delay, &mut i2c); println!("SSH1106 initialized."); - let mut gfx_buf = GraphicsBuf::new(); + let mut gfx_buf = sh1106_pico_rs::graphics::GraphicsBuf::new(); loop { gfx_buf.clear();