Mercurial > hg > dmlib
comparison tools/lib64gfx.c @ 1503:c7b9ef56319b
Factor all the c64 file format specific things into lib64fmt.c
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 11 May 2018 07:41:55 +0300 |
parents | 9ccf973f65ac |
children | 3265175b24d2 |
comparison
equal
deleted
inserted
replaced
1502:aa87cb6cf33b | 1503:c7b9ef56319b |
---|---|
10 | 10 |
11 #define BUF_SIZE_INITIAL (16*1024) | 11 #define BUF_SIZE_INITIAL (16*1024) |
12 #define BUF_SIZE_GROW (4*1024) | 12 #define BUF_SIZE_GROW (4*1024) |
13 | 13 |
14 | 14 |
15 // Based on Pepto's palette, stolen from VICE | |
16 DMColor dmDefaultC64Palette[C64_NCOLORS] = | |
17 { | |
18 { 0x00, 0x00, 0x00, 0xff }, | |
19 { 0xFF, 0xFF, 0xFF, 0xff }, | |
20 { 0x68, 0x37, 0x2B, 0xff }, | |
21 { 0x70, 0xA4, 0xB2, 0xff }, | |
22 { 0x6F, 0x3D, 0x86, 0xff }, | |
23 { 0x58, 0x8D, 0x43, 0xff }, | |
24 { 0x35, 0x28, 0x79, 0xff }, | |
25 { 0xB8, 0xC7, 0x6F, 0xff }, | |
26 { 0x6F, 0x4F, 0x25, 0xff }, | |
27 { 0x43, 0x39, 0x00, 0xff }, | |
28 { 0x9A, 0x67, 0x59, 0xff }, | |
29 { 0x44, 0x44, 0x44, 0xff }, | |
30 { 0x6C, 0x6C, 0x6C, 0xff }, | |
31 { 0x9A, 0xD2, 0x84, 0xff }, | |
32 { 0x6C, 0x5E, 0xB5, 0xff }, | |
33 { 0x95, 0x95, 0x95, 0xff }, | |
34 }; | |
35 | |
36 #define DM_RLE_MARKER 1 | |
37 #define DM_RLE_MASK 2 | |
38 | |
39 | |
40 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff) | |
41 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) | |
42 | |
43 | |
44 void dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt) | 15 void dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt) |
45 { | 16 { |
46 char typeStr[64]; | 17 char typeStr[64]; |
47 | 18 |
48 dmC64GetImageTypeString(typeStr, sizeof(typeStr), img->type, TRUE); | 19 dmC64GetImageTypeString(typeStr, sizeof(typeStr), img->type, TRUE); |
103 | 74 |
104 return buf; | 75 return buf; |
105 } | 76 } |
106 | 77 |
107 | 78 |
108 static BOOL dmCompareAddr16(const Uint8 *buf, const size_t offs, const Uint16 addr) | 79 BOOL dmCompareAddr16(const Uint8 *buf, const size_t offs, const Uint16 addr) |
109 { | 80 { |
110 return buf[offs ] == DM_GET_ADDR_LO(addr) && | 81 return buf[offs ] == DM_GET_ADDR_LO(addr) && |
111 buf[offs + 1] == DM_GET_ADDR_HI(addr); | 82 buf[offs + 1] == DM_GET_ADDR_HI(addr); |
112 } | 83 } |
113 | 84 |
269 | 240 |
270 return DMERR_OK; | 241 return DMERR_OK; |
271 } | 242 } |
272 | 243 |
273 | 244 |
274 static int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, | 245 void dmGenericRLEAnalyze(const DMGrowBuf *buf, Uint8 *rleMarker, const int rleType) |
246 { | |
247 | |
248 } | |
249 | |
250 | |
251 int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, | |
275 const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) | 252 const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) |
276 { | 253 { |
277 int res; | 254 int res; |
278 | 255 |
279 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) | 256 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) |
333 err: | 310 err: |
334 return res; | 311 return res; |
335 } | 312 } |
336 | 313 |
337 | 314 |
338 static int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, | 315 int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, |
339 const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) | 316 const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) |
340 { | 317 { |
341 int res; | 318 int res; |
342 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) | 319 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) |
343 return res; | 320 return res; |
389 | 366 |
390 return TRUE; | 367 return TRUE; |
391 } | 368 } |
392 | 369 |
393 | 370 |
394 static int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, | 371 int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, |
395 const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType) | 372 const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType) |
396 { | 373 { |
397 int res; | 374 int res; |
398 | 375 |
399 // Perform RLE encoding | 376 // Perform RLE encoding |
424 err: | 401 err: |
425 return res; | 402 return res; |
426 } | 403 } |
427 | 404 |
428 | 405 |
429 static int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, | 406 int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, |
430 const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType) | 407 const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType) |
431 { | 408 { |
432 int res; | 409 int res; |
433 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) | 410 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) |
434 return res; | 411 return res; |
435 | 412 |
436 return dmEncodeGenericRLE(dst, src, srcEnd, rleMarker, rleMinCount, rleMaxCount, rleType); | 413 return dmEncodeGenericRLE(dst, src, srcEnd, rleMarker, rleMinCount, rleMaxCount, rleType); |
437 } | 414 } |
438 | |
439 | |
440 static inline Uint8 dmC64GetGenericSCPixel( | |
441 const DMC64Image *img, const int bmoffs, const int scroffs, | |
442 const int vshift, const int vbank, const int vbitmap, const int cbank) | |
443 { | |
444 (void) cbank; | |
445 if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1) | |
446 return img->screen[vbank][scroffs] >> 4; | |
447 else | |
448 return img->screen[vbank][scroffs] & 15; | |
449 } | |
450 | |
451 | |
452 static inline Uint8 dmC64GetGenericMCPixel( | |
453 const DMC64Image *img, const int bmoffs, const int scroffs, | |
454 const int vshift, const int vbank, const int vbitmap, const int cbank) | |
455 { | |
456 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) | |
457 { | |
458 case 0: return img->bgcolor; break; | |
459 case 1: return img->screen[vbank][scroffs] >> 4; break; | |
460 case 2: return img->screen[vbank][scroffs] & 15; break; | |
461 default: return img->color[cbank][scroffs] & 15; break; | |
462 } | |
463 } | |
464 | |
465 | |
466 static inline Uint8 fmtGetGenericSCPixel( | |
467 const DMC64Image *img, const int bmoffs, const int scroffs, | |
468 const int vshift, const int vbitmap, const int raster) | |
469 { | |
470 (void) raster; | |
471 return dmC64GetGenericSCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0); | |
472 } | |
473 | |
474 | |
475 static inline Uint8 fmtGetGenericMCPixel( | |
476 const DMC64Image *img, const int bmoffs, const int scroffs, | |
477 const int vshift, const int vbitmap, const int raster) | |
478 { | |
479 (void) raster; | |
480 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0); | |
481 } | |
482 | |
483 | |
484 static int fmtProbeDrazPaint20Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
485 { | |
486 const char *ident = (const char *) buf + 2; | |
487 | |
488 if (len > 22 && | |
489 dmCompareAddr16(buf, 0, fmt->addr) && | |
490 strncmp(ident, "DRAZPAINT ", 10) == 0 && | |
491 ident[11] == '.' && ( | |
492 (ident[10] == '1' && ident[12] == '4') || | |
493 (ident[10] == '2' && ident[12] == '0') | |
494 )) | |
495 return DM_PROBE_SCORE_MAX; | |
496 | |
497 return DM_PROBE_SCORE_FALSE; | |
498 } | |
499 | |
500 | |
501 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
502 { | |
503 int res; | |
504 DMGrowBuf mem; | |
505 | |
506 if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, 0, DM_RLE_MARKER)) != DMERR_OK) | |
507 goto out; | |
508 | |
509 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); | |
510 | |
511 out: | |
512 dmGrowBufFree(&mem); | |
513 return res; | |
514 } | |
515 | |
516 | |
517 static int fmtEncodeDrazPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) | |
518 { | |
519 int res; | |
520 DMGrowBuf tmp; | |
521 Uint8 rleMarker; | |
522 const char *magicID = (fmt->type & D64_FMT_ILACE) ? "DRAZLACE! 1.0" : "DRAZPAINT 2.0"; | |
523 | |
524 // Encode the data to temp buffer | |
525 if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) | |
526 goto out; | |
527 | |
528 // Analyze the data .. | |
529 rleMarker = 0xff; | |
530 | |
531 // Add the header bits | |
532 if (!dmGrowBufPut(buf, magicID, strlen(magicID)) || | |
533 !dmGrowBufPutU8(buf, rleMarker)) | |
534 { | |
535 res = DMERR_MALLOC; | |
536 goto out; | |
537 } | |
538 | |
539 // And now RLE compress the data to the existing buffer | |
540 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, | |
541 rleMarker, 3, 255, DM_RLE_MARKER); | |
542 | |
543 out: | |
544 dmGrowBufFree(&tmp); | |
545 return res; | |
546 } | |
547 | |
548 | |
549 static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
550 { | |
551 if (len > 22 && | |
552 dmCompareAddr16(buf, 0, fmt->addr) && | |
553 strncmp((const char *) (buf + 2), "DRAZLACE! 1.0", 13) == 0) | |
554 return DM_PROBE_SCORE_MAX; | |
555 | |
556 return DM_PROBE_SCORE_FALSE; | |
557 } | |
558 | |
559 | |
560 static BOOL fmtDrazLaceSetLaceType(DMC64Image *img, const DMC64EncDecOp *op, | |
561 const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
562 { | |
563 (void) len; | |
564 (void) fmt; | |
565 img->laceType = buf[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR; | |
566 return TRUE; | |
567 } | |
568 | |
569 | |
570 static int fmtProbeGunPaint(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
571 { | |
572 if (len > 0x400 && | |
573 dmCompareAddr16(buf, 0, fmt->addr) && | |
574 strncmp((const char *) (buf + 0x3ea), "GUNPAINT (JZ) ", 14) == 0) | |
575 return DM_PROBE_SCORE_MAX; | |
576 | |
577 return DM_PROBE_SCORE_FALSE; | |
578 } | |
579 | |
580 | |
581 static int fmtProbeAmicaPaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
582 { | |
583 size_t i, n; | |
584 | |
585 if (len < 2048 || !dmCompareAddr16(buf, 0, fmt->addr)) | |
586 return DM_PROBE_SCORE_FALSE; | |
587 | |
588 // Interpaint Hi-Res gives a false positive | |
589 // as do some GunPaint images .. | |
590 if (len == 9002 || fmtProbeGunPaint(buf, len, fmt) > DM_PROBE_SCORE_GOOD) | |
591 return DM_PROBE_SCORE_FALSE; | |
592 | |
593 for (n = 0, i = 2; i < len; i++) | |
594 if (buf[i] == 0xC2) n++; | |
595 | |
596 if (n > 50) | |
597 return DM_PROBE_SCORE_GOOD; | |
598 if (n > 25) | |
599 return DM_PROBE_SCORE_AVG; | |
600 if (n > 10) | |
601 return DM_PROBE_SCORE_MAYBE; | |
602 | |
603 return DM_PROBE_SCORE_FALSE; | |
604 } | |
605 | |
606 | |
607 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
608 { | |
609 int res; | |
610 DMGrowBuf mem, tmp; | |
611 | |
612 // Amica Paint apparently is broken and stores one byte less than it should | |
613 // so we need to do some crappy buffer expansion here .. | |
614 if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK) | |
615 return res; | |
616 | |
617 tmp.len = len; | |
618 memcpy(tmp.data, buf, len); | |
619 tmp.data[tmp.len++] = 0; | |
620 | |
621 // Now do an RLE decode on the enlarged buffer | |
622 if ((res = dmDecodeGenericRLE(&mem, tmp.data, tmp.data + tmp.len, 0xC2, 0, 0, DM_RLE_MARKER)) != DMERR_OK) | |
623 goto out; | |
624 | |
625 // And finally decode to bitmap struct | |
626 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); | |
627 | |
628 out: | |
629 dmGrowBufFree(&tmp); | |
630 dmGrowBufFree(&mem); | |
631 return res; | |
632 } | |
633 | |
634 | |
635 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
636 { | |
637 if (len == fmt->size && | |
638 (dmCompareAddr16(buf, 0, 0x3c00) || dmCompareAddr16(buf, 0, 0x3ff0))) | |
639 return DM_PROBE_SCORE_MAX; | |
640 | |
641 return DM_PROBE_SCORE_FALSE; | |
642 } | |
643 | |
644 | |
645 static BOOL fmtTruePaintSetLaceType(DMC64Image *img, const DMC64EncDecOp *op, | |
646 const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
647 { | |
648 (void) op; | |
649 (void) buf; | |
650 (void) len; | |
651 (void) fmt; | |
652 img->laceType = D64_ILACE_RES; | |
653 return TRUE; | |
654 } | |
655 | |
656 | |
657 static Uint8 fmtGetPixelTruePaint( | |
658 const DMC64Image *img, const int bmoffs, const int scroffs, | |
659 const int vshift, const int vbitmap, const int raster) | |
660 { | |
661 (void) raster; | |
662 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0); | |
663 } | |
664 | |
665 | |
666 #define XX2_MIN_SIZE 4000 | |
667 | |
668 static int fmtProbeFormatXX2(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
669 { | |
670 if (len >= XX2_MIN_SIZE && len <= XX2_MIN_SIZE + 8 && | |
671 dmCompareAddr16(buf, 0, fmt->addr)) | |
672 return DM_PROBE_SCORE_MAYBE; | |
673 | |
674 return DM_PROBE_SCORE_FALSE; | |
675 } | |
676 | |
677 | |
678 static int fmtDecodeFormatXX2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
679 { | |
680 int res; | |
681 | |
682 // If there is only data for less than XX2_MIN_SIZE bytes, | |
683 // allocate a buffer of that size and copy data there. | |
684 // Otherwise allocate len bytes. | |
685 size_t nlen = len < XX2_MIN_SIZE ? XX2_MIN_SIZE : len; | |
686 Uint8 *mem = dmMalloc0(nlen); | |
687 if (mem == NULL) | |
688 return DMERR_MALLOC; | |
689 | |
690 memcpy(mem, buf, len); | |
691 res = dmC64DecodeGenericBMP(img, mem, nlen, fmt); | |
692 | |
693 dmFree(mem); | |
694 return res; | |
695 } | |
696 | |
697 | |
698 #define FUNPAINT2_HEADER_SIZE (0x10) | |
699 static const char *fmtFunPaint2MagicID = "FUNPAINT (MT) "; | |
700 | |
701 | |
702 static BOOL fmtProbeFunPaint2Header(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
703 { | |
704 return | |
705 len > 30 && | |
706 dmCompareAddr16(buf, 0, fmt->addr) && | |
707 strncmp((const char *) (buf + 2), fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) == 0; | |
708 } | |
709 | |
710 | |
711 static int fmtProbeFunPaint2Unpacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
712 { | |
713 if (fmtProbeFunPaint2Header(buf, len, fmt) && | |
714 buf[2 + 14] == 0) | |
715 return DM_PROBE_SCORE_MAX; | |
716 else | |
717 return DM_PROBE_SCORE_FALSE; | |
718 } | |
719 | |
720 | |
721 static int fmtProbeFunPaint2Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
722 { | |
723 if (fmtProbeFunPaint2Header(buf, len, fmt) && | |
724 buf[2 + 14] != 0) | |
725 return DM_PROBE_SCORE_MAX; | |
726 else | |
727 return DM_PROBE_SCORE_FALSE; | |
728 } | |
729 | |
730 | |
731 static int fmtDecodeFunPaint2Unpacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
732 { | |
733 return dmC64DecodeGenericBMP(img, buf + FUNPAINT2_HEADER_SIZE, len - FUNPAINT2_HEADER_SIZE, fmt); | |
734 } | |
735 | |
736 | |
737 static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | |
738 { | |
739 int res; | |
740 DMGrowBuf mem; | |
741 dmGrowBufInit(&mem); | |
742 | |
743 if ((res = dmDecodeGenericRLE(&mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, *(buf + 15), 0, 0, DM_RLE_MARKER)) != DMERR_OK) | |
744 goto out; | |
745 | |
746 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); | |
747 | |
748 out: | |
749 dmGrowBufFree(&mem); | |
750 return res; | |
751 } | |
752 | |
753 | |
754 static Uint8 fmtGetPixelFunPaint2( | |
755 const DMC64Image *img, const int bmoffs, const int scroffs, | |
756 const int vshift, const int vbitmap, const int raster) | |
757 { | |
758 const int vbank = (raster & 7) + (vbitmap * 8); | |
759 int vr, vb; | |
760 if (raster < 100) | |
761 { | |
762 vb = 0; | |
763 vr = raster; | |
764 } | |
765 else | |
766 { | |
767 vb = 0; | |
768 vr = raster - 100; | |
769 } | |
770 | |
771 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) | |
772 { | |
773 case 0: return img->extraData[vb][vr] & 15; break; | |
774 case 1: return img->screen[vbank][scroffs] >> 4; break; | |
775 case 2: return img->screen[vbank][scroffs] & 15; break; | |
776 default: return img->color[0][scroffs] & 15; break; | |
777 } | |
778 } | |
779 | |
780 | |
781 static Uint8 fmtGetPixelGunPaint( | |
782 const DMC64Image *img, const int bmoffs, const int scroffs, | |
783 const int vshift, const int vbitmap, const int raster) | |
784 { | |
785 const int vbank = (raster & 7);// + (vbitmap * 8); | |
786 int vr, vb; | |
787 if (raster < 177) | |
788 { | |
789 vb = 0; | |
790 vr = raster; | |
791 } | |
792 else | |
793 { | |
794 vb = 0; | |
795 vr = raster - 177; | |
796 } | |
797 | |
798 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) | |
799 { | |
800 case 0: return img->extraData[vb][vr] & 15; break; | |
801 case 1: return img->screen[vbank][scroffs] >> 4; break; | |
802 case 2: return img->screen[vbank][scroffs] & 15; break; | |
803 default: return img->color[0][scroffs] & 15; break; | |
804 } | |
805 } | |
806 | |
807 | |
808 static Uint8 fmtGetPixelBMFLI( | |
809 const DMC64Image *img, const int bmoffs, const int scroffs, | |
810 const int vshift, const int vbitmap, const int raster) | |
811 { | |
812 const int vbank = raster & 7; | |
813 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) | |
814 { | |
815 case 0: return img->extraData[0][raster]; break; | |
816 case 1: return img->screen[vbank][scroffs] >> 4; break; | |
817 case 2: return img->screen[vbank][scroffs] & 15; break; | |
818 default: return img->color[0][scroffs] & 15; break; | |
819 } | |
820 } | |
821 | |
822 | |
823 static Uint8 fmtGetPixelFLIDesigner( | |
824 const DMC64Image *img, const int bmoffs, const int scroffs, | |
825 const int vshift, const int vbitmap, const int raster) | |
826 { | |
827 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, raster & 7, vbitmap, 0); | |
828 } | |
829 | |
830 | |
831 static Uint8 fmtGetPixelCHFLI( | |
832 const DMC64Image *img, const int bmoffs, const int scroffs, | |
833 const int vshift, const int vbitmap, const int raster) | |
834 { | |
835 const int vbank = raster & 7; | |
836 | |
837 if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1) | |
838 return img->screen[vbank][scroffs] >> 4; | |
839 else | |
840 return img->screen[vbank][scroffs] & 15; | |
841 } | |
842 | |
843 | |
844 static int fmtEncodeStub(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) | |
845 { | |
846 (void) buf; | |
847 (void) img; | |
848 (void) fmt; | |
849 | |
850 return dmError(DMERR_NOT_SUPPORTED, | |
851 "Encoding of '%s' format not supported.\n", | |
852 fmt->name); | |
853 } | |
854 | |
855 | |
856 // | |
857 // Array with data for supported formats | |
858 // | |
859 #define DEF_SCREEN_RAM(start, oindex, bindex, osize) { DT_SCREEN_RAM, (start) + ((osize) * (oindex)), (bindex), 0, NULL, NULL } | |
860 #define DEF_SCREEN_RAMS_8(start, sindex, osize) \ | |
861 DEF_SCREEN_RAM((start), 0, (sindex + 0), (osize)), \ | |
862 DEF_SCREEN_RAM((start), 1, (sindex + 1), (osize)), \ | |
863 DEF_SCREEN_RAM((start), 2, (sindex + 2), (osize)), \ | |
864 DEF_SCREEN_RAM((start), 3, (sindex + 3), (osize)), \ | |
865 DEF_SCREEN_RAM((start), 4, (sindex + 4), (osize)), \ | |
866 DEF_SCREEN_RAM((start), 5, (sindex + 5), (osize)), \ | |
867 DEF_SCREEN_RAM((start), 6, (sindex + 6), (osize)), \ | |
868 DEF_SCREEN_RAM((start), 7, (sindex + 7), (osize)), | |
869 | |
870 | |
871 const DMC64ImageFormat dmC64ImageFormats[] = | |
872 { | |
873 { | |
874 D64_FMT_MC, "d2p", "DrazPaint 1.4/2.0 (packed)", 0x5800, 0, | |
875 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
876 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
877 fmtProbeDrazPaint20Packed, | |
878 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked, | |
879 NULL, NULL, | |
880 NULL, | |
881 { | |
882 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, | |
883 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, | |
884 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, | |
885 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, | |
886 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
887 } | |
888 }, | |
889 | |
890 { | |
891 D64_FMT_MC, "drp", "DrazPaint (unpacked)", 0x5800, 10051, | |
892 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
893 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
894 NULL, | |
895 NULL, NULL, | |
896 NULL, NULL, | |
897 NULL, | |
898 { | |
899 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, | |
900 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, | |
901 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, | |
902 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, | |
903 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
904 } | |
905 }, | |
906 | |
907 { | |
908 D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, 0, | |
909 C64_SCR_WIDTH , C64_SCR_HEIGHT, | |
910 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, | |
911 fmtProbeDrazLace10Packed, | |
912 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked, | |
913 NULL, NULL, | |
914 NULL, | |
915 { | |
916 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, | |
917 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, | |
918 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, | |
919 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, | |
920 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL }, | |
921 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, | |
922 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
923 } | |
924 }, | |
925 | |
926 { | |
927 D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, | |
928 C64_SCR_WIDTH , C64_SCR_HEIGHT, | |
929 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, | |
930 NULL, | |
931 NULL, NULL, | |
932 NULL, NULL, | |
933 NULL, | |
934 { | |
935 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, | |
936 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, | |
937 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, | |
938 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, | |
939 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL }, | |
940 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, | |
941 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
942 } | |
943 }, | |
944 | |
945 { | |
946 D64_FMT_MC | D64_FMT_ILACE, "mci", "Truepaint (unpacked)", 0x9c00, 19434, | |
947 C64_SCR_WIDTH , C64_SCR_HEIGHT, | |
948 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, | |
949 NULL, | |
950 NULL, NULL, | |
951 NULL, NULL, | |
952 fmtGetPixelTruePaint, | |
953 { | |
954 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, | |
955 { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL }, | |
956 { DT_BITMAP, 0x0400, 0, 0, NULL, NULL }, | |
957 { DT_BITMAP, 0x2400, 1, 0, NULL, NULL }, | |
958 { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL }, | |
959 { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL }, | |
960 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL }, | |
961 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
962 } | |
963 }, | |
964 | |
965 { | |
966 D64_FMT_MC, "kla", "Koala Paint (unpacked)", 0x6000, 10003, | |
967 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
968 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
969 NULL, | |
970 NULL, NULL, | |
971 NULL, NULL, | |
972 NULL, | |
973 { | |
974 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
975 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
976 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, | |
977 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, | |
978 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
979 } | |
980 }, | |
981 | |
982 { | |
983 D64_FMT_MC, "ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018, | |
984 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
985 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
986 NULL, | |
987 NULL, NULL, | |
988 NULL, NULL, | |
989 NULL, | |
990 { | |
991 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
992 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
993 { DT_COLOR_RAM, 0x2338, 0, 0, NULL, NULL }, | |
994 { DT_COLOR_REG, 0x2329, 0, DC_BGCOL, NULL, NULL }, | |
995 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
996 } | |
997 }, | |
998 | |
999 { | |
1000 D64_FMT_MC, "ami", "Amica Paint (packed)", 0x4000, 0, | |
1001 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
1002 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1003 fmtProbeAmicaPaintPacked, | |
1004 fmtDecodeAmicaPaintPacked, fmtEncodeStub, | |
1005 NULL, NULL, | |
1006 NULL, | |
1007 { | |
1008 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, | |
1009 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1010 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
1011 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, | |
1012 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1013 } | |
1014 }, | |
1015 | |
1016 { | |
1017 D64_FMT_MC, "rpm", "Run Paint (unpacked)", 0x6000, 10006, | |
1018 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
1019 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1020 NULL, | |
1021 NULL, NULL, | |
1022 NULL, NULL, | |
1023 NULL, | |
1024 { | |
1025 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, | |
1026 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1027 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
1028 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, | |
1029 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1030 } | |
1031 }, | |
1032 | |
1033 { | |
1034 D64_FMT_HIRES, "art", "Art Studio (unpacked)", 0x2000, 9009, | |
1035 C64_SCR_WIDTH , C64_SCR_HEIGHT, | |
1036 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1037 NULL, | |
1038 NULL, NULL, | |
1039 NULL, NULL, | |
1040 NULL, | |
1041 { | |
1042 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1043 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
1044 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1045 } | |
1046 }, | |
1047 | |
1048 { | |
1049 D64_FMT_HIRES, "iph", "Interpaint (unpacked)", 0x4000, 9002, | |
1050 C64_SCR_WIDTH , C64_SCR_HEIGHT, | |
1051 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, | |
1052 NULL, | |
1053 NULL, NULL, | |
1054 NULL, NULL, | |
1055 NULL, | |
1056 { | |
1057 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1058 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
1059 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1060 } | |
1061 }, | |
1062 | |
1063 { | |
1064 D64_FMT_MC, "ipc", "Interpaint MC (unpacked)", 0x4000, 10003, | |
1065 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
1066 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, | |
1067 NULL, | |
1068 NULL, NULL, | |
1069 NULL, NULL, | |
1070 NULL, | |
1071 { | |
1072 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1073 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, | |
1074 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, | |
1075 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, | |
1076 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1077 } | |
1078 }, | |
1079 | |
1080 { | |
1081 D64_FMT_HIRES, "dd", "Doodle (unpacked)", 0x1c00, 9218, | |
1082 C64_SCR_WIDTH , C64_SCR_HEIGHT, | |
1083 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, | |
1084 NULL, | |
1085 NULL, NULL, | |
1086 NULL, NULL, | |
1087 NULL, | |
1088 { | |
1089 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, | |
1090 { DT_BITMAP, 0x0400, 0, 0, NULL, NULL }, | |
1091 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1092 } | |
1093 }, | |
1094 | |
1095 { | |
1096 D64_FMT_MC | D64_FMT_FLI, "bml", "Blackmail FLI (unpacked)", 0x3b00, 17474, | |
1097 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
1098 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1099 NULL, | |
1100 NULL, NULL, | |
1101 NULL, NULL, | |
1102 fmtGetPixelBMFLI, | |
1103 { | |
1104 { DT_EXTRA_DATA, 0x0000, 0, 200, NULL, NULL }, | |
1105 { DT_COLOR_RAM, 0x0100, 0, 0, NULL, NULL }, | |
1106 DEF_SCREEN_RAMS_8( 0x0500, 0, 0x400) | |
1107 { DT_BITMAP, 0x2500, 0, 0, NULL, NULL }, | |
1108 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1109 } | |
1110 }, | |
1111 | |
1112 { | |
1113 D64_FMT_MC | D64_FMT_FLI, "fli", "FLI Designer (unpacked)", 0, 17409, | |
1114 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
1115 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1116 fmtProbeFLIDesigner, | |
1117 NULL, NULL, | |
1118 NULL, NULL, | |
1119 fmtGetPixelFLIDesigner, | |
1120 { | |
1121 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, | |
1122 DEF_SCREEN_RAMS_8( 0x0400, 0, 0x400) | |
1123 { DT_BITMAP, 0x2400, 0, 0, NULL, NULL }, | |
1124 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1125 } | |
1126 }, | |
1127 | |
1128 { | |
1129 D64_FMT_MC, "xx1", "Unknown $2000 format (unpacked)", 0x2000, 10242, | |
1130 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, | |
1131 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1132 NULL, | |
1133 NULL, NULL, | |
1134 NULL, NULL, | |
1135 NULL, | |
1136 { | |
1137 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1138 { DT_SCREEN_RAM, 0x2000, 0, 0, NULL, NULL }, | |
1139 { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL }, | |
1140 { DT_COLOR_SET, 0x00 , 0, DC_BGCOL, NULL, NULL }, | |
1141 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1142 } | |
1143 }, | |
1144 | |
1145 #define XX2_WIDTH_CH 40 | |
1146 #define XX2_HEIGHT_CH 10 | |
1147 #define XX2_SIZE (XX2_WIDTH_CH * XX2_HEIGHT_CH) | |
1148 #define XX2_BSIZE (XX2_SIZE * 8) | |
1149 | |
1150 { | |
1151 D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 0, | |
1152 XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8, | |
1153 XX2_WIDTH_CH , XX2_HEIGHT_CH, | |
1154 fmtProbeFormatXX2, | |
1155 fmtDecodeFormatXX2, NULL, | |
1156 NULL, NULL, | |
1157 NULL, | |
1158 { | |
1159 { DT_BITMAP, 0x0000, 0, XX2_BSIZE, NULL, NULL }, | |
1160 { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE, 0, XX2_SIZE, NULL, NULL }, | |
1161 { DT_SCREEN_RAM, XX2_BSIZE, 0, XX2_SIZE, NULL, NULL }, | |
1162 { DT_COLOR_SET, 11, 0, DC_BGCOL, NULL, NULL }, | |
1163 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1164 } | |
1165 }, | |
1166 | |
1167 { | |
1168 D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "fp2", "FunPaint II (unpacked)", 0x3ff0, 33694, | |
1169 C64_SCR_WIDTH, C64_SCR_HEIGHT, | |
1170 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1171 fmtProbeFunPaint2Unpacked, | |
1172 fmtDecodeFunPaint2Unpacked, fmtEncodeStub, | |
1173 NULL, NULL, | |
1174 fmtGetPixelFunPaint2, | |
1175 { | |
1176 DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400) | |
1177 { DT_BITMAP, 0x2000, 0, 0, NULL, NULL }, | |
1178 { DT_EXTRA_DATA, 0x3f40, 0, 100, NULL, NULL }, | |
1179 { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL }, | |
1180 DEF_SCREEN_RAMS_8( 0x43e8, 8, 0x400) | |
1181 { DT_BITMAP, 0x63e8, 1, 0, NULL, NULL }, | |
1182 { DT_EXTRA_DATA, 0x8328, 1, 100, NULL, NULL }, | |
1183 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1184 } | |
1185 }, | |
1186 | |
1187 { | |
1188 D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "fp2p", "FunPaint II (packed)", 0x3ff0, 0, | |
1189 C64_SCR_WIDTH, C64_SCR_HEIGHT, | |
1190 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1191 fmtProbeFunPaint2Packed, | |
1192 fmtDecodeFunPaint2Packed, fmtEncodeStub, | |
1193 NULL, NULL, | |
1194 fmtGetPixelFunPaint2, | |
1195 { | |
1196 DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400) | |
1197 { DT_BITMAP, 0x2000, 0, 0, NULL, NULL }, | |
1198 { DT_EXTRA_DATA, 0x3f40, 0, 100, NULL, NULL }, | |
1199 { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL }, | |
1200 DEF_SCREEN_RAMS_8( 0x43e8, 8, 0x400) | |
1201 { DT_BITMAP, 0x63e8, 1, 0, NULL, NULL }, | |
1202 { DT_EXTRA_DATA, 0x8328, 1, 100, NULL, NULL }, | |
1203 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1204 } | |
1205 }, | |
1206 | |
1207 { | |
1208 D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "gun", "GunPaint (unpacked)", 0x4000, 0, | |
1209 C64_SCR_WIDTH, C64_SCR_HEIGHT, | |
1210 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, | |
1211 fmtProbeGunPaint, | |
1212 NULL, NULL, | |
1213 NULL, NULL, | |
1214 fmtGetPixelGunPaint, | |
1215 { | |
1216 DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400) | |
1217 { DT_BITMAP, 0x2000, 0, 0, NULL, NULL }, | |
1218 { DT_EXTRA_DATA, 0x3f4f, 0, 177, NULL, NULL }, | |
1219 { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL }, | |
1220 DEF_SCREEN_RAMS_8( 0x4400, 8, 0x400) | |
1221 { DT_BITMAP, 0x6400, 1, 0, NULL, NULL }, | |
1222 { DT_EXTRA_DATA, 0x47e8, 1, 20, NULL, NULL }, | |
1223 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1224 } | |
1225 }, | |
1226 | |
1227 { | |
1228 D64_FMT_HIRES | D64_FMT_FLI, "chi", "Crest Hires FLI Designer (unpacked)", 0x4000, 16386, | |
1229 C64_SCR_WIDTH, 14 * 8, | |
1230 C64_SCR_CH_WIDTH , 14, | |
1231 NULL, | |
1232 NULL, NULL, | |
1233 NULL, NULL, | |
1234 fmtGetPixelCHFLI, | |
1235 { | |
1236 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, | |
1237 DEF_SCREEN_RAMS_8( 0x2000, 0, 0x400) | |
1238 { DT_LAST, 0, 0, 0, NULL, NULL }, | |
1239 } | |
1240 }, | |
1241 }; | |
1242 | |
1243 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]); | |
1244 | 415 |
1245 | 416 |
1246 // Perform probing of the given data buffer, trying to determine | 417 // Perform probing of the given data buffer, trying to determine |
1247 // if it contains a supported "C64" image format. Returns the | 418 // if it contains a supported "C64" image format. Returns the |
1248 // "probe score", see libgfx.h for list of values. If a match | 419 // "probe score", see libgfx.h for list of values. If a match |