From 856ee00999fb65ec8defaac9f90dbf5a264cb430 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Sat, 4 Jan 2025 12:17:56 -0500 Subject: [PATCH] Fix bugs around debugging lifecycle --- src/emulator.rs | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/emulator.rs b/src/emulator.rs index 43486d2..3de6a38 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -177,7 +177,7 @@ impl Emulator { messages: HashMap::new(), debuggers: HashMap::new(), eye_contents: vec![0u8; 384 * 224 * 2], - audio_samples: vec![0.0; EXPECTED_FRAME_SIZE], + audio_samples: Vec::with_capacity(EXPECTED_FRAME_SIZE), }) } @@ -286,6 +286,7 @@ impl Emulator { self.renderers.remove(&SimId::Player2); self.sims.truncate(1); self.sim_state[SimId::Player2.to_index()].store(SimState::Uninitialized, Ordering::Release); + self.stop_debugging(SimId::Player2); self.linked.store(false, Ordering::Release); Ok(()) } @@ -303,7 +304,12 @@ impl Emulator { fn stop_debugging(&mut self, sim_id: SimId) { self.debuggers.remove(&sim_id); if self.debuggers.is_empty() { - self.state.store(EmulatorState::Running, Ordering::Release); + let _ = self.state.compare_exchange( + EmulatorState::Debugging, + EmulatorState::Running, + Ordering::AcqRel, + Ordering::Relaxed, + ); } } @@ -364,6 +370,8 @@ impl Emulator { let p1_state = self.sim_state[SimId::Player1.to_index()].load(Ordering::Acquire); let p2_state = self.sim_state[SimId::Player2.to_index()].load(Ordering::Acquire); let state = self.state.load(Ordering::Acquire); + + // Emulation // Don't emulate if the state is "paused", or if any sim is paused in the debugger let running = match state { EmulatorState::Paused => false, @@ -381,6 +389,7 @@ impl Emulator { self.sims[SimId::Player2.to_index()].emulate(); } + // Video for sim_id in SimId::values() { let Some(renderer) = self.renderers.get_mut(&sim_id) else { continue; @@ -395,24 +404,27 @@ impl Emulator { } } } + + // Audio + // Audio playback speed is how we keep the emulator running in real time. + // Even if we're muted, call `read_samples` to know how many frames of silence to play. let p1_audio = p1_running && self.audio_on[SimId::Player1.to_index()].load(Ordering::Acquire); let p2_audio = p2_running && self.audio_on[SimId::Player2.to_index()].load(Ordering::Acquire); - let weight = if p1_audio && p2_audio { 0.5 } else { 1.0 }; - if p1_audio { - if let Some(sim) = self.sims.get_mut(SimId::Player1.to_index()) { - sim.read_samples(&mut self.audio_samples, weight); - } + let (p1_weight, p2_weight) = match (p1_audio, p2_audio) { + (true, true) => (0.5, 0.5), + (true, false) => (1.0, 0.0), + (false, true) => (0.0, 1.0), + (false, false) => (0.0, 0.0), + }; + if let Some(sim) = self.sims.get_mut(SimId::Player1.to_index()) { + sim.read_samples(&mut self.audio_samples, p1_weight); } - if p2_audio { - if let Some(sim) = self.sims.get_mut(SimId::Player2.to_index()) { - sim.read_samples(&mut self.audio_samples, weight); - } + if let Some(sim) = self.sims.get_mut(SimId::Player2.to_index()) { + sim.read_samples(&mut self.audio_samples, p2_weight); } - if self.audio_samples.is_empty() { - self.audio_samples.resize(EXPECTED_FRAME_SIZE, 0.0); - } else { + if !self.audio_samples.is_empty() { idle = false; } self.audio.update(&self.audio_samples);