diff view64.c @ 407:59244a7ae37f

Move c64 utilities to the engine lib, as we benefit from a common framework.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 03 Nov 2012 02:19:51 +0200
parents
children 936bc27a79d6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/view64.c	Sat Nov 03 02:19:51 2012 +0200
@@ -0,0 +1,348 @@
+/*
+ * view64 - Display some C64 etc graphics formats via libSDL
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2012 Tecnic Software productions (TNSP)
+ *
+ * Please read file 'COPYING' for information on license and distribution.
+ */
+#include "dmlib.h"
+#include "dmargs.h"
+#include "dmfile.h"
+#include "lib64gfx.h"
+#include <SDL.h>
+
+
+char * optFilename = NULL;
+int    optVFlags = SDL_SWSURFACE | SDL_HWPALETTE;
+int    optScrWidth, optScrHeight;
+int    optForcedFormat = -1;
+
+
+static DMOptArg optList[] =
+{
+    { 0, '?', "help",       "Show this help", OPT_NONE },
+    { 1, 'v', "verbose",    "Be more verbose", OPT_NONE },
+    { 2,   0, "fs",         "Fullscreen", OPT_NONE },
+    { 3, 'S', "scale",      "Scale image by factor (1-10)", OPT_ARGREQ },
+    { 4, 'f', "format",     "Force input format (see list below)", OPT_ARGREQ },
+};
+
+const int optListN = sizeof(optList) / sizeof(optList[0]);
+
+
+void dmSetScaleFactor(float factor)
+{
+    optScrWidth = (int) ((float) C64_SCR_WIDTH * factor * C64_SCR_PAR_XY);
+    optScrHeight = (int) ((float) C64_SCR_HEIGHT * factor);
+}
+
+
+void argShowHelp()
+{
+    int i;
+
+    dmPrintBanner(stdout, dmProgName, "[options] <input image file>");
+    dmArgsPrintHelp(stdout, optList, optListN);
+
+    printf("\nAvailable bitmap formats:\n");
+    for (i = 0; i < ndmC64ImageFormats; i++)
+    {
+        DMC64ImageFormat *fmt = &dmC64ImageFormats[i];
+        printf("%3d | %-5s | %-15s | %s\n",
+            i, fmt->extension,
+            dmC64ImageTypeNames[fmt->type],
+            fmt->name);
+    }
+}
+
+
+BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
+{
+    switch (optN)
+    {
+        case 0:
+            argShowHelp();
+            exit(0);
+            break;
+
+        case 1:
+            dmVerbosity++;
+            break;
+        
+        case 2:
+            optVFlags |= SDL_FULLSCREEN;
+            break;
+
+        case 3:
+            {
+                float factor;
+                if (sscanf(optArg, "%f", &factor) == 1)
+                {
+                    if (factor < 1 || factor >= 10)
+                    {
+                        dmError("Invalid scale factor %1.0f, see help for valid values.\n", factor);
+                        return FALSE;
+                    }
+
+                    dmSetScaleFactor(factor);
+                }
+                else
+                {
+                    dmError("Invalid scale factor '%s'.\n", optArg);
+                    return FALSE;
+                }
+            }
+            break;
+
+        case 4:
+            {
+                int i;
+                if (sscanf(optArg, "%d", &i) == 1)
+                {
+                    if (i < 0 || i >= ndmC64ImageFormats)
+                    {
+                        dmError("Invalid image format index %d, see help for valid values.\n", i);
+                        return FALSE;
+                    }
+                    optForcedFormat = i;
+                }
+                else
+                {
+                    dmError("Invalid image format argument '%s'.\n", optArg);
+                    return FALSE;
+                }
+            }
+            break;
+        
+        default:
+            dmError("Unknown option '%s'.\n", currArg);
+            return FALSE;
+    }
+    
+    return TRUE;
+}
+
+
+BOOL argHandleFile(char *filename)
+{
+    if (optFilename == NULL)
+    {
+        optFilename = dm_strdup(filename);
+        return TRUE;
+    }
+    else
+    {
+        dmError("Too many filenames specified ('%s')\n", filename);
+        return FALSE;
+    }
+}
+
+
+BOOL dmInitializeVideo(SDL_Surface **screen)
+{
+    *screen = SDL_SetVideoMode(optScrWidth, optScrHeight, 8, optVFlags | SDL_RESIZABLE);
+    if (*screen == NULL)
+    {
+        dmError("Can't SDL_SetVideoMode(): %s\n", SDL_GetError());
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+int main(int argc, char *argv[])
+{
+    SDL_Surface *screen = NULL, *surf = NULL;
+    DMImage bmap;
+    BOOL initSDL = FALSE, exitFlag, needRedraw;
+    DMC64ImageFormat *fmt;
+    DMC64Image image;
+    char *windowTitle;
+    Uint8 *dataBuf = NULL;
+    size_t dataSize;
+    int i, ret;
+
+    dmSetScaleFactor(2.0);
+    
+    dmInitProg("view64", "Display some C64 bitmap graphics formats", "0.2", NULL, NULL);
+
+    /* Parse arguments */
+    if (!dmArgsProcess(argc, argv, optList, optListN,
+        argHandleOpt, argHandleFile, FALSE))
+        exit(1);
+
+
+    if (optFilename == NULL)
+    {
+        dmError("No input file specified, perhaps you need some --help\n");
+        goto error_exit;
+    }
+        
+    if (dmReadDataFile(optFilename, &dataBuf, &dataSize) != 0)
+        goto error_exit;
+
+    // Probe for format
+    if (optForcedFormat >= 0)
+    {
+        fmt = &dmC64ImageFormats[optForcedFormat];
+        dmMsg(0,"Forced %s format image, type %d, %s\n", fmt->name, fmt->type, fmt->extension);
+
+        if (fmt->decode != NULL)
+            ret = fmt->decode(&image, dataBuf + 2, dataSize - 2, fmt);
+        else
+            ret = dmC64DecodeGenericBMP(&image, dataBuf + 2, dataSize - 2, fmt);
+
+        if (ret < 0)
+        {
+            dmError("Error decoding image format.\n");
+            return -1;
+        }
+    }
+    else
+    {
+        BOOL found = FALSE;
+        for (i = 0; i < ndmC64ImageFormats; i++)
+        {
+            fmt = &dmC64ImageFormats[i];
+            ret = fmt->probe(dataBuf, dataSize);
+            if (ret > 0)
+            {
+                dmMsg(0,"Probed %s format image, type %d, %s\n", fmt->name, fmt->type, fmt->extension);
+                if (fmt->decode != NULL)
+                    ret = fmt->decode(&image, dataBuf + 2, dataSize - 2, fmt);
+                else
+                    ret = dmC64DecodeGenericBMP(&image, dataBuf + 2, dataSize - 2, fmt);
+
+                if (ret < 0)
+                {
+                    dmError("Error decoding image format.\n");
+                    return -1;
+                }
+                
+                found = TRUE;
+                break;
+            }
+            else
+            if (ret < 0)
+            {
+                dmError("Error in probing.\n");
+            }
+        }
+        if (!found)
+        {
+            dmError("Probing could not find any matching image format. Perhaps try forcing a format via -f\n");
+            return -2;
+        }
+    }
+
+    // Initialize libSDL
+    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
+    {
+        dmError("Could not initialize SDL: %s\n", SDL_GetError());
+        goto error_exit;
+    }
+    initSDL = TRUE;
+
+
+    // Open window/set video mode
+    screen = SDL_SetVideoMode(optScrWidth, optScrHeight, 8, optVFlags | SDL_RESIZABLE);
+    if (screen == NULL)
+    {
+        dmError("Can't SDL_SetVideoMode(): %s\n", SDL_GetError());
+        goto error_exit;
+    }
+
+    // Create surface (we are lazy and ugly)
+    surf = SDL_CreateRGBSurface(SDL_SWSURFACE, C64_SCR_WIDTH, C64_SCR_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.data = surf->pixels;
+    bmap.pitch = surf->pitch;
+    bmap.width = surf->w;
+    bmap.height = surf->h;
+    bmap.constpal = TRUE;
+
+    if (fmt->convert != NULL)
+        ret = fmt->convert(&bmap, &image);
+    else
+        ret = dmC64ConvertGenericBMP2Image(&bmap, &image);
+
+
+    // Set window title and caption
+    windowTitle = dm_strdup_printf("%s - %s", dmProgName, optFilename);
+    SDL_WM_SetCaption(windowTitle, dmProgName);
+    dmFree(windowTitle);
+
+
+    // Start main loop
+    needRedraw = TRUE;
+    exitFlag = FALSE;
+    while (!exitFlag)
+    {
+        SDL_Event event;
+        while (SDL_PollEvent(&event))
+        switch (event.type)
+        {
+            case SDL_KEYDOWN:
+                switch (event.key.keysym.sym)
+                {
+                    case SDLK_ESCAPE: exitFlag = TRUE; break;
+                    
+                    default:
+                        break;
+                }
+
+                needRedraw = TRUE;
+                break;
+            
+            case SDL_VIDEORESIZE:
+                optScrWidth = event.resize.w;
+                optScrHeight = event.resize.h;
+
+                if (!dmInitializeVideo(&screen))
+                    goto error_exit;
+
+                needRedraw = TRUE;
+                break;
+            
+            case SDL_VIDEOEXPOSE:
+                needRedraw = TRUE;
+                break;
+
+            case SDL_QUIT:
+                exit(0);
+        }
+        
+        if (needRedraw)
+        {
+            if (SDL_MUSTLOCK(screen) != 0 && SDL_LockSurface(screen) != 0)
+            {
+                dmError("Can't lock surface.\n");
+                goto error_exit;
+            }
+            
+            dmScaledBlitSurface8to8(surf, 0, 0, screen->w, screen->h, screen);
+            SDL_SetColors(screen, (SDL_Color *)dmC64Palette, 0, C64_NCOLORS);
+
+            if (SDL_MUSTLOCK(screen) != 0)
+                SDL_UnlockSurface(screen);
+
+            SDL_Flip(screen);
+            needRedraw = FALSE;
+        }
+        
+        SDL_Delay(100);
+    }
+
+
+error_exit:
+    if (screen)
+        SDL_FreeSurface(screen);
+
+    if (initSDL)
+        SDL_Quit();
+
+    return 0;
+}