122 lines
4.4 KiB
Rust
122 lines
4.4 KiB
Rust
use crate::firmware::boot_target::BootTarget;
|
|
use crate::firmware::firmware_state::{FirmwareState, LoadCartridgeStep, ResetStep};
|
|
use crate::firmware::prometeu_context::PrometeuContext;
|
|
use crate::hardware::{HardwareBridge, InputSignals};
|
|
use crate::model::Cartridge;
|
|
use crate::prometeu_hub::PrometeuHub;
|
|
use crate::prometeu_os::PrometeuOS;
|
|
use crate::virtual_machine::VirtualMachine;
|
|
|
|
use crate::telemetry::CertificationConfig;
|
|
|
|
pub struct Firmware {
|
|
pub vm: VirtualMachine,
|
|
pub os: PrometeuOS,
|
|
pub hub: PrometeuHub,
|
|
pub state: FirmwareState,
|
|
pub boot_target: BootTarget,
|
|
state_initialized: bool,
|
|
}
|
|
|
|
impl Firmware {
|
|
pub fn new(cap_config: Option<CertificationConfig>) -> Self {
|
|
Self {
|
|
vm: VirtualMachine::default(),
|
|
os: PrometeuOS::new(cap_config),
|
|
hub: PrometeuHub::new(),
|
|
state: FirmwareState::Reset(ResetStep),
|
|
boot_target: BootTarget::Hub,
|
|
state_initialized: false,
|
|
}
|
|
}
|
|
|
|
pub fn step_frame(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) {
|
|
// Updates input once per host frame
|
|
hw.pad_mut().begin_frame(signals);
|
|
hw.touch_mut().begin_frame(signals);
|
|
|
|
if !self.state_initialized {
|
|
self.on_enter(signals, hw);
|
|
self.state_initialized = true;
|
|
}
|
|
|
|
if let Some(next_state) = self.on_update(signals, hw) {
|
|
self.change_state(next_state, signals, hw);
|
|
}
|
|
}
|
|
|
|
pub fn change_state(&mut self, new_state: FirmwareState, signals: &InputSignals, hw: &mut dyn HardwareBridge) {
|
|
self.on_exit(signals, hw);
|
|
self.state = new_state;
|
|
self.state_initialized = false;
|
|
|
|
// Enters the new state immediately
|
|
self.on_enter(signals, hw);
|
|
self.state_initialized = true;
|
|
}
|
|
|
|
fn on_enter(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) {
|
|
let mut req = PrometeuContext {
|
|
vm: &mut self.vm,
|
|
os: &mut self.os,
|
|
hub: &mut self.hub,
|
|
boot_target: &self.boot_target,
|
|
signals,
|
|
hw,
|
|
};
|
|
match &mut self.state {
|
|
FirmwareState::Reset(s) => s.on_enter(&mut req),
|
|
FirmwareState::SplashScreen(s) => s.on_enter(&mut req),
|
|
FirmwareState::LaunchHub(s) => s.on_enter(&mut req),
|
|
FirmwareState::HubHome(s) => s.on_enter(&mut req),
|
|
FirmwareState::LoadCartridge(s) => s.on_enter(&mut req),
|
|
FirmwareState::GameRunning(s) => s.on_enter(&mut req),
|
|
FirmwareState::AppCrashes(s) => s.on_enter(&mut req),
|
|
}
|
|
}
|
|
|
|
fn on_update(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) -> Option<FirmwareState> {
|
|
let mut req = PrometeuContext {
|
|
vm: &mut self.vm,
|
|
os: &mut self.os,
|
|
hub: &mut self.hub,
|
|
boot_target: &self.boot_target,
|
|
signals,
|
|
hw,
|
|
};
|
|
match &mut self.state {
|
|
FirmwareState::Reset(s) => s.on_update(&mut req),
|
|
FirmwareState::SplashScreen(s) => s.on_update(&mut req),
|
|
FirmwareState::LaunchHub(s) => s.on_update(&mut req),
|
|
FirmwareState::HubHome(s) => s.on_update(&mut req),
|
|
FirmwareState::LoadCartridge(s) => s.on_update(&mut req),
|
|
FirmwareState::GameRunning(s) => s.on_update(&mut req),
|
|
FirmwareState::AppCrashes(s) => s.on_update(&mut req),
|
|
}
|
|
}
|
|
|
|
fn on_exit(&mut self, signals: &InputSignals, hw: &mut dyn HardwareBridge) {
|
|
let mut req = PrometeuContext {
|
|
vm: &mut self.vm,
|
|
os: &mut self.os,
|
|
hub: &mut self.hub,
|
|
boot_target: &self.boot_target,
|
|
signals,
|
|
hw,
|
|
};
|
|
match &mut self.state {
|
|
FirmwareState::Reset(s) => s.on_exit(&mut req),
|
|
FirmwareState::SplashScreen(s) => s.on_exit(&mut req),
|
|
FirmwareState::LaunchHub(s) => s.on_exit(&mut req),
|
|
FirmwareState::HubHome(s) => s.on_exit(&mut req),
|
|
FirmwareState::LoadCartridge(s) => s.on_exit(&mut req),
|
|
FirmwareState::GameRunning(s) => s.on_exit(&mut req),
|
|
FirmwareState::AppCrashes(s) => s.on_exit(&mut req),
|
|
}
|
|
}
|
|
|
|
pub fn load_cartridge(&mut self, cartridge: Cartridge) {
|
|
self.state = FirmwareState::LoadCartridge(LoadCartridgeStep { cartridge });
|
|
self.state_initialized = false;
|
|
}
|
|
} |