//! Sounds format definition type. use crate::{bin::{u32b, usize_from_u32}, err::*, fixed::*, sound::Sound16}; use bitflags::bitflags; /// Reads a sound definition. pub fn read(b: &[u8]) -> ResultS, u16, SoundDef)>> { read_data! { endian: BIG, buf: b, size: 64, start: 0, data { let index = u16[0]; let volume = u16[2] enum Volume; let flags = u16[4] flag SoundFlags; let chance = u16[6]; let pitch_lo = Fixed[8]; let pitch_hi = Fixed[12]; let n_sounds = u16[16] usize; let grp_ofs = u32[20] usize; } } if index == u16::max_value() { return Ok(None); } if n_sounds > 5 { bail!("too many sounds"); } let mut ofs = Vec::with_capacity(n_sounds); let mut p = 36; for _ in 0..n_sounds { ofs.push(grp_ofs + usize_from_u32(u32b(&b[p..]))); p += 4; } let sounds = Vec::with_capacity(n_sounds); Ok(Some((ofs, index, SoundDef{volume, flags, chance, pitch_lo, pitch_hi, sounds}))) } /// A sound definition containing one, many or no sounds. #[derive(Debug, Eq, PartialEq)] pub struct SoundDef { /// The volume type for this sound. pub volume: Volume, /// The flags for this sound. pub flags: SoundFlags, /// The chance out of `u16::max_value()` that this sound will not play. pub chance: u16, /// The low random pitch bound. pub pitch_lo: Fixed, /// The high random pitch bound. pub pitch_hi: Fixed, /// All of the sounds in this collection. pub sounds: Vec, } bitflags! { /// Flags for `SoundDef`. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] pub struct SoundFlags: u16 { /// The sound will not restart when trying to play over itself. const NO_RESTART = 1; /// The sound will not switch channels when trying to play over itself. const NO_CHANNEL_SWITCH = 1 << 1; /// The pitch variance will be halved. const LESS_PITCH_CHANGE = 1 << 2; /// The pitch variance will be nullified. const NO_PITCH_CHANGE = 1 << 3; /// The sound will play even when completely obstructed by walls. const NO_OBSTRUCTION = 1 << 4; /// The sound will play even when completely obstructed by media. const NO_MEDIA_OBSTRUCT = 1 << 5; /// The sound will have special stereo effects. const AMBIENT = 1 << 6; } } c_enum! { /// The type of volume this sound has. #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))] pub enum Volume: u16 { Quiet = 0, Normal = 1, Loud = 2, } } // EOF