More refactoring

This commit is contained in:
JP Stringham
2025-12-28 10:14:55 -05:00
parent 3804321fcc
commit a4e99028cc
3 changed files with 136 additions and 100 deletions

121
src/graphics.rs Normal file
View File

@@ -0,0 +1,121 @@
use crate::sprite::{Sprite, SpriteAtlas};
pub struct GraphicsBuf {
buffer: [u8; 8192],
sprites: [Sprite; 30],
sprite_atlas: SpriteAtlas,
}
impl GraphicsBuf {
pub fn new() -> Self {
let sprite_atlas = SpriteAtlas::new(include_bytes!("../sprites/sprites_atlas.bin"));
let mut sprites = [Sprite::new(); 30];
sprites[0].sprite_index = 94;
sprites[0].x = 90;
sprites[0].y = 30;
sprites[0].visible = true;
GraphicsBuf {
buffer: [0u8; 8192],
sprites,
sprite_atlas,
}
}
pub fn clear(&mut self) {
self.buffer.iter_mut().for_each(|b| *b = 0);
}
pub fn redraw(&mut self) {
let mut gfx_buf = &mut self.buffer;
self.sprites.iter_mut().for_each(|s| {
if s.visible {
self.sprite_atlas.draw_sprite(
s.sprite_index,
s.x as u8,
s.y as u8,
s.flip,
&mut gfx_buf,
);
}
});
self.sprite_atlas
.draw_string(10, 10, "Hello World!", &mut gfx_buf);
self.sprite_atlas.draw_textfield(
10,
20,
110,
10,
"I think this font has a *lot* of 'character'! ;)",
&mut gfx_buf,
);
draw_bresenham_line(0, 0, 127, 0, &mut gfx_buf);
draw_bresenham_line(0, 63, 128, 63, &mut gfx_buf);
draw_bresenham_line(0, 0, 0, 63, &mut gfx_buf);
draw_bresenham_line(127, 0, 127, 63, &mut gfx_buf);
}
pub fn get_px_buffer(&self) -> &[u8; 8192] {
&self.buffer
}
}
fn draw_bresenham_line(x0: u8, y0: u8, x1: u8, y1: u8, gfx_buf: &mut [u8; 8192]) {
let x0 = (x0 as i32).clamp(0, 127);
let x1 = (x1 as i32).clamp(0, 127);
let y0 = (y0 as i32).clamp(0, 63);
let y1 = (y1 as i32).clamp(0, 63);
let mut dx = x1 - x0;
let mut dy = y1 - y0;
let mut x = x0;
let mut y = y0;
let mut err = 0;
let mut step_x = 1;
let mut step_y = 1;
if dx < 0 {
dx = -dx;
step_x = -1;
}
if dy < 0 {
dy = -dy;
step_y = -1;
}
if dx > dy {
for _ in 0..dx {
gfx_buf[(y * 128 + x) as usize] = 1;
x += step_x;
err += 2 * dy;
if err > dx {
y += step_y;
err -= 2 * dx;
}
}
} else {
for _ in 0..dy {
gfx_buf[(y * 128 + x) as usize] = 1;
y += step_y;
err += 2 * dx;
if err > dy {
x += step_x;
err -= 2 * dy;
}
}
}
}

View File

