comparison tools/lib64gfx.c @ 917:df3a74f230d9

Initial implementation of charmode support in lib64gfx.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 25 Feb 2015 03:53:34 +0200
parents 3985f596ece5
children 59615f9c2ca9
comparison
equal deleted inserted replaced
916:3985f596ece5 917:df3a74f230d9
12 #define BUF_SIZE_GROW (4*1024) 12 #define BUF_SIZE_GROW (4*1024)
13 13
14 14
15 char * dmC64GetImageTypeString(char *buf, const size_t len, const int type) 15 char * dmC64GetImageTypeString(char *buf, const size_t len, const int type)
16 { 16 {
17 snprintf(buf, len, 17 *buf = 0;
18 "%s%s%s", 18
19 (type & D64_FMT_FLI) ? "FLI " : "", 19 if (type & D64_FMT_FLI)
20 (type & D64_FMT_MC) ? "MCol" : "HiRes", 20 strncat(buf, "FLI ", len - strlen(buf));
21 (type & D64_FMT_ILACE) ? " Ilace" : "" 21
22 ); 22 strncat(buf, (type & D64_FMT_MC) ? "MCol " : "HiRes ", len - strlen(buf));
23
24 if (type & D64_FMT_ILACE)
25 strncat(buf, "Ilace ", len - strlen(buf));
26
27 if (type & D64_FMT_CHAR)
28 strncat(buf, "CharMap", len - strlen(buf));
23 29
24 return buf; 30 return buf;
25 } 31 }
26 32
27 33
51 { 57 {
52 C64_SCR_COLOR_SIZE, 58 C64_SCR_COLOR_SIZE,
53 C64_SCR_BITMAP_SIZE, 59 C64_SCR_BITMAP_SIZE,
54 C64_SCR_SCREEN_SIZE, 60 C64_SCR_SCREEN_SIZE,
55 1, 61 1,
62 0,
56 C64_SCR_EXTRADATA, 63 C64_SCR_EXTRADATA,
64 0,
65 0,
66 C64_MAX_CHARS * C64_CHR_HEIGHT * C64_CHR_WIDTH,
67 0
57 }; 68 };
58 69
59 70
60 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff) 71 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff)
61 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) 72 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff)
287 4, 298 4,
288 { 299 {
289 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 300 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
290 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, 301 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
291 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, 302 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
292 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL }, 303 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
293 } 304 }
294 }, 305 },
295 306
296 { 307 {
297 D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, -1, 308 D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, -1,
300 6, 311 6,
301 { 312 {
302 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 313 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
303 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, 314 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
304 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, 315 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
305 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL }, 316 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
306 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL }, 317 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL },
307 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, 318 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL },
308 } 319 }
309 }, 320 },
310 321
315 4, 326 4,
316 { 327 {
317 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 328 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
318 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, 329 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
319 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, 330 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
320 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL }, 331 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
321 } 332 }
322 }, 333 },
323 334
324 { 335 {
325 D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, 336 D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242,
328 6, 339 6,
329 { 340 {
330 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 341 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
331 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, 342 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
332 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, 343 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
333 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL }, 344 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
334 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL }, 345 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL },
335 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, 346 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL },
336 } 347 }
337 }, 348 },
338 349
341 NULL, NULL, 352 NULL, NULL,
342 NULL, NULL, NULL, 353 NULL, NULL, NULL,
343 6, 354 6,
344 { 355 {
345 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, 356 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL },
346 { DT_BGCOLOR, 0x03e8, 0, 0, NULL, NULL }, 357 { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL },
347 { DT_BITMAP, 0x0400, 0, 0, NULL, NULL }, 358 { DT_BITMAP, 0x0400, 0, 0, NULL, NULL },
348 { DT_BITMAP, 0x2400, 1, 0, NULL, NULL }, 359 { DT_BITMAP, 0x2400, 1, 0, NULL, NULL },
349 { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL }, 360 { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL },
350 { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL }, 361 { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL },
351 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL }, 362 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL },
359 4, 370 4,
360 { 371 {
361 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 372 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
362 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, 373 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
363 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, 374 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
364 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL }, 375 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
365 } 376 }
366 }, 377 },
367 378
368 { 379 {
369 D64_FMT_MC, "ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018, 380 D64_FMT_MC, "ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018,
372 4, 383 4,
373 { 384 {
374 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 385 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
375 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, 386 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
376 { DT_COLOR_RAM, 0x2338, 0, 0, NULL, NULL }, 387 { DT_COLOR_RAM, 0x2338, 0, 0, NULL, NULL },
377 { DT_BGCOLOR, 0x2329, 0, 0, NULL, NULL }, 388 { DT_COLOR_REG, 0x2329, 0, DC_BGCOL, NULL, NULL },
378 } 389 }
379 }, 390 },
380 391
381 { 392 {
382 D64_FMT_MC, "ami", "Amica Paint (packed)", 0x4000, -1, 393 D64_FMT_MC, "ami", "Amica Paint (packed)", 0x4000, -1,
385 4, 396 4,
386 { 397 {
387 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, 398 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
388 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 399 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
389 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, 400 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
390 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL }, 401 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
391 } 402 }
392 }, 403 },
393 404
394 { 405 {
395 D64_FMT_MC, "rpm", "Run Paint (unpacked)", 0x6000, 10006, 406 D64_FMT_MC, "rpm", "Run Paint (unpacked)", 0x6000, 10006,
398 4, 409 4,
399 { 410 {
400 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, 411 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
401 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 412 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
402 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, 413 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
403 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL }, 414 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
404 } 415 }
405 }, 416 },
406 417
407 { 418 {
408 D64_FMT_HIRES, "art", "Art Studio (unpacked)", 0x2000, 9009, 419 D64_FMT_HIRES, "art", "Art Studio (unpacked)", 0x2000, 9009,
487 4, 498 4,
488 { 499 {
489 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 500 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
490 { DT_SCREEN_RAM, 0x2000, 0, 0, NULL, NULL }, 501 { DT_SCREEN_RAM, 0x2000, 0, 0, NULL, NULL },
491 { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL }, 502 { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL },
492 { DT_BGCOLOR_SET, 0x00 , 0, 0, NULL, NULL }, 503 { DT_COLOR_SET, 0x00 , 0, DC_BGCOL, NULL, NULL },
493 } 504 }
494 }, 505 },
495 506
507 #define XX2_SIZE (40 * 10)
508 #define XX2_BSIZE (XX2_SIZE * 8)
509 {
510 D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 4002,
511 NULL, NULL,
512 NULL, NULL, NULL,
513 4,
514 {
515 { DT_BITMAP, 0x0000, 0, XX2_BSIZE, NULL, NULL },
516 { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE, 0, XX2_SIZE, NULL, NULL },
517 { DT_SCREEN_RAM, XX2_BSIZE, 0, XX2_SIZE, NULL, NULL },
518
519 { DT_COLOR_SET, 11 , 0, DC_BGCOL, NULL, NULL },
520 }
521 },
522
523 /*
524 #define XX2_SIZE (40 * 10)
525 #define XX2_BSIZE (XX2_SIZE * 8)
526 {
527 D64_FMT_MC | D64_FMT_CHAR, "xx2", "Unknown $2000 char format (unpacked)", 0x2000, 4002,
528 NULL, NULL,
529 NULL, NULL, NULL,
530 4,
531 {
532 { DT_CHAR_DATA, 0x0000, 0, XX2_BSIZE, NULL, NULL },
533 { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE , 0, XX2_SIZE, NULL, NULL },
534
535 { DT_CHAR_CONFIG, D64_CHCFG_LINEAR, 0, XX2_SIZE, NULL, NULL },
536 { DT_COLOR_SET, 1 , 0, DC_BGCOL, NULL, NULL },
537 { DT_COLOR_SET, 3 , 0, DC_D022, NULL, NULL },
538 { DT_COLOR_SET, 4 , 0, DC_D023, NULL, NULL },
539 }
540 },
541 */
496 }; 542 };
497 543
498 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]); 544 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]);
499 545
500 546
598 switch (op->type) 644 switch (op->type)
599 { 645 {
600 case DT_COLOR_RAM: memcpy(img->color[op->bank], src, size); break; 646 case DT_COLOR_RAM: memcpy(img->color[op->bank], src, size); break;
601 case DT_BITMAP: memcpy(img->bitmap[op->bank], src, size); break; 647 case DT_BITMAP: memcpy(img->bitmap[op->bank], src, size); break;
602 case DT_SCREEN_RAM: memcpy(img->screen[op->bank], src, size); break; 648 case DT_SCREEN_RAM: memcpy(img->screen[op->bank], src, size); break;
603 case DT_BGCOLOR: img->bgcolor = *src; break;
604 case DT_BGCOLOR_SET: img->bgcolor = op->offs; break;
605 case DT_EXTRADATA: memcpy(img->extradata, src, size); break; 649 case DT_EXTRADATA: memcpy(img->extradata, src, size); break;
650 case DT_CHAR_DATA: memcpy(img->charmem, src, size); break;
651
652 case DT_COLOR_REG:
653 switch (op->size)
654 {
655 case DC_D020: img->d020 = *src; break;
656 case DC_BGCOL:
657 case DC_D021: img->bgcolor = *src; break;
658 case DC_D022: img->d022 = *src; break;
659 case DC_D023: img->d023 = *src; break;
660 case DC_D024: img->d024 = *src; break;
661 default:
662 dmError("Unhandled DT_COLOR_REG mode %d in ",
663 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
664 op->size, i, op->offs, op->offs, op->bank, size, size, len, len);
665 return DMERR_INTERNAL;
666 }
667 break;
668
669 case DT_COLOR_SET:
670 switch (op->size)
671 {
672 case DC_D020: img->d020 = op->offs; break;
673 case DC_BGCOL:
674 case DC_D021: img->bgcolor = op->offs; break;
675 case DC_D022: img->d022 = op->offs; break;
676 case DC_D023: img->d023 = op->offs; break;
677 case DC_D024: img->d024 = op->offs; break;
678 default:
679 dmError("Unhandled DT_COLOR_SET mode %d in ",
680 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
681 op->size, i, op->offs, op->offs, op->bank, size, size, len, len);
682 return DMERR_INTERNAL;
683 }
684 break;
685
686 case DT_CHAR_CONFIG:
687 switch (op->offs)
688 {
689 case D64_CHCFG_SCREEN:
690 break;
691
692 case D64_CHCFG_LINEAR:
693 {
694 size_t bank, offs;
695 for (bank = 0; bank < C64_SCR_MAX_BANK; bank++)
696 for (offs = 0; offs < C64_SCR_SCREEN_SIZE; offs++)
697 img->screen[bank][offs] = offs & 0xff;
698 }
699 break;
700
701 default:
702 dmError("Unhandled DT_CHAR_CONFIG mode %d in ",
703 "op #%d, bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
704 op->offs, i, op->bank, size, size, len, len);
705 return DMERR_INTERNAL;
706 }
707 break;
708
606 case DT_DEC_FUNCTION: 709 case DT_DEC_FUNCTION:
607 if (op->decfunction == NULL) 710 if (op->decfunction == NULL)
608 { 711 {
609 dmError("Decode op is a function, but function ptr is NULL: " 712 dmError("Decode op is a function, but function ptr is NULL: "
610 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", 713 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
687 switch (op->type) 790 switch (op->type)
688 { 791 {
689 case DT_COLOR_RAM: memcpy(dst, img->color[op->bank], size); break; 792 case DT_COLOR_RAM: memcpy(dst, img->color[op->bank], size); break;
690 case DT_BITMAP: memcpy(dst, img->bitmap[op->bank], size); break; 793 case DT_BITMAP: memcpy(dst, img->bitmap[op->bank], size); break;
691 case DT_SCREEN_RAM: memcpy(dst, img->screen[op->bank], size); break; 794 case DT_SCREEN_RAM: memcpy(dst, img->screen[op->bank], size); break;
692 case DT_BGCOLOR: *dst = img->bgcolor; break;
693 case DT_EXTRADATA: memcpy(dst, img->extradata, size); break; 795 case DT_EXTRADATA: memcpy(dst, img->extradata, size); break;
796 case DT_CHAR_DATA: memcpy(dst, img->charmem, size); break;
797
798 case DT_COLOR_REG:
799 switch (op->size)
800 {
801 case DC_D020: *dst = img->d020; break;
802 case DC_BGCOL:
803 case DC_D021: *dst = img->bgcolor; break;
804 case DC_D022: *dst = img->d022; break;
805 case DC_D023: *dst = img->d023; break;
806 case DC_D024: *dst = img->d024; break;
807 default:
808 dmError("Unhandled DT_COLOR_REG mode %d in ",
809 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
810 op->size, i, op->offs, op->offs, op->bank, size, size, *plen, *plen);
811 return DMERR_INTERNAL;
812 }
813 break;
814
694 case DT_ENC_FUNCTION: 815 case DT_ENC_FUNCTION:
695 if (op->encfunction == NULL) 816 if (op->encfunction == NULL)
696 { 817 {
697 dmError("Encode op is a function, but function ptr is NULL: " 818 dmError("Encode op is a function, but function ptr is NULL: "
698 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", 819 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
750 return DMERR_NULLPTR; 871 return DMERR_NULLPTR;
751 872
752 if (dst->width < 8) 873 if (dst->width < 8)
753 return DMERR_INVALID_ARGS; 874 return DMERR_INVALID_ARGS;
754 875
755 // Perform generic conversion 876 if (src->type & D64_FMT_CHAR)
877 for (yc = 0; yc < dst->height; yc++)
878 {
879 Uint8 *d = dp;
880 const int y = yc / 8, yb = yc & 7;
881 const int scroffsy = y * C64_SCR_CH_WIDTH;
882 int xc;
883
884 if ((src->type & D64_FMT_MC) == D64_FMT_HIRES)
885 {
886 // Hi-res charmap
887 for (xc = 0; xc < dst->width; xc++)
888 {
889 const int x = xc / 8;
890 const int scroffs = scroffsy + x;
891 const int v = 7 - (xc & 7);
892 const int chr = src->screen[0][scroffs];
893
894 if ((src->charmem[chr][yb] >> v) & 1)
895 *d++ = src->color[0][scroffs];
896 else
897 *d++ = src->bgcolor;
898 }
899 }
900 else
901 {
902 // Multicolor variants
903 const int wdivisor = doubleMC ? 2 : 1;
904
905 for (xc = 0; xc < dst->width / wdivisor; xc++)
906 {
907 const int x = xc / 4;
908 const int scroffs = scroffsy + x;
909 const int v = 6 - ((xc * 2) & 6);
910 const int chr = src->screen[0][scroffs];
911 Uint8 c;
912
913 switch ((src->charmem[chr][yb] >> v) & 3)
914 {
915 case 0: c = src->bgcolor; break;
916 case 1: c = src->d022; break;
917 case 2: c = src->d023; break;
918 case 3: c = src->color[0][scroffs];
919 }
920
921 *d++ = c;
922 if (doubleMC)
923 *d++ = c;
924 }
925 }
926 dp += dst->pitch;
927 }
928 else
929 // Perform generic BITMAP conversion
756 for (yc = 0; yc < dst->height; yc++) 930 for (yc = 0; yc < dst->height; yc++)
757 { 931 {
758 Uint8 *d = dp; 932 Uint8 *d = dp;
759 const int y = yc / 8, yb = yc & 7; 933 const int y = yc / 8, yb = yc & 7;
760 const int scroffsy = y * C64_SCR_CH_WIDTH; 934 const int scroffsy = y * C64_SCR_CH_WIDTH;