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