Maraiah/maraiah/snd/defs.rs

101 lines
2.6 KiB
Rust

//! 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<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>,
}
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