Mercurial > hg > dmlib
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; +}