X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-game%2Fsrc%2Fcodecs%2Fvmd.rs;h=939dcd6d25891b719160d9375628cbd930afcfd3;hb=7d57ae2f680d7a1eba7af2ee831f305b2f0f9324;hp=c8ef7daa55c5d4f3cc5ef1508b92a0ee341f0889;hpb=3e91c67bfde3462596707d2d82fa6271f8b99301;p=nihav.git diff --git a/nihav-game/src/codecs/vmd.rs b/nihav-game/src/codecs/vmd.rs index c8ef7da..939dcd6 100644 --- a/nihav-game/src/codecs/vmd.rs +++ b/nihav-game/src/codecs/vmd.rs @@ -335,6 +335,12 @@ impl NADecoder for VMDVideoDecoder { } } +impl NAOptionHandler for VMDVideoDecoder { + fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } + fn set_options(&mut self, _options: &[NAOption]) { } + fn query_option_value(&self, _name: &str) -> Option { None } +} + pub fn get_decoder_video() -> Box { Box::new(VMDVideoDecoder::new()) @@ -435,9 +441,6 @@ impl VMDAudioDecoder { pred + i32::from(SOL_AUD_STEPS16[(val & 0x7F) as usize]) } } - fn cvt_u8(val: u8) -> u8 { - val ^ 0x80 - } } impl NADecoder for VMDAudioDecoder { @@ -465,13 +468,14 @@ impl NADecoder for VMDAudioDecoder { self.is_odd = (channels == 2) && ((self.blk_size & 1) != 0); } } else { - fmt = SND_S16P_FORMAT; self.blk_align = ainfo.get_block_len(); if (flags & 0x10) == 0 { + fmt = SND_S16P_FORMAT; self.blk_size = (ainfo.get_block_len() + 1) * channels; self.mode = VMDAudioMode::DPCM; } else { - self.blk_size = (ainfo.get_block_len() + 1) / 2 + 3; + fmt = SND_S16_FORMAT; + self.blk_size = (ainfo.get_block_len() * channels + 1) / 2 + 3 * channels; self.mode = VMDAudioMode::ADPCM; } }; @@ -532,10 +536,7 @@ impl NADecoder for VMDAudioDecoder { dst[doff + i] = br.read_byte()?; } } else { - for i in 0..self.blk_size { - let val = Self::cvt_u8(br.read_byte()?); - dst[doff + i] = val; - } + unreachable!(); } doff += self.blk_align * channels; mask >>= 1; @@ -603,6 +604,9 @@ impl NADecoder for VMDAudioDecoder { let mut ima = IMAState::new(); for _ in 0..nblocks { if (mask & 1) != 0 { + for i in 0..self.blk_align { + dst[doff + i] = 0; + } doff += self.blk_align; mask >>= 1; continue; @@ -624,7 +628,35 @@ impl NADecoder for VMDAudioDecoder { mask >>= 1; } } else { - return Err(DecoderError::InvalidData); + let mut mask = mask; + let mut ima1 = IMAState::new(); + let mut ima2 = IMAState::new(); + for _ in 0..nblocks { + if (mask & 1) != 0 { + for i in 0..self.blk_align * 2 { + dst[doff + i] = 0; + } + doff += self.blk_align * 2; + mask >>= 1; + continue; + } + let pred1 = br.read_u16le()? as i16; + let pred2 = br.read_u16le()? as i16; + let step1 = br.read_byte()?; + let step2 = br.read_byte()?; + validate!((step1 as usize) < IMA_STEP_TABLE.len()); + validate!((step2 as usize) < IMA_STEP_TABLE.len()); + ima1.reset(pred1, step1); + ima2.reset(pred2, step2); + for _ in 0..self.blk_align { + let b = br.read_byte()?; + dst[doff] = ima1.expand_sample(b >> 4); + doff += 1; + dst[doff] = ima2.expand_sample(b & 0xF); + doff += 1; + } + mask >>= 1; + } } }, }; @@ -641,6 +673,12 @@ impl NADecoder for VMDAudioDecoder { } } +impl NAOptionHandler for VMDAudioDecoder { + fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } + fn set_options(&mut self, _options: &[NAOption]) { } + fn query_option_value(&self, _name: &str) -> Option { None } +} + pub fn get_decoder_audio() -> Box { Box::new(VMDAudioDecoder::new()) }