From 1d6b799960f407c6dd260341857b4da320b0484a Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Mon, 15 Jun 2026 05:59:06 +0100 Subject: [PATCH] implements PLN-0105 --- .../src/firmware/firmware.rs | 34 +++++++------- .../firmware/firmware_step_crash_screen.rs | 12 +++-- .../firmware/firmware_step_game_running.rs | 2 +- .../src/firmware/firmware_step_hub_home.rs | 2 +- .../firmware/firmware_step_load_cartridge.rs | 2 +- .../firmware/firmware_step_shell_running.rs | 2 +- .../firmware/firmware_step_splash_screen.rs | 16 +++---- .../src/firmware/prometeu_context.rs | 4 +- crates/console/prometeu-hal/src/platform.rs | 4 ++ .../prometeu-system/src/os/facades/vm.rs | 6 +-- .../src/programs/prometeu_hub/prometeu_hub.rs | 44 +++++++++++-------- .../src/services/vm_runtime/tick.rs | 12 +++-- 12 files changed, 73 insertions(+), 67 deletions(-) diff --git a/crates/console/prometeu-firmware/src/firmware/firmware.rs b/crates/console/prometeu-firmware/src/firmware/firmware.rs index f7e4a1c8..d18531aa 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware.rs @@ -3,7 +3,7 @@ use crate::firmware::firmware_state::{FirmwareState, LoadCartridgeStep, ResetSte use crate::firmware::prometeu_context::PrometeuContext; use prometeu_hal::cartridge::Cartridge; use prometeu_hal::telemetry::CertificationConfig; -use prometeu_hal::{HardwareBridge, InputSignals}; +use prometeu_hal::{InputSignals, RuntimePlatform}; use prometeu_system::{PrometeuHub, SystemOS}; use prometeu_vm::VirtualMachine; @@ -54,24 +54,24 @@ impl Firmware { /// /// This method is called exactly once per Host frame (60Hz). /// It updates peripheral signals and delegates the logic to the current state. - pub fn tick(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) { + pub fn tick(&mut self, signals: &InputSignals, platform: &mut dyn RuntimePlatform) { // 0. Process asset commits at the beginning of the frame boundary. - hw.assets_mut().apply_commits(); + platform.assets_mut().apply_commits(); // 1. Update the peripheral state using the latest signals from the Host. // This ensures input is consistent throughout the entire update. - hw.pad_mut().begin_frame(signals); - hw.touch_mut().begin_frame(signals); + platform.input_mut().pad_mut().begin_frame(signals); + platform.input_mut().touch_mut().begin_frame(signals); // 2. State machine lifecycle management. if !self.state_initialized { - self.on_enter(signals, hw); + self.on_enter(signals, platform); self.state_initialized = true; } // 3. Update the current state and check for transitions. - if let Some(next_state) = self.on_update(signals, hw) { - self.change_state(next_state, signals, hw); + if let Some(next_state) = self.on_update(signals, platform) { + self.change_state(next_state, signals, platform); } } @@ -80,26 +80,26 @@ impl Firmware { &mut self, new_state: FirmwareState, signals: &InputSignals, - hw: &mut dyn HardwareBridge, + platform: &mut dyn RuntimePlatform, ) { - self.on_exit(signals, hw); + self.on_exit(signals, platform); self.state = new_state; self.state_initialized = false; // Enter the new state immediately to avoid "empty" frames during transitions. - self.on_enter(signals, hw); + self.on_enter(signals, platform); self.state_initialized = true; } /// Dispatches the `on_enter` event to the current state implementation. - fn on_enter(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) { + fn on_enter(&mut self, signals: &InputSignals, platform: &mut dyn RuntimePlatform) { let mut req = PrometeuContext { vm: &mut self.vm, os: &mut self.os, hub: &mut self.hub, boot_target: &self.boot_target, signals, - hw, + platform, }; match &mut self.state { FirmwareState::Reset(s) => s.on_enter(&mut req), @@ -118,7 +118,7 @@ impl Firmware { fn on_update( &mut self, signals: &InputSignals, - hw: &mut dyn HardwareBridge, + platform: &mut dyn RuntimePlatform, ) -> Option { let mut req = PrometeuContext { vm: &mut self.vm, @@ -126,7 +126,7 @@ impl Firmware { hub: &mut self.hub, boot_target: &self.boot_target, signals, - hw, + platform, }; match &mut self.state { FirmwareState::Reset(s) => s.on_update(&mut req), @@ -141,14 +141,14 @@ impl Firmware { } /// Dispatches the `on_exit` event to the current state implementation. - fn on_exit(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) { + fn on_exit(&mut self, signals: &InputSignals, platform: &mut dyn RuntimePlatform) { let mut req = PrometeuContext { vm: &mut self.vm, os: &mut self.os, hub: &mut self.hub, boot_target: &self.boot_target, signals, - hw, + platform, }; match &mut self.state { FirmwareState::Reset(s) => s.on_exit(&mut req), diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_crash_screen.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_crash_screen.rs index 7bbf14ac..be2f6d21 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_crash_screen.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_crash_screen.rs @@ -2,10 +2,7 @@ use crate::firmware::firmware_state::{FirmwareState, LaunchHubStep}; use crate::firmware::prometeu_context::PrometeuContext; use prometeu_hal::color::Color; use prometeu_hal::log::{LogLevel, LogSource}; -use prometeu_hal::{ - FrameId, GfxUiCommand, LegacyHardwareRenderSubmissionSink, RenderSubmission, - RenderSubmissionSink, ShellUiFramePacket, -}; +use prometeu_hal::{FrameId, GfxUiCommand, RenderSubmission, ShellUiFramePacket}; use prometeu_system::CrashReport; #[derive(Debug, Clone)] @@ -24,15 +21,16 @@ impl AppCrashesStep { pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option { // Update peripherals for input on the crash screen - ctx.hw.pad_mut().begin_frame(ctx.signals); + ctx.platform.input_mut().pad_mut().begin_frame(ctx.signals); let packet = ShellUiFramePacket::new(vec![GfxUiCommand::Clear { color: Color::RED }]); - LegacyHardwareRenderSubmissionSink::new(ctx.hw) + ctx.platform + .render_submission_sink() .submit_render_submission(RenderSubmission::shell_ui(FrameId::ZERO, packet)) .expect("firmware crash render submission should publish"); // If START is pressed, return to the Hub - if ctx.hw.pad().start().down { + if ctx.platform.input().pad().start().down { return Some(FirmwareState::LaunchHub(LaunchHubStep)); } diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs index 5a286f63..911e978b 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs @@ -36,7 +36,7 @@ impl GameRunningStep { return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); } - let result = ctx.os.vm().tick(ctx.vm, ctx.signals, ctx.hw); + let result = ctx.os.vm().tick(ctx.vm, ctx.signals, ctx.platform); if let Some(report) = result { let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs index a8a0cc8c..ac909263 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs @@ -16,7 +16,7 @@ impl HubHomeStep { } pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option { - let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.hw); + let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform); if let Some(report) = outcome.crash { return Some(FirmwareState::AppCrashes(AppCrashesStep { report })); } diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs index e8b1351e..bb26adfd 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs @@ -30,7 +30,7 @@ impl LoadCartridgeStep { ); // Initialize Asset Manager - ctx.hw.assets_mut().initialize_for_cartridge( + ctx.platform.assets_mut().initialize_for_cartridge( self.cartridge.asset_table.clone(), self.cartridge.preload.clone(), self.cartridge.assets.clone(), diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs index f471823e..b0a76f1c 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs @@ -59,7 +59,7 @@ impl ShellRunningStep { } } - let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.hw); + let outcome = ctx.hub.update_shell_profile(ctx.os, ctx.vm, ctx.signals, ctx.platform); if let Some(report) = outcome.crash { let _ = ctx.os.lifecycle().crash_task(self.task_id, Some(&report)); diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_splash_screen.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_splash_screen.rs index 0e49e7d5..f876c91a 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_splash_screen.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_splash_screen.rs @@ -3,10 +3,7 @@ use crate::firmware::prometeu_context::PrometeuContext; use prometeu_hal::color::Color; use prometeu_hal::log::{LogLevel, LogSource}; use prometeu_hal::primitives::Rect; -use prometeu_hal::{ - FrameId, GfxUiCommand, LegacyHardwareRenderSubmissionSink, RenderSubmission, - RenderSubmissionSink, ShellUiFramePacket, -}; +use prometeu_hal::{FrameId, GfxUiCommand, RenderSubmission, ShellUiFramePacket}; #[derive(Debug, Clone)] pub struct SplashScreenStep { @@ -17,7 +14,7 @@ impl SplashScreenStep { pub fn on_enter(&mut self, ctx: &mut PrometeuContext) { ctx.os.log(LogLevel::Info, LogSource::Pos, 0, "Showing SplashScreen".to_string()); // Play sound on enter - // ctx.hw.audio_mut().play(0, 0, 0, 255, 127, 1.0, 0, LoopMode::Off); + // ctx.platform.audio_mut().play(0, 0, 0, 255, 127, 1.0, 0, LoopMode::Off); } pub fn on_update(&mut self, ctx: &mut PrometeuContext) -> Option { @@ -25,10 +22,10 @@ impl SplashScreenStep { const TOTAL_DURATION: u32 = 240; // 4 seconds total (updated from 2s based on total_duration logic) // Update peripherals for input - ctx.hw.pad_mut().begin_frame(ctx.signals); + ctx.platform.input_mut().pad_mut().begin_frame(ctx.signals); // Draw expanding square - let (sw, sh) = ctx.hw.gfx().size(); + let (sw, sh) = ctx.platform.display_size(); let max_size = (sw.min(sh) as i32 / 2).max(1); let current_size = if self.frame < ANIMATION_DURATION { @@ -47,13 +44,14 @@ impl SplashScreenStep { color: Color::WHITE, }, ]); - LegacyHardwareRenderSubmissionSink::new(ctx.hw) + ctx.platform + .render_submission_sink() .submit_render_submission(RenderSubmission::shell_ui(FrameId::ZERO, packet)) .expect("firmware splash render submission should publish"); // Transition logic // If any button is pressed at any time after the animation ends - if self.frame >= ANIMATION_DURATION && ctx.hw.pad().any() { + if self.frame >= ANIMATION_DURATION && ctx.platform.input().pad().any() { return Some(FirmwareState::LaunchHub(LaunchHubStep)); } diff --git a/crates/console/prometeu-firmware/src/firmware/prometeu_context.rs b/crates/console/prometeu-firmware/src/firmware/prometeu_context.rs index b3412092..9c37beed 100644 --- a/crates/console/prometeu-firmware/src/firmware/prometeu_context.rs +++ b/crates/console/prometeu-firmware/src/firmware/prometeu_context.rs @@ -1,5 +1,5 @@ use crate::firmware::boot_target::BootTarget; -use prometeu_hal::{HardwareBridge, InputSignals}; +use prometeu_hal::{InputSignals, RuntimePlatform}; use prometeu_system::{PrometeuHub, SystemOS}; use prometeu_vm::VirtualMachine; @@ -9,5 +9,5 @@ pub struct PrometeuContext<'a> { pub hub: &'a mut PrometeuHub, pub boot_target: &'a BootTarget, pub signals: &'a InputSignals, - pub hw: &'a mut dyn HardwareBridge, + pub platform: &'a mut dyn RuntimePlatform, } diff --git a/crates/console/prometeu-hal/src/platform.rs b/crates/console/prometeu-hal/src/platform.rs index 68cc42b0..94b97292 100644 --- a/crates/console/prometeu-hal/src/platform.rs +++ b/crates/console/prometeu-hal/src/platform.rs @@ -215,6 +215,10 @@ impl TelemetryPlatform for NoopTelemetryPlatform {} static LEGACY_NOOP_TELEMETRY: NoopTelemetryPlatform = NoopTelemetryPlatform; pub trait RuntimePlatform { + fn display_size(&self) -> (usize, usize) { + (480, 270) + } + fn render_submission_sink(&mut self) -> &mut dyn RenderSubmissionSink; fn render_backend(&mut self) -> &mut dyn RenderBackend; fn game2d_frame_composer(&mut self) -> &mut dyn Game2DFrameComposer; diff --git a/crates/console/prometeu-system/src/os/facades/vm.rs b/crates/console/prometeu-system/src/os/facades/vm.rs index 1cf284b3..4786f5ce 100644 --- a/crates/console/prometeu-system/src/os/facades/vm.rs +++ b/crates/console/prometeu-system/src/os/facades/vm.rs @@ -3,7 +3,7 @@ use crate::os::SystemOS; use prometeu_hal::app_mode::AppMode; use prometeu_hal::cartridge::Cartridge; use prometeu_hal::telemetry::{CertificationConfig, TelemetryFrame}; -use prometeu_hal::{HardwareBridge, InputSignals}; +use prometeu_hal::{HardwareBridge, InputSignals, RuntimePlatform}; use prometeu_vm::VirtualMachine; use std::sync::atomic::Ordering; @@ -25,7 +25,7 @@ impl<'a> VmFacade<'a> { &mut self, vm: &mut VirtualMachine, signals: &InputSignals, - hw: &mut dyn HardwareBridge, + platform: &mut dyn RuntimePlatform, ) -> Option { self.os.vm_runtime.tick( &mut self.os.log_service, @@ -36,7 +36,7 @@ impl<'a> VmFacade<'a> { &mut self.os.next_handle, vm, signals, - hw, + platform, ) } diff --git a/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs b/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs index d10f2db8..947a8551 100644 --- a/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs +++ b/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs @@ -2,8 +2,8 @@ use crate::{CrashReport, SystemOS}; use prometeu_hal::color::Color; use prometeu_hal::primitives::Rect; use prometeu_hal::{ - FrameId, GfxUiCommand, HardwareBridge, InputSignals, LegacyHardwareRenderSubmissionSink, - RenderSubmission, RenderSubmissionSink, ShellUiFramePacket, + FrameId, GfxUiCommand, InputPlatform, InputSignals, RenderSubmission, RuntimePlatform, + ShellUiFramePacket, }; use prometeu_vm::VirtualMachine; @@ -101,31 +101,35 @@ impl PrometeuHub { pub fn gui_update( &mut self, os: &mut SystemOS, - hw: &mut dyn HardwareBridge, + platform: &mut dyn RuntimePlatform, ) -> Option { let in_shell = os.windows().focused_window().is_some(); if !in_shell { if !self.home_input_armed { - self.home_input_armed = !activation_input_down(hw); + self.home_input_armed = !activation_input_down(platform.input()); return None; } } else { self.home_input_armed = false; } - if let Some(action) = - action_for_click(in_shell, hw.touch().x(), hw.touch().y(), hw.touch().f().pressed) - { + let input = platform.input(); + if let Some(action) = action_for_click( + in_shell, + input.touch().x(), + input.touch().y(), + input.touch().f().pressed, + ) { return Some(action); } None } - pub fn render(&mut self, os: &mut SystemOS, hw: &mut dyn HardwareBridge) { - let pointer_x = hw.touch().x(); - let pointer_y = hw.touch().y(); + pub fn render(&mut self, os: &mut SystemOS, platform: &mut dyn RuntimePlatform) { + let pointer_x = platform.input().touch().x(); + let pointer_y = platform.input().touch().y(); let packet = if os.windows().window_count() == 0 { render_home_packet(pointer_x, pointer_y) @@ -143,7 +147,8 @@ impl PrometeuHub { } ShellUiFramePacket::new(commands) }; - LegacyHardwareRenderSubmissionSink::new(hw) + platform + .render_submission_sink() .submit_render_submission(RenderSubmission::shell_ui(FrameId::ZERO, packet)) .expect("hub render submission should publish"); } @@ -153,20 +158,20 @@ impl PrometeuHub { os: &mut SystemOS, vm: &mut VirtualMachine, signals: &InputSignals, - hw: &mut dyn HardwareBridge, + platform: &mut dyn RuntimePlatform, ) -> SystemProfileUpdate { let mut crash = None; - let mut action = self.gui_update(os, hw); + let mut action = self.gui_update(os, platform); if os.windows().focused_window().is_some() { - if hw.pad().start().down { + if platform.input().pad().start().down { action = Some(SystemProfileAction::CloseShell); } else if action != Some(SystemProfileAction::CloseShell) { - crash = os.vm().tick(vm, signals, hw); + crash = os.vm().tick(vm, signals, platform); } } - self.render(os, hw); + self.render(os, platform); SystemProfileUpdate { crash, action } } @@ -191,8 +196,11 @@ fn rect_contains(rect: Rect, x: i32, y: i32) -> bool { x >= rect.x && x < rect.x + rect.w && y >= rect.y && y < rect.y + rect.h } -fn activation_input_down(hw: &dyn HardwareBridge) -> bool { - hw.touch().f().down || hw.pad().a().down || hw.pad().b().down || hw.pad().start().down +fn activation_input_down(input: &dyn InputPlatform) -> bool { + input.touch().f().down + || input.pad().a().down + || input.pad().b().down + || input.pad().start().down } fn render_home_packet(pointer_x: i32, pointer_y: i32) -> ShellUiFramePacket { diff --git a/crates/console/prometeu-system/src/services/vm_runtime/tick.rs b/crates/console/prometeu-system/src/services/vm_runtime/tick.rs index 0aac4cb7..267852da 100644 --- a/crates/console/prometeu-system/src/services/vm_runtime/tick.rs +++ b/crates/console/prometeu-system/src/services/vm_runtime/tick.rs @@ -135,7 +135,7 @@ impl VirtualMachineRuntime { next_handle: &mut u32, vm: &mut VirtualMachine, signals: &InputSignals, - hw: &mut dyn HardwareBridge, + platform: &mut dyn RuntimePlatform, ) -> Option { let start = Instant::now(); self.tick_index += 1; @@ -145,8 +145,6 @@ impl VirtualMachineRuntime { } self.update_fs(log_service, fs, fs_state); - let mut platform = LegacyHardwareRuntimePlatform::new(hw); - if !self.logical_frame_active { if RenderManager::policy_for_app_mode(self.current_cartridge_app_mode) .uses_frame_scheduler() @@ -157,7 +155,7 @@ impl VirtualMachineRuntime { } self.logical_frame_active = true; self.logical_frame_remaining_cycles = Self::CYCLES_PER_LOGICAL_FRAME; - self.begin_logical_frame(signals, &mut platform); + self.begin_logical_frame(signals, platform); if self.needs_prepare_entry_call || vm.call_stack_is_empty() { vm.prepare_boot_call(); @@ -185,7 +183,7 @@ impl VirtualMachineRuntime { if budget > 0 { let run_result = { - let mut ctx = HostContext::new_platform(Some(&mut platform)); + let mut ctx = HostContext::new_platform(Some(platform)); let mut host = VmRuntimeHost { runtime: self, log_service, @@ -311,7 +309,7 @@ impl VirtualMachineRuntime { // 1. Snapshot full telemetry at logical frame end let (glyph_bank, sound_bank, scene_bank) = - Self::bank_telemetry_summary(&platform); + Self::bank_telemetry_summary(platform); self.atomic_telemetry .glyph_slots_used .store(glyph_bank.used_slots as u32, Ordering::Relaxed); @@ -402,7 +400,7 @@ impl VirtualMachineRuntime { // 2. High-frequency telemetry update (only if inspection is active) if self.inspection_active { - let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(&platform); + let (glyph_bank, sound_bank, scene_bank) = Self::bank_telemetry_summary(platform); self.atomic_telemetry .glyph_slots_used .store(glyph_bank.used_slots as u32, Ordering::Relaxed);