# HG changeset patch # User Matti Hamalainen # Date 1559124660 -10800 # Node ID 84780a9d8d1749b41ba4a7fd2137b9d8d8f398cb # Parent fdd0fd7dc0e63b5242ee2d79890fcadfb1ada964 Improve and fix charmap format decoding. diff -r fdd0fd7dc0e6 -r 84780a9d8d17 tools/lib64fmts.c --- a/tools/lib64fmts.c Wed May 29 11:31:38 2019 +0300 +++ b/tools/lib64fmts.c Wed May 29 13:11:00 2019 +0300 @@ -89,52 +89,64 @@ } +static int fmtSetMarqPETSCIIData(const DMC64EncDecOp *op, DMC64Image *img, + const DMGrowBuf *buf, const DMC64ImageCommonFormat *fmt) +{ + (void) op; + (void) buf; + (void) fmt; + + switch (img->extraData[0].data[0]) + { + case 20: img->extraInfo[D64_EI_CHAR_CASE] = 0; break; // upper case + case 23: img->extraInfo[D64_EI_CHAR_CASE] = 1; break; // lower case + default: + return DMERR_INVALID_DATA; + } + + img->extraInfo[D64_EI_CHAR_MODE] = D64_FMT_HIRES; + img->extraInfo[D64_EI_CHAR_CUSTOM] = 0; + + return DMERR_OK; +} + + static int fmtGetPixelPETSCII(Uint8 *col, const DMC64Image *img, const int rasterX, const int rasterY) { DM_C64_GENERIC_CHAR_PIXEL(img) int chr = img->screen[0].data[scroffs]; - if (img->extraData[0].data != NULL) + if (!img->extraInfo[D64_EI_CHAR_CUSTOM] && + img->extraInfo[D64_EI_CHAR_CASE]) + chr += 256; // lower case, so add 256 to char ROM offset + + switch (img->extraInfo[D64_EI_CHAR_MODE]) { - // Marq's PETSCII editor - // d018 has been copied to extraData[0].data[0] - switch (img->extraData[0].data[0]) - { - case 23: chr += 256; break; // lower case, so add 256 to char ROM offset - case 20: break; // upper case - default: - return DMERR_INVALID_DATA; - } - } - else - if (img->extraData[1].data != NULL) - { - // petscii.krissz.hu editor - if (img->extraData[1].data[0x0028 - 2] == 0xd8) - { + case D64_FMT_HIRES: + return dmC64GetGenericCharSCPixel( + col, img, + scroffs, rasterX, + 0, (chr * D64_CHR_SIZE) + (rasterY & 7), chr, + 0, img->bgcolor); + + case D64_FMT_MC: return dmC64GetGenericCharMCPixel( col, img, scroffs, rasterX, 0, (chr * D64_CHR_SIZE) + (rasterY & 7), chr, 0, img->bgcolor, img->d022, img->d023); - } - else - if (img->extraData[1].data[0x0028 - 2] == 0x01) - { + + case D64_FMT_ECM: return dmC64GetGenericCharECMPixel( col, img, scroffs, rasterX, 0, ((chr & 0x3f) * D64_CHR_SIZE) + (rasterY & 7), chr, 0, img->bgcolor, img->d022, img->d023, img->d024); - } + + default: + return DMERR_INVALID_DATA; } - - return dmC64GetGenericCharSCPixel( - col, img, - scroffs, rasterX, - 0, (chr * D64_CHR_SIZE) + (rasterY & 7), chr, - 0, img->bgcolor); } @@ -164,6 +176,54 @@ } +static int fmtSetPetsciiKrisszHuData(const DMC64EncDecOp *op, DMC64Image *img, + const DMGrowBuf *buf, const DMC64ImageCommonFormat *fmt) +{ + (void) op; + (void) buf; + (void) fmt; + + const Uint8 *data = img->extraData[0].data; + switch (data[0x0028 - 2]) + { + case 0x00: + img->extraInfo[D64_EI_CHAR_MODE] = D64_FMT_HIRES; + img->d020 = data[0x001e - 2]; + img->bgcolor = data[0x0023 - 2]; + break; + + case 0xd8: + img->extraInfo[D64_EI_CHAR_MODE] = D64_FMT_MC; + img->d020 = data[0x001e - 2]; + img->bgcolor = data[0x0023 - 2]; + img->d022 = data[0x002d - 2]; + img->d023 = data[0x0032 - 2]; + break; + + case 0x01: + img->extraInfo[D64_EI_CHAR_MODE] = D64_FMT_ECM; + img->d020 = data[0x001e - 2]; + img->bgcolor = data[0x0023 - 2]; + img->d022 = data[0x0028 - 2]; + img->d023 = data[0x002d - 2]; + img->d024 = data[0x0032 - 2]; + break; + + default: + return DMERR_INVALID_DATA; + } + + // XXX TODO this format saves the charset data (for 256 chars) + // in the PRG and there is no direct indication whether it is + // a customized one or copy of C64 ROM charset .. we could + // implement a hash-based detection at some point. + img->extraInfo[D64_EI_CHAR_CASE] = 0; + img->extraInfo[D64_EI_CHAR_CUSTOM] = 1; + + return DMERR_OK; +} + + static int fmtProbeKoalaPainter(const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int score = DM_PROBE_SCORE_FALSE; @@ -2141,7 +2201,8 @@ // For offset values see petscii/m_c64.pde :: save_prg() { DO_SET_MEM_LO , DS_D020 , 25 - 2, 0, 0, 0, NULL, NULL }, { DO_SET_MEM_LO , DS_BGCOL , 30 - 2, 0, 0, 0, NULL, NULL }, - { DO_COPY , DS_EXTRA_DATA , 20 - 2, 0, 1, 0, NULL, NULL }, // upper/lower + { DO_COPY , DS_EXTRA_DATA , 20 - 2, 0, 1, 0, NULL, NULL }, + { DO_FUNC , 0 , 0 , 0, 0, 0, fmtSetMarqPETSCIIData, NULL }, { DO_LAST , 0 , 0 , 0, 0, 0, NULL, NULL }, } @@ -2154,7 +2215,7 @@ fmtProbePetsciiKrisszHu, NULL, NULL, { - D64_FMT_HIRES | D64_FMT_CHAR, + D64_FMT_CHAR, D64_SCR_WIDTH , D64_SCR_HEIGHT, D64_SCR_CH_WIDTH, D64_SCR_CH_HEIGHT, 1, 1, @@ -2164,16 +2225,9 @@ { DO_COPY , DS_SCREEN_RAM , 0x2001 - 2, 0, 0, 0, NULL, NULL }, { DO_COPY , DS_COLOR_RAM , 0x23e9 - 2, 0, 0, 0, NULL, NULL }, - { DO_SET_MEM_LO , DS_D020 , 0x001e - 2, 0, 0, 0, NULL, NULL }, - { DO_SET_MEM_LO , DS_BGCOL , 0x0023 - 2, 0, 0, 0, NULL, NULL }, - - { DO_SET_MEM_LO , DS_D022 , 0x0028 - 2, 0, 0, 0, NULL, NULL }, - { DO_SET_MEM_LO , DS_D023 , 0x002d - 2, 0, 0, 0, NULL, NULL }, - { DO_SET_MEM_LO , DS_D024 , 0x0032 - 2, 0, 0, 0, NULL, NULL }, - - { DO_COPY , DS_EXTRA_DATA , 0x0000 , 1, 0x0100, 0, NULL, NULL }, - - { DO_COPY , DS_CHAR_DATA , 0x1801 - 2, 0, 0x0800, 0, NULL, NULL }, + { DO_COPY , DS_EXTRA_DATA , 0x0000 , 0, 0x0100, 0, NULL, NULL }, + { DO_COPY , DS_CHAR_DATA , 0x1801 - 2, 0, 0x0800, 0, NULL, NULL }, + { DO_FUNC , 0 , 0 , 0, 0 , 0, fmtSetPetsciiKrisszHuData, NULL }, { DO_LAST , 0 , 0 , 0, 0, 0, NULL, NULL }, } diff -r fdd0fd7dc0e6 -r 84780a9d8d17 tools/lib64gfx.h --- a/tools/lib64gfx.h Wed May 29 11:31:38 2019 +0300 +++ b/tools/lib64gfx.h Wed May 29 13:11:00 2019 +0300 @@ -28,7 +28,8 @@ #define D64_SCR_HEIGHT 200 #define D64_SCR_CH_WIDTH (D64_SCR_WIDTH/8) #define D64_SCR_CH_HEIGHT (D64_SCR_HEIGHT/8) -#define D64_MAX_EXTRA_DATA 64 +#define D64_MAX_EXTRA_DATA 16 +#define D64_MAX_EXTRA_INFO 64 // C64 video screen pixel aspect ratio on PAL #define D64_SCR_PAR_XY (0.9365f) @@ -87,6 +88,15 @@ }; +// Various extra settings (see DMC64Image::extraInfo[]) +enum +{ + D64_EI_CHAR_CASE = 0, + D64_EI_CHAR_MODE, + D64_EI_CHAR_CUSTOM, +}; + + // Image <-> bitmap conversion dithering enum { @@ -179,6 +189,11 @@ // for example raster colours might be stored DMC64MemBlock extraData[D64_MAX_EXTRA_DATA]; + // Extra information / settings used by some formats, + // for example some PETSCII-type formats. + // See D64_EI_* constants. + Uint8 extraInfo[D64_MAX_EXTRA_INFO]; + //DMC64Sprite sprites[D64_MAX_SPRITES]; } DMC64Image; @@ -474,7 +489,7 @@ case 0: *col = bgcolor; break; case 1: *col = bgd022; break; case 2: *col = bgd023; break; - case 3: *col = ccol & 15; + case 3: *col = ccol & 7; } } else