Implement GDB/LLDB compatible server #3
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue