use crate::firmware::firmware_state::FirmwareState; use crate::hardware::{HardwareBridge, InputSignals}; use crate::model::{Cartridge, Color}; use crate::prometeu_hub::PrometeuHub; use crate::prometeu_os::PrometeuOS; pub struct Firmware { pub os: PrometeuOS, pub hub: PrometeuHub, pub state: FirmwareState, } impl Firmware { pub fn new() -> Self { Self { os: PrometeuOS::new(), hub: PrometeuHub::new(), state: FirmwareState::Reset, } } pub fn step_frame(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) { let next_state = match &mut self.state { FirmwareState::Reset => Self::step_reset(&mut self.os), FirmwareState::SplashScreen => Self::step_splash_screen(), FirmwareState::LaunchHub => Self::step_launch_hub(&mut self.hub), FirmwareState::HubHome => Self::step_hub_home(&mut self.hub, &mut self.os, hw), FirmwareState::LoadApp(cartridge) => Self::step_init_app(&mut self.os, signals, hw, cartridge), FirmwareState::AppRunning => Self::step_run_app(&mut self.os, signals, hw), FirmwareState::AppCrashes(_error) => Self::step_crash_screen(signals, hw), }; if let Some(new_state) = next_state { self.state = new_state; } } fn step_reset(os: &mut PrometeuOS) -> Option { os.reset(); Some(FirmwareState::SplashScreen) } fn step_splash_screen() -> Option { Some(FirmwareState::LaunchHub) } fn step_launch_hub(hub: &mut PrometeuHub) -> Option { hub.init(); Some(FirmwareState::HubHome) } fn step_hub_home(hub: &mut PrometeuHub, os: &mut PrometeuOS, hw: &mut dyn HardwareBridge) -> Option { hw.gfx_mut().clear(Color::INDIGO); hub.gui_update(os); hw.gfx_mut().present(); None } fn step_init_app(os: &mut PrometeuOS, _signals: &InputSignals, _hw: &mut dyn HardwareBridge, cartridge: &Cartridge) -> Option { os.initialize_vm(cartridge); // a gente precisa carregar e inicializar o cartridge antes de mudar o estado para AppRunning Some(FirmwareState::AppRunning) } fn step_run_app(os: &mut PrometeuOS, signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option { os.step_frame(signals, hw).map(FirmwareState::AppCrashes) } fn step_crash_screen(signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option { // Atualiza periféricos para input na tela de crash hw.pad_mut().begin_frame(signals); // Tela de erro: fundo vermelho, texto branco hw.gfx_mut().clear(Color::RED); // Por enquanto apenas logamos ou mostramos algo simples // No futuro, usar draw_text hw.gfx_mut().present(); // Se apertar START, volta pro Hub if hw.pad().start.down { return Some(FirmwareState::LaunchHub); } None } pub fn load_cartridge(&mut self, cartridge: Cartridge) { self.state = FirmwareState::LoadApp(cartridge); // change state } }