From 4b34d138acbc6c5f07f3e56e47b14f83abba9e67 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Sat, 23 Nov 2024 20:17:28 -0500 Subject: [PATCH] Support muting sims --- src/app/game.rs | 12 +++++++++ src/emulator.rs | 43 +++++++++++++++++++++++++++------ src/emulator/shrooms_vb_core.rs | 1 + 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/app/game.rs b/src/app/game.rs index 8960450..432b677 100644 --- a/src/app/game.rs +++ b/src/app/game.rs @@ -238,6 +238,18 @@ impl GameWindow { } } }); + ui.menu("Audio", || { + let p1_enabled = self.client.is_audio_enabled(SimId::Player1); + let p2_enabled = self.client.is_audio_enabled(SimId::Player2); + if ui.menu_item_config("Player 1").selected(p1_enabled).build() { + self.client + .send_command(EmulatorCommand::SetAudioEnabled(!p1_enabled, p2_enabled)); + } + if ui.menu_item_config("Player 2").selected(p2_enabled).build() { + self.client + .send_command(EmulatorCommand::SetAudioEnabled(p1_enabled, !p2_enabled)); + } + }); ui.menu("Input", || { if ui.menu_item("Bind Inputs") { self.proxy.send_event(UserEvent::OpenInputWindow).unwrap(); diff --git a/src/emulator.rs b/src/emulator.rs index c0638a8..fd04520 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -12,8 +12,8 @@ use std::{ use anyhow::Result; use crate::{audio::Audio, graphics::TextureSink}; -use shrooms_vb_core::Sim; pub use shrooms_vb_core::VBKey; +use shrooms_vb_core::{Sim, EXPECTED_FRAME_SIZE}; mod shrooms_vb_core; @@ -23,6 +23,7 @@ pub struct EmulatorBuilder { sim_count: Arc, running: Arc<[AtomicBool; 2]>, has_game: Arc<[AtomicBool; 2]>, + audio_on: Arc<[AtomicBool; 2]>, linked: Arc, } @@ -52,6 +53,7 @@ impl EmulatorBuilder { sim_count: Arc::new(AtomicUsize::new(0)), running: Arc::new([AtomicBool::new(false), AtomicBool::new(false)]), has_game: Arc::new([AtomicBool::new(false), AtomicBool::new(false)]), + audio_on: Arc::new([AtomicBool::new(true), AtomicBool::new(true)]), linked: Arc::new(AtomicBool::new(false)), }; let client = EmulatorClient { @@ -59,6 +61,7 @@ impl EmulatorBuilder { sim_count: builder.sim_count.clone(), running: builder.running.clone(), has_game: builder.has_game.clone(), + audio_on: builder.audio_on.clone(), linked: builder.linked.clone(), }; (builder, client) @@ -77,6 +80,7 @@ impl EmulatorBuilder { self.sim_count, self.running, self.has_game, + self.audio_on, self.linked, )?; if let Some(path) = self.rom { @@ -93,6 +97,7 @@ pub struct Emulator { sim_count: Arc, running: Arc<[AtomicBool; 2]>, has_game: Arc<[AtomicBool; 2]>, + audio_on: Arc<[AtomicBool; 2]>, linked: Arc, renderers: HashMap, } @@ -103,6 +108,7 @@ impl Emulator { sim_count: Arc, running: Arc<[AtomicBool; 2]>, has_game: Arc<[AtomicBool; 2]>, + audio_on: Arc<[AtomicBool; 2]>, linked: Arc, ) -> Result { Ok(Self { @@ -112,6 +118,7 @@ impl Emulator { sim_count, running, has_game, + audio_on, linked, renderers: HashMap::new(), }) @@ -210,15 +217,28 @@ impl Emulator { } } } - let weight = 1.0 / self.sims.len() as f32; - for sim in self.sims.iter_mut() { - sim.read_samples(&mut audio_samples, weight); + 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 !audio_samples.is_empty() { + 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(); } + self.audio.update(&audio_samples); + audio_samples.clear(); if idle { // The game is paused, and we have output all the video/audio we have. // Block the thread until a new command comes in. @@ -274,6 +294,10 @@ impl Emulator { } } } + EmulatorCommand::SetAudioEnabled(p1, p2) => { + self.audio_on[SimId::Player1.to_index()].store(p1, Ordering::Release); + self.audio_on[SimId::Player2.to_index()].store(p2, Ordering::Release); + } EmulatorCommand::Link => { self.link_sims(); } @@ -302,6 +326,7 @@ pub enum EmulatorCommand { StopSecondSim, Pause, Resume, + SetAudioEnabled(bool, bool), Link, Unlink, Reset(SimId), @@ -314,6 +339,7 @@ pub struct EmulatorClient { sim_count: Arc, running: Arc<[AtomicBool; 2]>, has_game: Arc<[AtomicBool; 2]>, + audio_on: Arc<[AtomicBool; 2]>, linked: Arc, } @@ -330,6 +356,9 @@ impl EmulatorClient { pub fn are_sims_linked(&self) -> bool { self.linked.load(Ordering::Acquire) } + pub fn is_audio_enabled(&self, sim_id: SimId) -> bool { + self.audio_on[sim_id.to_index()].load(Ordering::Acquire) + } pub fn send_command(&self, command: EmulatorCommand) { if let Err(err) = self.queue.send(command) { eprintln!( diff --git a/src/emulator/shrooms_vb_core.rs b/src/emulator/shrooms_vb_core.rs index a241772..fe2fa27 100644 --- a/src/emulator/shrooms_vb_core.rs +++ b/src/emulator/shrooms_vb_core.rs @@ -120,6 +120,7 @@ extern "C" fn on_frame(sim: *mut VB) -> i32 { const AUDIO_CAPACITY_SAMPLES: usize = 834 * 4; const AUDIO_CAPACITY_FLOATS: usize = AUDIO_CAPACITY_SAMPLES * 2; +pub const EXPECTED_FRAME_SIZE: usize = 834 * 2; struct VBState { frame_seen: bool,