2026-03-24 13:40:14 +00:00

89 lines
3.2 KiB
Rust

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<FirmwareState> {
os.reset();
Some(FirmwareState::SplashScreen)
}
fn step_splash_screen() -> Option<FirmwareState> {
Some(FirmwareState::LaunchHub)
}
fn step_launch_hub(hub: &mut PrometeuHub) -> Option<FirmwareState> {
hub.init();
Some(FirmwareState::HubHome)
}
fn step_hub_home(hub: &mut PrometeuHub, os: &mut PrometeuOS, hw: &mut dyn HardwareBridge) -> Option<FirmwareState> {
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<FirmwareState> {
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<FirmwareState> {
os.step_frame(signals, hw).map(FirmwareState::AppCrashes)
}
fn step_crash_screen(signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option<FirmwareState> {
// 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
}
}