# HG changeset patch # User Matti Hamalainen # Date 1509847492 -7200 # Node ID d6ee4dcef692d8d8d72b95354d6239dbb52a1056 # Parent 0185bf5819c051993c35e9e506185acab72c18ee Implement multi file support in view64. diff -r 0185bf5819c0 -r d6ee4dcef692 tools/view64.c --- 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 -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();