fix 16 bit sounds
parent
58cbdd1a57
commit
1a802c47db
|
@ -41,6 +41,8 @@ pub trait Sound
|
|||
fn rate(&self) -> u16;
|
||||
fn len(&self) -> usize;
|
||||
fn index(&self, p: usize) -> i16;
|
||||
fn lp_beg(&self) -> usize;
|
||||
fn lp_end(&self) -> usize;
|
||||
|
||||
fn is_empty(&self) -> bool
|
||||
{
|
||||
|
@ -57,27 +59,18 @@ pub trait Sound
|
|||
}
|
||||
}
|
||||
|
||||
impl Sound8
|
||||
{
|
||||
/// Creates a new Sound8.
|
||||
pub fn new(rate: u16, len: usize) -> Self
|
||||
{
|
||||
Self{rate, data: Vec::with_capacity(len)}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sound16
|
||||
{
|
||||
/// Creates a new Sound16.
|
||||
pub fn new(rate: u16, len: usize) -> Self
|
||||
pub fn new(rate: u16, lp_beg: usize, lp_end: usize, len: usize) -> Self
|
||||
{
|
||||
Self{rate, data: Vec::with_capacity(len)}
|
||||
Self{rate, lp_beg, lp_end, data: Vec::with_capacity(len)}
|
||||
}
|
||||
|
||||
/// Creates a new Sound16 from an unsigned 8-bit stream.
|
||||
pub fn new_from_8(rate: u16, b: &[u8]) -> Self
|
||||
pub fn new_from_8(rate: u16, lp_beg: usize, lp_end: usize, b: &[u8]) -> Self
|
||||
{
|
||||
let mut snd = Sound16::new(rate, b.len());
|
||||
let mut snd = Sound16::new(rate, lp_beg, lp_end, b.len());
|
||||
|
||||
for &sample in b {
|
||||
snd.data.push(Sound16::sample_from_8(sample));
|
||||
|
@ -87,12 +80,12 @@ impl Sound16
|
|||
}
|
||||
|
||||
/// Creates a new Sound16 from a signed 16-bit stream.
|
||||
pub fn new_from_16(rate: u16, b: &[u8]) -> Self
|
||||
pub fn new_from_16(rate: u16, lp_beg: usize, lp_end: usize, b: &[u8]) -> Self
|
||||
{
|
||||
let mut snd = Sound16::new(rate, b.len() / 2);
|
||||
let mut snd = Sound16::new(rate, lp_beg, lp_end, b.len() / 2);
|
||||
|
||||
for (&x, &y) in b.iter().step_by(2).zip(b.iter().step_by(2).next()) {
|
||||
snd.data.push(i16::from_be_bytes([x, y]));
|
||||
for i in (0..b.len()).step_by(2) {
|
||||
snd.data.push(i16::from_le_bytes([b[i], b[i + 1]]));
|
||||
}
|
||||
|
||||
snd
|
||||
|
@ -101,18 +94,7 @@ impl Sound16
|
|||
/// Creates a signed 16-bit sample from an unsigned 8-bit sample.
|
||||
pub fn sample_from_8(sample: u8) -> i16
|
||||
{
|
||||
i16::from(sample) - 0x80 << 8
|
||||
}
|
||||
}
|
||||
|
||||
impl Sound for Sound8
|
||||
{
|
||||
fn rate(&self) -> u16 {self.rate}
|
||||
fn len(&self) -> usize {self.data.len()}
|
||||
|
||||
fn index(&self, p: usize) -> i16
|
||||
{
|
||||
Sound16::sample_from_8(self.data[p])
|
||||
(i16::from(sample) - 0x80) << 8
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,17 +103,15 @@ impl Sound for Sound16
|
|||
fn rate(&self) -> u16 {self.rate}
|
||||
fn len(&self) -> usize {self.data.len()}
|
||||
fn index(&self, p: usize) -> i16 {self.data[p]}
|
||||
}
|
||||
|
||||
pub struct Sound8
|
||||
{
|
||||
rate: u16,
|
||||
pub data: Vec<u8>,
|
||||
fn lp_beg(&self) -> usize {self.lp_beg}
|
||||
fn lp_end(&self) -> usize {self.lp_end}
|
||||
}
|
||||
|
||||
pub struct Sound16
|
||||
{
|
||||
rate: u16,
|
||||
lp_beg: usize,
|
||||
lp_end: usize,
|
||||
pub data: Vec<i16>,
|
||||
}
|
||||
|
||||
|
|
|
@ -392,8 +392,8 @@ pub type CollectionDef = (Option<Collection>, Option<Collection>);
|
|||
bitflags! {
|
||||
struct BmpFlags: u16
|
||||
{
|
||||
const Transparent = 0x40_00;
|
||||
const ColumnMajor = 0x80_00;
|
||||
const Transparent = 1 << 14;
|
||||
const ColumnMajor = 1 << 15;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,9 +401,9 @@ bitflags! {
|
|||
#[derive(Serialize)]
|
||||
pub struct FrameFlags: u16
|
||||
{
|
||||
const Obscure = 0x20_00;
|
||||
const FlipY = 0x40_00;
|
||||
const FlipX = 0x80_00;
|
||||
const Obscure = 1 << 13;
|
||||
const FlipY = 1 << 14;
|
||||
const FlipX = 1 << 15;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
//! Marathon Sounds format handling.
|
||||
|
||||
use crate::durandal::{bin::*, err::*, fixed::*, sound::*};
|
||||
//use bitflags::bitflags;
|
||||
use bitflags::bitflags;
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn sound(b: &[u8]) -> ResultS<Sound16>
|
||||
{
|
||||
let len = c_u32b(b, 4)? as usize;
|
||||
let rate = c_u16b(b, 8)?;
|
||||
let loop_beg = c_u32b(b, 12)?;
|
||||
let loop_end = c_u32b(b, 16)?;
|
||||
let magic = c_byte(b, 20)?;
|
||||
let len = c_u32b(b, 4)? as usize;
|
||||
let rate = c_u16b(b, 8)?;
|
||||
let lp_beg = c_u32b(b, 12)? as usize;
|
||||
let lp_end = c_u32b(b, 16)? as usize;
|
||||
let magic = c_byte(b, 20)?;
|
||||
|
||||
match magic {
|
||||
0 => Ok(Sound16::new_from_8(rate, c_data(b, 22..22 + len)?)),
|
||||
0 => {
|
||||
let stream = c_data(b, 22..22 + len)?;
|
||||
Ok(Sound16::new_from_8(rate, lp_beg, lp_end, stream))
|
||||
}
|
||||
0xFF => {
|
||||
let stream = c_data(b, 63..63 + len)?;
|
||||
match c_u16b(b, 47)? {
|
||||
16 => Ok(Sound16::new_from_16(rate, stream)),
|
||||
_ => Ok(Sound16::new_from_8(rate, stream)),
|
||||
let len = c_u32b(b, 22)? as usize;
|
||||
match c_u16b(b, 48)? {
|
||||
16 => {
|
||||
let stream = c_data(b, 63..63 + len * 2)?;
|
||||
Ok(Sound16::new_from_16(rate, lp_beg, lp_end, stream))
|
||||
}
|
||||
_ => {
|
||||
let stream = c_data(b, 63..63 + len)?;
|
||||
Ok(Sound16::new_from_8(rate, lp_beg, lp_end, stream))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => bail!("invalid magic number"),
|
||||
|
@ -37,6 +46,7 @@ fn sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
|
|||
let n_sounds = c_u16b(b, 16)? as usize;
|
||||
let grp_ofs = c_u32b(b, 20)? as usize;
|
||||
let volume = Volume::from_repr(volume)?;
|
||||
let flags = ok!(SoundFlags::from_bits(flags), "bad SoundFlags")?;
|
||||
let pitch_lo = Fixed::from_bits(pitch_lo);
|
||||
let pitch_hi = Fixed::from_bits(pitch_hi);
|
||||
|
||||
|
@ -56,7 +66,7 @@ fn sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
|
|||
p += 4;
|
||||
}
|
||||
|
||||
Ok(Some((ofs, index, SoundDef{volume, chance, pitch_lo, pitch_hi,
|
||||
Ok(Some((ofs, index, SoundDef{volume, flags, chance, pitch_lo, pitch_hi,
|
||||
sounds: Vec::with_capacity(n_sounds)})))
|
||||
}
|
||||
|
||||
|
@ -98,6 +108,7 @@ pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
|
|||
pub struct SoundDef
|
||||
{
|
||||
pub volume: Volume,
|
||||
pub flags: SoundFlags,
|
||||
pub chance: u16,
|
||||
pub pitch_lo: Fixed,
|
||||
pub pitch_hi: Fixed,
|
||||
|
@ -106,6 +117,20 @@ pub struct SoundDef
|
|||
|
||||
type SoundTable = HashMap<u16, SoundDef>;
|
||||
|
||||
bitflags! {
|
||||
#[derive(Serialize)]
|
||||
pub struct SoundFlags: u16
|
||||
{
|
||||
const NoRestart = 1;
|
||||
const NoChannelSwitch = 1 << 1;
|
||||
const LessPitchChange = 1 << 2;
|
||||
const NoPitchChange = 1 << 3;
|
||||
const NoObstruction = 1 << 4;
|
||||
const NoMediaObstruct = 1 << 5;
|
||||
const Ambient = 1 << 6;
|
||||
}
|
||||
}
|
||||
|
||||
c_enum! {
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum Volume: u16
|
||||
|
|
|
@ -109,8 +109,8 @@ bitflags! {
|
|||
#[derive(Serialize)]
|
||||
pub struct GroupFlags: u16
|
||||
{
|
||||
const DrawOnRight = 0x00_01;
|
||||
const DrawCenter = 0x00_02;
|
||||
const DrawOnRight = 1;
|
||||
const DrawCenter = 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue