use crate::peripherals::{Gfx, Input, Touch}; /// PROMETEU "hardware lógico" (v0). /// O host alimenta INPUT/TOUCH e chama `tick()` em 60Hz. pub struct Machine { pub gfx: Gfx, pub input: Input, pub touch: Touch, pub frame_index: u64, } impl Machine { pub const W: usize = 320; pub const H: usize = 180; pub fn new() -> Self { Self { gfx: Gfx::new(Self::W, Self::H), input: Input::default(), touch: Touch::default(), frame_index: 0, } } /// Um frame lógico do PROMETEU. /// (Depois isso chamará um "cartucho"; por enquanto é demo hardcoded.) pub fn tick(&mut self) { self.frame_index += 1; // Limpa self.gfx.clear(Color::rgb(0x10, 0x10, 0x10)); // Demo: quadrado que muda de cor se A ou touch estiver pressionado let (x, y) = self.demo_pos(); let color = if self.input.a_down || self.touch.down { Color::rgb(0x00, 0xFF, 0x00) } else { Color::rgb(0xFF, 0x40, 0x40) }; self.gfx.fill_rect(x, y, 24, 24, color); // Present (double buffer) self.gfx.present(); } fn demo_pos(&self) -> (i32, i32) { // Só para mostrar movimento sem input por enquanto. let t = (self.frame_index % 280) as i32; (20 + t, 80) } } /// Cor simples em RGBA8888 (0xRRGGBBAA). /// (Mais tarde, para hardware barato, você pode mudar o formato para RGB565.) #[derive(Clone, Copy, Debug, Default)] pub struct Color(pub u32); impl Color { pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self { Self(((r as u32) << 24) | ((g as u32) << 16) | ((b as u32) << 8) | (a as u32)) } pub const fn rgb(r: u8, g: u8, b: u8) -> Self { Self::rgba(r, g, b, 0xFF) } }