Files
creaturedex/src/display/sprite.rs
T
2026-08-23 16:07:45 +02:00

56 lines
1.7 KiB
Rust

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<D>(ili9341: &mut D, sprite: &[u8], palette: &Palette)
where
D: DrawTarget<Color = Rgb565>,
{
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);
}
}
}