@@ -5,18 +5,18 @@
#![no_main] #![no_main]
use defmt::println; use defmt::println;
use embedded_hal::{digital::OutputPin, i2c::I2c}; use embedded_hal::digital::OutputPin;
use hal::{fugit::RateExtU32, pac}; use hal::{fugit::RateExtU32, pac};
use rp2040_hal as hal; use rp2040_hal as hal;
use rp2040_hal::i2c::Error;
use defmt as _; use defmt_rtt as _;
use panic_probe as _; use panic_probe as _;
mod graphics;
mod sprite; mod sprite;
mod ssh1106; mod ssh1106;
use crate::sprite::*; use crate::graphics::*;
use crate::ssh1106::*; use crate::ssh1106::*;
#[link_section = ".boot_loader"] #[link_section = ".boot_loader"]
@@ -75,104 +75,14 @@ fn main() -> ! {
let ssh1106_dev = SSH1106Dev::new(&mut delay, &mut i2c); let ssh1106_dev = SSH1106Dev::new(&mut delay, &mut i2c);
println!("SSH1106 initialized."); println!("SSH1106 initialized.");
let mut gfx_buf = [0u8; 8192]; let mut gfx_buf = GraphicsBuf::new();
let sprite_atlas = SpriteAtlas::new(include_bytes!("../sprites/sprites_atlas.bin"));
let mut sprites = [Sprite::new(); 30];
sprites[0].sprite_index = 94;
sprites[0].x = 90;
sprites[0].y = 30;
sprites[0].visible = true;
loop { loop {
gfx_buf.iter_mut().for_each(|x| *x = 0); gfx_buf.clear();
gfx_buf.redraw();
sprites.iter_mut().for_each(|s| {
if s.visible {
sprite_atlas.draw_sprite(
s.sprite_index,
s.x as u8,
s.y as u8,
s.flip,
&mut gfx_buf,
);
}
});
sprite_atlas.draw_string(10, 10, "Hello World!", &mut gfx_buf);
sprite_atlas.draw_textfield(
10,
20,
110,
10,
"I think this font has a *lot* of 'character'! ;)",
&mut gfx_buf,
);
draw_bresenham_line(0, 0, 127, 0, &mut gfx_buf);
draw_bresenham_line(0, 63, 128, 63, &mut gfx_buf);
draw_bresenham_line(0, 0, 0, 63, &mut gfx_buf);
draw_bresenham_line(127, 0, 127, 63, &mut gfx_buf);
ssh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf); ssh1106_dev.blit_framebuffer(&mut i2c, &gfx_buf);
delay.delay_ms(1); delay.delay_ms(10);
}
}
// should probably go into some kind of graphics module
fn draw_bresenham_line(x0: u8, y0: u8, x1: u8, y1: u8, gfx_buf: &mut [u8; 8192]) {
let x0 = (x0 as i32).clamp(0, 127);
let x1 = (x1 as i32).clamp(0, 127);
let y0 = (y0 as i32).clamp(0, 63);
let y1 = (y1 as i32).clamp(0, 63);
let mut dx = x1 - x0;
let mut dy = y1 - y0;
let mut x = x0;
let mut y = y0;
let mut err = 0;
let mut step_x = 1;
let mut step_y = 1;
if dx < 0 {
dx = -dx;
step_x = -1;
}
if dy < 0 {
dy = -dy;
step_y = -1;
}
if dx > dy {
for _ in 0..dx {
gfx_buf[(y * 128 + x) as usize] = 1;
x += step_x;
err += 2 * dy;
if err > dx {
y += step_y;
err -= 2 * dx;
}
}
} else {
for _ in 0..dy {
gfx_buf[(y * 128 + x) as usize] = 1;
y += step_y;
err += 2 * dx;
if err > dy {
x += step_x;
err -= 2 * dy;
}
}
} }
} }

View File

@@ -2,6 +2,10 @@ use cortex_m::delay::Delay;
use embedded_hal::i2c::I2c; use embedded_hal::i2c::I2c;
use rp2040_hal::i2c::Error; use rp2040_hal::i2c::Error;
use defmt as _;
use crate::graphics::GraphicsBuf;
#[allow(unused)] #[allow(unused)]
#[repr(u8)] #[repr(u8)]
#[derive(PartialEq, Copy, Clone)] #[derive(PartialEq, Copy, Clone)]
@@ -37,11 +41,12 @@ impl SSH1106Dev {
SSH1106Dev { ready: true } SSH1106Dev { ready: true }
} }
pub fn blit_framebuffer(&self, i2c: &mut dyn I2c<Error = Error>, graphic: &[u8; 8192]) { pub fn blit_framebuffer(&self, i2c: &mut dyn I2c<Error = Error>, gfx_buf: &GraphicsBuf) {
if !self.ready { if !self.ready {
panic!("Attempted to use SSH1106 before initialized."); panic!("Attempted to use SSH1106 before initialized.");
} }
let buf = gfx_buf.get_px_buffer();
// for each row of 8x8 pixels // for each row of 8x8 pixels
for r in 0..8 { for r in 0..8 {
set_page(i2c, r); set_page(i2c, r);
@@ -60,7 +65,7 @@ impl SSH1106Dev {
for y in 0..8 { for y in 0..8 {
let pix_x = (c as usize) * 8 + x; let pix_x = (c as usize) * 8 + x;
let pix_y = (r as usize) * 8 + y; let pix_y = (r as usize) * 8 + y;
col_byte |= graphic[pix_y * 128 + pix_x] << y; col_byte |= buf[pix_y * 128 + pix_x] << y;
} }
cel[x] = col_byte; cel[x] = col_byte;