Mercurial > hg > dmlib
view view64.c @ 510:43ea59887c69
Start work on making C64 formats encoding possible by changing DMDecodeOps
to DMEncDecOps and adding fields and op enums for custom encode functions, renaming,
etc. Split generic op sanity checking into a separate function in
preparation for its use in generic encoding function.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 19 Nov 2012 15:06:01 +0200 |
parents | e8e244036ee4 |
children | 6f141f760c54 |
line wrap: on
line source
/* * 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, *forced; DMC64Image image; char *windowTitle; Uint8 *dataBuf = NULL; size_t dataSize; int 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; } if ((ret = dmReadDataFile(NULL, optFilename, &dataBuf, &dataSize)) != DMERR_OK) goto error; dmMsg(1, "Read %d bytes of input.\n", dataSize); // Probe for format if (optForcedFormat >= 0) { forced = &dmC64ImageFormats[optForcedFormat]; dmMsg(0,"Forced %s format image, type %d, %s\n", forced->name, forced->type, forced->extension); } else forced = NULL; ret = dmC64DecodeBMP(&image, dataBuf, dataSize, 0, 2, &fmt, forced); if (forced == NULL && fmt != NULL) { dmMsg(0,"Probed %s format image, type %d, %s\n", fmt->name, fmt->type, fmt->extension); } if (ret < 0) { dmError("Probing could not find any matching image format (%d). Perhaps try forcing a format via -f\n", ret); return -1; } // Initialize libSDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { dmError("Could not initialize SDL: %s\n", SDL_GetError()); goto error; } 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; } // 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->convertFrom != NULL) ret = fmt->convertFrom(&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; 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; } 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: if (screen) SDL_FreeSurface(screen); if (initSDL) SDL_Quit(); return 0; }