66 lines
1.8 KiB
Rust
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)
|
|
}
|
|
}
|