Maraiah/maraiah/snd/defs.rs

97 lines
2.3 KiB
Rust

//! Sounds format definition type.
use crate::{bin::{u32b, usize_from_u32}, err::*, fixed::*, sound::Sound16};
/// Reads a sound definition.
pub fn read(b: &[u8]) -> ResultS<Option<(Vec<usize>, 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<Sound16>,
}
c_bitfield! {
/// 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.
NO_RESTART = 0,
/// The sound will not switch channels when trying to play over itself.
NO_CHANNEL_SWITCH = 1,
/// The pitch variance will be halved.
LESS_PITCH_CHANGE = 2,
/// The pitch variance will be nullified.
NO_PITCH_CHANGE = 3,
/// The sound will play even when completely obstructed by walls.
NO_OBSTRUCTION = 4,
/// The sound will play even when completely obstructed by media.
NO_MEDIA_OBSTRUCT = 5,
/// The sound will have special stereo effects.
AMBIENT = 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