Mercurial > hg > dmlib
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/lib64fmts.c Fri May 11 07:41:55 2018 +0300 @@ -0,0 +1,838 @@ +/* + * Functions for reading and converting various restricted + * C64/etc and/or indexed/paletted graphics formats. + * Programmed and designed by Matti 'ccr' Hamalainen + * (C) Copyright 2012-2018 Tecnic Software productions (TNSP) + * + * Please read file 'COPYING' for information on license and distribution. + */ +#include "lib64gfx.h" + + +// Based on Pepto's palette, stolen from VICE +DMColor dmDefaultC64Palette[C64_NCOLORS] = +{ + { 0x00, 0x00, 0x00, 0xff }, + { 0xFF, 0xFF, 0xFF, 0xff }, + { 0x68, 0x37, 0x2B, 0xff }, + { 0x70, 0xA4, 0xB2, 0xff }, + { 0x6F, 0x3D, 0x86, 0xff }, + { 0x58, 0x8D, 0x43, 0xff }, + { 0x35, 0x28, 0x79, 0xff }, + { 0xB8, 0xC7, 0x6F, 0xff }, + { 0x6F, 0x4F, 0x25, 0xff }, + { 0x43, 0x39, 0x00, 0xff }, + { 0x9A, 0x67, 0x59, 0xff }, + { 0x44, 0x44, 0x44, 0xff }, + { 0x6C, 0x6C, 0x6C, 0xff }, + { 0x9A, 0xD2, 0x84, 0xff }, + { 0x6C, 0x5E, 0xB5, 0xff }, + { 0x95, 0x95, 0x95, 0xff }, +}; + + +static int fmtProbeDrazPaint20Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + const char *ident = (const char *) buf + 2; + + if (len > 22 && + dmCompareAddr16(buf, 0, fmt->addr) && + strncmp(ident, "DRAZPAINT ", 10) == 0 && + ident[11] == '.' && ( + (ident[10] == '1' && ident[12] == '4') || + (ident[10] == '2' && ident[12] == '0') + )) + return DM_PROBE_SCORE_MAX; + + return DM_PROBE_SCORE_FALSE; +} + + +static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + int res; + DMGrowBuf mem; + + if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, 0, DM_RLE_MARKER)) != DMERR_OK) + goto out; + + res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + +out: + dmGrowBufFree(&mem); + return res; +} + + +static int fmtEncodeDrazPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) +{ + int res; + DMGrowBuf tmp; + Uint8 rleMarker; + const char *magicID = (fmt->type & D64_FMT_ILACE) ? "DRAZLACE! 1.0" : "DRAZPAINT 2.0"; + + // Encode the data to temp buffer + if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) + goto out; + + // Analyze the data .. + dmGenericRLEAnalyze(&tmp, &rleMarker, DM_RLE_MARKER); + rleMarker = 0xff; + + // Add the header bits + if (!dmGrowBufPut(buf, magicID, strlen(magicID)) || + !dmGrowBufPutU8(buf, rleMarker)) + { + res = DMERR_MALLOC; + goto out; + } + + // And now RLE compress the data to the existing buffer + res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, + rleMarker, 3, 255, DM_RLE_MARKER); + +out: + dmGrowBufFree(&tmp); + return res; +} + + +static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + if (len > 22 && + dmCompareAddr16(buf, 0, fmt->addr) && + strncmp((const char *) (buf + 2), "DRAZLACE! 1.0", 13) == 0) + return DM_PROBE_SCORE_MAX; + + return DM_PROBE_SCORE_FALSE; +} + + +static BOOL fmtDrazLaceSetLaceType(DMC64Image *img, const DMC64EncDecOp *op, + const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + (void) len; + (void) fmt; + img->laceType = buf[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR; + return TRUE; +} + + +static int fmtProbeGunPaint(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + if (len > 0x400 && + dmCompareAddr16(buf, 0, fmt->addr) && + strncmp((const char *) (buf + 0x3ea), "GUNPAINT (JZ) ", 14) == 0) + return DM_PROBE_SCORE_MAX; + + return DM_PROBE_SCORE_FALSE; +} + + +static int fmtProbeAmicaPaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + size_t i, n; + + if (len < 2048 || !dmCompareAddr16(buf, 0, fmt->addr)) + return DM_PROBE_SCORE_FALSE; + + // Interpaint Hi-Res gives a false positive + // as do some GunPaint images .. + if (len == 9002 || fmtProbeGunPaint(buf, len, fmt) > DM_PROBE_SCORE_GOOD) + return DM_PROBE_SCORE_FALSE; + + for (n = 0, i = 2; i < len; i++) + if (buf[i] == 0xC2) n++; + + if (n > 50) + return DM_PROBE_SCORE_GOOD; + if (n > 25) + return DM_PROBE_SCORE_AVG; + if (n > 10) + return DM_PROBE_SCORE_MAYBE; + + return DM_PROBE_SCORE_FALSE; +} + + +static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + int res; + DMGrowBuf mem, tmp; + + // Amica Paint apparently is broken and stores one byte less than it should + // so we need to do some crappy buffer expansion here .. + if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK) + return res; + + tmp.len = len; + memcpy(tmp.data, buf, len); + tmp.data[tmp.len++] = 0; + + // Now do an RLE decode on the enlarged buffer + if ((res = dmDecodeGenericRLE(&mem, tmp.data, tmp.data + tmp.len, 0xC2, 0, 0, DM_RLE_MARKER)) != DMERR_OK) + goto out; + + // And finally decode to bitmap struct + res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + +out: + dmGrowBufFree(&tmp); + dmGrowBufFree(&mem); + return res; +} + + +static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + if (len == fmt->size && + (dmCompareAddr16(buf, 0, 0x3c00) || dmCompareAddr16(buf, 0, 0x3ff0))) + return DM_PROBE_SCORE_MAX; + + return DM_PROBE_SCORE_FALSE; +} + + +static BOOL fmtTruePaintSetLaceType(DMC64Image *img, const DMC64EncDecOp *op, + const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + (void) op; + (void) buf; + (void) len; + (void) fmt; + img->laceType = D64_ILACE_RES; + return TRUE; +} + + +static Uint8 fmtGetPixelTruePaint( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + (void) raster; + return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0); +} + + +#define XX2_MIN_SIZE 4000 + +static int fmtProbeFormatXX2(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + if (len >= XX2_MIN_SIZE && len <= XX2_MIN_SIZE + 8 && + dmCompareAddr16(buf, 0, fmt->addr)) + return DM_PROBE_SCORE_MAYBE; + + return DM_PROBE_SCORE_FALSE; +} + + +static int fmtDecodeFormatXX2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + int res; + + // If there is only data for less than XX2_MIN_SIZE bytes, + // allocate a buffer of that size and copy data there. + // Otherwise allocate len bytes. + size_t nlen = len < XX2_MIN_SIZE ? XX2_MIN_SIZE : len; + Uint8 *mem = dmMalloc0(nlen); + if (mem == NULL) + return DMERR_MALLOC; + + memcpy(mem, buf, len); + res = dmC64DecodeGenericBMP(img, mem, nlen, fmt); + + dmFree(mem); + return res; +} + + +#define FUNPAINT2_HEADER_SIZE (0x10) +static const char *fmtFunPaint2MagicID = "FUNPAINT (MT) "; + + +static BOOL fmtProbeFunPaint2Header(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + return + len > 30 && + dmCompareAddr16(buf, 0, fmt->addr) && + strncmp((const char *) (buf + 2), fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) == 0; +} + + +static int fmtProbeFunPaint2Unpacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + if (fmtProbeFunPaint2Header(buf, len, fmt) && + buf[2 + 14] == 0) + return DM_PROBE_SCORE_MAX; + else + return DM_PROBE_SCORE_FALSE; +} + + +static int fmtProbeFunPaint2Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + if (fmtProbeFunPaint2Header(buf, len, fmt) && + buf[2 + 14] != 0) + return DM_PROBE_SCORE_MAX; + else + return DM_PROBE_SCORE_FALSE; +} + + +static int fmtDecodeFunPaint2Unpacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + return dmC64DecodeGenericBMP(img, buf + FUNPAINT2_HEADER_SIZE, len - FUNPAINT2_HEADER_SIZE, fmt); +} + + +static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +{ + int res; + DMGrowBuf mem; + dmGrowBufInit(&mem); + + if ((res = dmDecodeGenericRLE(&mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, *(buf + 15), 0, 0, DM_RLE_MARKER)) != DMERR_OK) + goto out; + + res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + +out: + dmGrowBufFree(&mem); + return res; +} + + +static int fmtEncodeFunPaint2Unpacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) +{ + // Add the header bits + if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || + !dmGrowBufPutU8(buf, 0)) + return DMERR_MALLOC; + + return dmC64EncodeGenericBMP(FALSE, buf, img, fmt); +} + + +static int fmtEncodeFunPaint2Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) +{ + int res; + DMGrowBuf tmp; + Uint8 rleMarker; + + // Encode the data to temp buffer + if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) + goto out; + + // Analyze the data .. + dmGenericRLEAnalyze(&tmp, &rleMarker, DM_RLE_MARKER); + rleMarker = 0xff; + + // Add the header bits + if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || + !dmGrowBufPutU8(buf, rleMarker)) + { + res = DMERR_MALLOC; + goto out; + } + + // And now RLE compress the data to the existing buffer + res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, + rleMarker, 3, 255, DM_RLE_MARKER); + +out: + dmGrowBufFree(&tmp); + return res; +} + + +static Uint8 fmtGetPixelFunPaint2( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + const int vbank = (raster & 7) + (vbitmap * 8); + int vr, vb; + if (raster < 100) + { + vb = 0; + vr = raster; + } + else + { + vb = 0; + vr = raster - 100; + } + + switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) + { + case 0: return img->extraData[vb][vr] & 15; break; + case 1: return img->screen[vbank][scroffs] >> 4; break; + case 2: return img->screen[vbank][scroffs] & 15; break; + default: return img->color[0][scroffs] & 15; break; + } +} + + +static Uint8 fmtGetPixelGunPaint( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + const int vbank = (raster & 7);// + (vbitmap * 8); + int vr, vb; + if (raster < 177) + { + vb = 0; + vr = raster; + } + else + { + vb = 0; + vr = raster - 177; + } + + switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) + { + case 0: return img->extraData[vb][vr] & 15; break; + case 1: return img->screen[vbank][scroffs] >> 4; break; + case 2: return img->screen[vbank][scroffs] & 15; break; + default: return img->color[0][scroffs] & 15; break; + } +} + + +static Uint8 fmtGetPixelBMFLI( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + const int vbank = raster & 7; + switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) + { + case 0: return img->extraData[0][raster]; break; + case 1: return img->screen[vbank][scroffs] >> 4; break; + case 2: return img->screen[vbank][scroffs] & 15; break; + default: return img->color[0][scroffs] & 15; break; + } +} + + +static Uint8 fmtGetPixelFLIDesigner( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, raster & 7, vbitmap, 0); +} + + +static Uint8 fmtGetPixelCHFLI( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + const int vbank = raster & 7; + + if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1) + return img->screen[vbank][scroffs] >> 4; + else + return img->screen[vbank][scroffs] & 15; +} + + +static int fmtEncodeStub(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) +{ + (void) buf; + (void) img; + (void) fmt; + + return dmError(DMERR_NOT_SUPPORTED, + "Encoding of '%s' format not supported.\n", + fmt->name); +} + + +// +// Array with data for supported formats +// +#define DEF_SCREEN_RAM(start, oindex, bindex, osize) { DT_SCREEN_RAM, (start) + ((osize) * (oindex)), (bindex), 0, NULL, NULL } +#define DEF_SCREEN_RAMS_8(start, sindex, osize) \ + DEF_SCREEN_RAM((start), 0, (sindex + 0), (osize)), \ + DEF_SCREEN_RAM((start), 1, (sindex + 1), (osize)), \ + DEF_SCREEN_RAM((start), 2, (sindex + 2), (osize)), \ + DEF_SCREEN_RAM((start), 3, (sindex + 3), (osize)), \ + DEF_SCREEN_RAM((start), 4, (sindex + 4), (osize)), \ + DEF_SCREEN_RAM((start), 5, (sindex + 5), (osize)), \ + DEF_SCREEN_RAM((start), 6, (sindex + 6), (osize)), \ + DEF_SCREEN_RAM((start), 7, (sindex + 7), (osize)), + + +const DMC64ImageFormat dmC64ImageFormats[] = +{ + { + D64_FMT_MC, "d2p", "DrazPaint 1.4/2.0 (packed)", 0x5800, 0, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + fmtProbeDrazPaint20Packed, + fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked, + NULL, NULL, + NULL, + { + { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "drp", "DrazPaint (unpacked)", 0x5800, 10051, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, 0, + C64_SCR_WIDTH , C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, + fmtProbeDrazLace10Packed, + fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked, + NULL, NULL, + NULL, + { + { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, + { DT_BITMAP, 0x2800, 1, 0, NULL, NULL }, + { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, + C64_SCR_WIDTH , C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2740, 0, DC_BGCOL, NULL, NULL }, + { DT_BITMAP, 0x2800, 1, 0, NULL, NULL }, + { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceSetLaceType, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_ILACE, "mci", "Truepaint (unpacked)", 0x9c00, 19434, + C64_SCR_WIDTH , C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + fmtGetPixelTruePaint, + { + { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL }, + { DT_BITMAP, 0x0400, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x2400, 1, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL }, + { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL }, + { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintSetLaceType, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "kla", "Koala Paint (unpacked)", 0x6000, 10003, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "ocp", "Advanced Art Studio (unpacked)", 0x2000, 10018, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_COLOR_RAM, 0x2338, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2329, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "ami", "Amica Paint (packed)", 0x4000, 0, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + fmtProbeAmicaPaintPacked, + fmtDecodeAmicaPaintPacked, fmtEncodeStub, + NULL, NULL, + NULL, + { + { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "rpm", "Run Paint (unpacked)", 0x6000, 10006, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_HIRES, "art", "Art Studio (unpacked)", 0x2000, 9009, + C64_SCR_WIDTH , C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_HIRES, "iph", "Interpaint (unpacked)", 0x4000, 9002, + C64_SCR_WIDTH , C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "ipc", "Interpaint MC (unpacked)", 0x4000, 10003, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, + { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, + { DT_COLOR_REG, 0x2710, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_HIRES, "dd", "Doodle (unpacked)", 0x1c00, 9218, + C64_SCR_WIDTH , C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, + { DT_BITMAP, 0x0400, 0, 0, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_FLI, "bml", "Blackmail FLI (unpacked)", 0x3b00, 17474, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + fmtGetPixelBMFLI, + { + { DT_EXTRA_DATA, 0x0000, 0, 200, NULL, NULL }, + { DT_COLOR_RAM, 0x0100, 0, 0, NULL, NULL }, + DEF_SCREEN_RAMS_8( 0x0500, 0, 0x400) + { DT_BITMAP, 0x2500, 0, 0, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_FLI, "fli", "FLI Designer (unpacked)", 0, 17409, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + fmtProbeFLIDesigner, + NULL, NULL, + NULL, NULL, + fmtGetPixelFLIDesigner, + { + { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, + DEF_SCREEN_RAMS_8( 0x0400, 0, 0x400) + { DT_BITMAP, 0x2400, 0, 0, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC, "xx1", "Unknown $2000 format (unpacked)", 0x2000, 10242, + C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + NULL, + NULL, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + { DT_SCREEN_RAM, 0x2000, 0, 0, NULL, NULL }, + { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL }, + { DT_COLOR_SET, 0x00 , 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + +#define XX2_WIDTH_CH 40 +#define XX2_HEIGHT_CH 10 +#define XX2_SIZE (XX2_WIDTH_CH * XX2_HEIGHT_CH) +#define XX2_BSIZE (XX2_SIZE * 8) + + { + D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 0, + XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8, + XX2_WIDTH_CH , XX2_HEIGHT_CH, + fmtProbeFormatXX2, + fmtDecodeFormatXX2, NULL, + NULL, NULL, + NULL, + { + { DT_BITMAP, 0x0000, 0, XX2_BSIZE, NULL, NULL }, + { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE, 0, XX2_SIZE, NULL, NULL }, + { DT_SCREEN_RAM, XX2_BSIZE, 0, XX2_SIZE, NULL, NULL }, + { DT_COLOR_SET, 11, 0, DC_BGCOL, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "fp2", "FunPaint II (unpacked)", 0x3ff0, 33694, + C64_SCR_WIDTH, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + fmtProbeFunPaint2Unpacked, + fmtDecodeFunPaint2Unpacked, fmtEncodeFunPaint2Unpacked, + NULL, NULL, + fmtGetPixelFunPaint2, + { + DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400) + { DT_BITMAP, 0x2000, 0, 0, NULL, NULL }, + { DT_EXTRA_DATA, 0x3f40, 0, 100, NULL, NULL }, + { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL }, + DEF_SCREEN_RAMS_8( 0x43e8, 8, 0x400) + { DT_BITMAP, 0x63e8, 1, 0, NULL, NULL }, + { DT_EXTRA_DATA, 0x8328, 1, 100, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "fp2p", "FunPaint II (packed)", 0x3ff0, 0, + C64_SCR_WIDTH, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + fmtProbeFunPaint2Packed, + fmtDecodeFunPaint2Packed, fmtEncodeFunPaint2Packed, + NULL, NULL, + fmtGetPixelFunPaint2, + { + DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400) + { DT_BITMAP, 0x2000, 0, 0, NULL, NULL }, + { DT_EXTRA_DATA, 0x3f40, 0, 100, NULL, NULL }, + { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL }, + DEF_SCREEN_RAMS_8( 0x43e8, 8, 0x400) + { DT_BITMAP, 0x63e8, 1, 0, NULL, NULL }, + { DT_EXTRA_DATA, 0x8328, 1, 100, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_MC | D64_FMT_FLI | D64_FMT_ILACE, "gun", "GunPaint (unpacked)", 0x4000, 0, + C64_SCR_WIDTH, C64_SCR_HEIGHT, + C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, + fmtProbeGunPaint, + NULL, NULL, + NULL, NULL, + fmtGetPixelGunPaint, + { + DEF_SCREEN_RAMS_8( 0x0000, 0, 0x400) + { DT_BITMAP, 0x2000, 0, 0, NULL, NULL }, + { DT_EXTRA_DATA, 0x3f4f, 0, 177, NULL, NULL }, + { DT_COLOR_RAM, 0x4000, 0, 0, NULL, NULL }, + DEF_SCREEN_RAMS_8( 0x4400, 8, 0x400) + { DT_BITMAP, 0x6400, 1, 0, NULL, NULL }, + { DT_EXTRA_DATA, 0x47e8, 1, 20, NULL, NULL }, + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, + + { + D64_FMT_HIRES | D64_FMT_FLI, "chi", "Crest Hires FLI Designer (unpacked)", 0x4000, 16386, + C64_SCR_WIDTH, 14 * 8, + C64_SCR_CH_WIDTH , 14, + NULL, + NULL, NULL, + NULL, NULL, + fmtGetPixelCHFLI, + { + { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, + DEF_SCREEN_RAMS_8( 0x2000, 0, 0x400) + { DT_LAST, 0, 0, 0, NULL, NULL }, + } + }, +}; + +const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]); +