More refactoring
This commit is contained in:
121
src/graphics.rs
Normal file
121
src/graphics.rs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
106
src/main.rs
106
src/main.rs
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user