changeset 1414:d6ee4dcef692

Implement multi file support in view64.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 05 Nov 2017 04:04:52 +0200
parents 0185bf5819c0
children 1e4fb7c5527f
files tools/view64.c
diffstat 1 files changed, 182 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/tools/view64.c	Sun Nov 05 03:53:03 2017 +0200
+++ b/tools/view64.c	Sun Nov 05 04:04:52 2017 +0200
@@ -12,11 +12,12 @@
 #include <SDL.h>
 
 
-char * optFilename = NULL;
 int    optVFlags = SDL_SWSURFACE | SDL_HWPALETTE;
 int    optScrWidth, optScrHeight;
 int    optForcedFormat = -1;
 BOOL   optProbeOnly = FALSE;
+size_t noptFilenames1 = 0, noptFilenames2 = 0;
+char   **optFilenames = NULL;
 
 
 static const DMOptArg optList[] =
@@ -130,18 +131,24 @@
 }
 
 
-BOOL argHandleFile(char *filename)
+BOOL argHandleFile1(char *filename)
 {
-    if (optFilename == NULL)
+    (void) filename;
+
+    noptFilenames1++;
+    return TRUE;
+}
+
+
+BOOL argHandleFile2(char *filename)
+{
+    if (noptFilenames2 < noptFilenames1)
     {
-        optFilename = dm_strdup(filename);
+        optFilenames[noptFilenames2++] = filename;
         return TRUE;
     }
     else
-    {
-        dmErrorMsg("Too many filenames specified ('%s')\n", filename);
         return FALSE;
-    }
 }
 
 
@@ -157,7 +164,7 @@
 }
 
 
-void dmDumpC64Image(const size_t size, const DMC64Image *img, const DMC64ImageFormat *fmt)
+void dmDumpC64Image(const char *filename, const DMC64Image *img, const DMC64ImageFormat *fmt)
 {
     char typeStr[64];
 
@@ -170,12 +177,12 @@
         );
 
     dmPrint(1,
+        "\n%s\n"
         "Format              : %s [%s]\n"
-        "Data size           : %" DM_PRIu_SIZE_T "\n"
         "Type                : %s\n"
         "Banks               : %d\n",
+        filename,
         fmt->name, fmt->fext,
-        size,
         typeStr,
         img->nbanks);
 
@@ -201,40 +208,80 @@
 }
 
 
+int dmReadC64Image(const char *filename, const DMC64ImageFormat *forced, const DMC64ImageFormat **fmt, DMC64Image **cimage)
+{
+    Uint8 *dataBuf = NULL;
+    size_t dataSize;
+    int ret;
+
+    if ((ret = dmReadDataFile(NULL, filename, &dataBuf, &dataSize)) != DMERR_OK)
+        goto exit;
+
+    ret = dmC64DecodeBMP(cimage, dataBuf, dataSize, 0, 2, fmt, forced);
+
+exit:
+    dmFree(dataBuf);
+    return ret;
+}
+
+
+int dmDecodeC64Image(const DMC64Image *cimage, const DMC64ImageFormat *fmt, SDL_Surface *surf)
+{
+    DMImage bmap;
+    int ret;
+
+    bmap.size = surf->pitch * cimage->height;
+    bmap.data = surf->pixels;
+    bmap.pitch = surf->pitch;
+    bmap.width = cimage->width;
+    bmap.height = cimage->height;
+    bmap.constpal = TRUE;
+
+    if (fmt->convertFrom != NULL)
+        ret = fmt->convertFrom(&bmap, cimage, fmt);
+    else
+        ret = dmC64ConvertGenericBMP2Image(&bmap, cimage, fmt);
+
+    return ret;
+}
+
+
 int main(int argc, char *argv[])
 {
     SDL_Surface *screen = NULL, *surf = NULL;
-    DMImage bmap;
     BOOL initSDL = FALSE, exitFlag, needRedraw;
-    const DMC64ImageFormat *fmt = NULL, *forced;
-    DMC64Image *cimage = NULL;
-    char *windowTitle;
-    Uint8 *dataBuf = NULL;
-    size_t dataSize;
+    const DMC64ImageFormat *forced;
+    size_t currIndex, prevIndex;
     int ret;
 
     dmSetScaleFactor(2.0);
 
     dmInitProg("view64", "Display some C64 bitmap graphics formats", "0.2", NULL, NULL);
 
-    /* Parse arguments */
+    // Parse arguments, round #1
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, OPTH_BAILOUT))
+        argHandleOpt, argHandleFile1, OPTH_BAILOUT))
         exit(1);
 
