diff tools/lib64gfx.c @ 1588:ca087c0cc9c4

Refactor the c64 format memory handling a bit for more flexibility.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 14 May 2018 04:27:53 +0300
parents 3c9e5962eca6
children 3cc7b2aadda3
line wrap: on
line diff
--- 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;
                 }