comparison lib64gfx.c @ 530:5b37a2e427b7

Greatly simplify and also improve the multicolor/hires/lace bitmap->image conversion functionality. This breaks the API, however, adjust gfxconv and view64 accordingly.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 22 Nov 2012 15:28:27 +0200
parents 1bce06b5026f
children 2ac364d0ace9
comparison
equal deleted inserted replaced
529:1bce06b5026f 530:5b37a2e427b7
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 const char *dmC64ImageTypeNames[DM_C64IFMT_LAST_TYPE] = 15 char * dmC64GetImageTypeString(char *buf, const size_t len, const int type)
16 { 16 {
17 "hires", 17 snprintf(buf, len,
18 "multicolor", 18 "%s%s%s",
19 "hires interlace", 19 (type & D64_FMT_FLI) ? "FLI " : "",
20 "mc interlace", 20 (type & D64_FMT_MC) ? "MCol" : "HiRes",
21 "hires fli", 21 (type & D64_FMT_ILACE) ? " Ilace" : ""
22 "mc fli", 22 );
23 }; 23
24 return buf;
25 }
24 26
25 27
26 // Based on Pepto's palette, stolen from VICE 28 // Based on Pepto's palette, stolen from VICE
27 DMColor dmC64Palette[C64_NCOLORS] = 29 DMColor dmC64Palette[C64_NCOLORS] =
28 { 30 {
202 204
203 static BOOL fmtDrazLaceSetLaceType(DMC64Image *img, const struct _DMC64EncDecOp *op, const Uint8 *buf, const size_t len) 205 static BOOL fmtDrazLaceSetLaceType(DMC64Image *img, const struct _DMC64EncDecOp *op, const Uint8 *buf, const size_t len)
204 { 206 {
205 (void) len; 207 (void) len;
206 208
207 img->laceType = buf[op->offs] ? DM_C64ILACE_RES : DM_C64ILACE_COLOR; 209 img->laceType = buf[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR;
208 img->laceBank2 = 0; 210 img->laceBank1 = img->laceBank2 = 0;
209 return TRUE; 211 return TRUE;
210 } 212 }
211 213
212 214
213 #define AMICA_DM_PROBE_SIZE 1024 215 #define AMICA_DM_PROBE_SIZE 1024
252 static BOOL fmtTruePaintSetLaceType(DMC64Image *img, const struct _DMC64EncDecOp *op, const Uint8 *buf, const size_t len) 254 static BOOL fmtTruePaintSetLaceType(DMC64Image *img, const struct _DMC64EncDecOp *op, const Uint8 *buf, const size_t len)
253 { 255 {
254 (void) op; 256 (void) op;
255 (void) buf; 257 (void) buf;
256 (void) len; 258 (void) len;
257 img->laceType = DM_C64ILACE_RES; 259 img->laceType = D64_ILACE_RES;
260 img->laceBank1 = 0;
258 img->laceBank2 = 1; 261 img->laceBank2 = 1;
259 return TRUE; 262 return TRUE;
260 } 263 }
261 264
262 265
263 const DMC64ImageFormat dmC64ImageFormats[] = 266 const DMC64ImageFormat dmC64ImageFormats[] =
264 { 267 {
265 { 268 {
266 DM_C64IFMT_MC, ".drp", "DrazPaint 2.0 (packed)", 0x5800, -1, 269 D64_FMT_MC, ".drp", "DrazPaint 2.0 (packed)", 0x5800, -1,
267 fmtProbeDrazPaint20Packed, fmtDecodeDrazPaintPacked, 270 fmtProbeDrazPaint20Packed, fmtDecodeDrazPaintPacked,
268 NULL, NULL, NULL, 271 NULL, NULL, NULL,
269 4, 272 4,
270 { 273 {
271 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 274 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
274 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL }, 277 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL },
275 } 278 }
276 }, 279 },
277 280
278 { 281 {
279 DM_C64IFMT_MC_ILACE, ".dlp", "DrazLace 1.0 (packed)", 0x5800, -1, 282 D64_FMT_MC | D64_FMT_ILACE, ".dlp", "DrazLace 1.0 (packed)", 0x5800, -1,
280 fmtProbeDrazLace10Packed, fmtDecodeDrazPaintPacked, 283 fmtProbeDrazLace10Packed, fmtDecodeDrazPaintPacked,
281 NULL, NULL, NULL, 284 NULL, NULL, NULL,
282 6, 285 6,
283 { 286 {
284 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 287 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
289 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, 292 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL },
290 } 293 }
291 }, 294 },
292 295
293 { 296 {
294 DM_C64IFMT_MC, ".drp", "DrazPaint (unpacked)", 0x5800, 10051, 297 D64_FMT_MC, ".drp", "DrazPaint (unpacked)", 0x5800, 10051,
295 NULL, NULL, 298 NULL, NULL,
296 NULL, NULL, NULL, 299 NULL, NULL, NULL,
297 4, 300 4,
298 { 301 {
299 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 302 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
302 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL }, 305 { DT_BGCOLOR, 0x2740, 0, 0, NULL, NULL },
303 } 306 }
304 }, 307 },
305 308
306 { 309 {
307 DM_C64IFMT_MC_ILACE, ".drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, 310 D64_FMT_MC | D64_FMT_ILACE, ".drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242,
308 NULL, NULL, 311 NULL, NULL,
309 NULL, NULL, NULL, 312 NULL, NULL, NULL,
310 6, 313 6,
311 { 314 {
312 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, 315 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
317 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, 320 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL },
318 } 321 }
319 }, 322 },
320 323
321 { 324 {
322 DM_C64IFMT_MC_ILACE, ".mci", "Truepaint (unpacked)", 0x9c00, 19434, 325 D64_FMT_MC | D64_FMT_ILACE, ".mci", "Truepaint (unpacked)", 0x9c00, 19434,
323 NULL, NULL, 326 NULL, NULL,
324 NULL, NULL, NULL, 327 NULL, NULL, NULL,
325 6, 328 6,
326 { 329 {
327 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, 330 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL },
333 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL }, 336 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL },
334 } 337 }
335 }, 338 },
336 339
337 { 340 {
338 DM_C64IFMT_MC, ".kla", "Koala Paint (unpacked)", 0x6000, 10003, 341 D64_FMT_MC, ".kla", "Koala Paint (unpacked)", 0x6000, 10003,
339 NULL, NULL, 342 NULL, NULL,
340 NULL, NULL, NULL, 343 NULL, NULL, NULL,
341 4, 344 4,
342 { 345 {
343 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, 346 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
346 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL }, 349 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL },
347 } 350 }
348 }, 351 },
349 352
350 { 353 {
351 DM_C64IFMT_MC, ".ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018, 354 D64_FMT_MC, ".ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018,
352 NULL, NULL, 355 NULL, NULL,
353 NULL, NULL, NULL, 356 NULL, NULL, NULL,
354 4, 357 4,
355 { 358 {
356 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 359 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
359 { DT_BGCOLOR, 0x2329, 0, 0, NULL, NULL }, 362 { DT_BGCOLOR, 0x2329, 0, 0, NULL, NULL },
360 } 363 }
361 }, 364 },
362 365
363 { 366 {
364 DM_C64IFMT_MC, ".ami", "Amica Paint (packed)", 0x4000, -1, 367 D64_FMT_MC, ".ami", "Amica Paint (packed)", 0x4000, -1,
365 fmtProbeAmicaPaintPacked, fmtDecodeAmicaPaintPacked, 368 fmtProbeAmicaPaintPacked, fmtDecodeAmicaPaintPacked,
366 NULL, NULL, NULL, 369 NULL, NULL, NULL,
367 4, 370 4,
368 { 371 {
369 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, 372 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
372 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL }, 375 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL },
373 } 376 }
374 }, 377 },
375 378
376 { 379 {
377 DM_C64IFMT_MC, ".rpm", "Run Paint (unpacked)", 0x6000, 10006, 380 D64_FMT_MC, ".rpm", "Run Paint (unpacked)", 0x6000, 10006,
378 NULL, NULL, 381 NULL, NULL,
379 NULL, NULL, NULL, 382 NULL, NULL, NULL,
380 4, 383 4,
381 { 384 {
382 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, 385 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
385 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL }, 388 { DT_BGCOLOR, 0x2710, 0, 0, NULL, NULL },
386 } 389 }
387 }, 390 },
388 391
389 { 392 {
390 DM_C64IFMT_HIRES, ".art", "Art Studio (unpacked)", 0x2000, 9009, 393 D64_FMT_HIRES, ".art", "Art Studio (unpacked)", 0x2000, 9009,
391 NULL, NULL, 394 NULL, NULL,
392 NULL, NULL, NULL, 395 NULL, NULL, NULL,
393 2, 396 2,
394 { 397 {
395 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 398 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
396 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, 399 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
397 } 400 }
398 }, 401 },
399 402
400 { 403 {
401 DM_C64IFMT_HIRES, ".iph", "Interpaint (unpacked)", 0x4000, 9002, 404 D64_FMT_HIRES, ".iph", "Interpaint (unpacked)", 0x4000, 9002,
402 NULL, NULL, 405 NULL, NULL,
403 NULL, NULL, NULL, 406 NULL, NULL, NULL,
404 2, 407 2,
405 { 408 {
406 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, 409 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
407 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, 410 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
408 } 411 }
409 }, 412 },
410 413
411 { 414 {
412 DM_C64IFMT_HIRES, ".dd", "Doodle (unpacked)", 0x1c00, 9218, 415 D64_FMT_HIRES, ".dd", "Doodle (unpacked)", 0x1c00, 9218,
413 NULL, NULL, 416 NULL, NULL,
414 NULL, NULL, NULL, 417 NULL, NULL, NULL,
415 2, 418 2,
416 { 419 {
417 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, 420 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL },
545 548
546 return DMERR_OK; 549 return DMERR_OK;
547 } 550 }
548 551
549 552
550 static int dmC64ConvertHiResBMP(DMImage *screen, const DMC64Image *img) 553 static inline Uint8 dmC64GetMCColor(const DMC64Image *img, const int bits, const int bank, const int scroffs)
554 {
555 switch (bits)
556 {
557 case 0: return img->bgcolor; break;
558 case 1: return img->screen[bank][scroffs] >> 4; break;
559 case 2: return img->screen[bank][scroffs] & 15; break;
560 default: return img->color[bank][scroffs] & 15; break;
561 }
562 }
563
564
565 // Convert a generic "C64" format bitmap in DMC64Image struct to
566 // a indexed/paletted bitmap image.
567 int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src)
551 { 568 {
552 int yc; 569 int yc;
553 Uint8 *dp = screen->data; 570 Uint8 *dp = dst->data;
554 571
555 for (yc = 0; yc < C64_SCR_HEIGHT; yc++) 572 for (yc = 0; yc < C64_SCR_HEIGHT; yc++)
556 { 573 {
557 Uint8 *d = dp; 574 Uint8 *d = dp;
558 const int y = yc / 8, yb = yc & 7; 575 const int y = yc / 8, yb = yc & 7;
559 const int scroffsy = y * C64_SCR_CH_WIDTH; 576 const int scroffsy = y * C64_SCR_CH_WIDTH;
560 const int bmoffsy = y * C64_SCR_WIDTH; 577 const int bmoffsy = y * C64_SCR_WIDTH;
561 int xc; 578 int xc;
562 579
563 for (xc = 0; xc < C64_SCR_WIDTH; xc++) 580 if ((src->type & D64_FMT_MC) == D64_FMT_HIRES)
564 { 581 {
565 const int x = xc / 8; 582 for (xc = 0; xc < C64_SCR_WIDTH; xc++)
566 const int scroffs = scroffsy + x;
567 const int b = img->bitmap[0][bmoffsy + (x * 8) + yb];
568 const int v = 7 - (xc & 7);
569 Uint8 c;
570
571 if ((b >> v) & 1)
572 c = img->screen[0][scroffs] >> 4;
573 else
574 c = img->screen[0][scroffs] & 15;
575
576 *d++ = c;
577 }
578
579 dp += screen->pitch;
580 }
581
582 return DMERR_OK;
583 }
584
585
586 static inline Uint8 dmC64GetMCColor(const DMC64Image *img, const int bits, const int bank, const int scroffs)
587 {
588 switch (bits)
589 {
590 case 0: return img->bgcolor; break;
591 case 1: return img->screen[bank][scroffs] >> 4; break;
592 case 2: return img->screen[bank][scroffs] & 15; break;
593 default: return img->color[bank][scroffs] & 15; break;
594 }
595 }
596
597
598 static int dmC64ConvertMultiColorBMP(DMImage *screen, const DMC64Image *img)
599 {
600 int yc;
601 Uint8 *dp = screen->data;
602
603 for (yc = 0; yc < C64_SCR_HEIGHT; yc++)
604 {
605 Uint8 *d = dp;
606 const int y = yc / 8, yb = yc & 7;
607 const int scroffsy = y * C64_SCR_CH_WIDTH;
608 const int bmoffsy = y * C64_SCR_WIDTH;
609 int xc;
610
611 for (xc = 0; xc < C64_SCR_WIDTH / 2; xc++)
612 {
613 const int x = xc / 4;
614 const int scroffs = scroffsy + x;
615 const int bmoffs = bmoffsy + (x * 8) + yb;
616 const int v = 6 - ((xc * 2) & 6);
617 switch (img->type)
618 { 583 {
619 case DM_C64IFMT_MC: 584 const int x = xc / 8;
585 const int scroffs = scroffsy + x;
586 const int b = src->bitmap[0][bmoffsy + (x * 8) + yb];
587 const int v = 7 - (xc & 7);
588
589 if ((b >> v) & 1)
590 *d++ = src->screen[0][scroffs] >> 4;
591 else
592 *d++ = src->screen[0][scroffs] & 15;
593 }
594 }
595 else
596 {
597 for (xc = 0; xc < C64_SCR_WIDTH / 2; xc++)
598 {
599 const int x = xc / 4;
600 const int scroffs = scroffsy + x;
601 const int bmoffs = bmoffsy + (x * 8) + yb;
602 const int v = 6 - ((xc * 2) & 6);
603 Uint8 c;
604
605 if (src->type & D64_FMT_FLI)
606 {
607 int bank = 0;
608 switch (src->fliType)
620 { 609 {
621 const Uint8 c = dmC64GetMCColor(img, (img->bitmap[0][bmoffs] >> v) & 3, 0, scroffs); 610 case D64_FLI_2BANK:
611 bank = yb / 4;
612 break;
613 case D64_FLI_4BANK:
614 bank = yb / 2;
615 break;
616 case D64_FLI_8BANK:
617 bank = yb;
618 break;
619 }
620 c = dmC64GetMCColor(src, (src->bitmap[0][bmoffs] >> v) & 3, bank, scroffs);
622 *d++ = c; 621 *d++ = c;
623 *d++ = c; 622 *d++ = c;
624 } 623 }
625 break; 624 else
626 case DM_C64IFMT_MC_ILACE: 625 if (src->type & D64_FMT_ILACE)
627 *d++ = dmC64GetMCColor(img, (img->bitmap[0][bmoffs] >> v) & 3, 0, scroffs); 626 {
628 *d++ = dmC64GetMCColor(img, (img->bitmap[1][bmoffs] >> v) & 3, img->laceBank2, scroffs); 627 *d++ = dmC64GetMCColor(src, (src->bitmap[0][bmoffs] >> v) & 3, src->laceBank1, scroffs);
629 break; 628 *d++ = dmC64GetMCColor(src, (src->bitmap[1][bmoffs] >> v) & 3, src->laceBank2, scroffs);
629 }
630 else
631 {
632 c = dmC64GetMCColor(src, (src->bitmap[0][bmoffs] >> v) & 3, 0, scroffs);
633 *d++ = c;
634 *d++ = c;
635 }
630 } 636 }
631 } 637 }
632 638
633 dp += screen->pitch; 639 dp += dst->pitch;
634 } 640 }
635 641
636 return DMERR_OK; 642 return DMERR_OK;
637 }
638
639
640 // Convert a generic "C64" format bitmap in DMC64Image struct to
641 // a indexed/paletted bitmap image.
642 int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src)
643 {
644 switch (src->type)
645 {
646 case DM_C64IFMT_HIRES:
647 return dmC64ConvertHiResBMP(dst, src);
648
649 case DM_C64IFMT_MC:
650 case DM_C64IFMT_MC_ILACE:
651 return dmC64ConvertMultiColorBMP(dst, src);
652
653 default:
654 return DMERR_NOT_SUPPORTED;
655 }
656 } 643 }
657 644
658 645
659 646
660 int dmReadDataFile(FILE *inFile, const char *filename, Uint8 **pbuf, size_t *pbufSize) 647 int dmReadDataFile(FILE *inFile, const char *filename, Uint8 **pbuf, size_t *pbufSize)