use crate::card::model::Palette; use embedded_graphics::{ geometry::Size, pixelcolor::Rgb565, prelude::Point, primitives::Rectangle, }; use embedded_graphics_core::draw_target::DrawTarget; pub fn render_sprite_onto_ili9341(ili9341: &mut D, sprite: &[u8], palette: &Palette) where D: DrawTarget, { let pixel_count = sprite.len() * 2; if pixel_count == 0 { return; } let mut src_width = 1usize; while src_width * src_width < pixel_count { src_width += 1; } let target_width = 240usize; let scale = core::cmp::max(1, target_width / src_width); for y in 0..src_width { for x in 0..src_width { let pixel_index = y * src_width + x; if pixel_index >= pixel_count { break; } // Bitwise operations are slightly faster than division/modulo let byte_index = pixel_index >> 1; let pixel_byte = sprite[byte_index]; let color_index = if pixel_index.is_multiple_of(2) { (pixel_byte >> 4) & 0x0F } else { pixel_byte & 0x0F }; let color = palette[color_index as usize]; let start_x = (x * scale) as i32; let start_y = (y * scale) as i32; let end_x = core::cmp::min(start_x + scale as i32, target_width as i32); let end_y = core::cmp::min(start_y + scale as i32, target_width as i32); let width = u32::try_from(end_x - start_x).unwrap(); let height = u32::try_from(end_y - start_y).unwrap(); let area = Rectangle::new(Point::new(start_x, start_y), Size::new(width, height)); let _ = ili9341.fill_solid(&area, color); } } }