diff tools/lib64gfx.c @ 917:df3a74f230d9

Initial implementation of charmode support in lib64gfx.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 25 Feb 2015 03:53:34 +0200
parents 3985f596ece5
children 59615f9c2ca9
line wrap: on
line diff
--- a/tools/lib64gfx.c	Wed Feb 25 03:53:07 2015 +0200
+++ b/tools/lib64gfx.c	Wed Feb 25 03:53:34 2015 +0200
@@ -14,12 +14,18 @@
 
 char * dmC64GetImageTypeString(char *buf, const size_t len, const int type)
 {
-    snprintf(buf, len,
-        "%s%s%s",
-        (type & D64_FMT_FLI) ? "FLI " : "",
-        (type & D64_FMT_MC) ? "MCol" : "HiRes",
-        (type & D64_FMT_ILACE) ? " Ilace" : ""
-        );
+    *buf = 0;
+
+    if (type & D64_FMT_FLI)
+        strncat(buf, "FLI ", len - strlen(buf));
+
+    strncat(buf, (type & D64_FMT_MC) ? "MCol " : "HiRes ", len - strlen(buf));
+
+    if (type & D64_FMT_ILACE)
+        strncat(buf, "Ilace ", len - strlen(buf));
+
+    if (type & D64_FMT_CHAR)
+        strncat(buf, "CharMap", len - strlen(buf));
 
     return buf;
 }
@@ -53,7 +59,12 @@
     C64_SCR_BITMAP_SIZE,
     C64_SCR_SCREEN_SIZE,
     1,
+    0,
     C64_SCR_EXTRADATA,
+    0,
+    0,
+    C64_MAX_CHARS * C64_CHR_HEIGHT * C64_CHR_WIDTH,
+    0
 };
 
 
@@ -289,7 +300,7 @@
             { DT_COLOR_RAM,    0x0000, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x0800, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x0400, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2740, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2740, 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
@@ -302,7 +313,7 @@
             { DT_COLOR_RAM,    0x0000, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x0800, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x0400, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2740, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2740, 0,  DC_BGCOL, NULL, NULL },
             { DT_BITMAP,       0x2800, 1,  0, NULL, NULL },
             { DT_DEC_FUNCTION, 0x2742, 0,  1, fmtDrazLaceSetLaceType, NULL },
         }
@@ -317,7 +328,7 @@
             { DT_COLOR_RAM,    0x0000, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x0800, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x0400, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2740, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2740, 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
@@ -330,7 +341,7 @@
             { DT_COLOR_RAM,    0x0000, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x0800, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x0400, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2740, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2740, 0,  DC_BGCOL, NULL, NULL },
             { DT_BITMAP,       0x2800, 1,  0, NULL, NULL },
             { DT_DEC_FUNCTION, 0x2742, 0,  1, fmtDrazLaceSetLaceType, NULL },
         }
