remove trailing whitespaces
[nihav.git] / nihav-game / src / codecs / vmd.rs
CommitLineData
9895bd7b
KS
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
b4d5b851 3use nihav_codec_support::codecs::HAMShuffler;
9895bd7b 4use std::str::FromStr;
f45dfcf7 5use std::sync::Arc;
9895bd7b
KS
6
7macro_rules! lz_op {
8 (read; $dst:ident, $dpos:expr, $window:ident, $wpos:expr, $br:expr, $dst_size:expr) => {
9 validate!($dpos < $dst_size);
10 let b = $br.read_byte()?;
11 $dst[$dpos] = b;
12 $dpos += 1;
13 $window[$wpos] = b;
14 $wpos = ($wpos + 1) & 0xFFF;
15 };
16 (copy; $dst:ident, $dpos:expr, $window:ident, $wpos:expr, $off:expr, $dst_size:expr) => {
17 let b = $window[$off];
18 validate!($dpos < $dst_size);
19 $dst[$dpos] = b;
20 $dpos += 1;
21 $window[$wpos] = b;
22 $wpos = ($wpos + 1) & 0xFFF;
23 $off = ($off + 1) & 0xFFF;
24 };
25}
26fn lz_unpack(br: &mut ByteReader, dst: &mut [u8]) -> DecoderResult<()> {
27 let mut window: [u8; 0x1000] = [0x20; 0x1000];
28
29 let dst_size = br.read_u32le()? as usize;
30 validate!(dst_size <= dst.len());
31 let mut pos;
32 let esc_len;
33 if br.peek_u32le()? == 0x56781234 {
34 br.read_skip(4)?;
35 pos = 0x111;
36 esc_len = 15;
37 } else {
38 pos = 0xFEE;
39 esc_len = 255;
40 }
41
42 let mut opos = 0;
43 while br.left() > 0 && opos < dst_size {
44 let op = br.read_byte()?;
45 if (op == 0xFF) && (br.left() > 8) {
46 for _ in 0..8 {
47 lz_op!(read; dst, opos, window, pos, br, dst_size);
48 }
49 } else {
50 for i in 0..8 {
51 if opos == dst_size { break; }
52 let is_literal = ((op >> i) & 1) != 0;
53 if is_literal {
54 lz_op!(read; dst, opos, window, pos, br, dst_size);
55 } else {
56 let b0 = br.read_byte()? as usize;
57 let b1 = br.read_byte()? as usize;
58 let mut off = b0 | ((b1 & 0xF0) << 4);
59 let mut len = b1 & 0xF;
60 if len == esc_len {
61 len = (br.read_byte()? as usize) + esc_len;
62 }
63 for _ in 0..len+3 {
64 lz_op!(copy; dst, opos, window, pos, off, dst_size);
65 }
66 }
67 }
68 }
69 }
70 Ok(())
71}
72
73fn rle_unpack(br: &mut ByteReader, len: usize, dst: &mut [u8]) -> DecoderResult<()> {
74 let end = br.tell() + (len as u64);
75 let mut dpos = 0;
76 if (len & 1) != 0 {
77 dst[dpos] = br.read_byte()?;
78 dpos += 1;
79 }
80 while dpos < dst.len() && br.tell() < end {
81 let val = br.read_byte()?;
82 let len = ((val & 0x7F) as usize) * 2;
83 validate!(dpos + len <= dst.len());
84 if (val & 0x80) != 0 {
85 let dst = &mut dst[dpos..][..len];
86 br.read_buf(dst)?;
87 } else {
88 let val = br.read_byte()?;
89 for i in 0..len {
90 dst[dpos + i] = val;
91 }
92 }
93 dpos += len;
94 }
95 Ok(())
96}
97
98fn decode_frame_data(br: &mut ByteReader, dst: &mut [u8], mut dpos: usize, stride: usize, w: usize, h: usize, method: u8) -> DecoderResult<bool> {
99 match method {
100 1 => {
101 for _ in 0..h {
102 let mut x = 0;
103 while x < w {
104 let val = br.read_byte()?;
105 let len = ((val & 0x7F) as usize) + 1;
106 validate!(x + len <= w);
107 if (val & 0x80) != 0 {
108 let pix = &mut dst[dpos + x..][..len];
109 br.read_buf(pix)?;
110 } // otherwise skip already existing data
111 x += len;
112 }
113 dpos += stride;
114 }
115 Ok(false)
116 },
117 2 => {
118 for _ in 0..h {
119 let pix = &mut dst[dpos..][..w];
120 br.read_buf(pix)?;
121 dpos += stride;
122 }
123 Ok(true)
124 },
125 3 => {
126 for _ in 0..h {
127 let mut x = 0;
128 while x < w {
129 let val = br.read_byte()?;
130 let len = ((val & 0x7F) as usize) + 1;
131 validate!(x + len <= w);
132 if (val & 0x80) != 0 {
133 let pix = &mut dst[dpos + x..][..len];
134 if br.peek_byte()? == 0xFF {
135 br.read_skip(1)?;
136 rle_unpack(br, len, pix)?;
137 } else {
138 br.read_buf(pix)?;
139 }
140 } // otherwise data is already there
141 x += len;
142 }
143 dpos += stride;
144 }
145 Ok(false)
146 },
e69b1148 147 _ => Err(DecoderError::InvalidData),
9895bd7b
KS
148 }
149}
150
151struct VMDVideoDecoder {
2422d969 152 info: NACodecInfoRef,
9895bd7b
KS
153 pal: [u8; 768],
154 buf: Vec<u8>,
155 width: usize,
156 height: usize,
157 hams: HAMShuffler,
158}
159
160impl VMDVideoDecoder {
161 fn new() -> Self {
162 Self {
2422d969 163 info: NACodecInfoRef::default(),
9895bd7b
KS
164 pal: [0; 768],
165 buf: Vec::new(),
166 width: 0,
167 height: 0,
168 hams: HAMShuffler::default(),
169 }
170 }
171 fn decode_frame(&mut self, br: &mut ByteReader, buf: &mut NAVideoBuffer<u8>) -> DecoderResult<bool> {
172 let paloff = buf.get_offset(1);
173 let stride = buf.get_stride(0);
1a967e6b 174 let data = buf.get_data_mut().unwrap();
9895bd7b
KS
175 let dst = data.as_mut_slice();
176
177 let frame_x = br.read_u16le()? as usize;
178 let frame_y = br.read_u16le()? as usize;
179 let frame_l = br.read_u16le()? as usize;
180 let frame_d = br.read_u16le()? as usize;
181 br.read_skip(1)?;
182 let flags = br.read_byte()?;
183 let has_pal = (flags & 0x02) != 0;
5961ae1d
KS
184 if (frame_x == 0xFFFF) && (frame_y == 0xFFFF) && (frame_l == 0xFFFF) && (frame_d == 0xFFFF) {
185 return Ok(false);
186 }
9895bd7b
KS
187 validate!(frame_l >= frame_x && frame_d >= frame_y);
188 validate!(frame_l < self.width && frame_d < self.height);
189
190 if has_pal {
191 br.read_skip(2)?;
192 for e in self.pal.iter_mut() {
193 let val = br.read_byte()?;
194 *e = (val << 2) | (val >> 4);
195 }
196 }
197
198 let dpal = &mut dst[paloff..][..768];
199 dpal.copy_from_slice(&self.pal[0..]);
200
201 if br.left() == 0 { return Ok(false); }
202
203 let w = frame_l + 1 - frame_x;
204 let h = frame_d + 1 - frame_y;
205 let dpos = frame_x + frame_y * stride;
206
207 let method = br.read_byte()?;
208 let is_intra;
209 if (method & 0x80) != 0 {
e69b1148 210 validate!(!self.buf.is_empty());
9895bd7b
KS
211 lz_unpack(br, &mut self.buf)?;
212 let mut mr = MemoryReader::new_read(&self.buf);
213 let mut buf_br = ByteReader::new(&mut mr);
214 is_intra = decode_frame_data(&mut buf_br, dst, dpos, stride, w, h, method & 0x7F)?;
215 } else {
216 is_intra = decode_frame_data(br, dst, dpos, stride, w, h, method & 0x7F)?;
217 }
218 Ok(is_intra && frame_x == 0 && frame_y == 0 && w == self.width && h == self.height)
219 }
220}
221
222impl NADecoder for VMDVideoDecoder {
01613464 223 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
9895bd7b
KS
224 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
225 self.width = vinfo.get_width();
226 self.height = vinfo.get_height();
227 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, PAL8_FORMAT));
2422d969 228 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
9895bd7b
KS
229 validate!(info.get_extradata().is_some());
230
231 if let Some(ref edata) = info.get_extradata() {
232 validate!(edata.len() == 0x330);
233 let unp_size = read_u32le(&edata[800..])? as usize;
234 validate!(unp_size < self.width * self.height * 3 + 64); // just for sanity
235 self.buf.resize(unp_size, 0);
236 for i in 0..768 {
237 let el = edata[28 + i];
238 self.pal[i] = (el << 2) | (el >> 4);
239 }
240 }
241
242 Ok(())
243 } else {
244 Err(DecoderError::InvalidData)
245 }
246 }
01613464 247 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
9895bd7b
KS
248 let src = pkt.get_buffer();
249 validate!(src.len() >= 10);
250
251 let mut mr = MemoryReader::new_read(&src);
252 let mut br = ByteReader::new(&mut mr);
253
254 let mut buf;
255 let bufret = self.hams.clone_ref();
256 if let Some(bbuf) = bufret {
257 buf = bbuf;
258 } else {
e69b1148 259 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
9895bd7b
KS
260 buf = bufinfo.get_vbuf().unwrap();
261 self.hams.add_frame(buf);
262 buf = self.hams.get_output_frame().unwrap();
263 }
264
265 let is_intra = self.decode_frame(&mut br, &mut buf)?;
266
267 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
268 frm.set_keyframe(is_intra);
269 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
171860fc 270 Ok(frm.into_ref())
9895bd7b 271 }
f9be4e75
KS
272 fn flush(&mut self) {
273 self.hams.clear();
274 }
9895bd7b
KS
275}
276
277
08a1fab7 278pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
9895bd7b
KS
279 Box::new(VMDVideoDecoder::new())
280}
281
f45dfcf7
KS
282#[derive(Clone,Copy,PartialEq)]
283enum VMDAudioMode {
284 U8,
285 DPCM,
286 StereoDPCM,
287}
288
9895bd7b
KS
289struct VMDAudioDecoder {
290 ainfo: NAAudioInfo,
f45dfcf7 291 info: Arc<NACodecInfo>,
9895bd7b 292 chmap: NAChannelMap,
9895bd7b
KS
293 blk_align: usize,
294 blk_size: usize,
f45dfcf7
KS
295 mode: VMDAudioMode,
296 pred: [i32; 2],
297 last_byte: Option<u8>,
298 is_odd: bool,
299 ch: usize,
9895bd7b
KS
300}
301
302const SOL_AUD_STEPS16: [i16; 128] = [
303 0x00, 0x08, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
304 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
305 0xF0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160,
306 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 0x1D0, 0x1E0,
307 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
308 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270,
309 0x278, 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0,
310 0x2B8, 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0,
311 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330,
312 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
313 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0,
314 0x3B8, 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0,
315 0x3F8, 0x400, 0x440, 0x480, 0x4C0, 0x500, 0x540, 0x580,
316 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780,
317 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
318 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
319];
320
321impl VMDAudioDecoder {
322 fn new() -> Self {
323 Self {
324 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
f45dfcf7 325 info: NACodecInfo::new_dummy(),
9895bd7b 326 chmap: NAChannelMap::new(),
9895bd7b
KS
327 blk_align: 0,
328 blk_size: 0,
f45dfcf7
KS
329 mode: VMDAudioMode::U8,
330 pred: [0; 2],
331 last_byte: None,
332 is_odd: false,
333 ch: 0,
9895bd7b
KS
334 }
335 }
336 fn decode_16bit(&self, dst: &mut [i16], off1: usize, br: &mut ByteReader, nblocks: usize, mut mask: u32) -> DecoderResult<()> {
337 let channels = self.chmap.num_channels();
338 let mut off = [0, off1];
339 for _ in 0..nblocks {
340 if (mask & 1) != 0 {
341 for ch in 0..channels {
342 for i in 0..self.blk_align {
343 dst[off[ch] + i] = 0;
344 }
345 off[ch] += self.blk_align;
346 }
347 } else {
348 let mut pred: [i32; 2] = [0; 2];
349 for ch in 0..channels {
e69b1148 350 pred[ch] = i32::from(br.read_u16le()?);
9895bd7b
KS
351 dst[off[ch]] = pred[ch] as i16;
352 off[ch] += 1;
353 }
354 let mut ch = 0;
355 let flip_ch = if channels == 2 { 1 } else { 0 };
aa7e65d2 356 for _ in channels..self.blk_align*channels {
f45dfcf7 357 pred[ch] = Self::pred16(pred[ch], br.read_byte()?);
9895bd7b
KS
358 //pred[ch] = pred[ch].max(-32768).min(32767);
359 dst[off[ch]] = pred[ch] as i16;
360 off[ch] += 1;
361 ch ^= flip_ch;
362 }
363 }
364 mask >>= 1;
365 }
366 validate!(br.left() == 0);
367 Ok(())
368 }
f45dfcf7
KS
369 fn pred16(pred: i32, val: u8) -> i32 {
370 if (val & 0x80) != 0 {
371 pred - i32::from(SOL_AUD_STEPS16[(val & 0x7F) as usize])
372 } else {
373 pred + i32::from(SOL_AUD_STEPS16[(val & 0x7F) as usize])
374 }
375 }
376 fn cvt_u8(val: u8) -> u8 {
6eda3136 377 val ^ 0x80
f45dfcf7 378 }
9895bd7b
KS
379}
380
381impl NADecoder for VMDAudioDecoder {
01613464 382 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
9895bd7b
KS
383 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
384 let fmt;
f45dfcf7
KS
385 let channels = ainfo.get_channels() as usize;
386 let edata = info.get_extradata();
387 let flags = if let Some(ref buf) = edata {
388 validate!(buf.len() >= 2);
389 (buf[0] as u16) | ((buf[1] as u16) << 8)
390 } else {
391 0
392 };
393 validate!((channels == 1) ^ ((flags & 0x8200) != 0));
9895bd7b 394 if ainfo.get_format().get_bits() == 8 {
9895bd7b 395 self.blk_size = ainfo.get_block_len();
f45dfcf7
KS
396 self.blk_align = ainfo.get_block_len() / channels;
397 if (flags & 0x8000) == 0 {
398 fmt = SND_U8_FORMAT;
399 self.mode = VMDAudioMode::U8;
400 } else {
401 fmt = SND_S16_FORMAT;
402 self.mode = VMDAudioMode::StereoDPCM;
403 self.is_odd = (channels == 2) && ((self.blk_size & 1) != 0);
404 }
9895bd7b
KS
405 } else {
406 fmt = SND_S16P_FORMAT;
f45dfcf7 407 self.blk_size = (ainfo.get_block_len() + 1) * channels;
aa7e65d2 408 self.blk_align = ainfo.get_block_len();
f45dfcf7 409 self.mode = VMDAudioMode::DPCM;
9895bd7b 410 };
9895bd7b 411 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, ainfo.get_block_len());
f45dfcf7
KS
412 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo.clone()));
413 self.chmap = NAChannelMap::from_str(if channels == 1 { "C" } else { "L,R" }).unwrap();
9895bd7b
KS
414 Ok(())
415 } else {
416 Err(DecoderError::InvalidData)
417 }
418 }
01613464 419 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
9895bd7b
KS
420 let info = pkt.get_stream().get_info();
421 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
422 let pktbuf = pkt.get_buffer();
423 validate!(pktbuf.len() >= 6);
424 let mut mr = MemoryReader::new_read(&pktbuf);
425 let mut br = ByteReader::new(&mut mr);
426 let blk_type = br.read_byte()?;
427 br.read_skip(9)?;
428 let mask;
429 let nblocks;
430 if blk_type == 2 { // initial
431 mask = br.read_u32le()?;
432 nblocks = (mask.count_ones() as usize) + (pktbuf.len() - 14) / self.blk_size;
433 } else if blk_type == 3 { // silence
434 mask = 1;
435 nblocks = 1;
436 } else {
437 mask = 0;
438 nblocks = 1;
439 }
f45dfcf7
KS
440 let mut samples = nblocks * self.blk_align;
441 if self.mode == VMDAudioMode::StereoDPCM && self.is_odd {
442 samples += (nblocks + if self.last_byte.is_some() { 1 } else { 0 }) / 2;
443 }
9895bd7b 444 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
f45dfcf7
KS
445 match self.mode {
446 VMDAudioMode::DPCM => {
447 let mut adata = abuf.get_abuf_i16().unwrap();
448 let off1 = adata.get_offset(1);
449 let mut dst = adata.get_data_mut().unwrap();
450 self.decode_16bit(&mut dst, off1, &mut br, nblocks, mask)?;
451 },
452 VMDAudioMode::U8 => {
453 let mut adata = abuf.get_abuf_u8().unwrap();
454 let dst = adata.get_data_mut().unwrap();
455 let mut doff = 0;
456 let mut mask = mask;
457 let channels = self.chmap.num_channels();
458 for _ in 0..nblocks {
459 if (mask & 1) != 0 {
460 for i in 0..self.blk_align * channels {
461 dst[doff + i] = 128;
462 }
463 } else if channels == 1 {
464 for i in 0..self.blk_size {
465 dst[doff + i] = br.read_byte()?;
466 }
467 } else {
468 for i in 0..self.blk_size {
469 let val = Self::cvt_u8(br.read_byte()?);
470 dst[doff + i] = val;
471 }
9895bd7b 472 }
f45dfcf7
KS
473 doff += self.blk_align * channels;
474 mask >>= 1;
475 }
476 },
477 VMDAudioMode::StereoDPCM => {
478 let mut adata = abuf.get_abuf_i16().unwrap();
479 let dst = adata.get_data_mut().unwrap();
480 let mut doff = 0;
481 let mut mask = mask;
482 let mut ch = self.ch;
483 for _ in 0..nblocks {
484 let put_sample = self.last_byte.is_some();
485 if let (true, Some(val)) = (self.is_odd, self.last_byte) {
486 self.pred[ch] = Self::pred16(self.pred[ch], val);
487 dst[doff] = self.pred[ch] as i16;
488 doff += 1;
489 ch ^= 1;
490 self.last_byte = None;
9895bd7b 491 }
f45dfcf7
KS
492 if (mask & 1) != 0 {
493 for i in 0..self.blk_align {
494 dst[doff + i * 2 + 0] = self.pred[ch] as i16;
495 dst[doff + i * 2 + 1] = self.pred[ch ^ 1] as i16;
496 }
497 if self.is_odd {
498 if put_sample {
499 dst[doff + self.blk_align * 2] = self.pred[ch] as i16;
500 doff += 1;
501 ch ^= 1;
502 } else {
503 self.last_byte = Some(0);
504 }
505 }
506 } else {
507 for i in 0..self.blk_align {
508 self.pred[ch] = Self::pred16(self.pred[ch], br.read_byte()?);
509 dst[doff + i * 2] = self.pred[ch] as i16;
510 self.pred[ch ^ 1] = Self::pred16(self.pred[ch ^ 1], br.read_byte()?);
511 dst[doff + i * 2 + 1] = self.pred[ch ^ 1] as i16;
512 }
513 if self.is_odd {
514 let val = br.read_byte()?;
515 if put_sample {
516 self.pred[ch] = Self::pred16(self.pred[ch], val);
517 dst[doff + self.blk_align * 2] = self.pred[ch] as i16;
518 doff += 1;
519 ch ^= 1;
520 } else {
521 self.last_byte = Some(val);
522 }
aa7e65d2
KS
523 }
524 }
f45dfcf7
KS
525 doff += self.blk_align * 2;
526 mask >>= 1;
9895bd7b 527 }
f45dfcf7
KS
528 self.ch = ch;
529 },
530 };
9895bd7b 531
f45dfcf7 532 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
9895bd7b
KS
533 frm.set_duration(Some(samples as u64));
534 frm.set_keyframe(true);
171860fc 535 Ok(frm.into_ref())
9895bd7b
KS
536 } else {
537 Err(DecoderError::InvalidData)
538 }
539 }
f9be4e75
KS
540 fn flush(&mut self) {
541 }
9895bd7b
KS
542}
543
08a1fab7 544pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
9895bd7b
KS
545 Box::new(VMDAudioDecoder::new())
546}
547
548#[cfg(test)]
549mod test {
550 use nihav_core::codecs::RegisteredDecoders;
551 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 552 use nihav_codec_support::test::dec_video::*;
e64739f8
KS
553 use crate::game_register_all_codecs;
554 use crate::game_register_all_demuxers;
9895bd7b
KS
555 #[test]
556 fn test_vmd_video() {
557 let mut dmx_reg = RegisteredDemuxers::new();
558 game_register_all_demuxers(&mut dmx_reg);
559 let mut dec_reg = RegisteredDecoders::new();
560 game_register_all_codecs(&mut dec_reg);
561
fe435580
KS
562 test_decoding("vmd", "vmd-video", "assets/Game/2832.VMD", Some(10), &dmx_reg, &dec_reg,
563 ExpectedTestResult::MD5Frames(vec![
564 [0xd29e0214, 0xf38ad154, 0xccbd381f, 0x3de1109c],
565 [0x904074eb, 0x202b1d6f, 0xe3f68538, 0xf0db641c],
566 [0x9c8b1b6c, 0xe205b8dc, 0xbfb07406, 0x993ace41],
567 [0x71ce4220, 0x8747fd05, 0x854dd86d, 0x2664cde5],
568 [0x3bc65fa4, 0xebb95292, 0xe0a0fea6, 0x0acfdea1],
569 [0x33982045, 0x8d11b69b, 0xac254a75, 0x63896a21],
570 [0xa667db33, 0x90e122d3, 0x2243da15, 0xcc4bffd2],
571 [0x518621c1, 0xb91412bc, 0x12312869, 0x141ef647],
572 [0x3069977e, 0x68fd3fa0, 0x2bfdb00d, 0x1e694684],
573 [0x246c12aa, 0x15137fb0, 0xa4b0fc3e, 0x626a2676],
574 [0x72cce7e3, 0x98506d04, 0xd4d8bbaf, 0x3cc5e32d]]));
9895bd7b
KS
575 }
576 #[test]
fe435580 577 fn test_vmd_audio_u8() {
9895bd7b
KS
578 let mut dmx_reg = RegisteredDemuxers::new();
579 game_register_all_demuxers(&mut dmx_reg);
580 let mut dec_reg = RegisteredDecoders::new();
581 game_register_all_codecs(&mut dec_reg);
582
fe435580
KS
583 test_decoding("vmd", "vmd-audio", "assets/Game/1491.VMD", None, &dmx_reg, &dec_reg,
584 ExpectedTestResult::MD5([0x75037601, 0xbc7b3976, 0x6e1c948b, 0xf05a3d6c]));
585 }
586 #[test]
587 fn test_vmd_audio_s16_old() {
588 let mut dmx_reg = RegisteredDemuxers::new();
589 game_register_all_demuxers(&mut dmx_reg);
590 let mut dec_reg = RegisteredDecoders::new();
591 game_register_all_codecs(&mut dec_reg);
592
593 test_decoding("vmd", "vmd-audio", "assets/Game/2832.VMD", None, &dmx_reg, &dec_reg,
594 ExpectedTestResult::MD5([0x32dcdf0e, 0xee058684, 0x43ed5bf1, 0x2ff18b5a]));
595 }
596 #[test]
597 fn test_vmd_audio_s16_new() {
598 let mut dmx_reg = RegisteredDemuxers::new();
599 game_register_all_demuxers(&mut dmx_reg);
600 let mut dec_reg = RegisteredDecoders::new();
601 game_register_all_codecs(&mut dec_reg);
602
603 test_decoding("vmd", "vmd-audio", "assets/Game/1000.VMD", None, &dmx_reg, &dec_reg,
604 ExpectedTestResult::MD5([0xc36215d3, 0x96530a80, 0x89f1fa8e, 0x49da302b]));
9895bd7b
KS
605 }
606}