-
-    if (optFilename == NULL)
+    if (noptFilenames1 == 0)
     {
-        dmErrorMsg("No input file specified, perhaps you need some --help\n");
+        dmErrorMsg("No input file(s) specified, perhaps you need some --help\n");
         goto exit;
     }
 
-    dmPrint(1, "\n%s\n", optFilename);
-    if ((ret = dmReadDataFile(NULL, optFilename, &dataBuf, &dataSize)) != DMERR_OK)
+    // Allocate space for filename pointers
+    if ((optFilenames = dmCalloc(noptFilenames1, sizeof(char *))) == NULL)
+    {
+        dmErrorMsg("Could not allocate memory for input file list.\n");
+        goto exit;
+    }
+
+    // Assign the filename pointers
+    if (!dmArgsProcess(argc, argv, optList, optListN,
+        NULL, argHandleFile2, OPTH_BAILOUT | OPTH_ONLY_OTHER))
         goto exit;
 
-
-    // Probe for format
+    // Check for forced input format
     if (optForcedFormat >= 0)
     {
         forced = &dmC64ImageFormats[optForcedFormat];
@@ -244,25 +291,30 @@
     else
         forced = NULL;
 
-    ret = dmC64DecodeBMP(&cimage, dataBuf, dataSize, 0, 2, &fmt, forced);
+    // If we are simply probing, no need to initialize SDL etc
+    if (optProbeOnly)
+    {
+        for (size_t n = 0; n < noptFilenames2; n++)
+        {
+            char *filename = optFilenames[n];
+            const DMC64ImageFormat *fmt = NULL;
+            DMC64Image *cimage = NULL;
 
-    if (ret != DMERR_OK)
-    {
-        dmErrorMsg("Failed to decode bitmap data %d: %s\n", ret, dmErrorStr(ret));
+            if ((ret = dmReadC64Image(filename, forced, &fmt, &cimage)) != DMERR_OK)
+            {
+                dmErrorMsg("Could not read image file '%s', %d: %s\n",
+                    filename, ret, dmErrorStr(ret));
+            }
+            else
+            {
+                dmDumpC64Image(filename, cimage, fmt);
+            }
+
+            dmC64ImageFree(cimage);
+        }
         goto exit;
     }
 
-    if (fmt == NULL)
-    {
-        dmErrorMsg("Probing could not find any matching image format. Perhaps try forcing a format via -f.\n");
-        goto exit;
-    }
-
-    dmDumpC64Image(dataSize, cimage, fmt);
-
-    if (optProbeOnly)
-        goto exit;
-
     // Initialize libSDL
     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
     {
@@ -280,39 +332,9 @@
         goto exit;
     }
 
-    // Create surface (we are lazy and ugly)
-    surf = SDL_CreateRGBSurface(SDL_SWSURFACE, cimage->width, cimage->height, 8, 0, 0, 0, 0);
-    SDL_SetColors(surf, (SDL_Color *)dmC64Palette, 0, C64_NCOLORS);
-    SDL_SetColors(screen, (SDL_Color *)dmC64Palette, 0, C64_NCOLORS);
-
-    // Convert bitmap (this is a bit ugly and lazy here)
-    bmap.size = surf->pitch * surf->h;
-    bmap.data = surf->pixels;
-    bmap.pitch = surf->pitch;
-    bmap.width = surf->w;
-    bmap.height = surf->h;
-    bmap.constpal = TRUE;
-
-    if (fmt->convertFrom != NULL)
-        ret = fmt->convertFrom(&bmap, cimage, fmt);
-    else
-        ret = dmC64ConvertGenericBMP2Image(&bmap, cimage, fmt);
-
-    if (ret != DMERR_OK)
-    {
-        dmErrorMsg("Failed to convert bitmap data %d: %s\n", ret, dmErrorStr(ret));
-        goto exit;
-    }
-
-    // Set window title and caption
-    windowTitle = dm_strdup_printf("%s - %s (%d x %d)",
-        dmProgName, optFilename, cimage->width, cimage->height);
-
-    SDL_WM_SetCaption(windowTitle, dmProgName);
-    dmFree(windowTitle);
-
-
     // Start main loop
+    currIndex = 0;
+    prevIndex = 1;
     needRedraw = TRUE;
     exitFlag = FALSE;
     while (!exitFlag)
@@ -324,7 +346,19 @@
             case SDL_KEYDOWN:
                 switch (event.key.keysym.sym)
                 {
-                    case SDLK_ESCAPE: exitFlag = TRUE; break;
+                    case SDLK_ESCAPE:
+                        exitFlag = TRUE;
+                        break;
+
+                    case SDLK_LEFT:
+                        if (currIndex > 0)
+                            currIndex--;
+                        break;
+
+                    case SDLK_RIGHT:
+                        if (currIndex < noptFilenames2)
+                            currIndex++;
+                        break;
 
                     default:
                         break;
@@ -350,9 +384,76 @@
                 exit(0);
         }
 
+        if (currIndex != prevIndex)
+        {
+            char *filename = optFilenames[currIndex];
+            const DMC64ImageFormat *fmt = NULL;
+            DMC64Image *cimage = NULL;
+            char *title;
+
+            if (surf != NULL)
+            {
+                SDL_FreeSurface(surf);
+                surf = NULL;
+            }
+
+            if ((ret = dmReadC64Image(filename, forced, &fmt, &cimage)) != DMERR_OK)
+            {
+                dmErrorMsg("Failed to decode bitmap data %d: %s\n", ret, dmErrorStr(ret));
+                goto fail;
+            }
+
+            if (fmt == NULL)
+            {
+                dmErrorMsg("Probing could not find any matching image format. Perhaps try forcing a format via -f.\n");
+                goto fail;
+            }
+
+            // Create surface (we are lazy and ugly)
+            if ((surf = SDL_CreateRGBSurface(SDL_SWSURFACE, cimage->width, cimage->height, 8, 0, 0, 0, 0)) == NULL)
+            {
+                dmErrorMsg("Could not allocate surface.\n");
+                goto exit;
+            }
+
+            SDL_SetColors(surf, (SDL_Color *)dmC64Palette, 0, C64_NCOLORS);
+
+            if (dmDecodeC64Image(cimage, fmt, surf) == DMERR_OK)
+            {
+                title = dm_strdup_printf("%s - %s (%d x %d) [%d / %d]",
+                    dmProgName, filename,
+                    cimage->width, cimage->height,
+                    currIndex + 1, noptFilenames2);
+
+                dmDumpC64Image(filename, cimage, fmt);
+            }
+            else
+            {
+                title = dm_strdup_printf("%s [%d / %d]",
+                    dmProgName,
+                    currIndex + 1, noptFilenames2);
+            }
+
+            if (title != NULL)
+            {
+                SDL_WM_SetCaption(title, dmProgName);
+                dmFree(title);
+            }
+
+fail:
+            if (surf == NULL && (surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 200, 8, 0, 0, 0, 0)) == NULL)
+            {
+                dmErrorMsg("Could not allocate surface.\n");
+                goto exit;
+            }
+
+            needRedraw = TRUE;
+            prevIndex = currIndex;
+        }
+
         if (needRedraw)
         {
-            float aspect = (float) bmap.height / (float) bmap.width;
+            float aspect = (float) surf->h / (float) surf->w;
             int sheight = optScrHeight / aspect;
             int ypos = (optScrHeight - sheight) / 2;
 
@@ -372,15 +473,19 @@
             needRedraw = FALSE;
         }
 
-        SDL_Delay(100);
+        SDL_Delay(50);
     }
 
 exit:
-    dmC64ImageFree(cimage);
+    // Cleanup
+    dmFree(optFilenames);
 
-    if (screen)
+    if (screen != NULL)
         SDL_FreeSurface(screen);
 
+    if (surf != NULL)
+        SDL_FreeSurface(surf);
+
     if (initSDL)
         SDL_Quit();