]> git.nihav.org Git - nihav.git/blame - nihav-game/src/codecs/bmv3.rs
nihav_registry: fix clippy warnings and tests in detect module
[nihav.git] / nihav-game / src / codecs / bmv3.rs
CommitLineData
ecda1cc1
KS
1use nihav_core::formats;
2use nihav_core::codecs::*;
3use nihav_core::io::byteio::*;
4use std::str::FromStr;
5
410e63c2
KS
6const BMV_INTRA: u8 = 0x03;
7const BMV_SCROLL: u8 = 0x04;
8const BMV_PAL: u8 = 0x08;
9const BMV_COMMAND: u8 = 0x10;
10const BMV_PRINT: u8 = 0x80;
11
12const BMV_MAX_WIDTH: usize = 640;
13const BMV_MAX_HEIGHT: usize = 432;
14const BMV_MAX_SIZE: usize = BMV_MAX_WIDTH * (BMV_MAX_HEIGHT + 1);
15
16enum BMV3Mode {
17 Normal,
18 Copy,
19 Pixfunc,
20 After0,
21 After1,
22 After1C,
23 After4,
24 After5,
25}
26
27struct NibbleReader {
28 nib: u8,
29 has_nib: bool,
30}
31
32impl NibbleReader {
33 fn new() -> Self {
34 Self { nib: 0, has_nib: false }
35 }
36 fn get_nib(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
37 if self.has_nib {
38 self.has_nib = false;
39 Ok(self.nib)
40 } else {
41 let b = br.read_byte()?;
42 self.nib = b >> 4;
43 self.has_nib = true;
44 Ok(b & 0xF)
45 }
46 }
47 fn get_length(&mut self, br: &mut ByteReader, mut len: usize, mut shift: u8) -> DecoderResult<usize> {
48 loop {
49 let nib = self.get_nib(br)? as usize;
50 len |= nib << shift;
51 shift += 2;
52 if (nib & 0xC) != 0 {
53 return Ok(len - 1);
54 }
55 }
56 }
57 fn push(&mut self, val: u8) {
58 if self.has_nib {
59 panic!("nibble already in cache");
60 } else {
61 self.nib = val;
62 self.has_nib = true;
63 }
64 }
65 fn reset(&mut self) {
66 self.nib = 0;
67 self.has_nib = false;
68 }
69}
70
71struct BMV3VideoDecoder {
2422d969 72 info: NACodecInfoRef,
410e63c2
KS
73 stride: usize,
74 height: usize,
75 frame: Vec<u16>,
76 prev_frame: Vec<u16>,
77 pixels: [u16; 256],
78 pixbuf: [[u16; 256]; 7],
79 mode: BMV3Mode,
80 pos: usize,
81 end: usize,
82 nr: NibbleReader,
83 is_intra: bool,
84}
85
86impl BMV3VideoDecoder {
87 fn new() -> Self {
410e63c2
KS
88 let mut pixels = [0u16; 256];
89 for (i, el) in pixels.iter_mut().enumerate() {
90 *el = i as u16;
91 }
92 let mut pixbuf = [[0u16; 256]; 7];
93 for i in 0..7 {
94 for j in 0..256 {
95 pixbuf[i][j] = ((i << 8) + j + 0xF8) as u16;
96 }
97 }
98
99 Self {
2422d969 100 info: NACodecInfoRef::default(),
410e63c2
KS
101 stride: 0,
102 height: 0,
e69b1148
KS
103 frame: vec![0; BMV_MAX_SIZE],
104 prev_frame: vec![0; BMV_MAX_SIZE],
410e63c2
KS
105 pixels, pixbuf,
106 mode: BMV3Mode::Normal,
107 pos: 0,
108 end: 0,
109 nr: NibbleReader::new(),
110 is_intra: false,
111 }
112 }
7450554d 113 #[allow(clippy::identity_op)]
410e63c2
KS
114 fn decode_frame(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
115 let mut idx = 0;
116 loop {
117 let op = br.read_byte()?;
118 let mut len;
119 let skip;
120 if op < 0x90 {
121 let op2 = br.read_u16le()?;
d5f2d071 122 skip = ((op2 >> 12) as usize) | ((op as usize) << 4);
410e63c2
KS
123 len = (op2 & 0xFFF) as usize;
124 } else {
125 len = ((op & 7) + 1) as usize;
126 skip = ((op >> 3) - 0x11) as usize;
127 }
128 while (idx < 0xF8) && (len > 0) {
129 self.pixels[idx] = br.read_u16le()?;
130 idx += 1;
131 len -= 1;
132 }
133 while (idx < 0x7F8) && (len > 0) {
134 let nidx = idx - 0xF8;
135 self.pixbuf[nidx >> 8][nidx & 0xFF] = br.read_u16le()?;
136 idx += 1;
137 len -= 1;
138 }
139 validate!(len == 0);
140 if skip == 0 { break; }
141 idx += skip;
142 }
143 self.nr.reset();
144 self.mode = BMV3Mode::Normal;
145 while br.left() > 0 && self.pos < self.end {
146 match self.mode {
147 BMV3Mode::Normal => {
148 let op = br.read_byte()?;
149 self.decode_normal(br, op)?;
150 },
151 BMV3Mode::Copy => {
152 let op = br.read_byte()?;
153 if (op & 1) == 0 {
154 self.decode_normal(br, op + 1)?;
155 } else {
156 self.decode_copy(br, op)?;
157 }
158 },
159 BMV3Mode::Pixfunc => {
160 let op = br.read_byte()?;
161 if (op & 1) == 0 {
162 self.decode_copy(br, op + 1)?;
163 } else {
164 self.decode_normal(br, op - 1)?;
165 }
166 },
167 BMV3Mode::After0 => {
168 let cur_op = self.nr.get_nib(br)?;
169 if cur_op < 4 {
170 let op = self.nr.get_nib(br)?;
171 match cur_op {
172 0 => self.decode_mode5c(br, op | 0x10)?,
173 1 => self.decode_mode4 (br, op | 0x10)?,
174 2 => self.decode_mode5c(br, op | 0x30)?,
175 _ => self.decode_mode4 (br, op | 0x30)?,
176 };
177 } else {
178 let len = (cur_op >> 1) - 1;
179 if (cur_op & 1) == 0 {
180 self.pixfunc(br, len as usize)?;
181 } else {
182 self.repeat(len as usize)?;
183 }
184 }
185 }
186 BMV3Mode::After1 => {
187 let cur_op = self.nr.get_nib(br)?;
188 if cur_op < 4 {
189 let op = self.nr.get_nib(br)?;
190 match cur_op {
191 0 => self.decode_mode4 (br, op | 0x10)?,
192 1 => self.decode_mode5c(br, op | 0x00)?,
193 2 => self.decode_mode4 (br, op | 0x30)?,
194 _ => self.decode_mode5c(br, op | 0x20)?,
195 };
196 } else {
197 let len = (cur_op >> 1) - 1;
198 if (cur_op & 1) == 0 {
199 self.repeat(len as usize)?;
200 } else {
201 self.copy(len as usize)?;
202 }
203 }
204 },
205 BMV3Mode::After1C => {
206 let cur_op = self.nr.get_nib(br)?;
207 if cur_op < 4 {
208 let cur_op1 = self.nr.get_nib(br)?;
209 let m5_op = cur_op1 | (cur_op << 4);
210 self.decode_mode5c(br, m5_op)?;
211 } else if (cur_op & 1) == 0 {
212 let len = (cur_op >> 1) - 1;
213 self.copy(len as usize)?;
214 } else {
215 let len = (cur_op >> 1) - 1;
216 self.pixfunc(br, len as usize)?;
217 }
218 },
219 BMV3Mode::After4 => {
220 let cur_op0 = self.nr.get_nib(br)?;
221 let cur_op1 = self.nr.get_nib(br)?;
222 let cur_op = (cur_op0 << 4) | cur_op1;
223 if (cur_op & 0x10) == 0 {
224 self.decode_mode5c(br, cur_op | 0x10)?;
225 } else {
226 self.decode_mode4(br, cur_op)?;
227 }
228 },
229 BMV3Mode::After5 => {
230 let cur_op0 = self.nr.get_nib(br)?;
231 let cur_op1 = self.nr.get_nib(br)?;
232 let cur_op = (cur_op0 << 4) | cur_op1;
233 if (cur_op & 0x10) == 0 {
234 self.decode_mode4(br, cur_op | 0x10)?;
235 } else {
236 self.decode_mode5c(br, cur_op ^ 0x10)?;
237 }
238 },
239 };
240 if self.pos >= self.end { break; }
241 }
242 Ok(())
243 }
244
245 fn copy(&mut self, len: usize) -> DecoderResult<()> {
246 validate!(len <= self.end - self.pos);
247 if self.is_intra {
248 for _ in 0..len {
249 self.frame[self.pos] = self.frame[self.pos - self.stride];
250 self.pos += 1;
251 }
252 } else {
253 for _ in 0..len {
254 self.frame[self.pos] = self.prev_frame[self.pos];
255 self.pos += 1;
256 }
257 }
258 self.mode = BMV3Mode::Copy;
259 Ok(())
260 }
261 fn pixfunc(&mut self, br: &mut ByteReader, len: usize) -> DecoderResult<()> {
262 validate!(len <= self.end - self.pos);
263 for _ in 0..len {
264 let op = BMV_PIXFUNCS_MAP[br.read_byte()? as usize];
265 let val;
266 if op == 0xFF {
267 val = br.read_u16le()?;
268 } else if op >= 0xF8 {
269 let tab_idx = (op - 0xF8) as usize;
270 let sub_idx = br.read_byte()? as usize;
271 val = self.pixbuf[tab_idx][sub_idx];
272 } else {
273 val = self.pixels[op as usize];
274 }
275 self.frame[self.pos] = val;
276 self.pos += 1;
277 }
278 self.mode = BMV3Mode::Pixfunc;
279 Ok(())
280 }
281 fn repeat(&mut self, len: usize) -> DecoderResult<()> {
282 validate!(self.pos > 0);
283 validate!(len <= self.end - self.pos);
284 let pix = self.frame[self.pos - 1];
285 for _ in 0..len {
286 self.frame[self.pos] = pix;
287 self.pos += 1;
288 }
289 self.mode = BMV3Mode::Normal;
290 Ok(())
291 }
292
293 fn decode_normal(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
294 if op < 0x40 {
295 let mode = op & 1;
296 let len = ((op >> 1) & 0x7) as usize;
297 if len < 2 {
298 let mut len = (op >> 3) as usize;
299 if (op & 0xF) >= 2 {
300 len += 1;
301 }
302 len = self.nr.get_length(br, len, 3)?;
303 if (op & 1) == 0 {
304 self.copy(len)?;
305 if self.nr.has_nib {
306 self.mode = BMV3Mode::After0;
307 }
308 } else {
309 self.pixfunc(br, len)?;
310 if self.nr.has_nib {
311 self.mode = BMV3Mode::After1;
312 }
313 }
314 } else if mode == 0 {
315 self.copy(len - 1)?;
316 self.nr.push(op >> 4);
317 self.mode = BMV3Mode::After4;
318 } else {
319 self.pixfunc(br, len - 1)?;
320 self.nr.push(op >> 4);
321 self.mode = BMV3Mode::After5;
322 }
323 return Ok(());
324 }
325 let x_op = (op >> 4) as usize;
326 let y_op = ((op >> 1) & 7) as usize;
327 let flag = (op & 1) as usize;
328 if y_op == 0 || y_op == 1 {
329 let len = x_op * 2 - 1 + y_op;
330 if flag == 0 {
331 self.copy(len)?;
332 } else {
333 self.pixfunc(br, len)?;
334 }
335 } else {
336 let len1 = y_op - 1;
337 let len2 = (x_op >> 1) - 1;
338 if flag == 0 {
339 self.copy(len1)?;
340 } else {
341 self.pixfunc(br, len1)?;
342 }
343 match (x_op & 1) * 2 + flag {
344 0 => self.pixfunc(br, len2)?,
345 1 => self.repeat(len2)?,
346 2 => self.repeat(len2)?,
347 _ => self.copy(len2)?,
348 };
349 }
350 Ok(())
351 }
352 fn decode_copy(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
353 if op < 0x40 {
354 let len = ((op >> 1) & 0x7) as usize;
355 if len < 2 {
356 let mut len = (op >> 3) as usize;
357 if (op & 0xF) >= 2 {
358 len += 1;
359 }
360 len = self.nr.get_length(br, len, 3)?;
361 self.repeat(len)?;
362 if self.nr.has_nib {
363 self.mode = BMV3Mode::After1C;
364 }
365 } else {
366 self.repeat(len - 1)?;
367 if br.left() == 0 { return Ok(()); }
368 let op2 = self.nr.get_nib(br)?;
369 let cur_op = (op & 0xF0) | op2;
370 self.decode_mode5c(br, cur_op)?;
371 }
372 return Ok(());
373 }
374 let x_op = (op >> 4) as usize;
375 let y_op = ((op >> 1) & 7) as usize;
376 if y_op == 0 || y_op == 1 {
377 self.repeat(x_op * 2 - 1 + y_op)?;
378 } else {
379 self.repeat(y_op - 1)?;
380 let len = (x_op >> 1) - 1;
381 if (x_op & 1) == 0 {
382 self.copy(len)?;
383 } else {
384 self.pixfunc(br, len)?;
385 }
386 }
387 Ok(())
388 }
389 fn decode_mode4(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
390 if (op & 0xF) < 4 {
391 let mut len = ((op & 3) * 2) as usize;
392 if (op & 0xF0) >= 0x20 {
393 len += 1;
394 }
395 len = self.nr.get_length(br, len, 3)?;
396 self.repeat(len)?;
397 if self.nr.has_nib {
398 self.mode = BMV3Mode::After1C;
399 }
400 } else {
401 let len = ((op & 0xF) * 2 - 1 + (op >> 5)) as usize;
402 self.repeat(len)?;
403 self.mode = BMV3Mode::After1C;
404 }
405 Ok(())
406 }
407 fn decode_mode5c(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
408 if (op & 0xF) < 4 {
409 let mut len = ((op & 3) * 2) as usize;
410 if (op & 0xF0) >= 0x20 {
411 len += 1;
412 }
413 len = self.nr.get_length(br, len, 3)?;
414 if (op & 0x10) == 0 {
415 self.copy(len)?;
416 if self.nr.has_nib {
417 self.mode = BMV3Mode::After0;
418 }
419 } else {
420 self.pixfunc(br, len)?;
421 if self.nr.has_nib {
422 self.mode = BMV3Mode::After1;
423 }
424 }
425 } else {
426 let len = ((op & 0xF) * 2 - 1 + (op >> 5)) as usize;
427 if (op & 0x10) == 0 {
428 self.copy(len)?;
429 self.mode = BMV3Mode::After0;
430 } else {
431 self.pixfunc(br, len)?;
432 self.mode = BMV3Mode::After1;
433 }
434 }
435 Ok(())
436 }
437}
438
439impl NADecoder for BMV3VideoDecoder {
01613464 440 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
410e63c2
KS
441 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
442 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, RGB565_FORMAT));
2422d969 443 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
410e63c2
KS
444
445 self.stride = vinfo.get_width();
446 self.height = vinfo.get_height();
447 self.end = self.stride * (self.height + 1);
448
449 validate!((self.stride <= 640) && (self.height <= 432));
450
451 Ok(())
452 } else {
453 Err(DecoderError::InvalidData)
454 }
455 }
01613464 456 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
410e63c2
KS
457 let src = pkt.get_buffer();
458 validate!(src.len() > 1);
459
460 let mut mr = MemoryReader::new_read(&src);
461 let mut br = ByteReader::new(&mut mr);
462 let flags = br.read_byte()?;
463
464 if (flags & BMV_COMMAND) != 0 {
465 let size = if (flags & BMV_PRINT) != 0 { 8 } else { 10 };
466 br.read_skip(size)?;
467 }
468 if (flags & BMV_PAL) != 0 {
469 return Err(DecoderError::InvalidData);
470 }
471 let off;
472 if ((flags & 1) == 0) && ((flags & BMV_SCROLL) != 0) {
473 off = br.read_u16le()? as usize;
474 } else {
475 off = 0;
476 }
477 self.pos = off + self.stride;
478 self.is_intra = (flags & BMV_INTRA) == BMV_INTRA;
479
e69b1148 480 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 0)?;
410e63c2
KS
481
482 self.decode_frame(&mut br)?;
483
484 {
485 let mut buf = bufinfo.get_vbuf16().unwrap();
486 let stride = buf.get_stride(0);
1a967e6b 487 let data = buf.get_data_mut().unwrap();
410e63c2
KS
488 let dst = data.as_mut_slice();
489
490 let refbuf = &self.frame[self.stride..];
491 for (dst, src) in dst.chunks_mut(stride).zip(refbuf.chunks(self.stride)).take(self.height) {
492 let out = &mut dst[0..self.stride];
493 out.copy_from_slice(src);
494 }
495 }
496 std::mem::swap(&mut self.frame, &mut self.prev_frame);
497
498 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
499 frm.set_keyframe(self.is_intra);
500 frm.set_frame_type(if self.is_intra { FrameType::I } else { FrameType::P });
171860fc 501 Ok(frm.into_ref())
410e63c2 502 }
f9be4e75
KS
503 fn flush(&mut self) {
504 }
410e63c2
KS
505}
506
7d57ae2f
KS
507impl NAOptionHandler for BMV3VideoDecoder {
508 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
509 fn set_options(&mut self, _options: &[NAOption]) { }
510 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
511}
512
ecda1cc1 513
08a1fab7 514pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
410e63c2 515 Box::new(BMV3VideoDecoder::new())
ecda1cc1
KS
516}
517
518struct BMV3AudioDecoder {
519 ainfo: NAAudioInfo,
520 chmap: NAChannelMap,
521 pred: [i16; 2],
522 nframes: usize,
523}
524
525impl BMV3AudioDecoder {
526 fn new() -> Self {
527 Self {
528 ainfo: NAAudioInfo::new(0, 1, formats::SND_S16P_FORMAT, 0),
529 chmap: NAChannelMap::new(),
530 pred: [0; 2],
531 nframes: 0,
532 }
533 }
534}
535
7450554d 536#[allow(clippy::identity_op)]
ecda1cc1
KS
537fn decode_block(mode: u8, src: &[u8], dst: &mut [i16], mut pred: i16) -> i16 {
538 let steps = &BMV_AUDIO_STEPS[mode as usize];
539 let mut val2 = 0;
540 for i in 0..10 {
541 let val = (src[i * 2 + 0] as usize) + (src[i * 2 + 1] as usize) * 256;
542 pred = pred.wrapping_add(steps[(val >> 10) & 0x1F]);
543 dst[i * 3 + 0] = pred;
544 pred = pred.wrapping_add(steps[(val >> 5) & 0x1F]);
545 dst[i * 3 + 1] = pred;
546 pred = pred.wrapping_add(steps[(val >> 0) & 0x1F]);
547 dst[i * 3 + 2] = pred;
548 val2 = (val2 << 1) | (val >> 15);
549 }
550 pred = pred.wrapping_add(steps[(val2 >> 5) & 0x1F]);
551 dst[3 * 10 + 0] = pred;
552 pred = pred.wrapping_add(steps[(val2 >> 0) & 0x1F]);
553 dst[3 * 10 + 1] = pred;
554 pred
555}
556
557impl NADecoder for BMV3AudioDecoder {
01613464 558 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
ecda1cc1
KS
559 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
560 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), formats::SND_S16P_FORMAT, 32);
561 self.chmap = NAChannelMap::from_str("L,R").unwrap();
562 Ok(())
563 } else {
564 Err(DecoderError::InvalidData)
565 }
566 }
01613464 567 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
ecda1cc1
KS
568 let info = pkt.get_stream().get_info();
569 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
570 let pktbuf = pkt.get_buffer();
571 validate!(pktbuf.len() > 1);
572 let samples = (pktbuf.len() / 41) * 32;
573 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
574 let mut adata = abuf.get_abuf_i16().unwrap();
575 let off1 = adata.get_offset(1);
1a967e6b 576 let dst = adata.get_data_mut().unwrap();
ecda1cc1
KS
577 let mut first = pktbuf[0] == 0;
578 let psrc = &pktbuf[1..];
579 for (n, src) in psrc.chunks_exact(41).enumerate() {
580 let aoff0 = n * 32;
581 let aoff1 = aoff0 + off1;
582 if first {
583 let mode = src[40];
584 self.pred[0] = decode_block(mode >> 4, &src[0..], &mut dst[aoff0..], self.pred[0]);
585 self.pred[1] = decode_block(mode & 0xF, &src[20..], &mut dst[aoff1..], self.pred[1]);
586 } else {
587 let mode = src[0];
588 self.pred[0] = decode_block(mode >> 4, &src[1..], &mut dst[aoff0..], self.pred[0]);
589 self.pred[1] = decode_block(mode & 0xF, &src[21..], &mut dst[aoff1..], self.pred[1]);
590 }
591 first = !first;
592 }
593 self.nframes += 1;
594 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
595 frm.set_duration(Some(samples as u64));
596 frm.set_keyframe(false);
171860fc 597 Ok(frm.into_ref())
ecda1cc1
KS
598 } else {
599 Err(DecoderError::InvalidData)
600 }
601 }
f9be4e75
KS
602 fn flush(&mut self) {
603 }
ecda1cc1
KS
604}
605
7d57ae2f
KS
606impl NAOptionHandler for BMV3AudioDecoder {
607 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
608 fn set_options(&mut self, _options: &[NAOption]) { }
609 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
610}
611
08a1fab7 612pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
ecda1cc1
KS
613 Box::new(BMV3AudioDecoder::new())
614}
615
616#[cfg(test)]
617mod test {
618 use nihav_core::codecs::RegisteredDecoders;
619 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 620 use nihav_codec_support::test::dec_video::*;
78fb6560 621 use crate::game_register_all_decoders;
e64739f8 622 use crate::game_register_all_demuxers;
ecda1cc1
KS
623 #[test]
624 fn test_bmv_video() {
625 let mut dmx_reg = RegisteredDemuxers::new();
626 game_register_all_demuxers(&mut dmx_reg);
627 let mut dec_reg = RegisteredDecoders::new();
78fb6560 628 game_register_all_decoders(&mut dec_reg);
ecda1cc1 629
7343bcbf
KS
630 test_decoding("bmv3", "bmv3-video", "assets/Game/DW3-Loffnote.bmv", None, &dmx_reg, &dec_reg,
631 ExpectedTestResult::MD5([0xfa34b81b, 0xd0ab79e2, 0x78fb25cc, 0x98ae47ff]));
ecda1cc1
KS
632 }
633 #[test]
634 fn test_bmv_audio() {
635 let mut dmx_reg = RegisteredDemuxers::new();
636 game_register_all_demuxers(&mut dmx_reg);
637 let mut dec_reg = RegisteredDecoders::new();
78fb6560 638 game_register_all_decoders(&mut dec_reg);
ecda1cc1 639
7343bcbf
KS
640 test_decoding("bmv3", "bmv3-audio", "assets/Game/DW3-Loffnote.bmv", None, &dmx_reg, &dec_reg,
641 ExpectedTestResult::MD5([0xd8e743cc, 0x97604bd7, 0x8dbb89c6, 0xb34cad63]));
ecda1cc1
KS
642 }
643}
644
410e63c2
KS
645const BMV_PIXFUNCS_MAP: [u8; 256] = [
646 0x38, 0x78, 0xB8, 0xF9,
647 0x39, 0x79, 0xB9, 0xFA,
648 0x3A, 0x7A, 0xBA, 0xFB,
649 0x3B, 0x7B, 0xBB, 0xFC,
650 0x3C, 0x7C, 0xBC, 0xFD,
651 0x3D, 0x7D, 0xBD, 0xFE,
652 0x3E, 0x7E, 0xBE, 0xFF,
653 0x3F, 0x7F, 0xBF, 0x00,
654 0x40, 0x80, 0xC0, 0x01,
655 0x41, 0x81, 0xC1, 0x02,
656 0x42, 0x82, 0xC2, 0x03,
657 0x43, 0x83, 0xC3, 0x04,
658 0x44, 0x84, 0xC4, 0x05,
659 0x45, 0x85, 0xC5, 0x06,
660 0x46, 0x86, 0xC6, 0x07,
661 0x47, 0x87, 0xC7, 0x08,
662 0x48, 0x88, 0xC8, 0x09,
663 0x49, 0x89, 0xC9, 0x0A,
664 0x4A, 0x8A, 0xCA, 0x0B,
665 0x4B, 0x8B, 0xCB, 0x0C,
666 0x4C, 0x8C, 0xCC, 0x0D,
667 0x4D, 0x8D, 0xCD, 0x0E,
668 0x4E, 0x8E, 0xCE, 0x0F,
669 0x4F, 0x8F, 0xCF, 0x10,
670 0x50, 0x90, 0xD0, 0x11,
671 0x51, 0x91, 0xD1, 0x12,
672 0x52, 0x92, 0xD2, 0x13,
673 0x53, 0x93, 0xD3, 0x14,
674 0x54, 0x94, 0xD4, 0x15,
675 0x55, 0x95, 0xD5, 0x16,
676 0x56, 0x96, 0xD6, 0x17,
677 0x57, 0x97, 0xD7, 0x18,
678 0x58, 0x98, 0xD8, 0x19,
679 0x59, 0x99, 0xD9, 0x1A,
680 0x5A, 0x9A, 0xDA, 0x1B,
681 0x5B, 0x9B, 0xDB, 0x1C,
682 0x5C, 0x9C, 0xDC, 0x1D,
683 0x5D, 0x9D, 0xDD, 0x1E,
684 0x5E, 0x9E, 0xDE, 0x1F,
685 0x5F, 0x9F, 0xDF, 0x20,
686 0x60, 0xA0, 0xE0, 0x21,
687 0x61, 0xA1, 0xE1, 0x22,
688 0x62, 0xA2, 0xE2, 0x23,
689 0x63, 0xA3, 0xE3, 0x24,
690 0x64, 0xA4, 0xE4, 0x25,
691 0x65, 0xA5, 0xE5, 0x26,
692 0x66, 0xA6, 0xE6, 0x27,
693 0x67, 0xA7, 0xE7, 0x28,
694 0x68, 0xA8, 0xE8, 0x29,
695 0x69, 0xA9, 0xE9, 0x2A,
696 0x6A, 0xAA, 0xEA, 0x2B,
697 0x6B, 0xAB, 0xEB, 0x2C,
698 0x6C, 0xAC, 0xEC, 0x2D,
699 0x6D, 0xAD, 0xED, 0x2E,
700 0x6E, 0xAE, 0xEE, 0x2F,
701 0x6F, 0xAF, 0xEF, 0x30,
702 0x70, 0xB0, 0xF0, 0x31,
703 0x71, 0xB1, 0xF1, 0x32,
704 0x72, 0xB2, 0xF2, 0x33,
705 0x73, 0xB3, 0xF3, 0x34,
706 0x74, 0xB4, 0xF4, 0x35,
707 0x75, 0xB5, 0xF5, 0x36,
708 0x76, 0xB6, 0xF6, 0x37,
709 0x77, 0xB7, 0xF7, 0xF8
710];
711
ecda1cc1
KS
712const BMV_AUDIO_STEPS: [[i16; 32]; 16] = [
713 [
714 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00,
715 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00,
716 -0x4000, -0x3C00, -0x3800, -0x3400, -0x3000, -0x2C00, -0x2800, -0x2400,
717 -0x2000, -0x1C00, -0x1800, -0x1400, -0x1000, -0x0C00, -0x0800, -0x0400
718 ], [
719 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0A00, 0x0C00, 0x0E00,
720 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1A00, 0x1C00, 0x1E00,
721 -0x2000, -0x1E00, -0x1C00, -0x1A00, -0x1800, -0x1600, -0x1400, -0x1200,
722 -0x1000, -0x0E00, -0x0C00, -0x0A00, -0x0800, -0x0600, -0x0400, -0x0200
723 ], [
724 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
725 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00,
726 -0x1000, -0x0F00, -0x0E00, -0x0D00, -0x0C00, -0x0B00, -0x0A00, -0x0900,
727 -0x0800, -0x0700, -0x0600, -0x0500, -0x0400, -0x0300, -0x0200, -0x0100
728 ], [
729 0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380,
730 0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
731 -0x800, -0x780, -0x700, -0x680, -0x600, -0x580, -0x500, -0x480,
732 -0x400, -0x380, -0x300, -0x280, -0x200, -0x180, -0x100, -0x080
733 ], [
734 0x000, 0x048, 0x090, 0x0D8, 0x120, 0x168, 0x1B0, 0x1F8,
735 0x240, 0x288, 0x2D0, 0x318, 0x360, 0x3A8, 0x3F0, 0x438,
736 -0x480, -0x438, -0x3F0, -0x3A8, -0x360, -0x318, -0x2D0, -0x288,
737 -0x240, -0x1F8, -0x1B0, -0x168, -0x120, -0x0D8, -0x090, -0x048
738 ], [
739 0x000, 0x030, 0x060, 0x090, 0x0C0, 0x0F0, 0x120, 0x150,
740 0x180, 0x1B0, 0x1E0, 0x210, 0x240, 0x270, 0x2A0, 0x2D0,
741 -0x300, -0x2D0, -0x2A0, -0x270, -0x240, -0x210, -0x1E0, -0x1B0,
742 -0x180, -0x150, -0x120, -0x0F0, -0x0C0, -0x090, -0x060, -0x030
743 ], [
744 0x000, 0x020, 0x040, 0x060, 0x080, 0x0A0, 0x0C0, 0x0E0,
745 0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0, 0x1E0,
746 -0x200, -0x1E0, -0x1C0, -0x1A0, -0x180, -0x160, -0x140, -0x120,
747 -0x100, -0x0E0, -0x0C0, -0x0A0, -0x080, -0x060, -0x040, -0x020
748 ], [
749 0x000, 0x016, 0x02C, 0x042, 0x058, 0x06E, 0x084, 0x09A,
750 0x0B0, 0x0C6, 0x0DC, 0x0F2, 0x108, 0x11E, 0x134, 0x14A,
751 -0x160, -0x14A, -0x134, -0x11E, -0x108, -0x0F2, -0x0DC, -0x0C6,
752 -0x0B0, -0x09A, -0x084, -0x06E, -0x058, -0x042, -0x02C, -0x016
753 ], [
754 0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070,
755 0x080, 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0,
756 -0x100, -0x0F0, -0x0E0, -0x0D0, -0x0C0, -0x0B0, -0x0A0, -0x090,
757 -0x080, -0x070, -0x060, -0x050, -0x040, -0x030, -0x020, -0x010
758 ], [
759 0x00, 0x0B, 0x16, 0x21, 0x2C, 0x37, 0x42, 0x4D,
760 0x58, 0x63, 0x6E, 0x79, 0x84, 0x8F, 0x9A, 0xA5,
761 -0xB0, -0xA5, -0x9A, -0x8F, -0x84, -0x79, -0x6E, -0x63,
762 -0x58, -0x4D, -0x42, -0x37, -0x2C, -0x21, -0x16, -0x0B
763 ], [
764 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
765 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
766 -0x80, -0x78, -0x70, -0x68, -0x60, -0x58, -0x50, -0x48,
767 -0x40, -0x38, -0x30, -0x28, -0x20, -0x18, -0x10, -0x08
768 ], [
769 0x00, 0x06, 0x0C, 0x12, 0x18, 0x1E, 0x24, 0x2A,
770 0x30, 0x36, 0x3C, 0x42, 0x48, 0x4E, 0x54, 0x5A,
771 -0x60, -0x5A, -0x54, -0x4E, -0x48, -0x42, -0x3C, -0x36,
772 -0x30, -0x2A, -0x24, -0x1E, -0x18, -0x12, -0x0C, -0x06
773 ], [
774 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
775 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
776 -0x40, -0x3C, -0x38, -0x34, -0x30, -0x2C, -0x28, -0x24,
777 -0x20, -0x1C, -0x18, -0x14, -0x10, -0x0C, -0x08, -0x04
778 ], [
779 0x00, 0x02, 0x05, 0x08, 0x0B, 0x0D, 0x10, 0x13,
780 0x16, 0x18, 0x1B, 0x1E, 0x21, 0x23, 0x26, 0x29,
781 -0x2C, -0x2A, -0x27, -0x24, -0x21, -0x1F, -0x1C, -0x19,
782 -0x16, -0x14, -0x11, -0x0E, -0x0B, -0x09, -0x06, -0x03
783 ], [
784 0x00, 0x01, 0x03, 0x05, 0x07, 0x08, 0x0A, 0x0C,
785 0x0E, 0x0F, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A,
786 -0x1C, -0x1B, -0x19, -0x17, -0x15, -0x14, -0x12, -0x10,
787 -0x0E, -0x0D, -0x0B, -0x09, -0x07, -0x06, -0x04, -0x02
788 ], [
789 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
790 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
791 -0x10, -0x0F, -0x0E, -0x0D, -0x0C, -0x0B, -0x0A, -0x09,
792 -0x08, -0x07, -0x06, -0x05, -0x04, -0x03, -0x02, -0x01
793 ]
794];