2026-01-09 09:49:24 +00:00

66 lines
1.8 KiB
Rust

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)
}
}