From 606d7d43ce7f352b6d95327e8e168df65c008ad5 Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 13 Sep 2025 12:32:42 +0300 Subject: [PATCH] Draw a very high-resolution cat --- Cargo.lock | 23 +++++++++++++++++++++++ Cargo.toml | 1 + images/cat.qoi | Bin 0 -> 23731 bytes src/main.rs | 6 +++--- src/qoi.rs | 43 ++++++++++++++++++++++++++++++++++++++----- 5 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 images/cat.qoi diff --git a/Cargo.lock b/Cargo.lock index 85d2ba5..a6e634c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,6 +50,17 @@ dependencies = [ "unwrap-infallible", ] +[[package]] +name = "avr-progmem" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e93a9dd7da8f4eb57c912367e337687e06a8db6452d8c89eeb9eff1e0d2ba2d" +dependencies = [ + "cfg-if", + "derivative", + "ufmt", +] + [[package]] name = "az" version = "1.2.1" @@ -80,6 +91,17 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "embedded-graphics-core" version = "0.4.0" @@ -184,6 +206,7 @@ version = "0.1.0" dependencies = [ "atmega-hal", "avr-device", + "avr-progmem", "embedded-graphics-core", "embedded-hal 1.0.0", "panic-halt", diff --git a/Cargo.toml b/Cargo.toml index 100fde5..2ca442a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ atmega-hal = { git = "https://github.com/Rahix/avr-hal?tab=readme-ov-file", rev= ufmt = "0.2.0" embedded-graphics-core = "0.4.0" +avr-progmem = "0.4.0" # nb = "1.1.0" # pwm-pca9685 = "1.0.0" # infrared = "0.14.1" diff --git a/images/cat.qoi b/images/cat.qoi new file mode 100644 index 0000000000000000000000000000000000000000..53b953460ffb9c767fa158aad01e6435f379731f GIT binary patch literal 23731 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 Z$qxkYBqJR*rf58Is2U^6Z-0H_{{i6S&Cvh= literal 0 HcmV?d00001 diff --git a/src/main.rs b/src/main.rs index cee5a52..6588c17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ use panic_halt as _; use crate::{ display::{Display, Position, Rgb565}, peripherals::{Button, Knob}, - qoi::{MARIO, PIKA, PRESS_BTN, STEVE, draw_image}, + qoi::{MARIO, PRESS_BTN, draw_image}, }; mod display; @@ -78,12 +78,12 @@ fn main() -> ! { let mut button = Button::from(pins.pd5.into_pull_up_input()); let mut idx = 0; - let images = [&PIKA.as_slice(), &MARIO.as_slice(), &STEVE.as_slice()]; + let images = [&MARIO.as_slice()]; let len = images.len(); match draw_image( &mut serial, - &PIKA.as_slice(), + &MARIO.as_slice(), &mut display, Position { x: 0, y: 0 }, ) { diff --git a/src/qoi.rs b/src/qoi.rs index 3238c5d..ca987ed 100644 --- a/src/qoi.rs +++ b/src/qoi.rs @@ -8,20 +8,44 @@ use atmega_hal::{ pac::USART0, port::{PB3, PB5, PD0, PD1, Pin, PinOps, mode}, }; +use avr_progmem::{progmem, wrapper::ProgMem}; use embedded_hal::delay::DelayNs; use ufmt::derive::uDebug; use crate::{ CoreClock, display::{Color, Display, Position, Rgb565, Writeable}, + qoi, }; +progmem! { + /// Static byte stored in progmem! + static progmem P_BYTE: u8 = 42; + static progmem VERY_LARGE: [u8; 23731] = *include_bytes!("../images/cat.qoi"); +} + // https://qoiformat.org/qoi-specification.pdf pub static MARIO: [u8; 161] = *include_bytes!("../images/mario.qoi"); -pub static PIKA: [u8; 241] = *include_bytes!("../images/pikachu.qoi"); -pub static STEVE: [u8; 187] = *include_bytes!("../images/steve.qoi"); pub static PRESS_BTN: [u8; 174] = *include_bytes!("../images/press_btn.qoi"); +pub struct LargeIterator { + buffer: ProgMem<[u8; LENGTH]>, + index: usize, +} + +impl Iterator for LargeIterator { + type Item = u8; + + fn next(&mut self) -> Option { + if self.index >= LENGTH { + return None; + } + let item = self.buffer.load_at(self.index); + self.index += 1; + Some(item) + } +} + #[derive(Debug, uDebug)] pub enum QoiErr { InvalidMagicNumber, @@ -34,7 +58,12 @@ pub fn draw_image( display: &mut Display, position: Position, ) -> Result<(), QoiErr> { - let mut iter = buffer.iter().map(|b| *b); + // let mut iter = buffer.iter().map(|b| *b); + + let mut iter = LargeIterator { + buffer: VERY_LARGE, + index: 0, + }; if let (Some(113), Some(111), Some(105), Some(102)) = (iter.next(), iter.next(), iter.next(), iter.next()) @@ -73,7 +102,7 @@ pub fn draw_image( let qoi_iter = QoiIterator::from(&mut iter, width * height); let scale_iter = ScaleIterator { qoi: qoi_iter, - last_row: [Rgb565::yellow(); 64], + last_row: [Rgb565::yellow(); 120], scale_factor: scale_factor as usize, width: width as usize, counter: 0, @@ -96,7 +125,7 @@ pub fn draw_image( struct ScaleIterator<'a> { qoi: QoiIterator<'a>, - last_row: [Rgb565; 64], + last_row: [Rgb565; 120], width: usize, scale_factor: usize, counter: usize, @@ -107,6 +136,10 @@ impl<'a> Iterator for ScaleIterator<'a> { type Item = Rgb565; fn next(&mut self) -> Option { + if self.scale_factor == 1 { + return self.qoi.next(); + } + if self.index >= self.width * self.scale_factor { self.counter = (self.counter + 1) % self.scale_factor; self.index = 0;