feat(audio): centralize sound management with proper enum, improved iterator protocols, introduce new sound files

This commit is contained in:
Ryan Walters
2025-09-11 00:38:02 -05:00
parent 08c964c32e
commit 43532dac56
9 changed files with 124 additions and 42 deletions

View File

@@ -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<iter::Map<<Sound as IntoEnumIterator>::Iterator, fn(Sound) -> Asset>>,
state: u8,
}
impl Iterator for AssetIter {
type Item = Asset;
fn next(&mut self) -> Option<Self::Item> {
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",
}