From 62f680e8018b6d436a21236f1ed57c030ba48101 Mon Sep 17 00:00:00 2001 From: Atreya Bain Date: Wed, 6 Mar 2024 09:09:10 +0530 Subject: [PATCH] [cln] Restructure code --- src/device/device.rs | 9 ++++--- src/device/mod.rs | 1 - src/device/sound.rs | 1 - src/device/timer.rs | 18 +++++++------- src/main.rs | 23 +++++++----------- src/sdl_adapters/mod.rs | 3 +++ src/{ => sdl_adapters}/sdl_audio_adapter.rs | 24 ++++++++++++++----- .../sdl_graphics_adapter.rs | 0 .../sdl_keyboard_adapter.rs | 0 9 files changed, 43 insertions(+), 36 deletions(-) delete mode 100644 src/device/sound.rs create mode 100644 src/sdl_adapters/mod.rs rename src/{ => sdl_adapters}/sdl_audio_adapter.rs (59%) rename src/{ => sdl_adapters}/sdl_graphics_adapter.rs (100%) rename src/{ => sdl_adapters}/sdl_keyboard_adapter.rs (100%) diff --git a/src/device/device.rs b/src/device/device.rs index 12b886a..7baca1c 100644 --- a/src/device/device.rs +++ b/src/device/device.rs @@ -1,16 +1,15 @@ use std::sync::{Arc, Mutex}; -use std::thread::{JoinHandle, sleep}; use rand::random; use crate::device::instruction::Instruction; use crate::device::keyboard::Keyboard; -use crate::device::timer::TimerManager; +use crate::device::timer::DeviceTimerManager; use crate::util::EmulatorResult; pub struct Device { pub registers: RegisterFile, pub memory: Box<[u8; Self::DEVICE_MEMORY_SIZE]>, - pub timer: TimerManager, + pub timer: DeviceTimerManager, pub stack: Vec, pub frame_buffer: Arc>>, pub new_chip8_mode: bool, @@ -22,7 +21,7 @@ impl Device { pub const FRAME_BUFFER_WIDTH: usize = 64; pub const FRAME_BUFFER_HEIGHT: usize = 32; pub const FRAME_BUFFER_SIZE: usize = Self::FRAME_BUFFER_WIDTH * Self::FRAME_BUFFER_HEIGHT; - pub fn new(timer: TimerManager, fb: Arc>>, device_keyboard: Keyboard, new_chip8_mode: bool) -> Device { + pub fn new(timer: DeviceTimerManager, fb: Arc>>, device_keyboard: Keyboard, new_chip8_mode: bool) -> Device { let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap(); log::trace!("Successfully initiated device memory"); Device { @@ -222,7 +221,7 @@ impl Device { let reg_value = self.registers.v[x]; let index_original = self.registers.i; // newer instruction set requires wrapping on 12 bit overflow, and setting vf - let addn_res = if (self.new_chip8_mode) { + let addn_res = if self.new_chip8_mode { let overflowing = (reg_value as u16 + index_original) >= 0x1000; self.set_flag_register(overflowing); (reg_value as u16 + index_original) % 0x1000 diff --git a/src/device/mod.rs b/src/device/mod.rs index 17e513a..2bf1397 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -1,6 +1,5 @@ pub mod timer; pub mod keyboard; -mod sound; pub mod instruction; mod device; diff --git a/src/device/sound.rs b/src/device/sound.rs deleted file mode 100644 index 0ffdd02..0000000 --- a/src/device/sound.rs +++ /dev/null @@ -1 +0,0 @@ -// TODO \ No newline at end of file diff --git a/src/device/timer.rs b/src/device/timer.rs index b325c52..d52b090 100644 --- a/src/device/timer.rs +++ b/src/device/timer.rs @@ -7,22 +7,23 @@ use std::time::Duration; use crate::util::EmulatorResult; /// Manages the timer and the sound timer -pub struct TimerManager { +pub struct DeviceTimerManager { timer_left: Arc>, sound_left: Arc>, join_handle: Option<(JoinHandle<()>, std::sync::mpsc::Sender<()>)>, } -impl TimerManager { +impl DeviceTimerManager { pub const TIMER_THREAD_NAME: &'static str = "Timer"; - pub fn new() -> TimerManager { - TimerManager { + pub fn new(sound_timer: Arc>) -> DeviceTimerManager { + DeviceTimerManager { timer_left: Arc::new(Mutex::default()), - sound_left: Arc::new(Mutex::default()), + sound_left: sound_timer, join_handle: None, } } - pub fn start(&mut self) -> Arc> { + + pub fn start(&mut self) { let timer_left_ref = self.timer_left.clone(); let sound_timer_ref = self.sound_left.clone(); let (sender, receiver) = std::sync::mpsc::channel(); @@ -51,7 +52,6 @@ impl TimerManager { } }).expect("Failed to start timer thread"); self.join_handle = Some((res, sender)); - self.sound_left.clone() } /// Set a timer down tick from `val` @@ -72,8 +72,8 @@ impl TimerManager { Ok(res.clone()) } - pub fn stop(self) { - if let Some((u, _)) = self.join_handle { + pub fn _stop(self) { + if let Some((u, _dead_sender)) = self.join_handle { u.join().expect("Failed to close thread"); } else { log::warn!("Nothing present!"); diff --git a/src/main.rs b/src/main.rs index fa88ed6..361a20d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,43 +15,38 @@ use sdl2::render::BlendMode; use sdl2::render::WindowCanvas; use simple_logger::SimpleLogger; -use device::timer::TimerManager; +use device::timer::DeviceTimerManager; use crate::args::Porcel8ProgramArgs; use crate::device::Device; use crate::device::keyboard::Keyboard; use crate::util::EmulatorResult; use crate::kb_map::get_key_index; -use crate::sdl_audio_adapter::SdlAudioAdapter; -use crate::sdl_graphics_adapter::SdlGraphicsAdapter; -use crate::sdl_keyboard_adapter::SdlKeyboardAdapter; +use crate::sdl_adapters::sdl_audio_adapter::SdlAudioAdapter; +use crate::sdl_adapters::sdl_graphics_adapter::SdlGraphicsAdapter; +use crate::sdl_adapters::sdl_keyboard_adapter::SdlKeyboardAdapter; mod args; mod device; mod kb_map; -mod sdl_graphics_adapter; mod util; -mod sdl_keyboard_adapter; -mod sdl_audio_adapter; +mod sdl_adapters; fn main() -> EmulatorResult<()> { SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap(); let Porcel8ProgramArgs { filename, new_chip8_behaviour,draw_scale } = Porcel8ProgramArgs::parse(); log::info!("Started emulator"); - let mut timer = TimerManager::new(); - let (mut canvas, mut event_pump,audio_queue) = try_initiate_sdl(draw_scale)?; - let audio_state = timer.start(); - - let mut sdl_aud_adapter = SdlAudioAdapter::new(audio_state,440.0,0.85,audio_queue); - + let (mut timer,mut sdl_aud_adapter) = SdlAudioAdapter::new_timers(440.0,0.85,audio_queue); let (frame_buffer_for_display, frame_buffer_for_device) = get_frame_buffer_references(); let (sdl_kb_adapter, device_keyboard) = SdlKeyboardAdapter::new_keyboard(); let (device_termination_signal_sender, device_termination_signal_sender_receiver) = std::sync::mpsc::channel(); + + timer.start(); let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || { do_device_loop(timer, frame_buffer_for_device, device_termination_signal_sender_receiver, device_keyboard, filename, new_chip8_behaviour); })?; @@ -100,7 +95,7 @@ fn main() -> EmulatorResult<()> { Ok(()) } -fn do_device_loop(timer: TimerManager, frame_buffer: Arc>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option, new_chip_behaviour: bool) { +fn do_device_loop(timer: DeviceTimerManager, frame_buffer: Arc>>, receiver: Receiver<()>, device_keyboard: Keyboard, rom_file_location_option: Option, new_chip_behaviour: bool) { let mut device = Device::new(timer, frame_buffer, device_keyboard, new_chip_behaviour); device.set_default_font(); diff --git a/src/sdl_adapters/mod.rs b/src/sdl_adapters/mod.rs new file mode 100644 index 0000000..723796b --- /dev/null +++ b/src/sdl_adapters/mod.rs @@ -0,0 +1,3 @@ +pub mod sdl_graphics_adapter; +pub mod sdl_audio_adapter; +pub mod sdl_keyboard_adapter; \ No newline at end of file diff --git a/src/sdl_audio_adapter.rs b/src/sdl_adapters/sdl_audio_adapter.rs similarity index 59% rename from src/sdl_audio_adapter.rs rename to src/sdl_adapters/sdl_audio_adapter.rs index 855b811..83c91d9 100644 --- a/src/sdl_audio_adapter.rs +++ b/src/sdl_adapters/sdl_audio_adapter.rs @@ -1,28 +1,40 @@ use std::sync::{Arc, Mutex}; use sdl2::audio::AudioQueue; +use crate::device::timer::DeviceTimerManager; use crate::util::EmulatorResult; +/// An Audio adapter using `AudioQueue`. Generates a square wave of specified frequency pub struct SdlAudioAdapter { sound_timer: Arc>, phase_inc: f32, phase: f32, volume: f32, audio_queue: AudioQueue, - buf: Vec, + internal_buffer: Vec, } -/// An Audio adapter using `AudioQueue`. impl SdlAudioAdapter { + /// Number of samples per second pub const SAMPLING_FREQ:i32 = 15360; pub const SAMPLES_PER_FRAME: usize = (Self::SAMPLING_FREQ as usize / 60) * 2; - pub fn new(sound_timer: Arc>, + pub fn new_timers(freq: f32, + volume: f32, + audio_queue: AudioQueue) ->(DeviceTimerManager,SdlAudioAdapter){ + let device_sound_timer = Arc::new(Mutex::default()); + let device_timer_manager = DeviceTimerManager::new(device_sound_timer.clone()); + let sdl_audio_adapter = SdlAudioAdapter::new(device_sound_timer,freq,volume,audio_queue); + (device_timer_manager, sdl_audio_adapter) + } + fn new(sound_timer: Arc>, freq: f32, volume: f32, audio_queue: AudioQueue) -> SdlAudioAdapter { audio_queue.resume(); + // ensure frequency isn't too low + assert!(((2.0*freq) as i32) < Self::SAMPLING_FREQ); SdlAudioAdapter { sound_timer, - buf: vec![0f32; Self::SAMPLES_PER_FRAME], + internal_buffer: vec![0f32; Self::SAMPLES_PER_FRAME], phase: 0f32, phase_inc: freq/Self::SAMPLING_FREQ as f32, volume, @@ -37,13 +49,13 @@ impl SdlAudioAdapter { }; if sound_timer>0 && self.audio_queue.size() < Self::SAMPLING_FREQ as u32 { self.fill_audio(); - self.audio_queue.queue_audio(&self.buf)?; + self.audio_queue.queue_audio(&self.internal_buffer)?; } Ok(()) } fn fill_audio(&mut self) { - let out = &mut self.buf; + let out = &mut self.internal_buffer; // Generate a square wave for x in out.iter_mut() { diff --git a/src/sdl_graphics_adapter.rs b/src/sdl_adapters/sdl_graphics_adapter.rs similarity index 100% rename from src/sdl_graphics_adapter.rs rename to src/sdl_adapters/sdl_graphics_adapter.rs diff --git a/src/sdl_keyboard_adapter.rs b/src/sdl_adapters/sdl_keyboard_adapter.rs similarity index 100% rename from src/sdl_keyboard_adapter.rs rename to src/sdl_adapters/sdl_keyboard_adapter.rs