changeset 1378:c465860e44ed

Make c64 image bank allocation dynamic.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 24 Sep 2017 19:48:33 +0300
parents e274a7e6dff9
children 1e67dd44351e
files tools/lib64gfx.c tools/lib64gfx.h
diffstat 2 files changed, 53 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);