Store alphabet in progmem data

This commit is contained in:
Sofia 2025-09-13 18:43:57 +03:00
parent 9bb7af612c
commit c78db0c81a
3 changed files with 196 additions and 130 deletions

View File

@ -74,6 +74,17 @@ pub struct Vec2 {
pub y: u16, pub y: u16,
} }
impl Mul<u16> for Vec2 {
type Output = Vec2;
fn mul(self, rhs: u16) -> Self::Output {
Vec2 {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
#[derive(Default, Clone, Copy)] #[derive(Default, Clone, Copy)]
pub struct Color { pub struct Color {
pub bytes: [u8; 2], pub bytes: [u8; 2],

View File

@ -1,3 +1,8 @@
use core::{
arch::asm,
ptr::{addr_of, null},
};
use atmega_hal::port::PinOps; use atmega_hal::port::PinOps;
use embedded_hal::delay::DelayNs; use embedded_hal::delay::DelayNs;
@ -6,121 +11,154 @@ use crate::{
graphics::draw_stream, graphics::draw_stream,
}; };
fn letter(character: char) -> [u8; 8] { #[unsafe(link_section = ".progmem.data")]
pub static A: [u8; 8] = [
0b01111110, 0b01000010, 0b10000001, 0b11111111, 0b10000001, 0b10000001, 0b10000001, 0b10000001,
];
#[unsafe(link_section = ".progmem.data")]
pub static B: [u8; 8] = [
0b11111100, 0b10000010, 0b10000010, 0b10001100, 0b10000010, 0b10000001, 0b10000001, 0b11111110,
];
#[unsafe(link_section = ".progmem.data")]
pub static C: [u8; 8] = [
0b11111110, 0b10000001, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000001, 0b11111110,
];
#[unsafe(link_section = ".progmem.data")]
pub static D: [u8; 8] = [
0b11111100, 0b10000010, 0b10000010, 0b10000001, 0b10000001, 0b10000010, 0b10000010, 0b11111100,
];
#[unsafe(link_section = ".progmem.data")]
pub static E: [u8; 8] = [
0b11111111, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, 0b11111111,
];
#[unsafe(link_section = ".progmem.data")]
pub static F: [u8; 8] = [
0b11111111, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, 0b10000000,
];
#[unsafe(link_section = ".progmem.data")]
pub static G: [u8; 8] = [
0b11111110, 0b10000001, 0b10000000, 0b10000000, 0b10011111, 0b10010001, 0b01000010, 0b00111100,
];
#[unsafe(link_section = ".progmem.data")]
pub static H: [u8; 8] = [
0b10000001, 0b10000001, 0b10000001, 0b11111111, 0b10000001, 0b10000001, 0b10000001, 0b10000001,
];
#[unsafe(link_section = ".progmem.data")]
pub static I: [u8; 8] = [
0b00111100, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00111100,
];
#[unsafe(link_section = ".progmem.data")]
pub static J: [u8; 8] = [
0b00001110, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b10000010, 0b10000010, 0b01111100,
];
#[unsafe(link_section = ".progmem.data")]
pub static K: [u8; 8] = [
0b01000010, 0b01000100, 0b01001000, 0b01110000, 0b01001000, 0b01000100, 0b01000010, 0b01000001,
];
#[unsafe(link_section = ".progmem.data")]
pub static L: [u8; 8] = [
0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11111111,
];
#[unsafe(link_section = ".progmem.data")]
pub static M: [u8; 8] = [
0b00100100, 0b11011011, 0b10011001, 0b10011001, 0b10011001, 0b10000001, 0b10000001, 0b10000001,
];
#[unsafe(link_section = ".progmem.data")]
pub static N: [u8; 8] = [
0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10001001, 0b10000101, 0b10000111, 0b10000011,
];
#[unsafe(link_section = ".progmem.data")]
pub static O: [u8; 8] = [
0b11111111, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b11111111,
];
#[unsafe(link_section = ".progmem.data")]
pub static P: [u8; 8] = [
0b11111111, 0b10000001, 0b10000001, 0b11111111, 0b10000000, 0b10000000, 0b10000000, 0b00000000,
];
#[unsafe(link_section = ".progmem.data")]
pub static Q: [u8; 8] = [
0b01111110, 0b10000001, 0b10000001, 0b10000001, 0b10001001, 0b10000101, 0b10000011, 0b01111111,
];
#[unsafe(link_section = ".progmem.data")]
pub static R: [u8; 8] = [
0b11111111, 0b10000001, 0b10000001, 0b11111111, 0b11111100, 0b10000010, 0b10000001, 0b10000001,
];
#[unsafe(link_section = ".progmem.data")]
pub static S: [u8; 8] = [
0b01111111, 0b10000000, 0b10000000, 0b01111110, 0b00000001, 0b00000001, 0b00000001, 0b11111110,
];
#[unsafe(link_section = ".progmem.data")]
pub static T: [u8; 8] = [
0b11111111, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000,
];
#[unsafe(link_section = ".progmem.data")]
pub static U: [u8; 8] = [
0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b01111110,
];
#[unsafe(link_section = ".progmem.data")]
pub static V: [u8; 8] = [
0b10000001, 0b10000001, 0b01000010, 0b01000010, 0b00100100, 0b00100100, 0b00100100, 0b00011000,
];
#[unsafe(link_section = ".progmem.data")]
pub static W: [u8; 8] = [
0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10011001, 0b01011010, 0b00100100, 0b00100100,
];
#[unsafe(link_section = ".progmem.data")]
pub static X: [u8; 8] = [
0b10000001, 0b01000010, 0b00100100, 0b00011000, 0b00011000, 0b00100100, 0b01000010, 0b10000001,
];
#[unsafe(link_section = ".progmem.data")]
pub static Y: [u8; 8] = [
0b10000001, 0b01000010, 0b00100100, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000,
];
#[unsafe(link_section = ".progmem.data")]
pub static Z: [u8; 8] = [
0b11111111, 0b00000111, 0b00001100, 0b00011000, 0b00110000, 0b01100000, 0b11000000, 0b11111111,
];
#[unsafe(link_section = ".progmem.data")]
pub static EXCLAMATION: [u8; 8] = [
0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b00000000, 0b01000000,
];
#[unsafe(link_section = ".progmem.data")]
pub static COMMA: [u8; 8] = [
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01000000, 0b10000000,
];
#[unsafe(link_section = ".progmem.data")]
pub static EMPTY: [u8; 8] = [
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
];
fn letter(character: char) -> *const [u8; 8] {
match character { match character {
'a' => [ 'a' => addr_of!(A),
0b01111110, 0b01000010, 0b10000001, 0b11111111, 0b10000001, 0b10000001, 0b10000001, 'b' => addr_of!(B),
0b10000001, 'c' => addr_of!(C),
], 'd' => addr_of!(D),
'b' => [ 'e' => addr_of!(E),
0b11111100, 0b10000010, 0b10000010, 0b10001100, 0b10000010, 0b10000001, 0b10000001, 'f' => addr_of!(F),
0b11111110, 'g' => addr_of!(G),
], 'h' => addr_of!(H),
'c' => [ 'i' => addr_of!(I),
0b11111110, 0b10000001, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000001, 'j' => addr_of!(J),
0b11111110, 'k' => addr_of!(K),
], 'l' => addr_of!(L),
'd' => [ 'm' => addr_of!(M),
0b11111100, 0b10000010, 0b10000010, 0b10000001, 0b10000001, 0b10000010, 0b10000010, 'n' => addr_of!(N),
0b11111100, 'o' => addr_of!(O),
], 'p' => addr_of!(P),
'e' => [ 'q' => addr_of!(Q),
0b11111111, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, 'r' => addr_of!(R),
0b11111111, 's' => addr_of!(S),
], 't' => addr_of!(T),
'f' => [ 'u' => addr_of!(U),
0b11111111, 0b10000000, 0b10000000, 0b11111000, 0b10000000, 0b10000000, 0b10000000, 'v' => addr_of!(V),
0b10000000, 'w' => addr_of!(W),
], 'x' => addr_of!(X),
'g' => [ 'y' => addr_of!(Y),
0b11111110, 0b10000001, 0b10000000, 0b10000000, 0b10011111, 0b10010001, 0b01000010, 'z' => addr_of!(Z),
0b00111100, '!' => addr_of!(EXCLAMATION),
], ',' => addr_of!(COMMA),
'h' => [ _ => addr_of!(EMPTY),
0b10000001, 0b10000001, 0b10000001, 0b11111111, 0b10000001, 0b10000001, 0b10000001,
0b10000001,
],
'i' => [
0b00111100, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000,
0b00111100,
],
'j' => [
0b00001110, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b10000010, 0b10000010,
0b01111100,
],
'k' => [
0b01000010, 0b01000100, 0b01001000, 0b01110000, 0b01001000, 0b01000100, 0b01000010,
0b01000001,
],
'l' => [
0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000,
0b11111111,
],
'm' => [
0b00100100, 0b11011011, 0b10011001, 0b10011001, 0b10011001, 0b10000001, 0b10000001,
0b10000001,
],
'n' => [
0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10001001, 0b10000101, 0b10000111,
0b10000011,
],
'o' => [
0b11111111, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001,
0b11111111,
],
'p' => [
0b11111111, 0b10000001, 0b10000001, 0b11111111, 0b10000000, 0b10000000, 0b10000000,
0b00000000,
],
'q' => [
0b01111110, 0b10000001, 0b10000001, 0b10000001, 0b10001001, 0b10000101, 0b10000011,
0b01111111,
],
'r' => [
0b11111111, 0b10000001, 0b10000001, 0b11111111, 0b11111100, 0b10000010, 0b10000001,
0b10000001,
],
's' => [
0b01111111, 0b10000000, 0b10000000, 0b01111110, 0b00000001, 0b00000001, 0b00000001,
0b11111110,
],
't' => [
0b11111111, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000,
0b00010000,
],
'u' => [
0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10000001,
0b01111110,
],
'v' => [
0b10000001, 0b10000001, 0b01000010, 0b01000010, 0b00100100, 0b00100100, 0b00100100,
0b00011000,
],
'w' => [
0b10000001, 0b10000001, 0b10000001, 0b10000001, 0b10011001, 0b01011010, 0b00100100,
0b00100100,
],
'x' => [
0b10000001, 0b01000010, 0b00100100, 0b00011000, 0b00011000, 0b00100100, 0b01000010,
0b10000001,
],
'y' => [
0b10000001, 0b01000010, 0b00100100, 0b00011000, 0b00011000, 0b00011000, 0b00011000,
0b00011000,
],
'z' => [
0b11111111, 0b00000111, 0b00001100, 0b00011000, 0b00110000, 0b01100000, 0b11000000,
0b11111111,
],
'!' => [
0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b00000000,
0b01000000,
],
',' => [
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01000000,
0b10000000,
],
_ => [0; 8],
} }
} }
@ -174,11 +212,28 @@ pub struct Letter {
impl Letter { impl Letter {
pub fn from(character: char, fg: Rgb565, bg: Rgb565) -> Letter { pub fn from(character: char, fg: Rgb565, bg: Rgb565) -> Letter {
Letter { let mut out = [0u8; 8];
base: letter(character), let out_ptr = out.as_mut_ptr();
fg, let ptr_addr = letter(character);
bg,
unsafe {
asm!(
// Load value of Z to temporary register $1 and post-increment Z
"lpm {1}, Z+",
// Store value from register $1 to X and post-increment X
"st X+, {1}",
// Subtract loop counter at register $0
"subi {0}, 1",
// If equality failed, jump back 8 bytes (or 4 instructions)
"brne -8",
inout(reg) 8u8 => _,
out(reg) _,
inout("Z") ptr_addr => _,
inout("X") out_ptr => _
)
} }
Letter { base: out, fg, bg }
} }
pub fn iter<'a>(&'a self) -> LetterIter<'a> { pub fn iter<'a>(&'a self) -> LetterIter<'a> {

View File

@ -82,18 +82,7 @@ fn main() -> ! {
let images = [Image::from(addr_of!(LARGE_CAT_UNSAFE))]; let images = [Image::from(addr_of!(LARGE_CAT_UNSAFE))];
let len = images.len(); let len = images.len();
// match draw_image( ufmt::uwriteln!(serial, "Drawing text").unwrap();
// &mut serial,
// &mut Image::from(addr_of!(PRESS_BTN_UNSAFE)).iter(),
// &mut display,
// Vec2 { x: 0, y: 0 },
// ) {
// Ok(_) => ufmt::uwriteln!(serial, "Successfully read QOI").unwrap(),
// Err(e) => ufmt::uwriteln!(serial, "Error: {:?}", e).unwrap(),
// }
let letter = Letter::from('h', Rgb565::white(), Rgb565::black());
draw_text( draw_text(
&mut display, &mut display,
"hi,my name is adafruit!nice to meet you!", "hi,my name is adafruit!nice to meet you!",
@ -103,6 +92,8 @@ fn main() -> ! {
3, 3,
); );
ufmt::uwriteln!(serial, "Text drawn!").unwrap();
loop { loop {
if button.poll() { if button.poll() {
match draw_image( match draw_image(
@ -115,6 +106,15 @@ fn main() -> ! {
Err(e) => ufmt::uwriteln!(serial, "Error: {:?}", e).unwrap(), Err(e) => ufmt::uwriteln!(serial, "Error: {:?}", e).unwrap(),
} }
draw_text(
&mut display,
"you just lost the game!",
Rgb565::white(),
Rgb565::black(),
Vec2 { x: 10, y: 10 },
3,
);
idx = (idx + 1) % len; idx = (idx + 1) % len;
} }
} }