1mod helptext; 2 3use crate::app::widgets::{ClockModifier, OverclockSlider}; 4use crate::app::{App, OpenWindow}; 5use egui::{Context, Window}; 6use pce_config::{PceAspectRatio, PceAudioResampler, PcePaletteType, PceRegion}; 7use std::num::NonZeroU64; 8 9impl App { 10 pub(super) fn render_pce_general_settings(&mut self, ctx: &Context) { 11 const WINDOW: OpenWindow = OpenWindow::PceGeneral; 12 13 let mut open = true; 14 Window::new(WINDOW.title()).open(&mut open).show(ctx, |ui| { 15 ui.group(|ui| { 16 ui.label("Console region"); 17 18 ui.horizontal(|ui| { 19 ui.radio_value( 20 &mut self.config.pc_engine.region, 21 PceRegion::TurboGrafx16, 22 "TurboGrafx-16 (US)", 23 ); 24 ui.radio_value( 25 &mut self.config.pc_engine.region, 26 PceRegion::PcEngine, 27 "PC Engine (JP)", 28 ); 29 }); 30 }); 31 32 self.state.help_text.insert(WINDOW, helptext::REGION); 33 self.render_help_text(ui, WINDOW); 34 }); 35 if !open { 36 self.state.open_windows.remove(&WINDOW); 37 } 38 } 39 40 pub(super) fn render_pce_video_settings(&mut self, ctx: &Context) { 41 const WINDOW: OpenWindow = OpenWindow::PceVideo; 42 43 let mut open = true; 44 Window::new(WINDOW.title()).open(&mut open).show(ctx, |ui| { 45 let rect = ui 46 .group(|ui| { 47 ui.label("Aspect ratio"); 48 49 ui.horizontal(|ui| { 50 for (value, label) in [ 51 (PceAspectRatio::Ntsc, "NTSC"), 52 (PceAspectRatio::SquarePixels, "Square pixels"), 53 (PceAspectRatio::Stretched, "Stretched"), 54 ] { 55 ui.radio_value(&mut self.config.pc_engine.aspect_ratio, value, label); 56 } 57 }); 58 }) 59 .response 60 .interact_rect; 61 if ui.rect_contains_pointer(rect) { 62 self.state.help_text.insert(WINDOW, helptext::ASPECT_RATIO); 63 } 64 65 let rect = ui 66 .group(|ui| { 67 ui.label("Palette"); 68 69 ui.horizontal(|ui| { 70 ui.radio_value( 71 &mut self.config.pc_engine.palette, 72 PcePaletteType::PceComposite, 73 "PC Engine composite", 74 ); 75 76 ui.radio_value( 77 &mut self.config.pc_engine.palette, 78 PcePaletteType::Linear, 79 "Linear", 80 ); 81 }); 82 }) 83 .response 84 .interact_rect; 85 if ui.rect_contains_pointer(rect) { 86 self.state.help_text.insert(WINDOW, helptext::PALETTE); 87 } 88 89 ui.add_space(3.0); 90 91 let rect = ui 92 .checkbox(&mut self.config.pc_engine.crop_overscan, "Crop overscan area") 93 .interact_rect; 94 if ui.rect_contains_pointer(rect) { 95 self.state.help_text.insert(WINDOW, helptext::CROP_OVERSCAN); 96 } 97 98 let rect = ui 99 .checkbox( 100 &mut self.config.pc_engine.remove_sprite_limits, 101 "Remove sprite-per-scanline limits", 102 ) 103 .interact_rect; 104 if ui.rect_contains_pointer(rect) { 105 self.state.help_text.insert(WINDOW, helptext::REMOVE_SPRITE_LIMITS); 106 } 107 108 self.render_help_text(ui, WINDOW); 109 }); 110 if !open { 111 self.state.open_windows.remove(&WINDOW); 112 } 113 } 114 115 pub(super) fn render_pce_audio_settings(&mut self, ctx: &Context) { 116 const WINDOW: OpenWindow = OpenWindow::PceAudio; 117 118 let mut open = true; 119 Window::new(WINDOW.title()).open(&mut open).show(ctx, |ui| { 120 ui.group(|ui| { 121 ui.label("Audio resampling algorithm"); 122 123 ui.radio_value( 124 &mut self.config.pc_engine.audio_resampler, 125 PceAudioResampler::WindowedSinc, 126 "Windowed sinc interpolation (Higher quality)", 127 ); 128 ui.radio_value( 129 &mut self.config.pc_engine.audio_resampler, 130 PceAudioResampler::LowPassNearestNeighbor, 131 "Low-pass filter + nearest neighbor (Faster)", 132 ); 133 }); 134 135 self.state.help_text.insert(WINDOW, helptext::AUDIO_RESAMPLER); 136 self.render_help_text(ui, WINDOW); 137 }); 138 if !open { 139 self.state.open_windows.remove(&WINDOW); 140 } 141 } 142 143 pub(super) fn render_pce_overclock_settings(&mut self, ctx: &Context) { 144 const WINDOW: OpenWindow = OpenWindow::PceOverclock; 145 146 let mut open = true; 147 Window::new(WINDOW.title()).open(&mut open).show(ctx, |ui| { 148 let range = NonZeroU64::new(1).unwrap() 149 ..=NonZeroU64::new(pce_config::NATIVE_FAST_CPU_DIVIDER).unwrap(); 150 151 ui.add(OverclockSlider { 152 label: "CPU High-Speed Clock Divider", 153 current_value: &mut self.config.pc_engine.cpu_fast_clock_divider, 154 range, 155 master_clock: pce_core::api::MASTER_CLOCK_FREQUENCY, 156 default_divider: pce_config::NATIVE_FAST_CPU_DIVIDER as f64, 157 modifier: ClockModifier::Divider, 158 }); 159 160 self.state.help_text.insert(WINDOW, helptext::CPU_OVERCLOCK); 161 162 self.render_help_text(ui, WINDOW); 163 }); 164 if !open { 165 self.state.open_windows.remove(&WINDOW); 166 } 167 } 168}