nes.rsannotatednes.rssource96 lines · 3.1 KB · raw
1use crate::config::{CommonConfig, NesConfig};
2
3use crate::mainloop::{CreatedEmulator, NativeDebugFn, create, file_name_no_ext};
4use crate::{NativeEmulator, NativeEmulatorResult, extensions};
5
6use nes_core::api::NesEmulator;
7use nes_core::input::{NesInputDevice, NesInputs, ZapperState};
8
9use crate::mainloop::create::{CreatableEmulator, ReadInputResult};
10use jgenesis_common::frontend::SaveWriter;
11use jgenesis_native_config::common::WindowSize;
12use jgenesis_native_config::input::mappings::{ButtonMappingVec, NesControllerType};
13use nes_config::NesJoypadState;
14
15trait NesControllerTypeExt {
16    fn to_input_device(self) -> NesInputDevice;
17}
18
19impl NesControllerTypeExt for NesControllerType {
20    fn to_input_device(self) -> NesInputDevice {
21        match self {
22            Self::Gamepad => NesInputDevice::Controller(NesJoypadState::default()),
23            Self::Zapper => NesInputDevice::Zapper(ZapperState::default()),
24        }
25    }
26}
27
28pub type NativeNesEmulator = NativeEmulator<NesEmulator>;
29
30impl CreatableEmulator for NesEmulator {
31    type NativeConfig = NesConfig;
32    type CreateInput = Vec<u8>;
33
34    fn read_create_input(
35        config: &Self::NativeConfig,
36    ) -> NativeEmulatorResult<ReadInputResult<Self::CreateInput>> {
37        create::read_rom_file(&config.common.rom_file_path, extensions::NES)
38    }
39
40    fn create(
41        input: ReadInputResult<Self::CreateInput>,
42        config: &Self::NativeConfig,
43        save_writer: &mut impl SaveWriter,
44    ) -> NativeEmulatorResult<CreatedEmulator<Self>> {
45        let emulator = NesEmulator::create(input.input, config.emulator_config, save_writer)?;
46
47        let rom_title = file_name_no_ext(&input.rom_path)?;
48        let window_title = format!("nes - {rom_title}");
49
50        let default_window_size = WindowSize::new_nes(
51            config.common.initial_window_size,
52            config.emulator_config.aspect_ratio,
53            emulator.timing_mode(),
54            config.emulator_config.ntsc_crop_vertical_overscan,
55        );
56
57        Ok(CreatedEmulator { emulator, window_title, default_window_size })
58    }
59
60    fn common_config(config: &Self::NativeConfig) -> &CommonConfig {
61        &config.common
62    }
63
64    fn emulator_config(config: &Self::NativeConfig) -> &Self::Config {
65        &config.emulator_config
66    }
67
68    fn reload_native_config(
69        emulator: &mut NativeEmulator<Self>,
70        config: &Self::NativeConfig,
71    ) -> NativeEmulatorResult<()> {
72        emulator.inputs.p2 = config.inputs.p2_type.to_input_device();
73
74        Ok(())
75    }
76
77    fn initial_inputs(config: &Self::NativeConfig) -> Self::Inputs {
78        NesInputs { p1: NesJoypadState::default(), p2: config.inputs.p2_type.to_input_device() }
79    }
80
81    fn input_mappings(config: &Self::NativeConfig) -> ButtonMappingVec<'_, Self::Button> {
82        config.inputs.to_mapping_vec()
83    }
84
85    fn turbo_input_mappings(config: &Self::NativeConfig) -> ButtonMappingVec<'_, Self::Button> {
86        config.inputs.to_turbo_mapping_vec()
87    }
88
89    fn debug_fn() -> Option<NativeDebugFn<Self>> {
90        Some(|| {
91            jgenesis_debugger_frontend::partial_clone_debug_fn(
92                jgenesis_debugger_frontend::nes::render_fn(),
93            )
94        })
95    }
96}