diff --git a/src/audio.rs b/src/audio.rs index c242859..3fdeef4 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -15,6 +15,7 @@ pub struct Audio { _mixer_context: mixer::Sdl2MixerContext, sounds: Vec, next_sound_index: usize, + muted: bool, } impl Audio { @@ -51,6 +52,7 @@ impl Audio { _mixer_context: mixer_context, sounds, next_sound_index: 0, + muted: false, } } @@ -68,4 +70,18 @@ impl Audio { } self.next_sound_index = (self.next_sound_index + 1) % self.sounds.len(); } + + /// Instantly mute or unmute all channels. + pub fn set_mute(&mut self, mute: bool) { + let channels = 4; + let volume = if mute { 0 } else { 32 }; + for i in 0..channels { + mixer::Channel(i).set_volume(volume); + } + self.muted = mute; + } + + pub fn is_muted(&self) -> bool { + self.muted + } } diff --git a/src/game.rs b/src/game.rs index 70c5c88..d7ad6d2 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,5 +1,6 @@ //! This module contains the main game logic and state. use std::cell::RefCell; +use std::ops::Not; use std::rc::Rc; use rand::seq::IteratorRandom; @@ -37,7 +38,7 @@ pub struct Game<'a> { map: Rc>, debug_mode: DebugMode, score: u32, - audio: Audio, + pub audio: Audio, blinky: Blinky<'a>, edibles: Vec>, } @@ -107,18 +108,6 @@ impl<'a> Game<'a> { None, )); - // Load font from asset API - let font = { - let font_bytes = get_asset_bytes(Asset::FontKonami).expect("Failed to load asset").into_owned(); - let font_bytes_static: &'static [u8] = Box::leak(font_bytes.into_boxed_slice()); - let font_rwops = RWops::from_bytes(font_bytes_static).expect("Failed to create RWops for font"); - ttf_context - .load_font_from_rwops(font_rwops, 24) - .expect("Could not load font from asset API") - }; - - let audio = Audio::new(); - // Load map texture from asset API let map_bytes = get_asset_bytes(Asset::Map).expect("Failed to load asset"); let mut map_texture = texture_creator @@ -133,6 +122,18 @@ impl<'a> Game<'a> { Rc::clone(&pellet_texture), // placeholder for fruit sprite ); + // Load font from asset API + let font = { + let font_bytes = get_asset_bytes(Asset::FontKonami).expect("Failed to load asset").into_owned(); + let font_bytes_static: &'static [u8] = Box::leak(font_bytes.into_boxed_slice()); + let font_rwops = RWops::from_bytes(font_bytes_static).expect("Failed to create RWops for font"); + ttf_context + .load_font_from_rwops(font_rwops, 24) + .expect("Could not load font from asset API") + }; + + let audio = Audio::new(); + Game { canvas, pacman, @@ -173,6 +174,12 @@ impl<'a> Game<'a> { return; } + // Toggle mute + if keycode == Keycode::M { + self.audio.set_mute(self.audio.is_muted().not()); + return; + } + // Reset game if keycode == Keycode::R { self.reset(); diff --git a/src/main.rs b/src/main.rs index 98673e2..dafb967 100644 --- a/src/main.rs +++ b/src/main.rs @@ -107,6 +107,7 @@ pub fn main() { let texture_creator = canvas.texture_creator(); let mut game = Game::new(&mut canvas, &texture_creator, &ttf_context, &audio_subsystem); + game.audio.set_mute(cfg!(debug_assertions)); let mut event_pump = sdl_context.event_pump().expect("Could not get SDL EventPump");