Mercurial > hg > dmlib
view dmsimple.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 | e1c984404b6b |
children | 8a98037c5cf7 |
line wrap: on
line source
#include <SDL.h> #include "dmengine.h" #include "dmargs.h" static DMEngineData engine; static DMOptArg optList[] = { { 0, '?', "help", "Show this help", OPT_NONE }, { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, { 2, 'f', "fs", "Fullscreen", OPT_NONE }, }; const int optListN = sizeof(optList) / sizeof(optList[0]); static void argShowHelp() { dmPrintBanner(stdout, dmProgName, "[options]"); dmArgsPrintHelp(stdout, optList, optListN); } static BOOL argHandleOpt(const int optN, char *optArg, char *currArg) { (void) optArg; switch (optN) { case 0: argShowHelp(); exit(0); break; case 1: dmVerbosity++; break; case 2: engine.optVFlags |= SDL_FULLSCREEN; break; default: dmError("Unknown option '%s'.\n", currArg); return FALSE; } return TRUE; } static void engineAudioCallback(void *userdata, Uint8 *stream, int len) { (void) userdata; if (engine.paused) { memset(stream, 0, len); } else #ifdef DM_USE_JSS { if (engine.dev != NULL) jvmRenderAudio(engine.dev, stream, len / jvmGetSampleSize(engine.dev)); } #endif #ifdef DM_USE_TREMOR if (engine.audioPos + len >= engine.audioRes->rdataSize) { engine.exitFlag = TRUE; } else { memcpy(stream, engine.audioRes->rdata + engine.audioPos, len); engine.audioPos += len; } #endif } static int engineShowProgress(int loaded, int total) { int dx = 60, dh = 20, dw = engine.screen->w - (2 * dx), dy = (engine.screen->h - dh) / 2; if (SDL_MUSTLOCK(engine.screen) != 0 && SDL_LockSurface(engine.screen) != 0) return DMERR_INIT_FAIL; // Draw the progress bar dmClearSurface(engine.screen, dmMapRGBA(engine.screen, 0,0,0,0)); dmFillRect(engine.screen, dx, dy, dx+dw, dy+dh, dmMapRGB(engine.screen, 255,255,255)); dmFillRect(engine.screen, dx+1, dy+1, dx+dw-1, dy+dh-1, dmMapRGB(engine.screen, 0,0,0)); if (total > 0) { dmFillRect(engine.screen, dx+3, dy+3, dx + 3 + ((dw - 3) * loaded) / total, dy + dh - 3, dmMapRGB(engine.screen, 200,200,200)); } // Flip screen if (SDL_MUSTLOCK(engine.screen) != 0) SDL_UnlockSurface(engine.screen); SDL_Flip(engine.screen); return DMERR_OK; } static int engineLoadResources() { int err, loaded, total; err = dmres_preload(engine.resources, TRUE, &loaded, &total); while ((err = dmres_preload(engine.resources, FALSE, &loaded, &total)) == DMERR_PROGRESS) { // Show a nice progress bar while loading if (total > 0 && (loaded % 2) == 0) { if ((err = engineShowProgress(loaded, total)) != DMERR_OK) return err; } } return err; } static BOOL engineInitializeVideo() { dmPrint(1, "Initializing SDL video %d x %d x %dbpp, flags=0x%08x\n", engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, engine.optVFlags); SDL_FreeSurface(engine.screen); engine.screen = SDL_SetVideoMode(engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, engine.optVFlags); if (engine.screen == NULL) { dmError("Can't SDL_SetVideoMode(): %s\n", SDL_GetError()); return FALSE; } return TRUE; } int main(int argc, char *argv[]) { int err; BOOL initSDL = FALSE; memset(&engine, 0, sizeof(engine)); // Pre-initialization if ((err = demoPreInit(&engine)) != DMERR_OK) goto error_exit; if (!dmArgsProcess(argc, argv, optList, optListN, argHandleOpt, NULL, FALSE)) return DMERR_INIT_FAIL; dmPrint(0, "%s\n" "%s\n" "TNSP simple demoengine initializing.\n", dmProgDesc, dmProgAuthor); dmPrint(0, "Using libSDL, " #ifdef DM_USE_TREMOR "Tremor Vorbis codec" #endif #ifdef DM_USE_PACKFS ", zlib and modified stb_image.\n" #else " and modified stb_image.\n" #endif "See README.txt for more information.\n"); // Initialize resource subsystem dmPrint(1, "Initializing resources subsystem.\n"); if ((err = dmres_init(&engine.resources, engine.optPackFilename, engine.optDataPath, engine.optResFlags, engineClassifier)) != DMERR_OK) { dmError("Could not initialize resource manager: %d, %s.\n", err, dmErrorStr(err)); goto error_exit; } // Initialize SDL components dmPrint(1, "Initializing libSDL.\n"); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) != 0) { dmError("Could not initialize SDL: %s\n", SDL_GetError()); goto error_exit; } initSDL = TRUE; // Initialize audio parts if (engine.optAfmt.freq == 0 && engine.optAfmt.channels == 0) { // Defaults, if none seem to be set engine.optAfmt.freq = 44100; engine.optAfmt.format = AUDIO_S16SYS; engine.optAfmt.channels = 2; engine.optAfmt.samples = engine.optAfmt.freq / 16; } #ifdef DM_USE_JSS jssInit(); switch (engine.optAfmt.format) { case AUDIO_S16SYS: engine.jss_format = JSS_AUDIO_S16; break; case AUDIO_U16SYS: engine.jss_format = JSS_AUDIO_U16; break; case AUDIO_S8: engine.jss_format = JSS_AUDIO_S8; break; case AUDIO_U8: engine.jss_format = JSS_AUDIO_U8; break; } dmPrint(1, "Initializing miniJSS mixer with fmt=%d, chn=%d, freq=%d\n", engine.jss_format, engine.optAfmt.channels, engine.optAfmt.freq); if ((engine.dev = jvmInit(engine.jss_format, engine.optAfmt.channels, engine.optAfmt.freq, JMIX_AUTO)) == NULL) { dmError("jvmInit() returned NULL, voi perkele.\n"); goto error_exit; } if ((engine.plr = jmpInit(engine.dev)) == NULL) { dmError("jmpInit() returned NULL\n"); goto error_exit; } #endif // Initialize SDL audio dmPrint(1, "Trying to init SDL audio with: fmt=%d, chn=%d, freq=%d\n", engine.optAfmt.format, engine.optAfmt.channels, engine.optAfmt.freq); engine.optAfmt.callback = engineAudioCallback; if (SDL_OpenAudio(&engine.optAfmt, NULL) < 0) { dmError("Couldn't open SDL audio: %s\n", SDL_GetError()); goto error_exit; } // Initialize SDL video if (engine.demoInitPreVideo != NULL && (err = engine.demoInitPreVideo(&engine)) != DMERR_OK) { dmError("demoInitPreVideo() failed, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } if (!engineInitializeVideo()) goto error_exit; SDL_ShowCursor(SDL_DISABLE); SDL_WM_SetCaption(dmProgDesc, dmProgName); if (engine.demoInitPostVideo != NULL && (err = engine.demoInitPostVideo(&engine)) != DMERR_OK) { dmError("demoInitPostVideo() failed, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } // Load resources dmPrint(1, "Loading resources, please wait...\n"); if ((err = engineLoadResources()) != DMERR_OK) { dmError("Error loading resources, %d: %s.\n", err, dmErrorStr(err)); goto error_exit; } // Final initializations if ((err = engine.demoInit(&engine)) != DMERR_OK) { dmError("Failure in demoInit(), %d: %s\n", err, dmErrorStr(err)); goto error_exit; } // Initialize effects if ((err = engineInitializeEffects(&engine)) != DMERR_OK) { dmError("Effects initialization failed, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } // Use a timeline, if set if (engine.timeline != NULL) { if ((err = dmLoadTimeline(engine.timeline, &engine.tl)) != DMERR_OK) { dmError("Error loading timeline, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } if ((err = dmPrepareTimeline(engine.tl, engine.ptl)) != DMERR_OK) { dmError("Error creating prepared timeline, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } } dmPrint(1, "Starting up.\n"); SDL_LockAudio(); SDL_PauseAudio(0); SDL_UnlockAudio(); engine.startTime = SDL_GetTicks(); while (!engine.exitFlag) { while (SDL_PollEvent(&engine.event)) switch (engine.event.type) { case SDL_KEYDOWN: switch (engine.event.key.keysym.sym) { case SDLK_ESCAPE: engine.exitFlag = TRUE; break; case SDLK_SPACE: engine.pauseFlag = !engine.pauseFlag; break; case SDLK_f: engine.optVFlags ^= SDL_FULLSCREEN; if (!engineInitializeVideo()) goto error_exit; break; case SDLK_RETURN: if (engine.event.key.keysym.mod & KMOD_ALT) { engine.optVFlags ^= SDL_FULLSCREEN; if (!engineInitializeVideo()) goto error_exit; } break; default: break; } break; case SDL_VIDEOEXPOSE: break; case SDL_QUIT: engine.exitFlag = TRUE; break; } // Draw frame engine.frameTime = SDL_GetTicks(); if (engine.pauseFlag != engine.paused) { engine.paused = engine.pauseFlag; engine.pauseTime = engineGetTick(&engine); } if (engine.paused) { engine.startTime = engine.frameTime - engine.pauseTime; } if (SDL_MUSTLOCK(engine.screen) != 0 && SDL_LockSurface(engine.screen) != 0) { dmError("Can't lock surface.\n"); goto error_exit; } // Call main tick if (engine.demoRender != NULL) { if ((err = engine.demoRender(&engine)) != DMERR_OK) goto error_exit; } else { if ((err = dmExecuteTimeline(engine.ptl, engine.screen, engineGetTick(&engine))) != DMERR_OK) goto error_exit; } // Flip screen if (SDL_MUSTLOCK(engine.screen) != 0) SDL_UnlockSurface(engine.screen); SDL_Flip(engine.screen); SDL_Delay(engine.paused ? 100 : 20); engine.frameCount++; } // Print benchmark results engine.endTime = SDL_GetTicks(); dmPrint(1, "%d frames in %d ms, fps = %1.3f\n", engine.frameCount, engine.endTime - engine.startTime, (float) (engine.frameCount * 1000.0f) / (float) (engine.endTime - engine.startTime)); error_exit: dmPrint(1, "Shutting down.\n"); SDL_ShowCursor(SDL_ENABLE); if (engine.screen) SDL_FreeSurface(engine.screen); SDL_LockAudio(); SDL_PauseAudio(1); #ifdef DM_USE_JSS jmpClose(engine.plr); jvmClose(engine.dev); jssClose(); #endif SDL_UnlockAudio(); dmFreeTimeline(engine.tl); dmFreePreparedTimelineData(engine.ptl); engineShutdownEffects(&engine); dmres_close(engine.resources); if (engine.demoShutdown != NULL) engine.demoShutdown(&engine); if (initSDL) SDL_Quit(); if (engine.demoQuit != NULL) engine.demoQuit(&engine); return 0; }