1use genesis_config::{
2    GenesisAspectRatio, GenesisRegion, Opn2BusyBehavior, PcmInterpolation, S32XColorTint,
3    S32XPwmResampling, S32XVideoOut, S32XVoidColorType,
4};
5use jgenesis_common::frontend::TimingMode;
6use jgenesis_proc_macros::deserialize_default_on_error;
7use serde::{Deserialize, Serialize};
8use std::num::{NonZeroU16, NonZeroU64};
9use std::path::PathBuf;
10
11const DEFAULT_DRIVE_SPEED: NonZeroU16 = NonZeroU16::new(1).unwrap();
12
13#[deserialize_default_on_error]
14#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
15#[serde(default)]
16pub struct GenesisAppConfig {
17    pub forced_timing_mode: Option<TimingMode>,
18    pub forced_region: Option<GenesisRegion>,
19    pub allow_opposing_joypad_directions: bool,
20    pub mega_mouse_sensitivity: f64,
21    pub auto_3_button_mode: bool,
22    pub aspect_ratio: GenesisAspectRatio,
23    pub force_square_pixels_in_h40: bool,
24    pub adjust_aspect_ratio_in_2x_resolution: bool,
25    pub anamorphic_widescreen: bool,
26    pub remove_sprite_limits: bool,
27    pub m68k_clock_divider: u64,
28    pub non_linear_color_scale: bool,
29    pub deinterlace: bool,
30    pub render_vertical_border: bool,
31    pub render_horizontal_border: bool,
32    pub plane_a_enabled: bool,
33    pub plane_b_enabled: bool,
34    pub window_enabled: bool,
35    pub sprites_enabled: bool,
36    pub quantize_ym2612_output: bool,
37    pub opn2_busy_behavior: Opn2BusyBehavior,
38    pub emulate_ym2612_ladder_effect: bool,
39    pub genesis_lpf_enabled: bool,
40    pub genesis_lpf_cutoff: u32,
41    pub ym2612_2nd_lpf_enabled: bool,
42    pub ym2612_2nd_lpf_cutoff: u32,
43    pub ym2612_channels_enabled: [bool; 6],
44    pub ym2612_enabled: bool,
45    pub psg_enabled: bool,
46    pub ym2612_volume_adjustment_db: f64,
47    pub psg_volume_adjustment_db: f64,
48}
49
50impl Default for GenesisAppConfig {
51    fn default() -> Self {
52        Self {
53            forced_timing_mode: None,
54            forced_region: None,
55            allow_opposing_joypad_directions: false,
56            mega_mouse_sensitivity: 1.0,
57            auto_3_button_mode: true,
58            aspect_ratio: GenesisAspectRatio::default(),
59            force_square_pixels_in_h40: false,
60            adjust_aspect_ratio_in_2x_resolution: true,
61            anamorphic_widescreen: false,
62            remove_sprite_limits: false,
63            m68k_clock_divider: genesis_config::NATIVE_M68K_DIVIDER,
64            non_linear_color_scale: true,
65            deinterlace: true,
66            render_vertical_border: false,
67            render_horizontal_border: false,
68            plane_a_enabled: true,
69            plane_b_enabled: true,
70            window_enabled: true,
71            sprites_enabled: true,
72            quantize_ym2612_output: true,
73            opn2_busy_behavior: Opn2BusyBehavior::default(),
74            emulate_ym2612_ladder_effect: true,
75            genesis_lpf_enabled: true,
76            genesis_lpf_cutoff: genesis_config::MODEL_1_VA2_LPF_CUTOFF,
77            ym2612_2nd_lpf_enabled: false,
78            ym2612_2nd_lpf_cutoff: genesis_config::MODEL_2_2ND_LPF_CUTOFF,
79            ym2612_channels_enabled: [true; 6],
80            ym2612_enabled: true,
81            psg_enabled: true,
82            ym2612_volume_adjustment_db: 0.0,
83            psg_volume_adjustment_db: 0.0,
84        }
85    }
86}
87
88#[deserialize_default_on_error]
89#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90#[serde(default)]
91pub struct SegaCdAppConfig {
92    pub bios_path: Option<PathBuf>,
93    pub eu_bios_path: Option<PathBuf>,
94    pub jp_bios_path: Option<PathBuf>,
95    pub per_region_bios: bool,
96    pub pcm_interpolation: PcmInterpolation,
97    pub enable_ram_cartridge: bool,
98    pub load_disc_into_ram: bool,
99    pub disc_drive_speed: NonZeroU16,
100    pub sub_cpu_divider: NonZeroU64,
101    pub pcm_lpf_enabled: bool,
102    pub pcm_lpf_cutoff: u32,
103    pub apply_genesis_lpf_to_pcm: bool,
104    pub apply_genesis_lpf_to_cd_da: bool,
105    pub pcm_enabled: bool,
106    pub cd_audio_enabled: bool,
107    pub pcm_volume_adjustment_db: f64,
108    pub cd_volume_adjustment_db: f64,
109}
110
111impl Default for SegaCdAppConfig {
112    fn default() -> Self {
113        Self {
114            bios_path: None,
115            eu_bios_path: None,
116            jp_bios_path: None,
117            per_region_bios: true,
118            pcm_interpolation: PcmInterpolation::default(),
119            enable_ram_cartridge: true,
120            load_disc_into_ram: false,
121            disc_drive_speed: DEFAULT_DRIVE_SPEED,
122            sub_cpu_divider: NonZeroU64::new(genesis_config::NATIVE_SUB_CPU_DIVIDER).unwrap(),
123            pcm_lpf_enabled: true,
124            pcm_lpf_cutoff: genesis_config::DEFAULT_PCM_LPF_CUTOFF,
125            apply_genesis_lpf_to_pcm: false,
126            apply_genesis_lpf_to_cd_da: false,
127            pcm_enabled: true,
128            cd_audio_enabled: true,
129            pcm_volume_adjustment_db: 0.0,
130            cd_volume_adjustment_db: 0.0,
131        }
132    }
133}
134
135#[deserialize_default_on_error]
136#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
137#[serde(default)]
138pub struct Sega32XAppConfig {
139    pub sh2_clock_multiplier: NonZeroU64,
140    pub video_out: S32XVideoOut,
141    pub apply_genesis_lpf_to_pwm: bool,
142    pub darken_genesis_colors: bool,
143    pub color_tint: S32XColorTint,
144    pub show_high_priority: bool,
145    pub show_low_priority: bool,
146    pub void_color_type: S32XVoidColorType,
147    pub void_palette_index: u8,
148    pub void_direct: [u8; 3],
149    pub void_direct_priority: bool,
150    pub pwm_resampling: S32XPwmResampling,
151    pub pwm_enabled: bool,
152    pub pwm_volume_adjustment_db: f64,
153}
154
155impl Default for Sega32XAppConfig {
156    fn default() -> Self {
157        Self {
158            sh2_clock_multiplier: NonZeroU64::new(genesis_config::NATIVE_SH2_MULTIPLIER).unwrap(),
159            video_out: S32XVideoOut::default(),
160            apply_genesis_lpf_to_pwm: true,
161            darken_genesis_colors: true,
162            color_tint: S32XColorTint::default(),
163            show_high_priority: true,
164            show_low_priority: true,
165            void_color_type: S32XVoidColorType::default(),
166            void_palette_index: 0,
167            void_direct: [0; 3],
168            void_direct_priority: false,
169            pwm_resampling: S32XPwmResampling::default(),
170            pwm_enabled: true,
171            pwm_volume_adjustment_db: 0.0,
172        }
173    }
174}