comparison tools/lib64fmts.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
children 3265175b24d2
comparison
equal deleted inserted replaced
1502:aa87cb6cf33b 1503:c7b9ef56319b
1 /*
2 * Functions for reading and converting various restricted
3 * C64/etc and/or indexed/paletted graphics formats.
4 * Programmed and designed by Matti 'ccr' Hamalainen
5 * (C) Copyright 2012-2018 Tecnic Software productions (TNSP)
6 *
7 * Please read file 'COPYING' for information on license and distribution.
8 */
9 #include "lib64gfx.h"
10
11
12 // Based on Pepto's palette, stolen from VICE
13 DMColor dmDefaultC64Palette[C64_NCOLORS] =
14 {
15 { 0x00, 0x00, 0x00, 0xff },
16 { 0xFF, 0xFF, 0xFF, 0xff },
17 { 0x68, 0x37, 0x2B, 0xff },
18 { 0x70, 0xA4, 0xB2, 0xff },
19 { 0x6F, 0x3D, 0x86, 0xff },
20 { 0x58, 0x8D, 0x43, 0xff },
21 { 0x35, 0x28, 0x79, 0xff },
22 { 0xB8, 0xC7, 0x6F, 0xff },
23 { 0x6F, 0x4F, 0x25, 0xff },
24 { 0x43, 0x39, 0x00, 0xff },
25 { 0x9A, 0x67, 0x59, 0xff },
26 { 0x44, 0x44, 0x44, 0xff },
27 { 0x6C, 0x6C, 0x6C, 0xff },
28 { 0x9A, 0xD2, 0x84, 0xff },
29 { 0x6C, 0x5E, 0xB5, 0xff },
30 { 0x95, 0x95, 0x95, 0xff },
31 };
32
33
34 static int fmtProbeDrazPaint20Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
35 {
36 const char *ident = (const char *) buf + 2;
37
38 if (len > 22 &&
39 dmCompareAddr16(buf, 0, fmt->addr) &&
40 strncmp(ident, "DRAZPAINT ", 10) == 0 &&
41 ident[11] == '.' && (
42 (ident[10] == '1' && ident[12] == '4') ||
43 (ident[10] == '2' && ident[12] == '0')
44 ))
45 return DM_PROBE_SCORE_MAX;
46
47 return DM_PROBE_SCORE_FALSE;
48 }
49
50
51 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
52 {
53 int res;
54 DMGrowBuf mem;
55
56 if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, 0, DM_RLE_MARKER)) != DMERR_OK)
57 goto out;
58
59 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
60
61 out:
62 dmGrowBufFree(&mem);
63 return res;
64 }
65
66
67 static int fmtEncodeDrazPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
68 {
69 int res;
70 DMGrowBuf tmp;
71 Uint8 rleMarker;
72 const char *magicID = (fmt->type & D64_FMT_ILACE) ? "DRAZLACE! 1.0" : "DRAZPAINT 2.0";
73
74 // Encode the data to temp buffer
75 if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK)
76 goto out;
77
78 // Analyze the data ..
79 dmGenericRLEAnalyze(&tmp, &rleMarker, DM_RLE_MARKER);
80 rleMarker = 0xff;
81
82 // Add the header bits
83 if (!dmGrowBufPut(buf, magicID, strlen(magicID)) ||
84 !dmGrowBufPutU8(buf, rleMarker))
85 {
86 res = DMERR_MALLOC;
87 goto out;
88 }
89
90 // And now RLE compress the data to the existing buffer
91 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len,
92 rleMarker, 3, 255, DM_RLE_MARKER);
93
94 out:
95 dmGrowBufFree(&tmp);
96 return res;
97 }
98
99
100 static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
101 {
102 if (len > 22 &&
103 dmCompareAddr16(buf, 0, fmt->addr) &&
104 strncmp((const char *) (buf + 2), "DRAZLACE! 1.0", 13) == 0)
105 return DM_PROBE_SCORE_MAX;
106
107 return DM_PROBE_SCORE_FALSE;
108 }
109
110
111 static BOOL fmtDrazLaceSetLaceType(DMC64Image *img, const DMC64EncDecOp *op,
112 const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
113 {
114 (void) len;
115 (void) fmt;
116 img->laceType = buf[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR;
117 return TRUE;
118 }
119
120
121 static int fmtProbeGunPaint(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
122 {
123 if (len > 0x400 &&
124 dmCompareAddr16(buf, 0, fmt->addr) &&
125 strncmp((const char *) (buf + 0x3ea), "GUNPAINT (JZ) ", 14) == 0)
126 return DM_PROBE_SCORE_MAX;
127
128 return DM_PROBE_SCORE_FALSE;
129 }
130
131
132 static int fmtProbeAmicaPaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
133 {
134 size_t i, n;
135
136 if (len < 2048 || !dmCompareAddr16(buf, 0, fmt->addr))
137 return DM_PROBE_SCORE_FALSE;
138
139 // Interpaint Hi-Res gives a false positive
140 // as do some GunPaint images ..
141 if (len == 9002 || fmtProbeGunPaint(buf, len, fmt) > DM_PROBE_SCORE_GOOD)
142 return DM_PROBE_SCORE_FALSE;
143
144 for (n = 0, i = 2; i < len; i++)
145 if (buf[i] == 0xC2) n++;
146
147 if (n > 50)
148 return DM_PROBE_SCORE_GOOD;
149 if (n > 25)
150 return DM_PROBE_SCORE_AVG;
151 if (n > 10)
152 return DM_PROBE_SCORE_MAYBE;
153
154 return DM_PROBE_SCORE_FALSE;
155 }
156
157
158 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
159 {
160 int res;
161 DMGrowBuf mem, tmp;
162
163 // Amica Paint apparently is broken and stores one byte less than it should
164 // so we need to do some crappy buffer expansion here ..
165 if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK)
166 return res;
167
168 tmp.len = len;
169 memcpy(tmp.data, buf, len);
170 tmp.data[tmp.len++] = 0;
171
172 // Now do an RLE decode on the enlarged buffer
173 if ((res = dmDecodeGenericRLE(&mem, tmp.data, tmp.data + tmp.len, 0xC2, 0, 0, DM_RLE_MARKER)) != DMERR_OK)
174 goto out;
175
176 // And finally decode to bitmap struct
177 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
178
179 out:
180 dmGrowBufFree(&tmp);
181 dmGrowBufFree(&mem);
182 return res;
183 }
184
185
186 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
187 {
188 if (len == fmt->size &&
189 (dmCompareAddr16(buf, 0, 0x3c00) || dmCompareAddr16(buf, 0, 0x3ff0)))
190 return DM_PROBE_SCORE_MAX;
191
192 return DM_PROBE_SCORE_FALSE;
193 }
194
195
196 static BOOL fmtTruePaintSetLaceType(DMC64Image *img, const DMC64EncDecOp *op,
197 const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
198 {
199 (void) op;
200 (void) buf;
201 (void) len;
202 (void) fmt;
203 img->laceType = D64_ILACE_RES;
204 return TRUE;
205 }
206
207
208 static Uint8 fmtGetPixelTruePaint(
209 const DMC64Image *img, const int bmoffs, const int scroffs,
210 const int vshift, const int vbitmap, const int raster)
211 {
212 (void) raster;
213 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0);
214 }
215
216
217 #define XX2_MIN_SIZE 4000
218
219 static int fmtProbeFormatXX2(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
220 {
221 if (len >= XX2_MIN_SIZE && len <= XX2_MIN_SIZE + 8 &&
222 dmCompareAddr16(buf, 0, fmt->addr))
223 return DM_PROBE_SCORE_MAYBE;
224
225 return DM_PROBE_SCORE_FALSE;
226 }
227
228
229 static int fmtDecodeFormatXX2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
230 {
231 int res;
232
233 // If there is only data for less than XX2_MIN_SIZE bytes,
234 // allocate a buffer of that size and copy data there.
235 // Otherwise allocate len bytes.
236 size_t nlen = len < XX2_MIN_SIZE ? XX2_MIN_SIZE : len;
237 Uint8 *mem = dmMalloc0(nlen);
238 if (mem == NULL)
239 return DMERR_MALLOC;
240
241 memcpy(mem, buf, len);
242 res = dmC64DecodeGenericBMP(img, mem, nlen, fmt);
243
244 dmFree(mem);
245 return res;
246 }
247
248
249 #define FUNPAINT2_HEADER_SIZE (0x10)
250 static const char *fmtFunPaint2MagicID = "FUNPAINT (MT) ";
251
252
253 static BOOL fmtProbeFunPaint2Header(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
254 {
255 return
256 len > 30 &&
257 dmCompareAddr16(buf, 0, fmt->addr) &&
258 strncmp((const char *) (buf + 2), fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) == 0;
259 }
260
261
262 static int fmtProbeFunPaint2Unpacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
263 {
264 if (fmtProbeFunPaint2Header(buf, len, fmt) &&
265 buf[2 + 14] == 0)
266 return DM_PROBE_SCORE_MAX;
267 else
268 return DM_PROBE_SCORE_FALSE;
269 }
270
271
272 static int fmtProbeFunPaint2Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
273 {
274 if (fmtProbeFunPaint2Header(buf, len, fmt) &&
275 buf[2 + 14] != 0)
276 return DM_PROBE_SCORE_MAX;
277 else
278 return DM_PROBE_SCORE_FALSE;
279 }
280
281
282 static int fmtDecodeFunPaint2Unpacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
283 {
284 return dmC64DecodeGenericBMP(img, buf + FUNPAINT2_HEADER_SIZE, len - FUNPAINT2_HEADER_SIZE, fmt);
285 }
286
287
288 static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
289 {
290 int res;
291 DMGrowBuf mem;
292 dmGrowBufInit(&mem);
293
294 if ((res = dmDecodeGenericRLE(&mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, *(buf + 15), 0, 0, DM_RLE_MARKER)) != DMERR_OK)
295 goto out;
296
297 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
298
299 out:
300 dmGrowBufFree(&mem);
301 return res;
302 }
303
304
305 static int fmtEncodeFunPaint2Unpacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
306 {
307 // Add the header bits
308 if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) ||
309 !dmGrowBufPutU8(buf, 0))
310 return DMERR_MALLOC;
311
312 return dmC64EncodeGenericBMP(FALSE, buf, img, fmt);
313 }
314
315
316 static int fmtEncodeFunPaint2Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
317 {
318 int res;
319 DMGrowBuf tmp;
320 Uint8 rleMarker;
321
322 // Encode the data to temp buffer
323 if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK)
324 goto out;
325
326 // Analyze the data ..
327 dmGenericRLEAnalyze(&tmp, &rleMarker, DM_RLE_MARKER);
328 rleMarker = 0xff;
329
330 // Add the header bits
331 if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) ||
332 !dmGrowBufPutU8(buf, rleMarker))
333 {
334 res = DMERR_MALLOC;
335 goto out;
336 }
337
338 // And now RLE compress the data to the existing buffer
339 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len,
340 rleMarker, 3, 255, DM_RLE_MARKER);
341
342 out:
343 dmGrowBufFree(&tmp);
344 return res;
345 }
346
347
348 static Uint8 fmtGetPixelFunPaint2(
349 const DMC64Image *img, const int bmoffs, const int scroffs,
350 const int vshift, const int vbitmap, const int raster)
351 {
352 const int vbank = (raster & 7) + (vbitmap * 8);
353 int vr, vb;
354 if (raster < 100)
355 {
356 vb = 0;
357 vr = raster;
358 }
359 else
360 {
361 vb = 0;
362 vr = raster - 100;
363 }
364
365 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3)
366 {
367 case 0: return img->extraData[vb][vr] & 15; break;
368 case 1: return img->screen[vbank][scroffs] >> 4; break;
369 case 2: return img->screen[vbank][scroffs] & 15; break;
370 default: return img->color[0][scroffs] & 15; break;
371 }
372 }
373
374
375 static Uint8 fmtGetPixelGunPaint(
376 const DMC64Image *img, const int bmoffs, const int scroffs,
377 const int vshift, const int vbitmap, const int raster)
378 {
379 const int vbank = (raster & 7);// + (vbitmap * 8);
380 int vr, vb;
381 if (raster < 177)
382 {
383 vb = 0;
384 vr = raster;
385 }
386 else
387 {
388 vb = 0;
389 vr = raster - 177;
390 }
391
392 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3)
393 {
394 case 0: return img->extraData[vb][vr] & 15; break;
395 case 1: return img->screen[vbank][scroffs] >> 4; break;
396 case 2: return img->screen[vbank][scroffs] & 15; break;
397 default: return img->color[0][scroffs] & 15; break;
398 }
399 }
400
401
402 static Uint8 fmtGetPixelBMFLI(
403 const DMC64Image *img, const int bmoffs, const int scroffs,
404 const int vshift, const int vbitmap, const int raster)
405 {
406 const int vbank = raster & 7;
407 switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3)
408 {
409 case 0: return img->extraData[0][raster]; break;
410 case 1: return img->screen[vbank][scroffs] >> 4; break;
411 case 2: return img->screen[vbank][scroffs] & 15; break;
412 default: return img->color[0][scroffs] & 15; break;
413 }
414 }
415
416
417 static Uint8 fmtGetPixelFLIDesigner(
418 const DMC64Image *img, const int bmoffs, const int scroffs,
419 const int vshift, const int vbitmap, const int raster)
420 {
421 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, raster & 7, vbitmap, 0);
422 }
423
424
425 static Uint8 fmtGetPixelCHFLI(
426 const DMC64Image *img, const int bmoffs, const int scroffs,
427 const int vshift, const int vbitmap, const int raster)
428 {
429 const int vbank = raster & 7;
430
431 if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1)
432 return img->screen[vbank][scroffs] >> 4;
433 else
434 return img->screen[vbank][scroffs] & 15;
435 }
436
437
438 static int fmtEncodeStub(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
439 {
440 (void) buf;
441 (void) img;
442 (void) fmt;
443
444 return dmError(DMERR_NOT_SUPPORTED,
445 "Encoding of '%s' format not supported.\n",
446 fmt->name);
447 }
448
449
450 //
451 // Array with data for supported formats
452 //
453 #define DEF_SCREEN_RAM(start, oindex, bindex, osize) { DT_SCREEN_RAM, (start) + ((osize) * (oindex)), (bindex), 0, NULL, NULL }
454 #define DEF_SCREEN_RAMS_8(start, sindex, osize) \
455 DEF_SCREEN_RAM((start), 0, (sindex + 0), (osize)), \
456 DEF_SCREEN_RAM((start), 1, (sindex + 1), (osize)), \
457 DEF_SCREEN_RAM((start), 2, (sindex + 2), (osize)), \
458 DEF_SCREEN_RAM((start), 3, (sindex + 3), (osize)), \
459 DEF_SCREEN_RAM((start), 4, (sindex + 4), (osize)), \
460 DEF_SCREEN_RAM((start), 5, (sindex + 5), (osize)), \
461 DEF_SCREEN_RAM((start), 6, (sindex + 6), (osize)), \
462 DEF_SCREEN_RAM((start), 7, (sindex + 7), (osize)),
463
464
465 const DMC64ImageFormat dmC64ImageFormats[] =
466 {
467 {
468 D64_FMT_MC, "d2p", "DrazPaint 1.4/2.0 (packed)", 0x5800, 0,
469 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
470 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
471 fmtProbeDrazPaint20Packed,
472 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked,
473 NULL, NULL,
474 NULL,
475 {
476 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
477 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
478 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
479 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
480 { DT_LAST, 0, 0, 0, NULL, NULL },
481 }
482 },
483
484 {
485 D64_FMT_MC, "drp", "DrazPaint (unpacked)", 0x5800, 10051,
486 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
487 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
488 NULL,
489 NULL, NULL,
490 NULL, NULL,
491 NULL,
492 {
493 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
494 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
495 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
496 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
497 { DT_LAST, 0, 0, 0, NULL, NULL },
498 }
499 },
500
501 {
502 D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, 0,
503 C64_SCR_WIDTH , C64_SCR_HEIGHT,
504 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
505 fmtProbeDrazLace10Packed,
506 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked,
507 NULL, NULL,
508 NULL,
509 {
510 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
511 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
512 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
513 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
514 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL },
515 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL },
516 { DT_LAST, 0, 0, 0, NULL, NULL },
517 }
518 },
519
520 {
521 D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242,
522 C64_SCR_WIDTH , C64_SCR_HEIGHT,
523 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
524 NULL,
525 NULL, NULL,
526 NULL, NULL,
527 NULL,
528 {
529 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
530 { DT_BITMAP, 0x0800, 0, 0, NULL, NULL },
531 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
532 { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL },
533 { DT_BITMAP, 0x2800, 1, 0, NULL, NULL },
534 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL },
535 { DT_LAST, 0, 0, 0, NULL, NULL },
536 }
537 },
538
539 {
540 D64_FMT_MC | D64_FMT_ILACE, "mci", "Truepaint (unpacked)", 0x9c00, 19434,
541 C64_SCR_WIDTH , C64_SCR_HEIGHT,
542 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
543 NULL,
544 NULL, NULL,
545 NULL, NULL,
546 fmtGetPixelTruePaint,
547 {
548 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL },
549 { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL },
550 { DT_BITMAP, 0x0400, 0, 0, NULL, NULL },
551 { DT_BITMAP, 0x2400, 1, 0, NULL, NULL },
552 { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL },
553 { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL },
554 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL },
555 { DT_LAST, 0, 0, 0, NULL, NULL },
556 }
557 },
558
559 {
560 D64_FMT_MC, "kla", "Koala Paint (unpacked)", 0x6000, 10003,
561 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
562 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
563 NULL,
564 NULL, NULL,
565 NULL, NULL,
566 NULL,
567 {
568 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
569 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
570 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
571 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
572 { DT_LAST, 0, 0, 0, NULL, NULL },
573 }
574 },
575
576 {
577 D64_FMT_MC, "ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018,
578 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
579 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
580 NULL,
581 NULL, NULL,
582 NULL, NULL,
583 NULL,
584 {
585 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
586 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
587 { DT_COLOR_RAM, 0x2338, 0, 0, NULL, NULL },
588 { DT_COLOR_REG, 0x2329, 0, DC_BGCOL, NULL, NULL },
589 { DT_LAST, 0, 0, 0, NULL, NULL },
590 }
591 },
592
593 {
594 D64_FMT_MC, "ami", "Amica Paint (packed)", 0x4000, 0,
595 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
596 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
597 fmtProbeAmicaPaintPacked,
598 fmtDecodeAmicaPaintPacked, fmtEncodeStub,
599 NULL, NULL,
600 NULL,
601 {
602 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
603 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
604 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
605 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
606 { DT_LAST, 0, 0, 0, NULL, NULL },
607 }
608 },
609
610 {
611 D64_FMT_MC, "rpm", "Run Paint (unpacked)", 0x6000, 10006,
612 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
613 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
614 NULL,
615 NULL, NULL,
616 NULL, NULL,
617 NULL,
618 {
619 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
620 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
621 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
622 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
623 { DT_LAST, 0, 0, 0, NULL, NULL },
624 }
625 },
626
627 {
628 D64_FMT_HIRES, "art", "Art Studio (unpacked)", 0x2000, 9009,
629 C64_SCR_WIDTH , C64_SCR_HEIGHT,
630 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
631 NULL,
632 NULL, NULL,
633 NULL, NULL,
634 NULL,
635 {
636 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
637 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
638 { DT_LAST, 0, 0, 0, NULL, NULL },
639 }
640 },
641
642 {
643 D64_FMT_HIRES, "iph", "Interpaint (unpacked)", 0x4000, 9002,
644 C64_SCR_WIDTH , C64_SCR_HEIGHT,
645 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
646 NULL,
647 NULL, NULL,
648 NULL, NULL,
649 NULL,
650 {
651 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
652 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
653 { DT_LAST, 0, 0, 0, NULL, NULL },
654 }
655 },
656
657 {
658 D64_FMT_MC, "ipc", "Interpaint MC (unpacked)", 0x4000, 10003,
659 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
660 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
661 NULL,
662 NULL, NULL,
663 NULL, NULL,
664 NULL,
665 {
666 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
667 { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL },
668 { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL },
669 { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL },
670 { DT_LAST, 0, 0, 0, NULL, NULL },
671 }
672 },
673
674 {
675 D64_FMT_HIRES, "dd", "Doodle (unpacked)", 0x1c00, 9218,
676 C64_SCR_WIDTH , C64_SCR_HEIGHT,
677 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
678 NULL,
679 NULL, NULL,
680 NULL, NULL,
681 NULL,
682 {
683 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL },
684 { DT_BITMAP, 0x0400, 0, 0, NULL, NULL },
685 { DT_LAST, 0, 0, 0, NULL, NULL },
686 }
687 },
688
689 {
690 D64_FMT_MC | D64_FMT_FLI, "bml", "Blackmail FLI (unpacked)", 0x3b00, 17474,
691 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
692 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
693 NULL,
694 NULL, NULL,
695 NULL, NULL,
696 fmtGetPixelBMFLI,
697 {
698 { DT_EXTRA_DATA, 0x0000, 0, 200, NULL, NULL },
699 { DT_COLOR_RAM, 0x0100, 0, 0, NULL, NULL },
700 DEF_SCREEN_RAMS_8( 0x0500, 0, 0x400)
701 { DT_BITMAP, 0x2500, 0, 0, NULL, NULL },
702 { DT_LAST, 0, 0, 0, NULL, NULL },
703 }
704 },
705
706 {
707 D64_FMT_MC | D64_FMT_FLI, "fli", "FLI Designer (unpacked)", 0, 17409,
708 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
709 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
710 fmtProbeFLIDesigner,
711 NULL, NULL,
712 NULL, NULL,
713 fmtGetPixelFLIDesigner,
714 {
715 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
716 DEF_SCREEN_RAMS_8( 0x0400, 0, 0x400)
717 { DT_BITMAP, 0x2400, 0, 0, NULL, NULL },
718 { DT_LAST, 0, 0, 0, NULL, NULL },
719 }
720 },
721
722 {
723 D64_FMT_MC, "xx1", "Unknown $2000 format (unpacked)", 0x2000, 10242,
724 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
725 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
726 NULL,
727 NULL, NULL,
728 NULL, NULL,
729 NULL,
730 {
731 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
732 { DT_SCREEN_RAM, 0x2000, 0, 0, NULL, NULL },
733 { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL },
734 { DT_COLOR_SET, 0x00 , 0, DC_BGCOL, NULL, NULL },
735 { DT_LAST, 0, 0, 0, NULL, NULL },
736 }
737 },
738
739 #define XX2_WIDTH_CH 40
740 #define XX2_HEIGHT_CH 10
741 #define XX2_SIZE (XX2_WIDTH_CH * XX2_HEIGHT_CH)
742 #define XX2_BSIZE (XX2_SIZE * 8)
743
744 {
745 D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 0,
746 XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8,
747 XX2_WIDTH_CH , XX2_HEIGHT_CH,
748 fmtProbeFormatXX2,
749 fmtDecodeFormatXX2, NULL,
750 NULL, NULL,
751 NULL,
752 {
753 { DT_BITMAP, 0x0000, 0, XX2_BSIZE, NULL, NULL },
754 { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE, 0, XX2_SIZE, NULL, NULL },
755 { DT_SCREEN_RAM, XX2_BSIZE, 0, XX2_SIZE, NULL, NULL },
756 { DT_COLOR_SET, 11, 0, DC_BGCOL, NULL, NULL },
757 { DT_LAST, 0, 0, 0, NULL, NULL },
758 }
759 },
760
761 {
762 D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "fp2", "FunPaint II (unpacked)", 0x3ff0, 33694,
763 C64_SCR_WIDTH, C64_SCR_HEIGHT,
764 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
765 fmtProbeFunPaint2Unpacked,
766 fmtDecodeFunPaint2Unpacked, fmtEncodeFunPaint2Unpacked,
767 NULL, NULL,
768 fmtGetPixelFunPaint2,
769 {
770 DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400)
771 { DT_BITMAP, 0x2000, 0, 0, NULL, NULL },
772 { DT_EXTRA_DATA, 0x3f40, 0, 100, NULL, NULL },
773 { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL },
774 DEF_SCREEN_RAMS_8( 0x43e8, 8, 0x400)
775 { DT_BITMAP, 0x63e8, 1, 0, NULL, NULL },
776 { DT_EXTRA_DATA, 0x8328, 1, 100, NULL, NULL },
777 { DT_LAST, 0, 0, 0, NULL, NULL },
778 }
779 },
780
781 {
782 D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "fp2p", "FunPaint II (packed)", 0x3ff0, 0,
783 C64_SCR_WIDTH, C64_SCR_HEIGHT,
784 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
785 fmtProbeFunPaint2Packed,
786 fmtDecodeFunPaint2Packed, fmtEncodeFunPaint2Packed,
787 NULL, NULL,
788 fmtGetPixelFunPaint2,
789 {
790 DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400)
791 { DT_BITMAP, 0x2000, 0, 0, NULL, NULL },
792 { DT_EXTRA_DATA, 0x3f40, 0, 100, NULL, NULL },
793 { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL },
794 DEF_SCREEN_RAMS_8( 0x43e8, 8, 0x400)
795 { DT_BITMAP, 0x63e8, 1, 0, NULL, NULL },
796 { DT_EXTRA_DATA, 0x8328, 1, 100, NULL, NULL },
797 { DT_LAST, 0, 0, 0, NULL, NULL },
798 }
799 },
800
801 {
802 D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "gun", "GunPaint (unpacked)", 0x4000, 0,
803 C64_SCR_WIDTH, C64_SCR_HEIGHT,
804 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
805 fmtProbeGunPaint,
806 NULL, NULL,
807 NULL, NULL,
808 fmtGetPixelGunPaint,
809 {
810 DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400)
811 { DT_BITMAP, 0x2000, 0, 0, NULL, NULL },
812 { DT_EXTRA_DATA, 0x3f4f, 0, 177, NULL, NULL },
813 { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL },
814 DEF_SCREEN_RAMS_8( 0x4400, 8, 0x400)
815 { DT_BITMAP, 0x6400, 1, 0, NULL, NULL },
816 { DT_EXTRA_DATA, 0x47e8, 1, 20, NULL, NULL },
817 { DT_LAST, 0, 0, 0, NULL, NULL },
818 }
819 },
820
821 {
822 D64_FMT_HIRES | D64_FMT_FLI, "chi", "Crest Hires FLI Designer (unpacked)", 0x4000, 16386,
823 C64_SCR_WIDTH, 14 * 8,
824 C64_SCR_CH_WIDTH , 14,
825 NULL,
826 NULL, NULL,
827 NULL, NULL,
828 fmtGetPixelCHFLI,
829 {
830 { DT_BITMAP, 0x0000, 0, 0, NULL, NULL },
831 DEF_SCREEN_RAMS_8( 0x2000, 0, 0x400)
832 { DT_LAST, 0, 0, 0, NULL, NULL },
833 }
834 },
835 };
836
837 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]);
838