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