# HG changeset patch # User Matti Hamalainen # Date 1506271713 -10800 # Node ID c465860e44ed29da0bc16ace584963e8b29e7258 # Parent e274a7e6dff97f5e718e16be08efc57ac7979940 Make c64 image bank allocation dynamic. diff -r e274a7e6dff9 -r c465860e44ed tools/lib64gfx.c --- a/tools/lib64gfx.c Sun Sep 24 17:50:02 2017 +0300 +++ b/tools/lib64gfx.c Sun Sep 24 19:48:33 2017 +0300 @@ -12,27 +12,53 @@ #define BUF_SIZE_GROW (4*1024) -DMC64Image * dmC64ImageAlloc(int width, int height, int ch_width, int ch_height) +int dmC64ImageGetNumBanks(const DMC64ImageFormat *fmt) +{ + int nbanks = 0; + for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) + { + const DMC64EncDecOp *op = &fmt->encdecOps[i]; + if (op->type == DT_LAST) + break; + + if (op->bank > nbanks) + nbanks = op->bank; + } + + return nbanks + 1; +} + + +DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt) { DMC64Image *img = dmMalloc0(sizeof(DMC64Image)); if (img == NULL) return NULL; - img->width = width; - img->height = height; - img->ch_width = ch_width; - img->ch_height = ch_height; + // Initialize image information + img->width = fmt->width; + img->height = fmt->height; + img->ch_width = fmt->ch_width; + img->ch_height = fmt->ch_height; + img->nbanks = dmC64ImageGetNumBanks(fmt); - for (int i = 0; i < C64_SCR_MAX_BANK; i++) + // 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) + goto err; + + for (int i = 0; i < img->nbanks; i++) { - if ((img->color[i] = dmMalloc0(ch_width * ch_height)) == NULL) + if ((img->color[i] = dmMalloc0(img->ch_width * img->ch_height)) == NULL) goto err; - if ((img->bitmap[i] = dmMalloc0(ch_width * ch_height * 8)) == NULL) + if ((img->bitmap[i] = dmMalloc0(img->ch_width * img->ch_height * 8)) == NULL) goto err; - if ((img->screen[i] = dmMalloc0(ch_width * ch_height)) == NULL) + if ((img->screen[i] = dmMalloc0(img->ch_width * img->ch_height)) == NULL) goto err; if ((img->charmem[i] = dmMalloc0(C64_MAX_CHARS * C64_CHR_SIZE)) == NULL) @@ -51,7 +77,7 @@ { if (img != NULL) { - for (int i = 0; i < C64_SCR_MAX_BANK; i++) + for (int i = 0; i < img->nbanks; i++) { dmFree(img->color[i]); dmFree(img->bitmap[i]); @@ -751,7 +777,7 @@ } -static int dmC64SanityCheckEncDecOp(const int i, const DMC64EncDecOp *op) +static int dmC64SanityCheckEncDecOp(const int i, const DMC64EncDecOp *op, const DMC64Image *img) { switch (op->type) { @@ -759,11 +785,11 @@ case DT_BITMAP: case DT_SCREEN_RAM: case DT_CHAR_DATA: - if (op->bank < 0 || op->bank >= C64_SCR_MAX_BANK) + if (op->bank < 0 || op->bank > img->nbanks) { return dmError(DMERR_INTERNAL, - "Invalid bank %d definition in generic encode/decode operator %d @ #%d.\n", - op->bank, op->type, i); + "Invalid bank %d / %d definition in generic encode/decode operator %d @ #%d.\n", + op->bank, img->nbanks, op->type, i); } break; @@ -848,6 +874,7 @@ img->height = fmt->height; img->ch_width = fmt->ch_width; img->ch_height = fmt->ch_height; + img->nbanks = dmC64ImageGetNumBanks(fmt); // Perform decoding for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) @@ -856,12 +883,13 @@ const Uint8 *src; size_t size; int res; + // Check for last operator if (op->type == DT_LAST) break; // Check operation validity - if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK) + if ((res = dmC64SanityCheckEncDecOp(i, op, img)) != DMERR_OK) return res; // Check size @@ -952,7 +980,7 @@ case D64_CHCFG_LINEAR: { - for (int bank = 0; bank < C64_SCR_MAX_BANK; bank++) + for (int bank = 0; bank < img->nbanks; bank++) for (int offs = 0; offs < fmt->ch_height * fmt->ch_width; offs++) img->screen[bank][offs] = offs & 0xff; } @@ -1025,7 +1053,7 @@ break; // Check operation validity - if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK) + if ((res = dmC64SanityCheckEncDecOp(i, op, img)) != DMERR_OK) goto error; // Check size @@ -1329,9 +1357,7 @@ return DMERR_INVALID_DATA; // Allocate memory - if ((*img = dmC64ImageAlloc( - (*fmt)->width, (*fmt)->height, - (*fmt)->ch_width, (*fmt)->ch_height)) == NULL) + if ((*img = dmC64ImageAlloc(*fmt)) == NULL) return DMERR_MALLOC; // Decode the bitmap to memory layout diff -r e274a7e6dff9 -r c465860e44ed tools/lib64gfx.h --- a/tools/lib64gfx.h Sun Sep 24 17:50:02 2017 +0300 +++ b/tools/lib64gfx.h Sun Sep 24 19:48:33 2017 +0300 @@ -24,7 +24,6 @@ #define C64_SCR_COLOR_SIZE (C64_SCR_CH_WIDTH * C64_SCR_CH_HEIGHT) #define C64_SCR_SCREEN_SIZE (C64_SCR_CH_WIDTH * C64_SCR_CH_HEIGHT) #define C64_SCR_BITMAP_SIZE ((C64_SCR_WIDTH * C64_SCR_HEIGHT)/8) -#define C64_SCR_MAX_BANK 8 #define C64_MAX_EXTRA_DATA 64 // C64 video screen pixel aspect ratio on PAL @@ -102,16 +101,17 @@ typedef struct _DMC64Image { int type, // Image type (D64_FMT_*) - laceType; // Interlace type (D64_ILACE_*) + laceType, // Interlace type (D64_ILACE_*) + nbanks; int width, height; // Width and height in pixels int ch_width, ch_height; // Width and height in charblocks Uint8 - *color[C64_SCR_MAX_BANK], - *bitmap[C64_SCR_MAX_BANK], - *screen[C64_SCR_MAX_BANK], - *charmem[C64_SCR_MAX_BANK], + **color, + **bitmap, + **screen, + **charmem, *extraData[C64_MAX_EXTRA_DATA], d020, bgcolor, d022, d023, d024; @@ -185,7 +185,7 @@ extern const int ndmC64ImageFormats; -DMC64Image *dmC64ImageAlloc(int width, int height, int ch_width, int ch_height); +DMC64Image *dmC64ImageAlloc(const DMC64ImageFormat *fmt); void dmC64ImageFree(DMC64Image *img);