1 use nihav_core::formats;
2 use nihav_core::codecs::*;
3 use nihav_core::io::byteio::*;
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;
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);
34 Self { nib: 0, has_nib: false }
36 fn get_nib(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
41 let b = br.read_byte()?;
47 fn get_length(&mut self, br: &mut ByteReader, mut len: usize, mut shift: u8) -> DecoderResult<usize> {
49 let nib = self.get_nib(br)? as usize;
57 fn push(&mut self, val: u8) {
59 panic!("nibble already in cache");
71 struct BMV3VideoDecoder {
72 info: Rc<NACodecInfo>,
78 pixbuf: [[u16; 256]; 7],
86 impl BMV3VideoDecoder {
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);
94 let mut pixels = [0u16; 256];
95 for (i, el) in pixels.iter_mut().enumerate() {
98 let mut pixbuf = [[0u16; 256]; 7];
101 pixbuf[i][j] = ((i << 8) + j + 0xF8) as u16;
112 mode: BMV3Mode::Normal,
115 nr: NibbleReader::new(),
119 fn decode_frame(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
122 let op = br.read_byte()?;
126 let op2 = br.read_u16le()?;
127 skip = ((op2 >> 12) as usize) | ((op as usize) << 4);
128 len = (op2 & 0xFFF) as usize;
130 len = ((op & 7) + 1) as usize;
131 skip = ((op >> 3) - 0x11) as usize;
133 while (idx < 0xF8) && (len > 0) {
134 self.pixels[idx] = br.read_u16le()?;
138 while (idx < 0x7F8) && (len > 0) {
139 let nidx = idx - 0xF8;
140 self.pixbuf[nidx >> 8][nidx & 0xFF] = br.read_u16le()?;
145 if skip == 0 { break; }
149 self.mode = BMV3Mode::Normal;
150 while br.left() > 0 && self.pos < self.end {
152 BMV3Mode::Normal => {
153 let op = br.read_byte()?;
154 self.decode_normal(br, op)?;
157 let op = br.read_byte()?;
159 self.decode_normal(br, op + 1)?;
161 self.decode_copy(br, op)?;
164 BMV3Mode::Pixfunc => {
165 let op = br.read_byte()?;
167 self.decode_copy(br, op + 1)?;
169 self.decode_normal(br, op - 1)?;
172 BMV3Mode::After0 => {
173 let cur_op = self.nr.get_nib(br)?;
175 let op = self.nr.get_nib(br)?;
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)?,
183 let len = (cur_op >> 1) - 1;
184 if (cur_op & 1) == 0 {
185 self.pixfunc(br, len as usize)?;
187 self.repeat(len as usize)?;
191 BMV3Mode::After1 => {
192 let cur_op = self.nr.get_nib(br)?;
194 let op = self.nr.get_nib(br)?;
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)?,
202 let len = (cur_op >> 1) - 1;
203 if (cur_op & 1) == 0 {
204 self.repeat(len as usize)?;
206 self.copy(len as usize)?;
210 BMV3Mode::After1C => {
211 let cur_op = self.nr.get_nib(br)?;
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)?;
220 let len = (cur_op >> 1) - 1;
221 self.pixfunc(br, len as usize)?;
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)?;
231 self.decode_mode4(br, cur_op)?;
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)?;
241 self.decode_mode5c(br, cur_op ^ 0x10)?;
245 if self.pos >= self.end { break; }
250 fn copy(&mut self, len: usize) -> DecoderResult<()> {
251 validate!(len <= self.end - self.pos);
254 self.frame[self.pos] = self.frame[self.pos - self.stride];
259 self.frame[self.pos] = self.prev_frame[self.pos];
263 self.mode = BMV3Mode::Copy;
266 fn pixfunc(&mut self, br: &mut ByteReader, len: usize) -> DecoderResult<()> {
267 validate!(len <= self.end - self.pos);
269 let op = BMV_PIXFUNCS_MAP[br.read_byte()? as usize];
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];
278 val = self.pixels[op as usize];
280 self.frame[self.pos] = val;
283 self.mode = BMV3Mode::Pixfunc;
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];
291 self.frame[self.pos] = pix;
294 self.mode = BMV3Mode::Normal;
298 fn decode_normal(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
301 let len = ((op >> 1) & 0x7) as usize;
303 let mut len = (op >> 3) as usize;
307 len = self.nr.get_length(br, len, 3)?;
311 self.mode = BMV3Mode::After0;
314 self.pixfunc(br, len)?;
316 self.mode = BMV3Mode::After1;
319 } else if mode == 0 {
321 self.nr.push(op >> 4);
322 self.mode = BMV3Mode::After4;
324 self.pixfunc(br, len - 1)?;
325 self.nr.push(op >> 4);
326 self.mode = BMV3Mode::After5;
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;
338 self.pixfunc(br, len)?;
342 let len2 = (x_op >> 1) - 1;
346 self.pixfunc(br, len1)?;
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)?,
357 fn decode_copy(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
359 let len = ((op >> 1) & 0x7) as usize;
361 let mut len = (op >> 3) as usize;
365 len = self.nr.get_length(br, len, 3)?;
368 self.mode = BMV3Mode::After1C;
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)?;
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)?;
384 self.repeat(y_op - 1)?;
385 let len = (x_op >> 1) - 1;
389 self.pixfunc(br, len)?;
394 fn decode_mode4(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
396 let mut len = ((op & 3) * 2) as usize;
397 if (op & 0xF0) >= 0x20 {
400 len = self.nr.get_length(br, len, 3)?;
403 self.mode = BMV3Mode::After1C;
406 let len = ((op & 0xF) * 2 - 1 + (op >> 5)) as usize;
408 self.mode = BMV3Mode::After1C;
412 fn decode_mode5c(&mut self, br: &mut ByteReader, op: u8) -> DecoderResult<()> {
414 let mut len = ((op & 3) * 2) as usize;
415 if (op & 0xF0) >= 0x20 {
418 len = self.nr.get_length(br, len, 3)?;
419 if (op & 0x10) == 0 {
422 self.mode = BMV3Mode::After0;
425 self.pixfunc(br, len)?;
427 self.mode = BMV3Mode::After1;
431 let len = ((op & 0xF) * 2 - 1 + (op >> 5)) as usize;
432 if (op & 0x10) == 0 {
434 self.mode = BMV3Mode::After0;
436 self.pixfunc(br, len)?;
437 self.mode = BMV3Mode::After1;
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()));
450 self.stride = vinfo.get_width();
451 self.height = vinfo.get_height();
452 self.end = self.stride * (self.height + 1);
454 validate!((self.stride <= 640) && (self.height <= 432));
458 Err(DecoderError::InvalidData)
461 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
462 let src = pkt.get_buffer();
463 validate!(src.len() > 1);
465 let mut mr = MemoryReader::new_read(&src);
466 let mut br = ByteReader::new(&mut mr);
467 let flags = br.read_byte()?;
469 if (flags & BMV_COMMAND) != 0 {
470 let size = if (flags & BMV_PRINT) != 0 { 8 } else { 10 };
473 if (flags & BMV_PAL) != 0 {
474 return Err(DecoderError::InvalidData);
477 if ((flags & 1) == 0) && ((flags & BMV_SCROLL) != 0) {
478 off = br.read_u16le()? as usize;
482 self.pos = off + self.stride;
483 self.is_intra = (flags & BMV_INTRA) == BMV_INTRA;
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();
489 self.decode_frame(&mut br)?;
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();
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);
503 std::mem::swap(&mut self.frame, &mut self.prev_frame);
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)))
513 pub fn get_decoder_video() -> Box<NADecoder> {
514 Box::new(BMV3VideoDecoder::new())
517 struct BMV3AudioDecoder {
524 impl BMV3AudioDecoder {
527 ainfo: NAAudioInfo::new(0, 1, formats::SND_S16P_FORMAT, 0),
528 chmap: NAChannelMap::new(),
535 fn decode_block(mode: u8, src: &[u8], dst: &mut [i16], mut pred: i16) -> i16 {
536 let steps = &BMV_AUDIO_STEPS[mode as usize];
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);
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;
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();
562 Err(DecoderError::InvalidData)
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() {
579 let aoff1 = aoff0 + off1;
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]);
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]);
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)))
597 Err(DecoderError::InvalidData)
602 pub fn get_decoder_audio() -> Box<NADecoder> {
603 Box::new(BMV3AudioDecoder::new())
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;
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);
620 let file = "assets/Game/DW3-Loffnote.bmv";
621 test_file_decoding("bmv3", file, None, true, false, None, &dmx_reg, &dec_reg);
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);
630 let file = "assets/Game/DW3-Loffnote.bmv";
631 test_decode_audio("bmv3", file, None, "bmv3", &dmx_reg, &dec_reg);
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
702 const BMV_AUDIO_STEPS: [[i16; 32]; 16] = [
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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