Mercurial > hg > dmlib
view tools/lib64fmts.c @ 1579:4288b21e97b9
Improve and simplify Fun Paint 2 format support.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 13 May 2018 10:07:25 +0300 |
parents | fb60abb09a65 |
children | 5aa1c3ec91d5 |
line wrap: on
line source
/* * 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 fmtDecodeKoalaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) { int res; DMGrowBuf mem; DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER2; cfg.rleMarker = 0xfe; if ((res = dmDecodeGenericRLEAlloc(&mem, buf, buf + len, &cfg)) != DMERR_OK) goto out; res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); out: dmGrowBufFree(&mem); return res; } static int fmtEncodeKoalaPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { int res; DMGrowBuf tmp; DMCompParams cfg; // Encode the data to temp buffer if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) goto out; // And now RLE compress the data to the existing buffer cfg.type = DM_COMP_RLE_MARKER2; cfg.rleMarker = 0xfe; cfg.rleMinCount = 3; cfg.rleMaxCount = 255; res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); out: dmGrowBufFree(&tmp); return res; } 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; DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER1; cfg.rleMarker = buf[0x0d]; if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, &cfg)) != 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; DMCompParams cfg; 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, &cfg.rleMarker, DM_COMP_RLE_MARKER1); // Add the header bits if (!dmGrowBufPut(buf, magicID, strlen(magicID)) || !dmGrowBufPutU8(buf, cfg.rleMarker)) { res = DMERR_MALLOC; goto out; } // And now RLE compress the data to the existing buffer cfg.type = DM_COMP_RLE_MARKER1; cfg.rleMinCount = 3; cfg.rleMaxCount = 255; res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 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 fmtDrazLaceGetLaceType(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 BOOL fmtDrazLaceSetLaceType(const DMC64EncDecOp *op, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { (void) fmt; buf->data[op->offs] = (img->laceType == D64_ILACE_RES) ? 1 : 0; 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; DMCompParams cfg; // 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; memcpy(tmp.data, buf, len); tmp.len = len + 1; // Now do an RLE decode on the enlarged buffer cfg.type = DM_COMP_RLE_MARKER1; cfg.rleMarker = 0xC2; if ((res = dmDecodeGenericRLEAlloc(&mem, tmp.data, tmp.data + tmp.len, &cfg)) != 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 fmtEncodeAmicaPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { int res; DMGrowBuf tmp; DMCompParams cfg; // Encode the data to temp buffer if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) goto out; // And now RLE compress the data to the existing buffer cfg.type = DM_COMP_RLE_MARKER1; cfg.rleMarker = 0xC2; cfg.rleMinCount = 3; cfg.rleMaxCount = 255; res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); out: dmGrowBufFree(&tmp); 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 fmtTruePaintGetLaceType(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, img->bgcolor); } #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 int fmtProbeFunPaint2(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) { if (len > 30 && dmCompareAddr16(buf, 0, fmt->addr) && strncmp((const char *) (buf + 2), fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) == 0) return DM_PROBE_SCORE_MAX; else return DM_PROBE_SCORE_FALSE; } static int fmtDecodeFunPaint2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) { int res; // Check if the data is compressed if (buf[14]) { DMGrowBuf mem; DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER1; cfg.rleMarker = buf[15]; if ((res = dmDecodeGenericRLEAlloc(&mem, buf + FUNPAINT2_HEADER_SIZE, buf + len + 1, // XXX TODO: nasty +1 &cfg)) == DMERR_OK) res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); dmGrowBufFree(&mem); } else { res = dmC64DecodeGenericBMP(img, buf + FUNPAINT2_HEADER_SIZE, len - FUNPAINT2_HEADER_SIZE, fmt); } 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; DMCompParams cfg; // Encode the data to temp buffer if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) goto out; // Analyze the data .. dmGenericRLEAnalyze(&tmp, &cfg.rleMarker, DM_COMP_RLE_MARKER1); // Add the header bits if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || !dmGrowBufPutU8(buf, cfg.rleMarker)) { res = DMERR_MALLOC; goto out; } // And now RLE compress the data to the existing buffer cfg.type = DM_COMP_RLE_MARKER1; cfg.rleMinCount = 3; cfg.rleMaxCount = 255; res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 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; } return dmC64GetGenericMCPixel( img, bmoffs, scroffs, vshift, vbank, vbitmap, 0, img->extraData[vb][vr] & 15); } 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; } return dmC64GetGenericMCPixel( img, bmoffs, scroffs, vshift, vbank, vbitmap, 0, img->extraData[vb][vr] & 15); } 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; return dmC64GetGenericMCPixel( img, bmoffs, scroffs, vshift, vbank, vbitmap, 0, img->extraData[0][raster] & 15); } 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, img->bgcolor); } 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; } // // 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, DM_FMT_RDWR, 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, DM_FMT_RDWR, 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, DM_FMT_RDWR, 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, fmtDrazLaceGetLaceType, NULL }, { DT_ENC_FUNCTION, 0x2742, 0, 1, NULL, fmtDrazLaceSetLaceType }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, DM_FMT_RDWR, 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, fmtDrazLaceGetLaceType, NULL }, { DT_ENC_FUNCTION, 0x2742, 0, 1, NULL, fmtDrazLaceSetLaceType }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC, "vid", "Vidcom 64 (unpacked)", 0x5800, 10050, DM_FMT_RDWR, 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, 0x07e8, 0, DC_BGCOL, NULL, NULL }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC, "p64", "Picasso 64 (unpacked)", 0x1800, 10050, DM_FMT_RDWR, 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, 0x07fe, 0, DC_BGCOL, NULL, NULL }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC | D64_FMT_ILACE, "mci", "Truepaint (unpacked)", 0x9c00, 19434, DM_FMT_RD, 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, fmtTruePaintGetLaceType, NULL }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC, "kla", "Koala Paint (unpacked)", 0x6000, 10003, DM_FMT_RDWR, 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, 0x270f, 0, DC_BGCOL, NULL, NULL }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC, "klp", "Koala Paint (packed)", 0x6000, 0, DM_FMT_RDWR, C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, fmtDecodeKoalaPaintPacked, fmtEncodeKoalaPaintPacked, 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, 0x270f, 0, DC_BGCOL, NULL, NULL }, { DT_LAST, 0, 0, 0, NULL, NULL }, } }, { D64_FMT_MC, "aas", "Advanced Art Studio (unpacked)", 0x2000, 10018, DM_FMT_RDWR, 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, DM_FMT_RDWR, C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, fmtProbeAmicaPaintPacked, fmtDecodeAmicaPaintPacked, fmtEncodeAmicaPaintPacked, 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, DM_FMT_RDWR, 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, DM_FMT_RD, 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, DM_FMT_RD, 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, DM_FMT_RDWR, 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, DM_FMT_RDWR, 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, DM_FMT_RDWR, 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, DM_FMT_RD, 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, DM_FMT_RD, 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, DM_FMT_RD, 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, DM_FMT_RD, C64_SCR_WIDTH, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, fmtProbeFunPaint2, fmtDecodeFunPaint2, 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, DM_FMT_RD, C64_SCR_WIDTH, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, fmtDecodeFunPaint2, 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, DM_FMT_RD, 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, DM_FMT_RD, 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]);