From 43532dac5651d1593b17a154611a0c379731b744 Mon Sep 17 00:00:00 2001 From: Ryan Walters Date: Thu, 11 Sep 2025 00:38:02 -0500 Subject: [PATCH] feat(audio): centralize sound management with proper enum, improved iterator protocols, introduce new sound files --- assets/game/sound/begin.ogg | Bin 0 -> 18740 bytes assets/game/sound/intermission.ogg | Bin 0 -> 22775 bytes assets/game/sound/pacman/extra_life.ogg | Bin 0 -> 8098 bytes assets/game/sound/pacman/fruit.ogg | Bin 0 -> 4554 bytes assets/game/sound/pacman/ghost.ogg | Bin 0 -> 4900 bytes src/asset.rs | 66 +++++++++++++++++--- src/audio.rs | 79 ++++++++++++++++-------- src/platform/desktop.rs | 18 ++++-- tests/asset.rs | 3 +- 9 files changed, 124 insertions(+), 42 deletions(-) create mode 100644 assets/game/sound/begin.ogg create mode 100644 assets/game/sound/intermission.ogg create mode 100644 assets/game/sound/pacman/extra_life.ogg create mode 100644 assets/game/sound/pacman/fruit.ogg create mode 100644 assets/game/sound/pacman/ghost.ogg diff --git a/assets/game/sound/begin.ogg b/assets/game/sound/begin.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7d2616cec766e8f74c941afa69355bcb1fa0880d GIT binary patch literal 18740 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 R!GdwW&h7rZlFDAM(*^?b`z-(f literal 0 HcmV?d00001 diff --git a/assets/game/sound/intermission.ogg b/assets/game/sound/intermission.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8786ef82a07c65f6a0dccd20dadb2bf09d452046 GIT binary patch literal 22775 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 S=WD^LRY8Em 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 E3(3j)-~a#s literal 0 HcmV?d00001 diff --git a/assets/game/sound/pacman/fruit.ogg b/assets/game/sound/pacman/fruit.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f033f88f12b60dcc8820f83cc03b685d7928ccba GIT binary patch literal 4554 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 literal 0 HcmV?d00001 diff --git a/assets/game/sound/pacman/ghost.ogg b/assets/game/sound/pacman/ghost.ogg new file mode 100644 index 0000000000000000000000000000000000000000..88fc498e197c40cd4f928b573a344488b9f58fd2 GIT binary patch literal 4900 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 H&Y}JXNeG3E literal 0 HcmV?d00001 diff --git a/src/asset.rs b/src/asset.rs index 7619962..ef7ebf8 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -2,21 +2,62 @@ //! On desktop, assets are embedded using include_bytes!; on Emscripten, assets are loaded from the filesystem. use std::borrow::Cow; -use strum_macros::EnumIter; +use std::iter; + +use crate::audio::Sound; /// Enumeration of all game assets with cross-platform loading support. /// /// Each variant corresponds to a specific file that can be loaded either from /// binary-embedded data or embedded filesystem (Emscripten). -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Asset { - Waka(u8), /// Main sprite atlas containing all game graphics (atlas.png) AtlasImage, /// Terminal Vector font for text rendering (TerminalVector.ttf) Font, - /// Sound effect for Pac-Man's death - DeathSound, + /// Sound file assets + SoundFile(Sound), +} + +use strum::IntoEnumIterator; + +impl Asset { + #[allow(dead_code)] + pub fn into_iter() -> AssetIter { + AssetIter { + sound_iter: None, + state: 0, + } + } +} + +#[allow(clippy::type_complexity)] +pub struct AssetIter { + sound_iter: Option::Iterator, fn(Sound) -> Asset>>, + state: u8, +} + +impl Iterator for AssetIter { + type Item = Asset; + + fn next(&mut self) -> Option { + match self.state { + 0 => { + self.state = 1; + Some(Asset::AtlasImage) + } + 1 => { + self.state = 2; + Some(Asset::Font) + } + 2 => self + .sound_iter + .get_or_insert_with(|| Sound::iter().map(Asset::SoundFile)) + .next(), + _ => None, + } + } } impl Asset { @@ -29,11 +70,16 @@ impl Asset { pub fn path(&self) -> &str { use Asset::*; match self { - Waka(0) => "sound/pacman/waka/1.ogg", - Waka(1) => "sound/pacman/waka/2.ogg", - Waka(2) => "sound/pacman/waka/3.ogg", - Waka(3..=u8::MAX) => "sound/pacman/waka/4.ogg", - DeathSound => "sound/pacman/death.ogg", + SoundFile(Sound::Waka(0)) => "sound/pacman/waka/1.ogg", + SoundFile(Sound::Waka(1)) => "sound/pacman/waka/2.ogg", + SoundFile(Sound::Waka(2)) => "sound/pacman/waka/3.ogg", + SoundFile(Sound::Waka(3..=u8::MAX)) => "sound/pacman/waka/4.ogg", + SoundFile(Sound::PacmanDeath) => "sound/pacman/death.ogg", + SoundFile(Sound::ExtraLife) => "sound/pacman/extra_life.ogg", + SoundFile(Sound::Fruit) => "sound/pacman/fruit.ogg", + SoundFile(Sound::Ghost) => "sound/pacman/ghost.ogg", + SoundFile(Sound::Beginning) => "sound/begin.ogg", + SoundFile(Sound::Intermission) => "sound/intermission.ogg", AtlasImage => "atlas.png", Font => "TerminalVector.ttf", } diff --git a/src/audio.rs b/src/audio.rs index 13516da..f7fe4ee 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -1,11 +1,43 @@ //! This module handles the audio playback for the game. +use std::collections::HashMap; + use crate::asset::{get_asset_bytes, Asset}; use sdl2::{ mixer::{self, Chunk, InitFlag, LoaderRWops, AUDIO_S16LSB, DEFAULT_CHANNELS}, rwops::RWops, }; +use strum::IntoEnumIterator; -const SOUND_ASSETS: [Asset; 4] = [Asset::Waka(0), Asset::Waka(1), Asset::Waka(2), Asset::Waka(3)]; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Sound { + Waka(u8), + PacmanDeath, + ExtraLife, + Fruit, + Ghost, + Beginning, + Intermission, +} + +impl IntoEnumIterator for Sound { + type Iterator = std::vec::IntoIter; + + fn iter() -> Self::Iterator { + vec![ + Sound::Waka(0), + Sound::Waka(1), + Sound::Waka(2), + Sound::Waka(3), + Sound::PacmanDeath, + Sound::ExtraLife, + Sound::Fruit, + Sound::Ghost, + Sound::Beginning, + Sound::Intermission, + ] + .into_iter() + } +} /// The audio system for the game. /// @@ -14,9 +46,8 @@ const SOUND_ASSETS: [Asset; 4] = [Asset::Waka(0), Asset::Waka(1), Asset::Waka(2) /// functions will silently do nothing. pub struct Audio { _mixer_context: Option, - sounds: Vec, - death_sound: Option, - next_sound_index: usize, + sounds: HashMap, + next_waka_index: u8, muted: bool, disabled: bool, } @@ -54,9 +85,8 @@ impl Audio { tracing::warn!("Failed to open audio: {}. Audio will be disabled.", e); return Self { _mixer_context: None, - sounds: Vec::new(), - death_sound: None, - next_sound_index: 0, + sounds: HashMap::new(), + next_waka_index: 0u8, muted: false, disabled: true, }; @@ -77,9 +107,8 @@ impl Audio { tracing::warn!("Failed to initialize SDL2_mixer: {}. Audio will be disabled.", e); return Self { _mixer_context: None, - sounds: Vec::new(), - death_sound: None, - next_sound_index: 0, + sounds: HashMap::new(), + next_waka_index: 0u8, muted: false, disabled: true, }; @@ -87,12 +116,14 @@ impl Audio { }; // Try to load sounds, but don't panic if any fail - let mut sounds = Vec::new(); - for (i, asset) in SOUND_ASSETS.iter().enumerate() { - match get_asset_bytes(*asset) { + let mut sounds = HashMap::new(); + for (i, asset) in Sound::iter().enumerate() { + match get_asset_bytes(Asset::SoundFile(asset)) { Ok(data) => match RWops::from_bytes(&data) { Ok(rwops) => match rwops.load_wav() { - Ok(chunk) => sounds.push(chunk), + Ok(chunk) => { + sounds.insert(asset, chunk); + } Err(e) => { tracing::warn!("Failed to load sound {} from asset API: {}", i + 1, e); } @@ -107,7 +138,7 @@ impl Audio { } } - let death_sound = match get_asset_bytes(Asset::DeathSound) { + let death_sound = match get_asset_bytes(Asset::SoundFile(Sound::PacmanDeath)) { Ok(data) => match RWops::from_bytes(&data) { Ok(rwops) => match rwops.load_wav() { Ok(chunk) => Some(chunk), @@ -132,9 +163,8 @@ impl Audio { tracing::warn!("No sounds loaded successfully. Audio will be disabled."); return Self { _mixer_context: Some(mixer_context), - sounds: Vec::new(), - death_sound: None, - next_sound_index: 0, + sounds: HashMap::new(), + next_waka_index: 0u8, muted: false, disabled: true, }; @@ -143,8 +173,7 @@ impl Audio { Audio { _mixer_context: Some(mixer_context), sounds, - death_sound, - next_sound_index: 0, + next_waka_index: 0u8, muted: false, disabled: false, } @@ -160,17 +189,17 @@ impl Audio { return; } - if let Some(chunk) = self.sounds.get(self.next_sound_index) { + if let Some(chunk) = self.sounds.get(&Sound::Waka(self.next_waka_index)) { match mixer::Channel(0).play(chunk, 0) { Ok(channel) => { - tracing::trace!("Playing sound #{} on channel {:?}", self.next_sound_index + 1, channel); + tracing::trace!("Playing sound #{} on channel {:?}", self.next_waka_index + 1, channel); } Err(e) => { - tracing::warn!("Could not play sound #{}: {}", self.next_sound_index + 1, e); + tracing::warn!("Could not play sound #{}: {}", self.next_waka_index + 1, e); } } } - self.next_sound_index = (self.next_sound_index + 1) % self.sounds.len(); + self.next_waka_index = (self.next_waka_index + 1) & 3; } /// Plays the death sound effect. @@ -179,7 +208,7 @@ impl Audio { return; } - if let Some(chunk) = &self.death_sound { + if let Some(chunk) = self.sounds.get(&Sound::PacmanDeath) { mixer::Channel::all().play(chunk, 0).ok(); } } diff --git a/src/platform/desktop.rs b/src/platform/desktop.rs index e92beeb..addb3a7 100644 --- a/src/platform/desktop.rs +++ b/src/platform/desktop.rs @@ -6,6 +6,7 @@ use std::time::Duration; use rand::rngs::ThreadRng; use crate::asset::Asset; +use crate::audio::Sound; use crate::error::{AssetError, PlatformError}; /// Desktop platform implementation. @@ -59,13 +60,20 @@ pub fn init_console() -> Result<(), PlatformError> { pub fn get_asset_bytes(asset: Asset) -> Result, AssetError> { match asset { - Asset::Waka(0) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/1.ogg"))), - Asset::Waka(1) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/2.ogg"))), - Asset::Waka(2) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/3.ogg"))), - Asset::Waka(3..=u8::MAX) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/4.ogg"))), + Asset::SoundFile(sound) => match sound { + Sound::Waka(0) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/1.ogg"))), + Sound::Waka(1) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/2.ogg"))), + Sound::Waka(2) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/3.ogg"))), + Sound::Waka(3..=u8::MAX) => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/waka/4.ogg"))), + Sound::PacmanDeath => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/death.ogg"))), + Sound::ExtraLife => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/extra_life.ogg"))), + Sound::Fruit => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/fruit.ogg"))), + Sound::Ghost => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/ghost.ogg"))), + Sound::Beginning => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/begin.ogg"))), + Sound::Intermission => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/intermission.ogg"))), + }, Asset::AtlasImage => Ok(Cow::Borrowed(include_bytes!("../../assets/game/atlas.png"))), Asset::Font => Ok(Cow::Borrowed(include_bytes!("../../assets/game/TerminalVector.ttf"))), - Asset::DeathSound => Ok(Cow::Borrowed(include_bytes!("../../assets/game/sound/pacman/death.ogg"))), } } diff --git a/tests/asset.rs b/tests/asset.rs index b344dd5..4ea8dbc 100644 --- a/tests/asset.rs +++ b/tests/asset.rs @@ -1,10 +1,9 @@ use pacman::asset::Asset; use speculoos::prelude::*; -use strum::IntoEnumIterator; #[test] fn all_asset_paths_exist() { - for asset in Asset::iter() { + for asset in Asset::into_iter() { let path = asset.path(); let full_path = format!("assets/game/{}", path);