@@ -343,7 +354,7 @@
         6,
         {
             { DT_SCREEN_RAM,   0x0000, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x03e8, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x03e8, 0,  DC_BGCOL, NULL, NULL },
             { DT_BITMAP,       0x0400, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x2400, 1,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x4400, 1,  0, NULL, NULL },
@@ -361,7 +372,7 @@
             { DT_BITMAP,       0x0000, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x1f40, 0,  0, NULL, NULL },
             { DT_COLOR_RAM,    0x2328, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2710, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2710, 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
@@ -374,7 +385,7 @@
             { DT_BITMAP,       0x0000, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x1f40, 0,  0, NULL, NULL },
             { DT_COLOR_RAM,    0x2338, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2329, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2329, 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
@@ -387,7 +398,7 @@
             { DT_COLOR_RAM,    0x2328, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x0000, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x1f40, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2710, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2710, 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
@@ -400,7 +411,7 @@
             { DT_COLOR_RAM,    0x2328, 0,  0, NULL, NULL },
             { DT_BITMAP,       0x0000, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x1f40, 0,  0, NULL, NULL },
-            { DT_BGCOLOR,      0x2710, 0,  0, NULL, NULL },
+            { DT_COLOR_REG,    0x2710, 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
@@ -489,10 +500,45 @@
             { DT_BITMAP,       0x0000, 0,  0, NULL, NULL },
             { DT_SCREEN_RAM,   0x2000, 0,  0, NULL, NULL },
             { DT_COLOR_RAM,    0x2400, 0,  0, NULL, NULL },
-            { DT_BGCOLOR_SET,  0x00  , 0,  0, NULL, NULL },
+            { DT_COLOR_SET,    0x00  , 0,  DC_BGCOL, NULL, NULL },
+        }
+    },
+
+#define XX2_SIZE (40 * 10)
+#define XX2_BSIZE (XX2_SIZE * 8)
+    {
+        D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 4002,
+        NULL, NULL,
+        NULL, NULL, NULL,
+        4,
+        {
+            { DT_BITMAP,       0x0000, 0,  XX2_BSIZE, NULL, NULL },
+            { DT_COLOR_RAM,    XX2_BSIZE + XX2_SIZE, 0,  XX2_SIZE, NULL, NULL },
+            { DT_SCREEN_RAM,   XX2_BSIZE, 0,  XX2_SIZE, NULL, NULL },
+
+            { DT_COLOR_SET,    11  , 0,  DC_BGCOL, NULL, NULL },
         }
     },
 
+/*
+#define XX2_SIZE (40 * 10)
+#define XX2_BSIZE (XX2_SIZE * 8)
+    {
+        D64_FMT_MC | D64_FMT_CHAR, "xx2", "Unknown $2000 char format (unpacked)", 0x2000, 4002,
+        NULL, NULL,
+        NULL, NULL, NULL,
+        4,
+        {
+            { DT_CHAR_DATA,    0x0000, 0,  XX2_BSIZE, NULL, NULL },
+            { DT_COLOR_RAM,    XX2_BSIZE + XX2_SIZE , 0,  XX2_SIZE, NULL, NULL },
+
+            { DT_CHAR_CONFIG,  D64_CHCFG_LINEAR, 0,  XX2_SIZE, NULL, NULL },
+            { DT_COLOR_SET,    1  , 0,  DC_BGCOL, NULL, NULL },
+            { DT_COLOR_SET,    3  , 0,  DC_D022, NULL, NULL },
+            { DT_COLOR_SET,    4  , 0,  DC_D023, NULL, NULL },
+        }
+    },
+*/
 };
 
 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]);
@@ -600,9 +646,66 @@
             case DT_COLOR_RAM:   memcpy(img->color[op->bank], src, size); break;
             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_BGCOLOR:     img->bgcolor = *src; break;
-            case DT_BGCOLOR_SET: img->bgcolor = op->offs; break;
             case DT_EXTRADATA:   memcpy(img->extradata, src, size); break;
