Mercurial > hg > dmlib
view vview.c @ 83:6b42aed2745b
Cleanups and correct the dmf_create_stdio() issue here as well.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 02 Oct 2012 09:57:38 +0300 |
parents | daeb5d4f6bad |
children |
line wrap: on
line source
#include "dmlib.h" #include "dmargs.h" #include "dmtext.h" #define DM_COLORS (256) char *optFilename = NULL, *optFontFile = "font.ttf"; int optVFlags = SDL_SWSURFACE | SDL_HWPALETTE; int optScrWidth = 640, optScrHeight = 480, optFontSize = 20, optScrDepth = 32; BOOL optShowSurfaceInfo = FALSE; DMOptArg optList[] = { { 0, '?', "help", "Show this help", OPT_NONE }, { 2, 'v', "verbose", "Be more verbose", OPT_NONE }, { 3, 'f', "full", "Fullscreen", OPT_NONE }, { 4, 'h', "hw", "Use SDL hardware surface", OPT_NONE }, { 5, 's', "size", "Initial window size/resolution -s 640x480", OPT_ARGREQ }, { 6, 'd', "depth", "Color depth of mode/window in bits (8/15/16/32)", OPT_ARGREQ }, { 7, 'i', "info", "Print out extra information on used SDL surfaces", OPT_NONE } }; const int optListN = sizeof(optList) / sizeof(optList[0]); void argShowHelp() { dmPrintBanner(stdout, dmProgName, "[options] <datafile>"); dmArgsPrintHelp(stdout, optList, optListN); } BOOL argHandleOpt(const int optN, char *optArg, char *currArg) { switch (optN) { case 0: argShowHelp(); exit(0); break; case 2: dmVerbosity++; break; case 3: optVFlags |= SDL_FULLSCREEN; break; case 6: if (optArg) optScrDepth = atoi(optArg); break; case 7: optShowSurfaceInfo = TRUE; break; case 5: { int w, h; if (sscanf(optArg, "%dx%d", &w, &h) == 2) { if (w < 320 || h < 200 || w > 3200 || h > 3200) { dmError("Invalid width or height: %d x %d\n", w, h); return FALSE; } optScrWidth = w; optScrHeight = h; } else { dmError("Invalid size 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; } } void DM_MakePalette(SDL_Color *pal) { int n; for (n = 0; n < 64; n++) { pal[n].r = n * 2; pal[n].g = 0; pal[n].b = 0; } for (n = 64; n < 128; n++) { pal[n].r = n * 2; pal[n].g = (n - 64) * 4; pal[n].b = (n - 64) * 4; } for (n = 128; n < 192; n++) { pal[n].r = (255 - n) * 4; pal[n].g = (255 - n) * 2; pal[n].b = (255 - n) * 2; } for (n = 192; n < 256; n++) { pal[n].r = 0; pal[n].g = (255 - n) * 2; pal[n].b = (255 - n) * 2; } } void DM_CreatePaletteFrom(SDL_Color *pal, Uint8 *buf) { int n, offs; for (offs = n = 0; n < DM_COLORS; n++) { pal[n].r = buf[offs++]; pal[n].g = buf[offs++]; pal[n].b = buf[offs++]; } } void printSurface(FILE *f, SDL_Surface *s, const char *name) { if (!optShowSurfaceInfo || s == NULL) return; fprintf(f, "\nSDL_Surface[%p]: %s:\n" " flags : 0x%08x\n" " format : %p\n", s, name, s->flags, s->format); if (s->format != NULL) { SDL_PixelFormat *pf = s->format; fprintf(f, " palette : %p\n" " BitsPerPixel : %d\n" " BytesPerPixel : %d\n" " colorkey : %d (%08x)\n" " alpha : %d\n", pf->palette, pf->BitsPerPixel, pf->BytesPerPixel, pf->colorkey, pf->colorkey, pf->alpha); fprintf(f, " R/G/B/A loss : %d / %d / %d / %d\n" " R/G/B/A shift : %d / %d / %d / %d\n" " R/G/B/A mask : %08x / %08x / %08x / %08x\n", pf->Rloss , pf->Gloss , pf->Bloss , pf->Aloss, pf->Rshift , pf->Gshift , pf->Bshift , pf->Ashift, pf->Rmask , pf->Gmask , pf->Bmask , pf->Amask ); } fprintf(f, " W x H : %d x %d\n" " pitch : %d bytes\n" " pixels : %p\n\n", s->w, s->h, s->pitch, s->pixels); } BOOL DM_InitializeVideo(SDL_Surface **screen) { *screen = SDL_SetVideoMode(optScrWidth, optScrHeight, optScrDepth, optVFlags | SDL_RESIZABLE); if (*screen == NULL) { dmError("Can't SDL_SetVideoMode(): %s\n", SDL_GetError()); return FALSE; } printSurface(stdout, *screen, "screen"); return TRUE; } void DM_UnRLE(Uint8 *dst, Uint8 **udata, const Uint8 *dp, const int rleMarker, const Uint8 *de) { Uint8 *data = *udata; while (data < dp && dst < de) { int c = *data++; if ((c & rleMarker) == rleMarker) { int cnt = c & (0xff ^ rleMarker); c = *data++; while (cnt-- && dst < de) *dst++ = c; } else *dst++ = c; } *udata = data; } void DM_Redraw(SDL_Surface *screen, Uint8 *data, int skip, int useRLE, int rleMarker) { Uint8 *pix = screen->pixels; if (useRLE) { const int tmpmax = screen->w * 64; Uint8 *tmp = dmMalloc(tmpmax); const Uint8 *dp = data + (screen->w * screen->h); if (skip > tmpmax) skip = tmpmax; if (useRLE == 1) { int yc; for (yc = 0; yc < screen->h; yc++) { memset(tmp, 0xff, tmpmax); DM_UnRLE(tmp, &data, dp, rleMarker, tmp + tmpmax); memcpy(pix, tmp, screen->w); pix += screen->pitch; } } else if (useRLE == 2) { int yc; for (yc = 0; yc < screen->h; yc++) { memset(tmp, 0xff, tmpmax); DM_UnRLE(tmp, &data, dp, rleMarker, tmp + skip); memcpy(pix, tmp, screen->w); pix += screen->pitch; } } else { printf("useRLE=%d\n", useRLE); } dmFree(tmp); } else { int yc; for (yc = 0; yc < screen->h; yc++) { int xc; for (xc = 0; xc < screen->w; xc++) pix[xc] = *data++; pix += screen->pitch; } } } void DM_Random(SDL_Surface *screen, int q) { Uint8 *pix = screen->pixels; int xc, yc; for (yc = 0; yc < screen->h; yc++) { Uint8 *dp = pix; for (xc = 0; xc < screen->w; xc++) *dp++ = (xc * q + yc * q); pix += screen->pitch; } } void adjustValue(int *val, int min, int max, int delta) { *val += delta; if (*val < min) *val = min; else if (*val > max) *val = max; } int main(int argc, char *argv[]) { SDL_Color pal[256]; SDL_Surface *screen = NULL, *bmap = NULL; TTF_Font *font = NULL; SDL_Color fontcol={255,255,255,0}; SDL_Event event; Uint8 *scrData = NULL; size_t scrSize = 0; int scrWidth = 128, scrHeight = 128, scrPalOffs = 0, scrOffs = 0, scrSkip = 0; BOOL initSDL = FALSE, initTTF = FALSE, exitFlag, needRedraw, palChanged = FALSE, showTest = FALSE, useRLE = FALSE, showHex = FALSE, scrPalette = FALSE, scrChanged; // Initialize dmInitProg("vtest", "vtester", "0.1", NULL, NULL); // Parse arguments if (!dmArgsProcess(argc, argv, optList, optListN, argHandleOpt, argHandleFile, FALSE)) exit(1); if (optFilename == NULL) { dmError("No input file specified.\n"); goto error_exit; } else { FILE *f = fopen(optFilename, "rb"); if (f == NULL) { dmError("Could not open input file '%s'\n"); goto error_exit; } fseek(f, 0L, SEEK_END); scrSize = ftell(f); fseek(f, 0L, SEEK_SET); if ((scrData = malloc(scrSize)) == NULL) { fclose(f); dmError("Error allocating memory for data, %d bytes.\n", scrSize); goto error_exit; } fread(scrData, 1, scrSize, f); fclose(f); } if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { dmError("Could not initialize SDL: %s\n", SDL_GetError()); goto error_exit; } initSDL = TRUE; if (TTF_Init() < 0) { dmError("Could not initialize FreeType/TTF: %s\n", SDL_GetError()); goto error_exit; } initTTF = TRUE; font = TTF_OpenFont(optFontFile, optFontSize); if (font == NULL) { dmError("Could not load TTF font '%s' (%d): %s\n", optFontFile, optFontSize, SDL_GetError()); goto error_exit; } TTF_SetFontStyle(font, TTF_STYLE_NORMAL); if (!DM_InitializeVideo(&screen)) goto error_exit; SDL_WM_SetCaption("Halleluja", "DMT"); exitFlag = FALSE; scrChanged = palChanged = TRUE; while (!exitFlag) { while (SDL_PollEvent(&event)) switch (event.type) { case SDL_KEYDOWN: { int amount = 10; if ((event.key.keysym.mod & KMOD_CTRL)) amount = 50; if ((event.key.keysym.mod & KMOD_SHIFT)) amount = 1; switch (event.key.keysym.sym) { case SDLK_ESCAPE: exitFlag = TRUE; break; case SDLK_LEFT: adjustValue(&scrWidth, 0, 1024, -amount); scrChanged = TRUE; break; case SDLK_RIGHT: adjustValue(&scrWidth, 0, 1024, amount); scrChanged = TRUE; break; case SDLK_UP: adjustValue(&scrHeight, 0, 1024, -amount); scrChanged = TRUE; break; case SDLK_DOWN: adjustValue(&scrHeight, 0, 1024, amount); scrChanged = TRUE; break; case SDLK_F1: scrPalette = !scrPalette; palChanged = TRUE; break; case SDLK_F2: showTest = !showTest; break; case SDLK_F3: adjustValue(&scrPalOffs, 0, scrSize - 256 * 3, -amount); palChanged = TRUE; break; case SDLK_F4: adjustValue(&scrPalOffs, 0, scrSize - 256 * 3, amount); palChanged = TRUE; break; case SDLK_F5: adjustValue(&scrOffs, 0, scrSize, -amount); break; case SDLK_F6: adjustValue(&scrOffs, 0, scrSize, amount); break; case SDLK_F7: adjustValue(&scrSkip, 0, scrSize, -amount); break; case SDLK_F8: adjustValue(&scrSkip, 0, scrSize, amount); break; case SDLK_F9: showHex = !showHex; break; case SDLK_r: useRLE = (useRLE + 1) % 3; break; default: break; } } needRedraw = TRUE; break; case SDL_VIDEORESIZE: optScrWidth = event.resize.w; optScrHeight = event.resize.h; if (!DM_InitializeVideo(&screen)) goto error_exit; needRedraw = TRUE; break; case SDL_VIDEOEXPOSE: needRedraw = TRUE; break; case SDL_QUIT: exit(0); } if (scrChanged) { SDL_FreeSurface(bmap); bmap = SDL_CreateRGBSurface(SDL_SWSURFACE, scrWidth, scrHeight, 8, 0, 0, 0, 0); printSurface(stdout, bmap, "bmap"); needRedraw = TRUE; scrChanged = FALSE; palChanged = TRUE; } if (palChanged) { if (scrPalette) DM_CreatePaletteFrom(pal, scrData + scrPalOffs); else DM_MakePalette(pal); SDL_SetColors(bmap, pal, 0, DM_COLORS); palChanged = FALSE; } if (needRedraw) { if (SDL_MUSTLOCK(screen) != 0 && SDL_LockSurface(screen) != 0) { dmError("Can't lock surface.\n"); goto error_exit; } dmClearSurface(screen, dmMapRGB(screen, 255, 255, 150)); dmFillRect(screen, 0, 0, screen->w, TTF_FontHeight(font) + 10, dmMapRGB(screen, 50, 50, 150)); dmDrawTTFText(screen, font, fontcol, 5, 5, "%3d x %3d @ 0x%08x, skip=%d/0x%x", scrWidth, scrHeight, scrOffs, scrSkip, scrSkip); dmFillRect(screen, 0, screen->h - TTF_FontHeight(font) - 10, screen->w, screen->h, dmMapRGB(screen, 150, 50, 50)); if (scrPalette) { dmDrawTTFText(screen, font, fontcol, 5, screen->h - TTF_FontHeight(font) - 5, "Palette offset 0x%08x/%08x", scrPalOffs, scrSize); } else { dmDrawTTFText(screen, font, fontcol, 5, screen->h - TTF_FontHeight(font) - 5, "Generated palette."); } dmDrawTTFText(screen, font, fontcol, 450, screen->h - TTF_FontHeight(font) - 5, "useRLE=%d", useRLE); if (showTest) DM_Random(bmap, SDL_GetTicks() / 100); else DM_Redraw(bmap, scrData + scrOffs, scrSkip, useRLE, 0xc0); // float f = SDL_GetTicks() / 200.0f; // dmScaledBlitSurfaceAny(bmap, sin(f) * 50, 40, screen->w + 100 * cos(f), screen->h - 80, screen, DMD_NONE); dmScaledBlitSurfaceAny(bmap, 5, 40, screen->w - 10, screen->h - 80, screen, DMD_NONE); if (showHex) { int w = 350, h = screen->h - 50; int i, x = screen->w - w, y = 25; int fh = TTF_FontHeight(font); dmFillRect(screen, screen->w - 350, - 5, w, h, dmMapRGB(screen, 50, 50, 50)); dmDrawTTFText(screen, font, fontcol, x, y, "Palette hexdump"); y += fh + 5; for (i = 0; i < 16; i++) { int offs = scrPalOffs + i * 3; dmDrawTTFText(screen, font, fontcol, x, y + fh * i, "%04x: %02x %02x %02x | '%c' '%c' '%c'", offs, scrData[offs], scrData[offs+1], scrData[offs+2], scrData[offs], scrData[offs+1], scrData[offs+2]); } } if (SDL_MUSTLOCK(screen) != 0) SDL_UnlockSurface(screen); SDL_Flip(screen); needRedraw = FALSE; } SDL_Delay(10); } error_exit: if (screen) SDL_FreeSurface(screen); if (font) TTF_CloseFont(font); if (initSDL) SDL_Quit(); if (initTTF) TTF_Quit(); return 0; }