changeset 1373:fc5ee5b4b0e9

Improve handling of extra data.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 24 Sep 2017 15:22:12 +0300
parents b3e561e2209a
children 9edb17aa4a0a
files tools/lib64gfx.c tools/lib64gfx.h
diffstat 2 files changed, 68 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/tools/lib64gfx.c	Sun Sep 24 15:20:23 2017 +0300
+++ b/tools/lib64gfx.c	Sun Sep 24 15:22:12 2017 +0300
@@ -58,6 +58,10 @@
             dmFree(img->screen[i]);
             dmFree(img->charmem[i]);
         }
+
+        for (int i = 0; i < C64_MAX_EXTRA_DATA; i++)
+            dmFree(img->extraData[i]);
+
         dmMemset(img, 0, sizeof(DMC64Image));
         dmFree(img);
     }
@@ -688,11 +692,28 @@
 
 static int dmC64SanityCheckEncDecOp(const int i, const DMC64EncDecOp *op)
 {
-    if (op->bank < 0 || op->bank >= C64_SCR_MAX_BANK)
+    switch (op->type)
     {
-        return dmError(DMERR_INTERNAL,
-            "Invalid bank %d definition in generic encode/decode operator %d @ #%d.\n",
-            op->bank, op->type, i);
+        case DT_COLOR_RAM:
+        case DT_BITMAP:
+        case DT_SCREEN_RAM:
+        case DT_CHAR_DATA:
+            if (op->bank < 0 || op->bank >= C64_SCR_MAX_BANK)
+            {
+                return dmError(DMERR_INTERNAL,
+                    "Invalid bank %d definition in generic encode/decode operator %d @ #%d.\n",
+                    op->bank, op->type, i);
+            }
+            break;
+
+        case DT_EXTRA_DATA:
+            if (op->bank < 0 || op->bank >= C64_MAX_EXTRA_DATA)
+            {
+                return dmError(DMERR_INTERNAL,
+                    "Invalid bank %d definition in generic encode/decode operator %d @ #%d.\n",
+                    op->bank, op->type, i);
+            }
+            break;
     }
 
     if (op->type < 0 || op->type >= DT_LAST)
@@ -722,8 +743,8 @@
             check = TRUE;
             break;
 
-        case DT_EXTRADATA:
-            *size = C64_SCR_EXTRADATA;
+        case DT_EXTRA_DATA:
+            *size = op->size;
             check = TRUE;
             break;
 
@@ -809,7 +830,24 @@
             case DT_BITMAP:      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_EXTRADATA:   memcpy(img->extradata, src, size); break;
+            case DT_EXTRA_DATA:
+                if (img->extraData[op->bank] != NULL)
+                {
+                    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);
+                }
+                if ((img->extraData[op->bank] = dmMalloc0(size)) == NULL)
+                {
+                    return dmError(DMERR_MALLOC,
+                        "Could not allocate extradata 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);
+                }
+                img->extraDataSizes[op->bank] = size;
+                memcpy(img->extraData[op->bank], src, size);
+                break;
 
             case DT_COLOR_REG:
                 switch (op->size)
@@ -967,7 +1005,25 @@
             case DT_BITMAP:      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_EXTRADATA:   memcpy(dst, img->extradata, size); break;
+            case DT_EXTRA_DATA:
+                if (img->extraData[op->bank] == NULL)
+                {
+                    res = dmError(DMERR_NULLPTR,
+                        "DT_EXTRA_DATA 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, *plen, *plen);
+                    goto error;
+                }
+                if (size > img->extraDataSizes[op->bank])
+                {
+                    res = dmError(DMERR_INTERNAL,
+                        "DT_EXTRA_DATA 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, *plen, *plen);
+                    goto error;
+                }
+                memcpy(dst, img->extraData[op->bank], size);
+                break;
 
             case DT_COLOR_REG:
                 switch (op->size)
--- a/tools/lib64gfx.h	Sun Sep 24 15:20:23 2017 +0300
+++ b/tools/lib64gfx.h	Sun Sep 24 15:22:12 2017 +0300
@@ -24,8 +24,8 @@
 #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_EXTRADATA      1024
 #define C64_SCR_MAX_BANK       8
+#define C64_MAX_EXTRA_DATA     64
 
 // C64 video screen pixel aspect ratio on PAL
 #define C64_SCR_PAR_XY         (0.9365f)
@@ -123,9 +123,10 @@
         *bitmap[C64_SCR_MAX_BANK],
         *screen[C64_SCR_MAX_BANK],
         *charmem[C64_SCR_MAX_BANK],
-        extradata[C64_SCR_EXTRADATA],
+        *extraData[C64_MAX_EXTRA_DATA],
         d020, bgcolor, d022, d023, d024;
 
+    size_t extraDataSizes[C64_MAX_EXTRA_DATA];
     DMC64Sprite sprites[C64_MAX_SPRITES];
 } DMC64Image;
 
@@ -137,7 +138,7 @@
     DT_SCREEN_RAM,
     DT_COLOR_REG,
     DT_COLOR_SET,
-    DT_EXTRADATA,
+    DT_EXTRA_DATA,
 
     DT_DEC_FUNCTION,
     DT_ENC_FUNCTION,