From ba673b45471019237b1a4e1855e2718e75efea7d Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Fri, 9 Jan 2026 09:49:24 +0000 Subject: [PATCH] =?UTF-8?q?added=20minimal=20machine=20structure=C2=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 4 +- crates/core/Cargo.toml | 6 +-- crates/core/src/lib.rs | 16 ++----- crates/core/src/machine.rs | 65 ++++++++++++++++++++++++++++ crates/core/src/peripherals/gfx.rs | 55 +++++++++++++++++++++++ crates/core/src/peripherals/input.rs | 13 ++++++ crates/core/src/peripherals/mod.rs | 7 +++ crates/core/src/peripherals/touch.rs | 9 ++++ 8 files changed, 157 insertions(+), 18 deletions(-) create mode 100644 crates/core/src/machine.rs create mode 100644 crates/core/src/peripherals/gfx.rs create mode 100644 crates/core/src/peripherals/input.rs create mode 100644 crates/core/src/peripherals/mod.rs create mode 100644 crates/core/src/peripherals/touch.rs diff --git a/Cargo.lock b/Cargo.lock index 1479fd17..ef69a1e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 143436c4..a28c407d 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "core" +name = "prometeu-core" version = "0.1.0" -edition = "2024" +edition = "2021" -[dependencies] +[dependencies] \ No newline at end of file diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index b93cf3ff..4a41e16a 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -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; diff --git a/crates/core/src/machine.rs b/crates/core/src/machine.rs new file mode 100644 index 00000000..b73f1b15 --- /dev/null +++ b/crates/core/src/machine.rs @@ -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) + } +} diff --git a/crates/core/src/peripherals/gfx.rs b/crates/core/src/peripherals/gfx.rs new file mode 100644 index 00000000..e7e4ae7c --- /dev/null +++ b/crates/core/src/peripherals/gfx.rs @@ -0,0 +1,55 @@ +use crate::machine::Color; + +pub struct Gfx { + w: usize, + h: usize, + front: Vec, + back: Vec, +} + +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); + } +} diff --git a/crates/core/src/peripherals/input.rs b/crates/core/src/peripherals/input.rs new file mode 100644 index 00000000..8b8e21fd --- /dev/null +++ b/crates/core/src/peripherals/input.rs @@ -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, +} diff --git a/crates/core/src/peripherals/mod.rs b/crates/core/src/peripherals/mod.rs new file mode 100644 index 00000000..3f7225d7 --- /dev/null +++ b/crates/core/src/peripherals/mod.rs @@ -0,0 +1,7 @@ +mod gfx; +mod input; +mod touch; + +pub use gfx::Gfx; +pub use input::Input; +pub use touch::Touch; diff --git a/crates/core/src/peripherals/touch.rs b/crates/core/src/peripherals/touch.rs new file mode 100644 index 00000000..1e2658f2 --- /dev/null +++ b/crates/core/src/peripherals/touch.rs @@ -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, +}