snes.rsannotatedsnes.rssource126 lines · 4.1 KB · raw
1use crate::config::{CommonConfig, SnesConfig};
2
3use crate::mainloop::{CreatedEmulator, NativeDebugFn, create};
4use crate::{NativeEmulator, NativeEmulatorResult, extensions};
5
6use crate::mainloop::create::{CreatableEmulator, ReadInputResult};
7use jgenesis_common::frontend::SaveWriter;
8use jgenesis_native_config::common::WindowSize;
9use jgenesis_native_config::input::mappings::{ButtonMappingVec, SnesControllerType};
10use snes_config::SnesJoypadState;
11use snes_core::api::SnesEmulator;
12use snes_core::input::{SnesController, SnesInputs, SnesMouseState, SuperScopeState};
13
14trait SnesControllerTypeExt {
15    fn to_controller(self) -> SnesController;
16}
17
18impl SnesControllerTypeExt for SnesControllerType {
19    fn to_controller(self) -> SnesController {
20        match self {
21            Self::Gamepad => SnesController::Gamepad(SnesJoypadState::default()),
22            Self::Mouse => SnesController::Mouse(SnesMouseState::default()),
23            Self::SuperScope => SnesController::SuperScope(SuperScopeState::default()),
24            Self::None => SnesController::None,
25        }
26    }
27}
28
29trait SnesControllerExt {
30    fn to_type(self) -> SnesControllerType;
31}
32
33impl SnesControllerExt for SnesController {
34    fn to_type(self) -> SnesControllerType {
35        match self {
36            Self::Gamepad(_) => SnesControllerType::Gamepad,
37            Self::Mouse(_) => SnesControllerType::Mouse,
38            Self::SuperScope(_) => SnesControllerType::SuperScope,
39            Self::None => SnesControllerType::None,
40        }
41    }
42}
43
44pub type NativeSnesEmulator = NativeEmulator<SnesEmulator>;
45
46impl CreatableEmulator for SnesEmulator {
47    type NativeConfig = SnesConfig;
48    type CreateInput = Vec<u8>;
49
50    fn read_create_input(
51        config: &Self::NativeConfig,
52    ) -> NativeEmulatorResult<ReadInputResult<Self::CreateInput>> {
53        create::read_rom_file(&config.common.rom_file_path, extensions::SNES)
54    }
55
56    fn create(
57        input: ReadInputResult<Self::CreateInput>,
58        config: &Self::NativeConfig,
59        save_writer: &mut impl SaveWriter,
60    ) -> NativeEmulatorResult<CreatedEmulator<Self>> {
61        let coprocessor_roms = config.to_coprocessor_roms();
62        let mut emulator = SnesEmulator::create(
63            input.input,
64            config.emulator_config,
65            coprocessor_roms,
66            save_writer,
67        )?;
68
69        let cartridge_title = emulator.cartridge_title();
70        let window_title = format!("snes - {cartridge_title}");
71
72        let default_window_size = WindowSize::new_snes(
73            config.common.initial_window_size,
74            config.emulator_config.aspect_ratio,
75        );
76
77        Ok(CreatedEmulator { emulator, window_title, default_window_size })
78    }
79
80    fn common_config(config: &Self::NativeConfig) -> &CommonConfig {
81        &config.common
82    }
83
84    fn emulator_config(config: &Self::NativeConfig) -> &Self::Config {
85        &config.emulator_config
86    }
87
88    fn reload_native_config(
89        emulator: &mut NativeEmulator<Self>,
90        config: &Self::NativeConfig,
91    ) -> NativeEmulatorResult<()> {
92        for (inputs, controller_type) in [
93            (&mut emulator.inputs.p1, config.inputs.p1_type),
94            (&mut emulator.inputs.p2, config.inputs.p2_type),
95        ] {
96            if inputs.to_type() != controller_type {
97                *inputs = controller_type.to_controller();
98            }
99        }
100
101        Ok(())
102    }
103
104    fn initial_inputs(config: &Self::NativeConfig) -> Self::Inputs {
105        SnesInputs {
106            p1: config.inputs.p1_type.to_controller(),
107            p2: config.inputs.p2_type.to_controller(),
108        }
109    }
110
111    fn input_mappings(config: &Self::NativeConfig) -> ButtonMappingVec<'_, Self::Button> {
112        config.inputs.to_mapping_vec()
113    }
114
115    fn turbo_input_mappings(config: &Self::NativeConfig) -> ButtonMappingVec<'_, Self::Button> {
116        config.inputs.to_turbo_mapping_vec()
117    }
118
119    fn debug_fn() -> Option<NativeDebugFn<Self>> {
120        Some(|| {
121            jgenesis_debugger_frontend::partial_clone_debug_fn(
122                jgenesis_debugger_frontend::snes::render_fn(),
123            )
124        })
125    }
126}