pr 00.3
This commit is contained in:
parent
d6bbef06a5
commit
eb3156dd8c
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -1920,6 +1920,7 @@ dependencies = [
|
|||||||
"prometeu-abi",
|
"prometeu-abi",
|
||||||
"prometeu-bytecode",
|
"prometeu-bytecode",
|
||||||
"prometeu-hardware-contract",
|
"prometeu-hardware-contract",
|
||||||
|
"prometeu-kernel",
|
||||||
"prometeu-vm",
|
"prometeu-vm",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -1936,6 +1937,19 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prometeu-kernel"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"prometeu-abi",
|
||||||
|
"prometeu-bytecode",
|
||||||
|
"prometeu-core",
|
||||||
|
"prometeu-hardware-contract",
|
||||||
|
"prometeu-vm",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometeu-lsp"
|
name = "prometeu-lsp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
members = [
|
members = [
|
||||||
"crates/prometeu-abi",
|
"crates/prometeu-abi",
|
||||||
"crates/prometeu-vm",
|
"crates/prometeu-vm",
|
||||||
|
"crates/prometeu-kernel",
|
||||||
"crates/prometeu-core",
|
"crates/prometeu-core",
|
||||||
"crates/prometeu-runtime-desktop",
|
"crates/prometeu-runtime-desktop",
|
||||||
"crates/prometeu",
|
"crates/prometeu",
|
||||||
|
|||||||
@ -8,6 +8,7 @@ license.workspace = true
|
|||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
prometeu-vm = { path = "../prometeu-vm" }
|
prometeu-vm = { path = "../prometeu-vm" }
|
||||||
|
prometeu-kernel = { path = "../prometeu-kernel" }
|
||||||
prometeu-bytecode = { path = "../prometeu-bytecode" }
|
prometeu-bytecode = { path = "../prometeu-bytecode" }
|
||||||
prometeu-abi = { path = "../prometeu-abi" }
|
prometeu-abi = { path = "../prometeu-abi" }
|
||||||
prometeu-hardware-contract = { path = "../prometeu-hardware-contract" }
|
prometeu-hardware-contract = { path = "../prometeu-hardware-contract" }
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use std::collections::HashMap;
|
|||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
use prometeu_hardware_contract::AssetBridge;
|
||||||
|
|
||||||
/// Resident metadata for a decoded/materialized asset inside a BankPolicy.
|
/// Resident metadata for a decoded/materialized asset inside a BankPolicy.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -93,19 +94,6 @@ impl<T> BankPolicy<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AssetBridge {
|
|
||||||
fn initialize_for_cartridge(&self, assets: Vec<AssetEntry>, preload: Vec<PreloadEntry>, assets_data: Vec<u8>);
|
|
||||||
fn load(&self, asset_name: &str, slot: SlotRef) -> Result<HandleId, String>;
|
|
||||||
fn status(&self, handle: HandleId) -> LoadStatus;
|
|
||||||
fn commit(&self, handle: HandleId);
|
|
||||||
fn cancel(&self, handle: HandleId);
|
|
||||||
fn apply_commits(&self);
|
|
||||||
fn bank_info(&self, kind: BankType) -> BankStats;
|
|
||||||
fn slot_info(&self, slot: SlotRef) -> SlotStats;
|
|
||||||
fn find_slot_by_name(&self, asset_name: &str, kind: BankType) -> Option<u8>;
|
|
||||||
fn shutdown(&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AssetManager {
|
pub struct AssetManager {
|
||||||
assets: Arc<RwLock<HashMap<u32, AssetEntry>>>,
|
assets: Arc<RwLock<HashMap<u32, AssetEntry>>>,
|
||||||
name_to_id: Arc<RwLock<HashMap<String, u32>>>,
|
name_to_id: Arc<RwLock<HashMap<String, u32>>>,
|
||||||
@ -136,7 +124,7 @@ struct LoadHandleInfo {
|
|||||||
status: LoadStatus,
|
status: LoadStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl prometeu_hardware_contract::AssetBridge for AssetManager {
|
impl AssetBridge for AssetManager {
|
||||||
fn initialize_for_cartridge(&self, assets: Vec<AssetEntry>, preload: Vec<PreloadEntry>, assets_data: Vec<u8>) { self.initialize_for_cartridge(assets, preload, assets_data) }
|
fn initialize_for_cartridge(&self, assets: Vec<AssetEntry>, preload: Vec<PreloadEntry>, assets_data: Vec<u8>) { self.initialize_for_cartridge(assets, preload, assets_data) }
|
||||||
fn load(&self, asset_name: &str, slot: SlotRef) -> Result<HandleId, String> { self.load(asset_name, slot) }
|
fn load(&self, asset_name: &str, slot: SlotRef) -> Result<HandleId, String> { self.load(asset_name, slot) }
|
||||||
fn status(&self, handle: HandleId) -> LoadStatus { self.status(handle) }
|
fn status(&self, handle: HandleId) -> LoadStatus { self.status(handle) }
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::hardware::memory_banks::SoundBankPoolAccess;
|
use crate::hardware::memory_banks::SoundBankPoolAccess;
|
||||||
use crate::model::Sample;
|
use crate::model::Sample;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use prometeu_hardware_contract::AudioBridge;
|
||||||
|
|
||||||
/// Maximum number of simultaneous audio voices supported by the hardware.
|
/// Maximum number of simultaneous audio voices supported by the hardware.
|
||||||
pub const MAX_CHANNELS: usize = 16;
|
pub const MAX_CHANNELS: usize = 16;
|
||||||
@ -101,17 +102,6 @@ pub enum AudioCommand {
|
|||||||
/// - **16 Simultaneous Voices**: Independent volume, pan, and pitch.
|
/// - **16 Simultaneous Voices**: Independent volume, pan, and pitch.
|
||||||
/// - **Sample-based Synthesis**: Plays PCM data stored in SoundBanks.
|
/// - **Sample-based Synthesis**: Plays PCM data stored in SoundBanks.
|
||||||
/// - **Stereo Output**: 48kHz output target.
|
/// - **Stereo Output**: 48kHz output target.
|
||||||
pub trait AudioBridge {
|
|
||||||
fn play(&mut self, bank_id: u8, sample_id: u16, voice_id: usize, volume: u8, pan: u8, pitch: f64, priority: u8, loop_mode: LoopMode) -> ();
|
|
||||||
fn play_sample(&mut self, sample: Arc<Sample>, voice_id: usize, volume: u8, pan: u8, pitch: f64, priority: u8, loop_mode: LoopMode) -> ();
|
|
||||||
fn stop(&mut self, voice_id: usize) -> ();
|
|
||||||
fn set_volume(&mut self, voice_id: usize, volume: u8) -> ();
|
|
||||||
fn set_pan(&mut self, voice_id: usize, pan: u8) -> ();
|
|
||||||
fn set_pitch(&mut self, voice_id: usize, pitch: f64) -> ();
|
|
||||||
fn is_playing(&self, voice_id: usize) -> bool;
|
|
||||||
fn clear_commands(&mut self) -> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Audio {
|
pub struct Audio {
|
||||||
/// Local state of the hardware voices. This state is used for logic
|
/// Local state of the hardware voices. This state is used for logic
|
||||||
/// (e.g., checking if a sound is still playing) and is synchronized with the Host.
|
/// (e.g., checking if a sound is still playing) and is synchronized with the Host.
|
||||||
@ -123,7 +113,7 @@ pub struct Audio {
|
|||||||
pub sound_banks: Arc<dyn SoundBankPoolAccess>,
|
pub sound_banks: Arc<dyn SoundBankPoolAccess>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl prometeu_hardware_contract::AudioBridge for Audio {
|
impl AudioBridge for Audio {
|
||||||
fn play(&mut self, bank_id: u8, sample_id: u16, voice_id: usize, volume: u8, pan: u8, pitch: f64, priority: u8, loop_mode: prometeu_hardware_contract::LoopMode) {
|
fn play(&mut self, bank_id: u8, sample_id: u16, voice_id: usize, volume: u8, pan: u8, pitch: f64, priority: u8, loop_mode: prometeu_hardware_contract::LoopMode) {
|
||||||
let lm = match loop_mode { prometeu_hardware_contract::LoopMode::Off => LoopMode::Off, prometeu_hardware_contract::LoopMode::On => LoopMode::On };
|
let lm = match loop_mode { prometeu_hardware_contract::LoopMode::Off => LoopMode::Off, prometeu_hardware_contract::LoopMode::On => LoopMode::On };
|
||||||
self.play(bank_id, sample_id, voice_id, volume, pan, pitch, priority, lm)
|
self.play(bank_id, sample_id, voice_id, volume, pan, pitch, priority, lm)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::hardware::memory_banks::TileBankPoolAccess;
|
use crate::hardware::memory_banks::TileBankPoolAccess;
|
||||||
use crate::model::{Color, HudTileLayer, ScrollableTileLayer, Sprite, TileBank, TileMap, TileSize};
|
use crate::model::{Color, HudTileLayer, ScrollableTileLayer, Sprite, TileBank, TileMap, TileSize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use prometeu_hardware_contract::GfxBridge;
|
||||||
|
|
||||||
/// Blending modes inspired by classic 16-bit hardware.
|
/// Blending modes inspired by classic 16-bit hardware.
|
||||||
/// Defines how source pixels are combined with existing pixels in the framebuffer.
|
/// Defines how source pixels are combined with existing pixels in the framebuffer.
|
||||||
@ -41,47 +42,6 @@ pub enum BlendMode {
|
|||||||
/// 6. **Scene Fade**: Global brightness/color filter.
|
/// 6. **Scene Fade**: Global brightness/color filter.
|
||||||
/// 7. **HUD Layer**: Fixed UI elements (always on top).
|
/// 7. **HUD Layer**: Fixed UI elements (always on top).
|
||||||
/// 8. **HUD Fade**: Independent fade for the UI.
|
/// 8. **HUD Fade**: Independent fade for the UI.
|
||||||
pub trait GfxBridge {
|
|
||||||
fn size(&self) -> (usize, usize);
|
|
||||||
fn front_buffer(&self) -> &[u16];
|
|
||||||
fn clear(&mut self, color: Color) -> ();
|
|
||||||
fn fill_rect_blend(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color, mode: BlendMode) -> ();
|
|
||||||
fn fill_rect(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color) -> ();
|
|
||||||
fn draw_pixel(&mut self, x: i32, y: i32, color: Color) -> ();
|
|
||||||
fn draw_line(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: Color) -> ();
|
|
||||||
fn draw_circle(&mut self, xc: i32, yc: i32, r: i32, color: Color) -> ();
|
|
||||||
fn draw_circle_points(&mut self, xc: i32, yc: i32, x: i32, y: i32, color: Color) -> ();
|
|
||||||
fn fill_circle(&mut self, xc: i32, yc: i32, r: i32, color: Color) -> ();
|
|
||||||
fn draw_circle_lines(&mut self, xc: i32, yc: i32, x: i32, y: i32, color: Color) -> ();
|
|
||||||
fn draw_disc(&mut self, x: i32, y: i32, r: i32, border_color: Color, fill_color: Color) -> ();
|
|
||||||
fn draw_rect(&mut self, x: i32, y: i32, w: i32, h: i32, color: Color) -> ();
|
|
||||||
fn draw_square(&mut self, x: i32, y: i32, w: i32, h: i32, border_color: Color, fill_color: Color) -> ();
|
|
||||||
fn draw_horizontal_line(&mut self, x0: i32, x1: i32, y: i32, color: Color) -> ();
|
|
||||||
fn draw_vertical_line(&mut self, x: i32, y0: i32, y1: i32, color: Color) -> ();
|
|
||||||
fn present(&mut self) -> ();
|
|
||||||
fn render_all(&mut self) -> ();
|
|
||||||
fn render_layer(&mut self, layer_idx: usize) -> ();
|
|
||||||
fn render_hud(&mut self) -> ();
|
|
||||||
fn draw_text(&mut self, x: i32, y: i32, text: &str, color: Color) -> ();
|
|
||||||
fn draw_char(&mut self, x: i32, y: i32, c: char, color: Color) -> ();
|
|
||||||
|
|
||||||
fn layer(&self, index: usize) -> &ScrollableTileLayer;
|
|
||||||
fn layer_mut(&mut self, index: usize) -> &mut ScrollableTileLayer;
|
|
||||||
fn hud(&self) -> &HudTileLayer;
|
|
||||||
fn hud_mut(&mut self) -> &mut HudTileLayer;
|
|
||||||
fn sprite(&self, index: usize) -> &Sprite;
|
|
||||||
fn sprite_mut(&mut self, index: usize) -> &mut Sprite;
|
|
||||||
|
|
||||||
fn scene_fade_level(&self) -> u8;
|
|
||||||
fn set_scene_fade_level(&mut self, level: u8);
|
|
||||||
fn scene_fade_color(&self) -> Color;
|
|
||||||
fn set_scene_fade_color(&mut self, color: Color);
|
|
||||||
fn hud_fade_level(&self) -> u8;
|
|
||||||
fn set_hud_fade_level(&mut self, level: u8);
|
|
||||||
fn hud_fade_color(&self) -> Color;
|
|
||||||
fn set_hud_fade_color(&mut self, color: Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Gfx {
|
pub struct Gfx {
|
||||||
/// Width of the internal framebuffer in pixels.
|
/// Width of the internal framebuffer in pixels.
|
||||||
w: usize,
|
w: usize,
|
||||||
@ -114,7 +74,7 @@ pub struct Gfx {
|
|||||||
priority_buckets: [Vec<usize>; 5],
|
priority_buckets: [Vec<usize>; 5],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl prometeu_hardware_contract::GfxBridge for Gfx {
|
impl GfxBridge for Gfx {
|
||||||
fn size(&self) -> (usize, usize) { self.size() }
|
fn size(&self) -> (usize, usize) { self.size() }
|
||||||
fn front_buffer(&self) -> &[u16] { self.front_buffer() }
|
fn front_buffer(&self) -> &[u16] { self.front_buffer() }
|
||||||
fn clear(&mut self, color: Color) { self.clear(color) }
|
fn clear(&mut self, color: Color) { self.clear(color) }
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
#[derive(Default, Clone, Copy, Debug)]
|
|
||||||
pub struct InputSignals {
|
|
||||||
// PAD
|
|
||||||
pub up_signal: bool,
|
|
||||||
pub down_signal: bool,
|
|
||||||
pub left_signal: bool,
|
|
||||||
pub right_signal: bool,
|
|
||||||
|
|
||||||
pub a_signal: bool,
|
|
||||||
pub b_signal: bool,
|
|
||||||
pub x_signal: bool,
|
|
||||||
pub y_signal: bool,
|
|
||||||
pub l_signal: bool,
|
|
||||||
pub r_signal: bool,
|
|
||||||
|
|
||||||
pub start_signal: bool,
|
|
||||||
pub select_signal: bool,
|
|
||||||
|
|
||||||
// TOUCH
|
|
||||||
pub f_signal: bool,
|
|
||||||
pub x_pos: i32,
|
|
||||||
pub y_pos: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputSignals {
|
|
||||||
}
|
|
||||||
@ -1,24 +1,7 @@
|
|||||||
|
use prometeu_hardware_contract::PadBridge;
|
||||||
use crate::hardware::InputSignals;
|
use crate::hardware::InputSignals;
|
||||||
use crate::model::Button;
|
use crate::model::Button;
|
||||||
|
|
||||||
pub trait PadBridge {
|
|
||||||
fn begin_frame(&mut self, signals: &InputSignals);
|
|
||||||
fn any(&self) -> bool;
|
|
||||||
|
|
||||||
fn up(&self) -> &Button;
|
|
||||||
fn down(&self) -> &Button;
|
|
||||||
fn left(&self) -> &Button;
|
|
||||||
fn right(&self) -> &Button;
|
|
||||||
fn a(&self) -> &Button;
|
|
||||||
fn b(&self) -> &Button;
|
|
||||||
fn x(&self) -> &Button;
|
|
||||||
fn y(&self) -> &Button;
|
|
||||||
fn l(&self) -> &Button;
|
|
||||||
fn r(&self) -> &Button;
|
|
||||||
fn start(&self) -> &Button;
|
|
||||||
fn select(&self) -> &Button;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, Debug)]
|
#[derive(Default, Clone, Copy, Debug)]
|
||||||
pub struct Pad {
|
pub struct Pad {
|
||||||
pub up: Button,
|
pub up: Button,
|
||||||
@ -37,7 +20,7 @@ pub struct Pad {
|
|||||||
pub select: Button,
|
pub select: Button,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl prometeu_hardware_contract::PadBridge for Pad {
|
impl PadBridge for Pad {
|
||||||
fn begin_frame(&mut self, signals: &InputSignals) { self.begin_frame(signals) }
|
fn begin_frame(&mut self, signals: &InputSignals) { self.begin_frame(signals) }
|
||||||
fn any(&self) -> bool { self.any() }
|
fn any(&self) -> bool { self.any() }
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,7 @@
|
|||||||
|
use prometeu_hardware_contract::TouchBridge;
|
||||||
use crate::hardware::InputSignals;
|
use crate::hardware::InputSignals;
|
||||||
use crate::model::Button;
|
use crate::model::Button;
|
||||||
|
|
||||||
pub trait TouchBridge {
|
|
||||||
fn begin_frame(&mut self, signals: &InputSignals);
|
|
||||||
fn f(&self) -> &Button;
|
|
||||||
fn x(&self) -> i32;
|
|
||||||
fn y(&self) -> i32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, Debug)]
|
#[derive(Default, Clone, Copy, Debug)]
|
||||||
pub struct Touch {
|
pub struct Touch {
|
||||||
pub f: Button,
|
pub f: Button,
|
||||||
@ -15,7 +9,7 @@ pub struct Touch {
|
|||||||
pub y: i32,
|
pub y: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl prometeu_hardware_contract::TouchBridge for Touch {
|
impl TouchBridge for Touch {
|
||||||
fn begin_frame(&mut self, signals: &InputSignals) { self.begin_frame(signals) }
|
fn begin_frame(&mut self, signals: &InputSignals) { self.begin_frame(signals) }
|
||||||
fn f(&self) -> &Button { &self.f }
|
fn f(&self) -> &Button { &self.f }
|
||||||
fn x(&self) -> i32 { self.x }
|
fn x(&self) -> i32 { self.x }
|
||||||
|
|||||||
@ -17,10 +17,18 @@
|
|||||||
|
|
||||||
pub mod hardware;
|
pub mod hardware;
|
||||||
pub mod firmware;
|
pub mod firmware;
|
||||||
pub mod fs;
|
// pub mod fs;
|
||||||
pub mod prometeu_os;
|
// pub mod prometeu_os;
|
||||||
mod prometeu_hub;
|
mod prometeu_hub;
|
||||||
|
|
||||||
|
pub mod fs {
|
||||||
|
pub use prometeu_kernel::fs::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod prometeu_os {
|
||||||
|
pub use prometeu_kernel::*;
|
||||||
|
}
|
||||||
|
|
||||||
// Facade/reexports for ABI modules (temporary during PR-00.x)
|
// Facade/reexports for ABI modules (temporary during PR-00.x)
|
||||||
pub use prometeu_abi as abi;
|
pub use prometeu_abi as abi;
|
||||||
pub use prometeu_abi::debugger_protocol;
|
pub use prometeu_abi::debugger_protocol;
|
||||||
|
|||||||
16
crates/prometeu-kernel/Cargo.toml
Normal file
16
crates/prometeu-kernel/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "prometeu-kernel"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
|
serde_json = "1.0.149"
|
||||||
|
prometeu-vm = { path = "../prometeu-vm" }
|
||||||
|
prometeu-bytecode = { path = "../prometeu-bytecode" }
|
||||||
|
prometeu-abi = { path = "../prometeu-abi" }
|
||||||
|
prometeu-hardware-contract = { path = "../prometeu-hardware-contract" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
prometeu-core = { path = "../prometeu-core" }
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
pub mod fs;
|
||||||
mod prometeu_os;
|
mod prometeu_os;
|
||||||
|
|
||||||
pub use prometeu_os::PrometeuOS;
|
pub use prometeu_os::PrometeuOS;
|
||||||
@ -1,9 +1,9 @@
|
|||||||
use crate::abi::syscalls::Syscall;
|
use prometeu_abi::syscalls::Syscall;
|
||||||
use crate::fs::{FsBackend, FsState, VirtualFS};
|
use crate::fs::{FsBackend, FsState, VirtualFS};
|
||||||
use crate::hardware::{HardwareBridge, InputSignals};
|
use prometeu_hardware_contract::{HardwareBridge, InputSignals};
|
||||||
use crate::log::{LogLevel, LogService, LogSource};
|
use prometeu_abi::log::{LogLevel, LogService, LogSource};
|
||||||
use crate::model::{BankType, Cartridge, Color};
|
use prometeu_abi::model::{BankType, Cartridge, Color};
|
||||||
use crate::telemetry::{CertificationConfig, Certifier, TelemetryFrame};
|
use prometeu_abi::telemetry::{CertificationConfig, Certifier, TelemetryFrame};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use prometeu_abi::virtual_machine::{Value, VmFault};
|
use prometeu_abi::virtual_machine::{Value, VmFault};
|
||||||
@ -51,7 +51,7 @@ pub struct PrometeuOS {
|
|||||||
pub current_app_id: u32,
|
pub current_app_id: u32,
|
||||||
pub current_cartridge_title: String,
|
pub current_cartridge_title: String,
|
||||||
pub current_cartridge_app_version: String,
|
pub current_cartridge_app_version: String,
|
||||||
pub current_cartridge_app_mode: crate::model::AppMode,
|
pub current_cartridge_app_mode: prometeu_abi::model::AppMode,
|
||||||
pub current_entrypoint: String,
|
pub current_entrypoint: String,
|
||||||
/// Rate-limiter to prevent apps from flooding the log buffer and killing performance.
|
/// Rate-limiter to prevent apps from flooding the log buffer and killing performance.
|
||||||
pub logs_written_this_frame: HashMap<u32, u32>,
|
pub logs_written_this_frame: HashMap<u32, u32>,
|
||||||
@ -101,7 +101,7 @@ impl PrometeuOS {
|
|||||||
current_app_id: 0,
|
current_app_id: 0,
|
||||||
current_cartridge_title: String::new(),
|
current_cartridge_title: String::new(),
|
||||||
current_cartridge_app_version: String::new(),
|
current_cartridge_app_version: String::new(),
|
||||||
current_cartridge_app_mode: crate::model::AppMode::Game,
|
current_cartridge_app_mode: prometeu_abi::model::AppMode::Game,
|
||||||
current_entrypoint: String::new(),
|
current_entrypoint: String::new(),
|
||||||
logs_written_this_frame: HashMap::new(),
|
logs_written_this_frame: HashMap::new(),
|
||||||
telemetry_current: TelemetryFrame::default(),
|
telemetry_current: TelemetryFrame::default(),
|
||||||
@ -375,7 +375,7 @@ impl PrometeuOS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper para syscalls
|
// Helper para syscalls
|
||||||
pub fn get_button<'a>(&self, id: u32, hw: &'a dyn HardwareBridge) -> Option<&'a crate::model::Button> {
|
pub fn get_button<'a>(&self, id: u32, hw: &'a dyn HardwareBridge) -> Option<&'a prometeu_abi::model::Button> {
|
||||||
let pad = hw.pad();
|
let pad = hw.pad();
|
||||||
match id {
|
match id {
|
||||||
0 => Some(pad.up()),
|
0 => Some(pad.up()),
|
||||||
@ -416,11 +416,10 @@ impl PrometeuOS {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use prometeu_abi::virtual_machine::Value;
|
use prometeu_abi::virtual_machine::Value;
|
||||||
use prometeu_hardware_contract::HostReturn;
|
use prometeu_hardware_contract::{HostReturn, InputSignals};
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::hardware::InputSignals;
|
use prometeu_abi::model::{AppMode, Cartridge};
|
||||||
use crate::model::{AppMode, Cartridge};
|
use prometeu_core::Hardware;
|
||||||
use crate::Hardware;
|
|
||||||
|
|
||||||
fn call_syscall(os: &mut PrometeuOS, id: u32, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Result<(), VmFault> {
|
fn call_syscall(os: &mut PrometeuOS, id: u32, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Result<(), VmFault> {
|
||||||
let args_count = Syscall::from_u32(id).expect(&format!("Invalid syscall id: 0x{:08X}", id)).args_count();
|
let args_count = Syscall::from_u32(id).expect(&format!("Invalid syscall id: 0x{:08X}", id)).args_count();
|
||||||
@ -756,7 +755,7 @@ mod tests {
|
|||||||
fn test_os_unknown_syscall_returns_trap() {
|
fn test_os_unknown_syscall_returns_trap() {
|
||||||
let mut os = PrometeuOS::new(None);
|
let mut os = PrometeuOS::new(None);
|
||||||
let mut vm = VirtualMachine::default();
|
let mut vm = VirtualMachine::default();
|
||||||
let mut hw = crate::Hardware::new();
|
let mut hw = Hardware::new();
|
||||||
let mut ret = HostReturn::new(&mut vm.operand_stack);
|
let mut ret = HostReturn::new(&mut vm.operand_stack);
|
||||||
|
|
||||||
let res = os.syscall(0xDEADBEEF, &[], &mut ret, &mut HostContext::new(Some(&mut hw)));
|
let res = os.syscall(0xDEADBEEF, &[], &mut ret, &mut HostContext::new(Some(&mut hw)));
|
||||||
@ -959,11 +958,11 @@ impl NativeInterface for PrometeuOS {
|
|||||||
let flip_y = expect_bool(args, 8)?;
|
let flip_y = expect_bool(args, 8)?;
|
||||||
let priority = expect_int(args, 9)? as u8;
|
let priority = expect_int(args, 9)? as u8;
|
||||||
|
|
||||||
let bank_id = hw.assets().find_slot_by_name(&asset_name, crate::model::BankType::TILES).unwrap_or(0);
|
let bank_id = hw.assets().find_slot_by_name(&asset_name, prometeu_abi::model::BankType::TILES).unwrap_or(0);
|
||||||
|
|
||||||
if index < 512 {
|
if index < 512 {
|
||||||
*hw.gfx_mut().sprite_mut(index) = crate::model::Sprite {
|
*hw.gfx_mut().sprite_mut(index) = prometeu_abi::model::Sprite {
|
||||||
tile: crate::model::Tile { id: tile_id, flip_x: false, flip_y: false, palette_id },
|
tile: prometeu_abi::model::Tile { id: tile_id, flip_x: false, flip_y: false, palette_id },
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
bank_id,
|
bank_id,
|
||||||
@ -1094,7 +1093,7 @@ impl NativeInterface for PrometeuOS {
|
|||||||
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Expected number for pitch".into())),
|
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Expected number for pitch".into())),
|
||||||
};
|
};
|
||||||
|
|
||||||
hw.audio_mut().play(0, sample_id as u16, voice_id, volume, pan, pitch, 0, crate::hardware::LoopMode::Off);
|
hw.audio_mut().play(0, sample_id as u16, voice_id, volume, pan, pitch, 0, prometeu_hardware_contract::LoopMode::Off);
|
||||||
ret.push_null();
|
ret.push_null();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1117,11 +1116,11 @@ impl NativeInterface for PrometeuOS {
|
|||||||
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Expected number for pitch".into())),
|
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Expected number for pitch".into())),
|
||||||
};
|
};
|
||||||
let loop_mode = match expect_int(args, 6)? {
|
let loop_mode = match expect_int(args, 6)? {
|
||||||
0 => crate::hardware::LoopMode::Off,
|
0 => prometeu_hardware_contract::LoopMode::Off,
|
||||||
_ => crate::hardware::LoopMode::On,
|
_ => prometeu_hardware_contract::LoopMode::On,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bank_id = hw.assets().find_slot_by_name(&asset_name, crate::model::BankType::SOUNDS).unwrap_or(0);
|
let bank_id = hw.assets().find_slot_by_name(&asset_name, prometeu_abi::model::BankType::SOUNDS).unwrap_or(0);
|
||||||
|
|
||||||
hw.audio_mut().play(bank_id, sample_id, voice_id, volume, pan, pitch, 0, loop_mode);
|
hw.audio_mut().play(bank_id, sample_id, voice_id, volume, pan, pitch, 0, loop_mode);
|
||||||
ret.push_null();
|
ret.push_null();
|
||||||
@ -1253,11 +1252,11 @@ impl NativeInterface for PrometeuOS {
|
|||||||
let slot_index = expect_int(args, 2)? as usize;
|
let slot_index = expect_int(args, 2)? as usize;
|
||||||
|
|
||||||
let asset_type = match asset_type_val {
|
let asset_type = match asset_type_val {
|
||||||
0 => crate::model::BankType::TILES,
|
0 => prometeu_abi::model::BankType::TILES,
|
||||||
1 => crate::model::BankType::SOUNDS,
|
1 => prometeu_abi::model::BankType::SOUNDS,
|
||||||
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Invalid asset type".to_string())),
|
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Invalid asset type".to_string())),
|
||||||
};
|
};
|
||||||
let slot = crate::model::SlotRef { asset_type, index: slot_index };
|
let slot = prometeu_abi::model::SlotRef { asset_type, index: slot_index };
|
||||||
|
|
||||||
match hw.assets().load(&asset_id, slot) {
|
match hw.assets().load(&asset_id, slot) {
|
||||||
Ok(handle) => {
|
Ok(handle) => {
|
||||||
@ -1271,12 +1270,12 @@ impl NativeInterface for PrometeuOS {
|
|||||||
let handle = expect_int(args, 0)? as u32;
|
let handle = expect_int(args, 0)? as u32;
|
||||||
let status = hw.assets().status(handle);
|
let status = hw.assets().status(handle);
|
||||||
let status_val = match status {
|
let status_val = match status {
|
||||||
crate::model::LoadStatus::PENDING => 0,
|
prometeu_abi::model::LoadStatus::PENDING => 0,
|
||||||
crate::model::LoadStatus::LOADING => 1,
|
prometeu_abi::model::LoadStatus::LOADING => 1,
|
||||||
crate::model::LoadStatus::READY => 2,
|
prometeu_abi::model::LoadStatus::READY => 2,
|
||||||
crate::model::LoadStatus::COMMITTED => 3,
|
prometeu_abi::model::LoadStatus::COMMITTED => 3,
|
||||||
crate::model::LoadStatus::CANCELED => 4,
|
prometeu_abi::model::LoadStatus::CANCELED => 4,
|
||||||
crate::model::LoadStatus::ERROR => 5,
|
prometeu_abi::model::LoadStatus::ERROR => 5,
|
||||||
};
|
};
|
||||||
ret.push_int(status_val);
|
ret.push_int(status_val);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1296,8 +1295,8 @@ impl NativeInterface for PrometeuOS {
|
|||||||
Syscall::BankInfo => {
|
Syscall::BankInfo => {
|
||||||
let asset_type_val = expect_int(args, 0)? as u32;
|
let asset_type_val = expect_int(args, 0)? as u32;
|
||||||
let asset_type = match asset_type_val {
|
let asset_type = match asset_type_val {
|
||||||
0 => crate::model::BankType::TILES,
|
0 => prometeu_abi::model::BankType::TILES,
|
||||||
1 => crate::model::BankType::SOUNDS,
|
1 => prometeu_abi::model::BankType::SOUNDS,
|
||||||
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Invalid asset type".to_string())),
|
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Invalid asset type".to_string())),
|
||||||
};
|
};
|
||||||
let info = hw.assets().bank_info(asset_type);
|
let info = hw.assets().bank_info(asset_type);
|
||||||
@ -1309,11 +1308,11 @@ impl NativeInterface for PrometeuOS {
|
|||||||
let asset_type_val = expect_int(args, 0)? as u32;
|
let asset_type_val = expect_int(args, 0)? as u32;
|
||||||
let slot_index = expect_int(args, 1)? as usize;
|
let slot_index = expect_int(args, 1)? as usize;
|
||||||
let asset_type = match asset_type_val {
|
let asset_type = match asset_type_val {
|
||||||
0 => crate::model::BankType::TILES,
|
0 => prometeu_abi::model::BankType::TILES,
|
||||||
1 => crate::model::BankType::SOUNDS,
|
1 => prometeu_abi::model::BankType::SOUNDS,
|
||||||
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Invalid asset type".to_string())),
|
_ => return Err(VmFault::Trap(prometeu_bytecode::abi::TRAP_TYPE, "Invalid asset type".to_string())),
|
||||||
};
|
};
|
||||||
let slot = crate::model::SlotRef { asset_type, index: slot_index };
|
let slot = prometeu_abi::model::SlotRef { asset_type, index: slot_index };
|
||||||
let info = hw.assets().slot_info(slot);
|
let info = hw.assets().slot_info(slot);
|
||||||
let json = serde_json::to_string(&info).unwrap_or_default();
|
let json = serde_json::to_string(&info).unwrap_or_default();
|
||||||
ret.push_string(json);
|
ret.push_string(json);
|
||||||
@ -405,30 +405,6 @@ pub struct AnalysisDb {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## PR-00.2 — Extrair `prometeu-vm` do `prometeu-core`
|
|
||||||
|
|
||||||
**Branch:** `pr-00-2-prometeu-vm`
|
|
||||||
|
|
||||||
### Objetivo
|
|
||||||
|
|
||||||
Mover `virtual_machine/*` para `crates/prometeu-vm/`.
|
|
||||||
|
|
||||||
### Passos prescritivos
|
|
||||||
|
|
||||||
1. Criar crate `crates/prometeu-vm/`.
|
|
||||||
2. Mover `crates/prometeu-core/src/virtual_machine/**` → `crates/prometeu-vm/src/**`.
|
|
||||||
3. Ajustar `use` paths em todos os crates.
|
|
||||||
4. Adicionar shim temporário no `prometeu-core` (se ainda existir):
|
|
||||||
|
|
||||||
* `pub mod virtual_machine { pub use prometeu_vm::*; }`
|
|
||||||
|
|
||||||
### Critérios de aceite
|
|
||||||
|
|
||||||
* `cargo test` verde.
|
|
||||||
* runtime desktop ainda roda.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PR-00.3 — Extrair `prometeu-kernel` (OS + FS + syscalls)
|
## PR-00.3 — Extrair `prometeu-kernel` (OS + FS + syscalls)
|
||||||
|
|
||||||
**Branch:** `pr-00-3-prometeu-kernel`
|
**Branch:** `pr-00-3-prometeu-kernel`
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user