added minimal machine structure£

This commit is contained in:
bQUARKz 2026-01-09 09:49:24 +00:00
parent 6782c54354
commit ba673b4547
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
8 changed files with 157 additions and 18 deletions

4
Cargo.lock generated
View File

@ -7,9 +7,9 @@ name = "cart_demo"
version = "0.1.0"
[[package]]
name = "core"
name = "host_desktop"
version = "0.1.0"
[[package]]
name = "host_desktop"
name = "prometeu-core"
version = "0.1.0"

View File

@ -1,6 +1,6 @@
[package]
name = "core"
name = "prometeu-core"
version = "0.1.0"
edition = "2024"
edition = "2021"
[dependencies]
[dependencies]

View File

@ -1,14 +1,4 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
pub mod machine;
pub mod peripherals;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
pub use machine::Machine;

View File

@ -0,0 +1,65 @@
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)
}
}

View File

@ -0,0 +1,55 @@
use crate::machine::Color;
pub struct Gfx {
w: usize,
h: usize,
front: Vec<u32>,
back: Vec<u32>,
}
impl Gfx {
pub fn new(w: usize, h: usize) -> Self {
let len = w * h;
Self {
w,
h,
front: vec![0; len],
back: vec![0; len],
}
}
pub fn size(&self) -> (usize, usize) {
(self.w, self.h)
}
/// O buffer que o host deve exibir.
pub fn front_buffer(&self) -> &[u32] {
&self.front
}
pub fn clear(&mut self, color: Color) {
self.back.fill(color.0);
}
pub fn fill_rect(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color) {
let fw = self.w as i32;
let fh = self.h as i32;
let x0 = x.clamp(0, fw);
let y0 = y.clamp(0, fh);
let x1 = (x + w).clamp(0, fw);
let y1 = (y + h).clamp(0, fh);
for yy in y0..y1 {
let row = (yy as usize) * self.w;
for xx in x0..x1 {
self.back[row + (xx as usize)] = color.0;
}
}
}
/// Double buffer swap.
pub fn present(&mut self) {
std::mem::swap(&mut self.front, &mut self.back);
}
}

View File

@ -0,0 +1,13 @@
#[derive(Default, Clone, Copy, Debug)]
pub struct Input {
pub up: bool,
pub down: bool,
pub left: bool,
pub right: bool,
pub a_down: bool,
pub b_down: bool,
pub start: bool,
pub select: bool,
}

View File

@ -0,0 +1,7 @@
mod gfx;
mod input;
mod touch;
pub use gfx::Gfx;
pub use input::Input;
pub use touch::Touch;

View File

@ -0,0 +1,9 @@
#[derive(Default, Clone, Copy, Debug)]
pub struct Touch {
pub present: bool,
pub down: bool,
pub pressed: bool,
pub released: bool,
pub x: i32,
pub y: i32,
}