gba.rsannotatedgba.rssource98 lines · 3.3 KB · raw
1use crate::config::{CommonConfig, GameBoyAdvanceConfig};
2use crate::mainloop::create::{CreatableEmulator, ReadInputResult};
3use crate::mainloop::{CreatedEmulator, NativeDebugFn, create, file_name_no_ext};
4use crate::{NativeEmulator, NativeEmulatorError, NativeEmulatorResult, extensions};
5use gba_config::{GbaInputs, SolarSensorState};
6use gba_core::api::GameBoyAdvanceEmulator;
7use jgenesis_common::frontend::SaveWriter;
8use jgenesis_native_config::common::WindowSize;
9use jgenesis_native_config::input::mappings::ButtonMappingVec;
10use std::fs;
11
12pub type NativeGbaEmulator = NativeEmulator<GameBoyAdvanceEmulator>;
13
14impl CreatableEmulator for GameBoyAdvanceEmulator {
15    type NativeConfig = GameBoyAdvanceConfig;
16    type CreateInput = Vec<u8>;
17
18    fn read_create_input(
19        config: &Self::NativeConfig,
20    ) -> NativeEmulatorResult<ReadInputResult<Self::CreateInput>> {
21        create::read_rom_file(&config.common.rom_file_path, extensions::GAME_BOY_ADVANCE)
22    }
23
24    fn create(
25        input: ReadInputResult<Self::CreateInput>,
26        config: &Self::NativeConfig,
27        save_writer: &mut impl SaveWriter,
28    ) -> NativeEmulatorResult<CreatedEmulator<Self>> {
29        let Some(bios_path) = &config.bios_path else {
30            return Err(NativeEmulatorError::GbaNoBios);
31        };
32
33        let bios_rom = fs::read(bios_path).map_err(NativeEmulatorError::GbaBiosLoad)?;
34
35        let emulator = GameBoyAdvanceEmulator::create(
36            input.input,
37            bios_rom,
38            config.emulator_config,
39            save_writer,
40        )?;
41
42        let rom_title = file_name_no_ext(&input.rom_path)?;
43        let window_title = format!("gba - {rom_title}");
44
45        let default_window_size = WindowSize::new_gba(config.common.initial_window_size);
46
47        Ok(CreatedEmulator { emulator, window_title, default_window_size })
48    }
49
50    fn common_config(config: &Self::NativeConfig) -> &CommonConfig {
51        &config.common
52    }
53
54    fn emulator_config(config: &Self::NativeConfig) -> &Self::Config {
55        &config.emulator_config
56    }
57
58    fn reload_native_config(
59        emulator: &mut NativeEmulator<Self>,
60        config: &Self::NativeConfig,
61    ) -> NativeEmulatorResult<()> {
62        emulator.inputs.solar = SolarSensorState {
63            brightness: emulator.inputs.solar.brightness,
64            ..new_solar_state(config)
65        };
66
67        Ok(())
68    }
69
70    fn initial_inputs(config: &Self::NativeConfig) -> Self::Inputs {
71        GbaInputs { solar: new_solar_state(config), ..GbaInputs::default() }
72    }
73
74    fn input_mappings(config: &Self::NativeConfig) -> ButtonMappingVec<'_, Self::Button> {
75        config.inputs.to_mapping_vec()
76    }
77
78    fn turbo_input_mappings(config: &Self::NativeConfig) -> ButtonMappingVec<'_, Self::Button> {
79        config.inputs.to_turbo_mapping_vec()
80    }
81
82    fn debug_fn() -> Option<NativeDebugFn<Self>> {
83        Some(|| {
84            jgenesis_debugger_frontend::partial_clone_debug_fn(
85                jgenesis_debugger_frontend::gba::render_fn(),
86            )
87        })
88    }
89}
90
91fn new_solar_state(config: &GameBoyAdvanceConfig) -> SolarSensorState {
92    SolarSensorState {
93        brightness: config.solar_min_brightness,
94        brightness_step: config.solar_brightness_step,
95        min_brightness: config.solar_min_brightness,
96        max_brightness: config.solar_max_brightness,
97    }
98}