# HG changeset patch # User Matti Hamalainen # Date 1526013715 -10800 # Node ID c7b9ef56319b088c8737a4ad75c523154e00ee64 # Parent aa87cb6cf33b276e396d77d0f75b773876ac3a3f Factor all the c64 file format specific things into lib64fmt.c diff -r aa87cb6cf33b -r c7b9ef56319b tools/lib64fmts.c --- /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]); + diff -r aa87cb6cf33b -r c7b9ef56319b tools/lib64gfx.c --- a/tools/lib64gfx.c Fri May 11 07:20:58 2018 +0300 +++ b/tools/lib64gfx.c Fri May 11 07:41:55 2018 +0300 @@ -12,35 +12,6 @@ #define BUF_SIZE_GROW (4*1024) -// 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 }, -}; - -#define DM_RLE_MARKER 1 -#define DM_RLE_MASK 2 - - -#define DM_GET_ADDR_LO(addr) ((addr) & 0xff) -#define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) - - void dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt) { char typeStr[64]; @@ -105,7 +76,7 @@ } -static BOOL dmCompareAddr16(const Uint8 *buf, const size_t offs, const Uint16 addr) +BOOL dmCompareAddr16(const Uint8 *buf, const size_t offs, const Uint16 addr) { return buf[offs ] == DM_GET_ADDR_LO(addr) && buf[offs + 1] == DM_GET_ADDR_HI(addr); @@ -271,7 +242,13 @@ } -static int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, +void dmGenericRLEAnalyze(const DMGrowBuf *buf, Uint8 *rleMarker, const int rleType) +{ + +} + + +int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) { int res; @@ -335,7 +312,7 @@ } -static int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, +int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) { int res; @@ -391,7 +368,7 @@ } -static int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, +int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType) { int res; @@ -426,7 +403,7 @@ } -static int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, +int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType) { int res; @@ -437,812 +414,6 @@ } -static inline Uint8 dmC64GetGenericSCPixel( - const DMC64Image *img, const int bmoffs, const int scroffs, - const int vshift, const int vbank, const int vbitmap, const int cbank) -{ - (void) cbank; - if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1) - return img->screen[vbank][scroffs] >> 4; - else - return img->screen[vbank][scroffs] & 15; -} - - -static inline Uint8 dmC64GetGenericMCPixel( - const DMC64Image *img, const int bmoffs, const int scroffs, - const int vshift, const int vbank, const int vbitmap, const int cbank) -{ - switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) - { - case 0: return img->bgcolor; break; - case 1: return img->screen[vbank][scroffs] >> 4; break; - case 2: return img->screen[vbank][scroffs] & 15; break; - default: return img->color[cbank][scroffs] & 15; break; - } -} - - -static inline Uint8 fmtGetGenericSCPixel( - const DMC64Image *img, const int bmoffs, const int scroffs, - const int vshift, const int vbitmap, const int raster) -{ - (void) raster; - return dmC64GetGenericSCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0); -} - - -static inline Uint8 fmtGetGenericMCPixel( - 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); -} - - -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 .. - 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 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, fmtEncodeStub, - 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, fmtEncodeStub, - 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]); - - // Perform probing of the given data buffer, trying to determine // if it contains a supported "C64" image format. Returns the // "probe score", see libgfx.h for list of values. If a match diff -r aa87cb6cf33b -r c7b9ef56319b tools/lib64gfx.h --- a/tools/lib64gfx.h Fri May 11 07:20:58 2018 +0300 +++ b/tools/lib64gfx.h Fri May 11 07:41:55 2018 +0300 @@ -51,6 +51,14 @@ #define C64_MAX_CHARS 256 +#define DM_RLE_MARKER 1 +#define DM_RLE_MASK 2 + + +#define DM_GET_ADDR_LO(addr) ((addr) & 0xff) +#define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) + + // Different supported C64 bitmap "modes" enum { @@ -190,22 +198,31 @@ } DMC64ImageFormat; +// +// Global variables +// extern DMColor dmDefaultC64Palette[C64_NCOLORS]; extern const DMC64ImageFormat dmC64ImageFormats[]; extern const int ndmC64ImageFormats; +// +// Miscellaneous functions +// void dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt); void dmSetDefaultC64Palette(DMImage *img); char * dmC64GetImageTypeString(char *buf, const size_t len, const int type, const BOOL lng); +int dmC64ConvertCSDataToImage(DMImage *img, int xoffs, int yoffs, const Uint8 *inBuf, int width, int height, BOOL multicolor, int *colors); +int dmC64ImageGetNumBanks(const DMC64ImageFormat *fmt); +BOOL dmCompareAddr16(const Uint8 *buf, const size_t offs, const Uint16 addr); +// C64 bitmap image allocation/freeing DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt); void dmC64ImageFree(DMC64Image *img); -int dmC64ConvertCSDataToImage(DMImage *img, int xoffs, int yoffs, const Uint8 *inBuf, int width, int height, BOOL multicolor, int *colors); - +// Encoding and decoding of formats and images int dmC64ProbeBMP(const Uint8 *buf, const size_t len, const DMC64ImageFormat **fmt); int dmC64DecodeGenericBMP(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt); @@ -220,6 +237,65 @@ int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src, const DMC64ImageFormat *fmt); int dmC64ConvertGenericImage2BMP(DMC64Image *dst, const DMImage *src, const DMC64ImageFormat *fmt); +void dmGenericRLEAnalyze(const DMGrowBuf *buf, Uint8 *rleMarker, const int rleType); + +int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, + const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType); +int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, + const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType); + +int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, + const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType); +int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, + const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType); + + +// +// Inline helper functions for pixel format decoding +// +static inline Uint8 dmC64GetGenericSCPixel( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbank, const int vbitmap, const int cbank) +{ + (void) cbank; + if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1) + return img->screen[vbank][scroffs] >> 4; + else + return img->screen[vbank][scroffs] & 15; +} + + +static inline Uint8 dmC64GetGenericMCPixel( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbank, const int vbitmap, const int cbank) +{ + switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) + { + case 0: return img->bgcolor; break; + case 1: return img->screen[vbank][scroffs] >> 4; break; + case 2: return img->screen[vbank][scroffs] & 15; break; + default: return img->color[cbank][scroffs] & 15; break; + } +} + + +static inline Uint8 fmtGetGenericSCPixel( + const DMC64Image *img, const int bmoffs, const int scroffs, + const int vshift, const int vbitmap, const int raster) +{ + (void) raster; + return dmC64GetGenericSCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0); +} + + +static inline Uint8 fmtGetGenericMCPixel( + 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); +} + #ifdef __cplusplus }