Mercurial > hg > dmlib
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) |