slight restructuring
This commit is contained in:
parent
249a44e278
commit
1c730b3d77
106
src/emulator.rs
106
src/emulator.rs
|
@ -141,6 +141,8 @@ pub struct Emulator {
|
||||||
linked: Arc<AtomicBool>,
|
linked: Arc<AtomicBool>,
|
||||||
renderers: HashMap<SimId, TextureSink>,
|
renderers: HashMap<SimId, TextureSink>,
|
||||||
messages: HashMap<SimId, mpsc::Sender<Toast>>,
|
messages: HashMap<SimId, mpsc::Sender<Toast>>,
|
||||||
|
eye_contents: Vec<u8>,
|
||||||
|
audio_samples: Vec<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Emulator {
|
impl Emulator {
|
||||||
|
@ -164,6 +166,8 @@ impl Emulator {
|
||||||
linked,
|
linked,
|
||||||
renderers: HashMap::new(),
|
renderers: HashMap::new(),
|
||||||
messages: HashMap::new(),
|
messages: HashMap::new(),
|
||||||
|
eye_contents: vec![0u8; 384 * 224 * 2],
|
||||||
|
audio_samples: vec![0.0; EXPECTED_FRAME_SIZE],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,56 +261,8 @@ impl Emulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
let mut eye_contents = vec![0u8; 384 * 224 * 2];
|
|
||||||
let mut audio_samples = vec![];
|
|
||||||
loop {
|
loop {
|
||||||
let p1_running = self.running[SimId::Player1.to_index()].load(Ordering::Acquire);
|
let idle = self.tick();
|
||||||
let p2_running = self.running[SimId::Player2.to_index()].load(Ordering::Acquire);
|
|
||||||
let mut idle = p1_running || p2_running;
|
|
||||||
if p1_running && p2_running {
|
|
||||||
Sim::emulate_many(&mut self.sims);
|
|
||||||
} else if p1_running {
|
|
||||||
self.sims[SimId::Player1.to_index()].emulate();
|
|
||||||
} else if p2_running {
|
|
||||||
self.sims[SimId::Player2.to_index()].emulate();
|
|
||||||
}
|
|
||||||
|
|
||||||
for sim_id in SimId::values() {
|
|
||||||
let Some(renderer) = self.renderers.get_mut(&sim_id) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
if sim.read_pixels(&mut eye_contents) {
|
|
||||||
idle = false;
|
|
||||||
if renderer.queue_render(&eye_contents).is_err() {
|
|
||||||
self.renderers.remove(&sim_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 audio_samples, weight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p2_audio {
|
|
||||||
if let Some(sim) = self.sims.get_mut(SimId::Player2.to_index()) {
|
|
||||||
sim.read_samples(&mut audio_samples, weight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if audio_samples.is_empty() {
|
|
||||||
audio_samples.resize(EXPECTED_FRAME_SIZE, 0.0);
|
|
||||||
} else {
|
|
||||||
idle = false;
|
|
||||||
}
|
|
||||||
self.audio.update(&audio_samples);
|
|
||||||
audio_samples.clear();
|
|
||||||
if idle {
|
if idle {
|
||||||
// The game is paused, and we have output all the video/audio we have.
|
// The game is paused, and we have output all the video/audio we have.
|
||||||
// Block the thread until a new command comes in.
|
// Block the thread until a new command comes in.
|
||||||
|
@ -331,6 +287,58 @@ impl Emulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if the emulator is "idle" (i.e. this didn't output anything)
|
||||||
|
pub fn tick(&mut self) -> bool {
|
||||||
|
let p1_running = self.running[SimId::Player1.to_index()].load(Ordering::Acquire);
|
||||||
|
let p2_running = self.running[SimId::Player2.to_index()].load(Ordering::Acquire);
|
||||||
|
let mut idle = p1_running || p2_running;
|
||||||
|
if p1_running && p2_running {
|
||||||
|
Sim::emulate_many(&mut self.sims);
|
||||||
|
} else if p1_running {
|
||||||
|
self.sims[SimId::Player1.to_index()].emulate();
|
||||||
|
} else if p2_running {
|
||||||
|
self.sims[SimId::Player2.to_index()].emulate();
|
||||||
|
}
|
||||||
|
|
||||||
|
for sim_id in SimId::values() {
|
||||||
|
let Some(renderer) = self.renderers.get_mut(&sim_id) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if sim.read_pixels(&mut self.eye_contents) {
|
||||||
|
idle = false;
|
||||||
|
if renderer.queue_render(&self.eye_contents).is_err() {
|
||||||
|
self.renderers.remove(&sim_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p2_audio {
|
||||||
|
if let Some(sim) = self.sims.get_mut(SimId::Player2.to_index()) {
|
||||||
|
sim.read_samples(&mut self.audio_samples, weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.audio_samples.is_empty() {
|
||||||
|
self.audio_samples.resize(EXPECTED_FRAME_SIZE, 0.0);
|
||||||
|
} else {
|
||||||
|
idle = false;
|
||||||
|
}
|
||||||
|
self.audio.update(&self.audio_samples);
|
||||||
|
self.audio_samples.clear();
|
||||||
|
idle
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_command(&mut self, command: EmulatorCommand) {
|
fn handle_command(&mut self, command: EmulatorCommand) {
|
||||||
match command {
|
match command {
|
||||||
EmulatorCommand::ConnectToSim(sim_id, renderer, messages) => {
|
EmulatorCommand::ConnectToSim(sim_id, renderer, messages) => {
|
||||||
|
|
Loading…
Reference in New Issue