+            case DT_CHAR_DATA:   memcpy(img->charmem, src, size); break;
+
+            case DT_COLOR_REG:
+                switch (op->size)
+                {
+                    case DC_D020: img->d020 = *src; break;
+                    case DC_BGCOL:
+                    case DC_D021: img->bgcolor = *src; break;
+                    case DC_D022: img->d022 = *src; break;
+                    case DC_D023: img->d023 = *src; break;
+                    case DC_D024: img->d024 = *src; break;
+                    default:
+                        dmError("Unhandled DT_COLOR_REG mode %d in ", 
+                        "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
+                        op->size, i, op->offs, op->offs, op->bank, size, size, len, len);
+                        return DMERR_INTERNAL;
+                }
+                break;
+
+            case DT_COLOR_SET:
+                switch (op->size)
+                {
+                    case DC_D020: img->d020 = op->offs; break;
+                    case DC_BGCOL:
+                    case DC_D021: img->bgcolor = op->offs; break;
+                    case DC_D022: img->d022 = op->offs; break;
+                    case DC_D023: img->d023 = op->offs; break;
+                    case DC_D024: img->d024 = op->offs; break;
+                    default:
+                        dmError("Unhandled DT_COLOR_SET mode %d in ", 
+                        "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
+                        op->size, i, op->offs, op->offs, op->bank, size, size, len, len);
+                        return DMERR_INTERNAL;
+                }
+                break;
+
+            case DT_CHAR_CONFIG:
+                switch (op->offs)
+                {
+                    case D64_CHCFG_SCREEN:
+                        break;
+
+                    case D64_CHCFG_LINEAR:
+                        {
+                            size_t bank, offs;
+                            for (bank = 0; bank < C64_SCR_MAX_BANK; bank++)
+                            for (offs = 0; offs < C64_SCR_SCREEN_SIZE; offs++)
+                                img->screen[bank][offs] = offs & 0xff;
+                        }
+                        break;
+
+                    default:
+                        dmError("Unhandled DT_CHAR_CONFIG mode %d in ", 
+                        "op #%d, bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
+                        op->offs, i, op->bank, size, size, len, len);
+                        return DMERR_INTERNAL;
+                }
+                break;
+
             case DT_DEC_FUNCTION:
                 if (op->decfunction == NULL)
                 {
@@ -689,8 +792,26 @@
             case DT_COLOR_RAM:   memcpy(dst, img->color[op->bank], size); break;
             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_BGCOLOR:     *dst = img->bgcolor; break;
             case DT_EXTRADATA:   memcpy(dst, img->extradata, size); break;
+            case DT_CHAR_DATA:   memcpy(dst, img->charmem, size); break;
+
+            case DT_COLOR_REG:
+                switch (op->size)
+                {
+                    case DC_D020: *dst = img->d020; break;
+                    case DC_BGCOL:
+                    case DC_D021: *dst = img->bgcolor; break;
+                    case DC_D022: *dst = img->d022; break;
+                    case DC_D023: *dst = img->d023; break;
+                    case DC_D024: *dst = img->d024; break;
+                    default:
+                        dmError("Unhandled DT_COLOR_REG mode %d in ", 
+                        "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
+                        op->size, i, op->offs, op->offs, op->bank, size, size, *plen, *plen);
+                        return DMERR_INTERNAL;
+                }
+                break;
+
             case DT_ENC_FUNCTION:
                 if (op->encfunction == NULL)
                 {
@@ -752,7 +873,60 @@
     if (dst->width < 8)
         return DMERR_INVALID_ARGS;
 
-    // Perform generic conversion
+    if (src->type & D64_FMT_CHAR)
+    for (yc = 0; yc < dst->height; yc++)
+    {
+        Uint8 *d = dp;
+        const int y = yc / 8, yb = yc & 7;
+        const int scroffsy = y * C64_SCR_CH_WIDTH;
+        int xc;
+
+        if ((src->type & D64_FMT_MC) == D64_FMT_HIRES)
+        {
+            // Hi-res charmap
+            for (xc = 0; xc < dst->width; xc++)
+            {
+                const int x = xc / 8;
+                const int scroffs = scroffsy + x;
+                const int v = 7 - (xc & 7);
+                const int chr = src->screen[0][scroffs];
+
+                if ((src->charmem[chr][yb] >> v) & 1)
+                    *d++ = src->color[0][scroffs];
+                else
+                    *d++ = src->bgcolor;
+            }
+        }
+        else
+        {
+            // Multicolor variants
+            const int wdivisor = doubleMC ? 2 : 1;
+
+            for (xc = 0; xc < dst->width / wdivisor; xc++)
+            {
+                const int x = xc / 4;
+                const int scroffs = scroffsy + x;
+                const int v = 6 - ((xc * 2) & 6);
+                const int chr = src->screen[0][scroffs];
+                Uint8 c;
+            
+                switch ((src->charmem[chr][yb] >> v) & 3)
+                {
+                    case 0: c = src->bgcolor; break;
+                    case 1: c = src->d022; break;
+                    case 2: c = src->d023; break;
+                    case 3: c = src->color[0][scroffs];
+                }
+
+                *d++ = c;
+                if (doubleMC)
+                    *d++ = c;
+            }
+        }
+        dp += dst->pitch;
+    }
+    else
+    // Perform generic BITMAP conversion
     for (yc = 0; yc < dst->height; yc++)
     {
         Uint8 *d = dp;