# HG changeset patch # User Matti Hamalainen # Date 1526261273 -10800 # Node ID ca087c0cc9c4c4d5de0c0b39c60bf7792a48e91b # Parent e6a228b50bd6c9a00a112df1324bc3a20e8429e0 Refactor the c64 format memory handling a bit for more flexibility. diff -r e6a228b50bd6 -r ca087c0cc9c4 tools/gfxconv.c --- a/tools/gfxconv.c Mon May 14 04:11:45 2018 +0300 +++ b/tools/gfxconv.c Mon May 14 04:27:53 2018 +0300 @@ -1003,10 +1003,9 @@ { for (int i = 0; i < dst->nbanks; i++) { - memcpy(dst->color[i], src->color[i], dst->screenSize); - memcpy(dst->bitmap[i], src->bitmap[i], dst->bitmapSize); - memcpy(dst->screen[i], src->screen[i], dst->screenSize); - memcpy(dst->charmem[i], src->charmem[i], dst->charmemSize); + dmC64MemBlockCopy(&dst->color[i], &src->color[i]); + dmC64MemBlockCopy(&dst->screen[i], &src->screen[i]); + dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[i]); } } else @@ -1017,33 +1016,31 @@ dmMsg(1, "Upconverting multicolor to FLI.\n"); for (int i = 0; i < dst->nbanks; i++) { - memcpy(dst->color[i], src->color[0], dst->screenSize); - memcpy(dst->screen[i], src->screen[0], dst->screenSize); - memcpy(dst->bitmap[i], src->bitmap[0], dst->bitmapSize); - memcpy(dst->charmem[i], src->charmem[0], dst->charmemSize); + dmC64MemBlockCopy(&dst->color[i], &src->color[0]); + dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]); + dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]); } + } + + for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) + { + const DMC64EncDecOp *op = &dstFmt->encdecOps[i]; + size_t size; - for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) + // Check for last operator + if (op->type == DT_LAST) + break; + + // Check size + if (!dmC64GetOpSize(op, dstFmt, &size)) + return DMERR_INVALID_DATA; + + // Perform operation + switch (op->type) { - const DMC64EncDecOp *op = &dstFmt->encdecOps[i]; - size_t size; - - // Check for last operator - if (op->type == DT_LAST) + case DT_EXTRA_DATA: + dmC64MemBlockAlloc(&dst->extraData[op->bank], size); break; - - // Check size - if (!dmC64GetOpSize(op, dstFmt, &size)) - return DMERR_INVALID_DATA; - - // Perform operation - switch (op->type) - { - case DT_EXTRA_DATA: - dst->extraData[op->bank] = dmMalloc0(size); - dst->extraDataSizes[op->bank] = size; - break; - } } } } diff -r e6a228b50bd6 -r ca087c0cc9c4 tools/lib64fmts.c --- a/tools/lib64fmts.c Mon May 14 04:11:45 2018 +0300 +++ b/tools/lib64fmts.c Mon May 14 04:27:53 2018 +0300 @@ -436,7 +436,7 @@ return dmC64GetGenericMCPixel( img, bmoffs, scroffs, vshift, vbank, vbitmap, 0, - img->extraData[vb][vr] & 15); + img->extraData[vb].data[vr] & 15); } @@ -460,7 +460,7 @@ return dmC64GetGenericMCPixel( img, bmoffs, scroffs, vshift, vbank, vbitmap, 0, - img->extraData[vb][vr] & 15); + img->extraData[vb].data[vr] & 15); } @@ -491,7 +491,7 @@ return dmC64GetGenericMCPixel( img, bmoffs, scroffs, vshift, vbank, vbitmap, 0, - img->extraData[0][raster] & 15); + img->extraData[0].data[raster] & 15); } @@ -509,10 +509,10 @@ { const int vbank = raster & 7; - if ((img->bitmap[vbitmap][bmoffs] >> vshift) & 1) - return img->screen[vbank][scroffs] >> 4; + if ((img->bitmap[vbitmap].data[bmoffs] >> vshift) & 1) + return img->screen[vbank].data[scroffs] >> 4; else - return img->screen[vbank][scroffs] & 15; + return img->screen[vbank].data[scroffs] & 15; } diff -r e6a228b50bd6 -r ca087c0cc9c4 tools/lib64gfx.c --- a/tools/lib64gfx.c Mon May 14 04:11:45 2018 +0300 +++ b/tools/lib64gfx.c Mon May 14 04:27:53 2018 +0300 @@ -100,6 +100,41 @@ } +int dmC64MemBlockAlloc(DMC64MemBlock *blk, const size_t size) +{ + if ((blk->data = dmMalloc0(size)) == NULL) + return DMERR_MALLOC; + + blk->size = size; + return DMERR_OK; +} + + +int dmC64MemBlockCopy(DMC64MemBlock *dst, const DMC64MemBlock *src) +{ + if (src->data != NULL && src->size > 0) + { + dst->size = src->size; + if ((dst->data = dmMalloc(src->size)) == NULL) + return DMERR_MALLOC; + + memcpy(dst->data, src->data, src->size); + } + + return DMERR_OK; +} + + +void dmC64MemBlockFree(DMC64MemBlock *blk) +{ + if (blk != NULL) + { + dmFreeR(&blk->data); + blk->size = 0; + } +} + + DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt) { DMC64Image *img = dmMalloc0(sizeof(DMC64Image)); @@ -115,32 +150,13 @@ img->chHeight = fmt->chHeight; img->nbanks = dmC64ImageGetNumBanks(fmt); - img->screenSize = img->chWidth * img->chHeight; - img->bitmapSize = img->screenSize * 8; - img->charmemSize = C64_MAX_CHARS * C64_CHR_SIZE; - // Allocate banks - if ((img->color = dmCalloc(img->nbanks, sizeof(Uint8 *))) == NULL || - (img->bitmap = dmCalloc(img->nbanks, sizeof(Uint8 *))) == NULL || - (img->screen = dmCalloc(img->nbanks, sizeof(Uint8 *))) == NULL || - (img->charmem = dmCalloc(img->nbanks, sizeof(Uint8 *))) == NULL) + if ((img->color = dmCalloc(img->nbanks, sizeof(DMC64MemBlock))) == NULL || + (img->bitmap = dmCalloc(img->nbanks, sizeof(DMC64MemBlock))) == NULL || + (img->screen = dmCalloc(img->nbanks, sizeof(DMC64MemBlock))) == NULL || + (img->charData = dmCalloc(img->nbanks, sizeof(DMC64MemBlock))) == NULL) goto err; - for (int i = 0; i < img->nbanks; i++) - { - if ((img->color[i] = dmMalloc0(img->screenSize)) == NULL) - goto err; - - if ((img->bitmap[i] = dmMalloc0(img->bitmapSize)) == NULL) - goto err; - - if ((img->screen[i] = dmMalloc0(img->screenSize)) == NULL) - goto err; - - if ((img->charmem[i] = dmMalloc0(img->charmemSize)) == NULL) - goto err; - } - return img; err: @@ -156,21 +172,21 @@ // Free the allocated areas for (int i = 0; i < img->nbanks; i++) { - dmFree(img->color[i]); - dmFree(img->bitmap[i]); - dmFree(img->screen[i]); - dmFree(img->charmem[i]); + dmC64MemBlockFree(&img->color[i]); + dmC64MemBlockFree(&img->bitmap[i]); + dmC64MemBlockFree(&img->screen[i]); + dmC64MemBlockFree(&img->charData[i]); } // Free the pointers to the areas dmFree(img->color); dmFree(img->bitmap); dmFree(img->screen); - dmFree(img->charmem); + dmFree(img->charData); // Extra data .. for (int i = 0; i < C64_MAX_EXTRA_DATA; i++) - dmFree(img->extraData[i]); + dmC64MemBlockFree(&img->extraData[i]); dmMemset(img, 0, sizeof(DMC64Image)); dmFree(img); @@ -596,6 +612,8 @@ { const DMC64EncDecOp *op = &fmt->encdecOps[i]; const Uint8 *src; + DMC64MemBlock *blk; + char *blkname; size_t size; // Check for last operator @@ -615,11 +633,11 @@ i, op->type, op->offs, op->offs, op->bank, size, size, op->size, op->size); } - // Do we need to reallocate some more space? + // Is the operation inside the bounds? if (op->offs + size > len + 1) { return dmError(DMERR_INVALID_DATA, - "Decode out of bounds, op #%d type=%d, offs=%d ($%04x), " + "Decode DATA out of bounds, op #%d type=%d, offs=%d ($%04x), " "bank=%d, size=%d ($%04x) @ %d ($%04x)\n", i, op->type, op->offs, op->offs, op->bank, size, size, len, len); } @@ -629,27 +647,28 @@ // Perform operation switch (op->type) { - case DT_COLOR_RAM: memcpy(img->color[op->bank], src, size); break; - case DT_BITMAP_RAM: memcpy(img->bitmap[op->bank], src, size); break; - case DT_SCREEN_RAM: memcpy(img->screen[op->bank], src, size); break; - case DT_CHAR_DATA: memcpy(img->charmem[op->bank], src, size); break; + case DT_COLOR_RAM: + case DT_SCREEN_RAM: + case DT_BITMAP_RAM: + case DT_CHAR_DATA: case DT_EXTRA_DATA: - if (img->extraData[op->bank] != NULL) + switch (op->type) { - return dmError(DMERR_INTERNAL, - "Extra data block already allocated and used! " - "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - i, op->offs, op->offs, op->bank, size, size, len, len); + case DT_COLOR_RAM : blk = &img->color[op->bank]; blkname = "Color RAM"; break; + case DT_SCREEN_RAM : blk = &img->screen[op->bank]; blkname = "Screen RAM"; break; + case DT_BITMAP_RAM : blk = &img->bitmap[op->bank]; blkname = "Bitmap RAM"; break; + case DT_CHAR_DATA : blk = &img->charData[op->bank]; blkname = "Character data"; break; + case DT_EXTRA_DATA : blk = &img->extraData[op->bank]; blkname = "Extra data"; break; } - if ((img->extraData[op->bank] = dmMalloc0(size)) == NULL) + if ((dmC64MemBlockAlloc(blk, size)) != DMERR_OK) { return dmError(DMERR_MALLOC, - "Could not allocate extradata block! " + "Could not allocate '%s' block! " "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - i, op->offs, op->offs, op->bank, size, size, len, len); + blkname, i, op->offs, op->offs, op->bank, size, size, len, len); } - img->extraDataSizes[op->bank] = size; - memcpy(img->extraData[op->bank], src, size); + blk->size = size; + memcpy(blk->data, src, size); break; case DT_COLOR_REG: @@ -696,7 +715,7 @@ { for (int bank = 0; bank < img->nbanks; bank++) for (int offs = 0; offs < fmt->chHeight * fmt->chWidth; offs++) - img->screen[bank][offs] = offs & 0xff; + img->screen[bank].data[offs] = offs & 0xff; } break; @@ -754,6 +773,8 @@ { const DMC64EncDecOp *op = &fmt->encdecOps[i]; size_t size, chksize; + const DMC64MemBlock *blk; + char *blkname; // Check for last operator if (op->type == DT_LAST) @@ -790,28 +811,36 @@ Uint8 *dst = buf->data + op->offs; switch (op->type) { - case DT_COLOR_RAM: memcpy(dst, img->color[op->bank], size); break; - case DT_BITMAP_RAM: memcpy(dst, img->bitmap[op->bank], size); break; - case DT_SCREEN_RAM: memcpy(dst, img->screen[op->bank], size); break; - case DT_CHAR_DATA: memcpy(dst, img->charmem[op->bank], size); break; + case DT_COLOR_RAM: + case DT_SCREEN_RAM: + case DT_BITMAP_RAM: + case DT_CHAR_DATA: case DT_EXTRA_DATA: - if (img->extraData[op->bank] == NULL) + switch (op->type) + { + case DT_COLOR_RAM : blk = &img->color[op->bank]; blkname = "Color RAM"; break; + case DT_SCREEN_RAM : blk = &img->screen[op->bank]; blkname = "Screen RAM"; break; + case DT_BITMAP_RAM : blk = &img->bitmap[op->bank]; blkname = "Bitmap RAM"; break; + case DT_CHAR_DATA : blk = &img->charData[op->bank]; blkname = "Character data"; break; + case DT_EXTRA_DATA : blk = &img->extraData[op->bank]; blkname = "Extra data"; break; + } + if (blk->data == NULL) { res = dmError(DMERR_NULLPTR, - "DT_EXTRA_DATA block is NULL in " + "'%s' block is NULL in " "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); + blkname, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); goto err; } - if (size > img->extraDataSizes[op->bank]) + if (size > blk->size) { res = dmError(DMERR_INTERNAL, - "DT_EXTRA_DATA size mismatch %d <> %d in " + "'%s' size mismatch %d <> %d in " "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", - op->size, img->extraDataSizes[op->bank], i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); + blkname, op->size, blk->size, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); goto err; } - memcpy(dst, img->extraData[op->bank], size); + memcpy(dst, blk->data, size); break; case DT_COLOR_REG: @@ -910,11 +939,11 @@ { const int x = xc / 8; const int scroffs = scroffsy + x; - const int chr = src->screen[0][scroffs]; + const int chr = src->screen[0].data[scroffs]; const int v = 7 - (xc & 7); - if ((src->charmem[0][chr * C64_CHR_SIZE + yb] >> v) & 1) - *d++ = src->color[0][scroffs]; + if ((src->charData[0].data[chr * C64_CHR_SIZE + yb] >> v) & 1) + *d++ = src->color[0].data[scroffs]; else *d++ = src->bgcolor; } @@ -924,13 +953,13 @@ { const int x = xc / 4; const int scroffs = scroffsy + x; - const int chr = src->screen[0][scroffs]; - const int col = src->color[0][scroffs] & 15; + const int chr = src->screen[0].data[scroffs]; + const int col = src->color[0].data[scroffs] & 15; if (col & 8) { const int v = 6 - ((xc * 2) & 6); - switch ((src->charmem[0][chr * C64_CHR_SIZE + yb] >> v) & 3) + switch ((src->charData[0].data[chr * C64_CHR_SIZE + yb] >> v) & 3) { case 0: *d++ = src->bgcolor; break; case 1: *d++ = src->d022; break; @@ -941,8 +970,8 @@ else { const int v = 7 - (xc & 7); - if ((src->charmem[0][chr * C64_CHR_SIZE + yb] >> v) & 1) - *d++ = src->color[0][scroffs]; + if ((src->charData[0].data[chr * C64_CHR_SIZE + yb] >> v) & 1) + *d++ = src->color[0].data[scroffs]; else *d++ = src->bgcolor; } diff -r e6a228b50bd6 -r ca087c0cc9c4 tools/lib64gfx.h --- a/tools/lib64gfx.h Mon May 14 04:11:45 2018 +0300 +++ b/tools/lib64gfx.h Mon May 14 04:27:53 2018 +0300 @@ -98,6 +98,13 @@ }; +typedef struct +{ + Uint8 *data; + size_t size; +} DMC64MemBlock; + + typedef struct _DMC64Image { int type, // Image type (D64_FMT_*) @@ -107,20 +114,20 @@ int width, height; // Width and height in pixels int chWidth, chHeight; // Width and height in charblocks - size_t - screenSize, - bitmapSize, - charmemSize; + // Bitmaps, color RAM, screen, etc. blocks * nbanks + // Not all of them may be allocated + DMC64MemBlock + *color, + *bitmap, + *screen, + *charData; - Uint8 - **color, - **bitmap, - **screen, - **charmem, - *extraData[C64_MAX_EXTRA_DATA], - d020, bgcolor, d022, d023, d024; + // Other standard colours + Uint8 d020, bgcolor, d022, d023, d024; - size_t extraDataSizes[C64_MAX_EXTRA_DATA]; + // Extra data areas used by some formats, + // for example raster colours might be stored + DMC64MemBlock extraData[C64_MAX_EXTRA_DATA]; DMC64Sprite sprites[C64_MAX_SPRITES]; } DMC64Image; @@ -217,14 +224,20 @@ // Miscellaneous functions // void dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt); +char * dmC64GetImageTypeString(char *buf, const size_t len, const int type, const BOOL lng); + void dmSetDefaultC64Palette(DMImage *img); -char * dmC64GetImageTypeString(char *buf, const size_t len, const int type, const BOOL lng); +int dmC64ImageGetNumBanks(const DMC64ImageFormat *fmt); 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); + int dmC64SanityCheckEncDecOp(const int i, const DMC64EncDecOp *op, const DMC64Image *img); BOOL dmC64GetOpSize(const DMC64EncDecOp *op, const DMC64ImageFormat *fmt, size_t *size); +int dmC64MemBlockAlloc(DMC64MemBlock *blk, const size_t size); +int dmC64MemBlockCopy(DMC64MemBlock *dst, const DMC64MemBlock *src); +void dmC64MemBlockFree(DMC64MemBlock *blk); + // C64 bitmap image allocation/freeing DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt); @@ -263,10 +276,10 @@ 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; + if ((img->bitmap[vbitmap].data[bmoffs] >> vshift) & 1) + return img->screen[vbank].data[scroffs] >> 4; else - return img->screen[vbank][scroffs] & 15; + return img->screen[vbank].data[scroffs] & 15; } @@ -275,12 +288,12 @@ const int vshift, const int vbank, const int vbitmap, const int cbank, const int bgcolor) { - switch ((img->bitmap[vbitmap][bmoffs] >> vshift) & 3) + switch ((img->bitmap[vbitmap].data[bmoffs] >> vshift) & 3) { case 0: return bgcolor; - case 1: return img->screen[vbank][scroffs] >> 4; - case 2: return img->screen[vbank][scroffs] & 15; - default: return img->color[cbank][scroffs] & 15; + case 1: return img->screen[vbank].data[scroffs] >> 4; + case 2: return img->screen[vbank].data[scroffs] & 15; + default: return img->color[cbank].data[scroffs] & 15; } }