From c62aef51ba10b491fb0ad1a5a7c4aba3bea3f76e Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Mon, 15 Jun 2026 05:52:48 +0100 Subject: [PATCH] implements PLN-0103 --- .../console/prometeu-drivers/src/hardware.rs | 73 ++++++++++++- crates/console/prometeu-drivers/src/lib.rs | 2 + .../prometeu-drivers/src/test_platform.rs | 100 ++++++++++++++++++ crates/console/prometeu-hal/src/lib.rs | 5 +- crates/console/prometeu-hal/src/platform.rs | 5 + 5 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 crates/console/prometeu-drivers/src/test_platform.rs diff --git a/crates/console/prometeu-drivers/src/hardware.rs b/crates/console/prometeu-drivers/src/hardware.rs index 63e9b2be..30349a28 100644 --- a/crates/console/prometeu-drivers/src/hardware.rs +++ b/crates/console/prometeu-drivers/src/hardware.rs @@ -10,7 +10,10 @@ use crate::pad::Pad; use crate::touch::Touch; use prometeu_hal::cartridge::AssetsPayloadSource; use prometeu_hal::sprite::Sprite; -use prometeu_hal::{AssetBridge, AudioBridge, GfxBridge, HardwareBridge, PadBridge, TouchBridge}; +use prometeu_hal::{ + AssetBridge, AudioBridge, GfxBridge, HardwareBridge, InputPlatform, NoopTelemetryPlatform, + PadBridge, RenderBackend, RuntimePlatform, TelemetryPlatform, TouchBridge, +}; use prometeu_hal::{ Game2DFrameComposer, Game2DFramePacket, RenderSubmission, RenderSubmissionPacket, }; @@ -151,6 +154,12 @@ impl RenderSubmissionSink for Hardware { } } +impl RenderBackend for Hardware { + fn render_frame(&mut self) { + HardwareBridge::render_frame(self); + } +} + impl Game2DFrameComposer for Hardware { fn begin_frame(&mut self) { self.frame_composer.begin_frame(); @@ -190,6 +199,68 @@ impl Game2DFrameComposer for Hardware { } } +impl InputPlatform for Hardware { + fn pad(&self) -> &dyn PadBridge { + &self.pad + } + + fn pad_mut(&mut self) -> &mut dyn PadBridge { + &mut self.pad + } + + fn touch(&self) -> &dyn TouchBridge { + &self.touch + } + + fn touch_mut(&mut self) -> &mut dyn TouchBridge { + &mut self.touch + } +} + +static NOOP_TELEMETRY: NoopTelemetryPlatform = NoopTelemetryPlatform; + +impl RuntimePlatform for Hardware { + fn render_submission_sink(&mut self) -> &mut dyn RenderSubmissionSink { + self + } + + fn render_backend(&mut self) -> &mut dyn RenderBackend { + self + } + + fn game2d_frame_composer(&mut self) -> &mut dyn Game2DFrameComposer { + self + } + + fn audio(&self) -> &dyn prometeu_hal::AudioPlatform { + &self.audio + } + + fn audio_mut(&mut self) -> &mut dyn prometeu_hal::AudioPlatform { + &mut self.audio + } + + fn input(&self) -> &dyn InputPlatform { + self + } + + fn input_mut(&mut self) -> &mut dyn InputPlatform { + self + } + + fn assets(&self) -> &dyn prometeu_hal::AssetStoragePlatform { + &self.assets + } + + fn assets_mut(&mut self) -> &mut dyn prometeu_hal::AssetStoragePlatform { + &mut self.assets + } + + fn telemetry(&self) -> &dyn TelemetryPlatform { + &NOOP_TELEMETRY + } +} + impl Hardware { /// Internal hardware width in pixels. pub const W: usize = 480; diff --git a/crates/console/prometeu-drivers/src/lib.rs b/crates/console/prometeu-drivers/src/lib.rs index d5173830..dacd2eb2 100644 --- a/crates/console/prometeu-drivers/src/lib.rs +++ b/crates/console/prometeu-drivers/src/lib.rs @@ -5,6 +5,7 @@ mod gfx; pub mod hardware; mod memory_banks; mod pad; +mod test_platform; mod touch; pub use crate::asset::AssetManager; @@ -16,3 +17,4 @@ pub use crate::memory_banks::{ SceneBankPoolAccess, SceneBankPoolInstaller, SoundBankPoolAccess, SoundBankPoolInstaller, }; pub use crate::pad::Pad; +pub use crate::test_platform::TestPlatform; diff --git a/crates/console/prometeu-drivers/src/test_platform.rs b/crates/console/prometeu-drivers/src/test_platform.rs new file mode 100644 index 00000000..3769d964 --- /dev/null +++ b/crates/console/prometeu-drivers/src/test_platform.rs @@ -0,0 +1,100 @@ +use crate::hardware::Hardware; +use crate::memory_banks::MemoryBanks; +use prometeu_hal::{ + AssetStoragePlatform, AudioPlatform, Game2DFrameComposer, InputPlatform, RenderBackend, + RenderSubmissionSink, RuntimePlatform, TelemetryPlatform, +}; +use std::sync::Arc; + +pub struct TestPlatform { + hardware: Hardware, +} + +impl Default for TestPlatform { + fn default() -> Self { + Self::new() + } +} + +impl TestPlatform { + pub fn new() -> Self { + Self { hardware: Hardware::new() } + } + + pub fn new_with_memory_banks(memory_banks: Arc) -> Self { + Self { hardware: Hardware::new_with_memory_banks(memory_banks) } + } + + pub fn local_hardware(&self) -> &Hardware { + &self.hardware + } + + pub fn local_hardware_mut(&mut self) -> &mut Hardware { + &mut self.hardware + } +} + +impl RuntimePlatform for TestPlatform { + fn render_submission_sink(&mut self) -> &mut dyn RenderSubmissionSink { + self.hardware.render_submission_sink() + } + + fn render_backend(&mut self) -> &mut dyn RenderBackend { + self.hardware.render_backend() + } + + fn game2d_frame_composer(&mut self) -> &mut dyn Game2DFrameComposer { + self.hardware.game2d_frame_composer() + } + + fn audio(&self) -> &dyn AudioPlatform { + self.hardware.audio() + } + + fn audio_mut(&mut self) -> &mut dyn AudioPlatform { + self.hardware.audio_mut() + } + + fn input(&self) -> &dyn InputPlatform { + self.hardware.input() + } + + fn input_mut(&mut self) -> &mut dyn InputPlatform { + self.hardware.input_mut() + } + + fn assets(&self) -> &dyn AssetStoragePlatform { + self.hardware.assets() + } + + fn assets_mut(&mut self) -> &mut dyn AssetStoragePlatform { + self.hardware.assets_mut() + } + + fn telemetry(&self) -> &dyn TelemetryPlatform { + self.hardware.telemetry() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use prometeu_hal::{FrameId, Game2DFramePacket, RenderSubmission}; + + #[test] + fn test_platform_initializes_required_facades() { + let mut platform = TestPlatform::new(); + + platform.game2d_frame_composer().begin_frame(); + platform + .render_submission_sink() + .submit_render_submission(RenderSubmission::game2d( + FrameId::ZERO, + Game2DFramePacket::default(), + )) + .expect("test platform render sink should accept local submission"); + assert!(!platform.audio().is_playing(0)); + assert!(!platform.input().pad().any()); + assert!(platform.telemetry().telemetry_snapshot().is_none()); + } +} diff --git a/crates/console/prometeu-hal/src/lib.rs b/crates/console/prometeu-hal/src/lib.rs index 517b8099..868b1401 100644 --- a/crates/console/prometeu-hal/src/lib.rs +++ b/crates/console/prometeu-hal/src/lib.rs @@ -49,8 +49,9 @@ pub use native_interface::{NativeInterface, SyscallId}; pub use pad_bridge::PadBridge; pub use platform::{ AssetStoragePlatform, AudioPlatform, ClockPacingPlatform, Game2DFrameComposer, InputPlatform, - LegacyHardwareGame2DFrameComposer, LegacyHardwareRenderSubmissionSink, RenderBackend, - RenderSubmissionSink, RenderSubmitError, RuntimePlatform, TelemetryPlatform, TestPlatform, + LegacyHardwareGame2DFrameComposer, LegacyHardwareRenderSubmissionSink, NoopTelemetryPlatform, + RenderBackend, RenderSubmissionSink, RenderSubmitError, RuntimePlatform, TelemetryPlatform, + TestPlatform, }; pub use render_submission::{ BoundScenePacket, Camera2D, ComposerFramePacket, FrameId, Game2DFramePacket, GameSpritePacket, diff --git a/crates/console/prometeu-hal/src/platform.rs b/crates/console/prometeu-hal/src/platform.rs index 57b1d1a9..e50dc0ed 100644 --- a/crates/console/prometeu-hal/src/platform.rs +++ b/crates/console/prometeu-hal/src/platform.rs @@ -124,6 +124,11 @@ pub trait TelemetryPlatform { } } +#[derive(Debug, Default)] +pub struct NoopTelemetryPlatform; + +impl TelemetryPlatform for NoopTelemetryPlatform {} + pub trait RuntimePlatform { fn render_submission_sink(&mut self) -> &mut dyn RenderSubmissionSink; fn render_backend(&mut self) -> &mut dyn RenderBackend;