Mercurial > hg > dmlib
changeset 32:d1a6833a5d67
Added a simple demo engine core.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 29 Sep 2012 16:59:46 +0300 |
parents | 7ad2c6b57932 |
children | b2fe4301384d |
files | Makefile.gen dmsimple.c dmsimple.h |
diffstat | 3 files changed, 418 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.gen Sat Sep 29 08:42:15 2012 +0300 +++ b/Makefile.gen Sat Sep 29 16:59:46 2012 +0300 @@ -170,7 +170,8 @@ DMLIB_A=$(OBJPATH)dmlib.a DMLIB_OBJS += dmfile.o dmlib.o dmlerp.o dmstring.o \ - dmargs.o dmvecmat.o dmperlin.o dmimage.o dmres.o + dmargs.o dmvecmat.o dmperlin.o dmimage.o dmres.o \ + dmsimple.o ifeq ($(DM_BUILD_TESTS),yes) BINARIES += vecmattest fptest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmsimple.c Sat Sep 29 16:59:46 2012 +0300 @@ -0,0 +1,352 @@ +#include "dmsimple.h" + + +DMEngineData engine; +DMFrameData frame; + + +int engineLoadResources() +{ + int err, loaded, total; + + err = dmres_preload(TRUE, &loaded, &total); + + while ((err = dmres_preload(FALSE, &loaded, &total)) == DMERR_PROGRESS) + { + // Show a nice progress bar while loading + if (total > 0 && (loaded % 2) == 0) + { + 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 err; +} + + +int engineGetTick() +{ + return (frame.startTime - engine.startTime) + engine.debugTime * 1000; +} + + +float engineGetTimeDT() +{ + return (float) engineGetTick() / 1000.0f; +} + + +int engineGetTimeDTi() +{ + return (float) engineGetTick() / 1000; +} + + +int engineGetTime(int t) +{ + return engineGetTick() - (1000 * t);; +} + + +int engineGetDT(int t) +{ + return engineGetTime(t) / 1000; +} + + +static int engineResImageLoad(DMResource *res) +{ + SDL_Surface *img = dmLoadImage(res); + if (res != NULL) + { + res->rdata = img; + return DMERR_OK; + } + else + return dmferror(res); +} + +static void engineResImageFree(DMResource *res) +{ + SDL_FreeSurface((SDL_Surface *)res->rdata); +} + +static int engineResModuleLoad(DMResource *res) +{ + return jssLoadXM(res, (JSSModule **) &(res->rdata)); +} + +static void engineResModuleFree(DMResource *res) +{ + jssFreeModule((JSSModule *) res->rdata); +} + + +static DMResourceDataOps engineResImage = +{ + engineResImageLoad, + engineResImageFree +}; + +static DMResourceDataOps engineResModule = +{ + engineResModuleLoad, + engineResModuleFree +}; + + +static int engineClassifier(DMResource *res) +{ + DMResourceDataOps *rops = NULL; + char *fext; + + if (res == NULL) + return DMERR_NULLPTR; + + if ((fext = strrchr(res->filename, '.')) != NULL) + { + if (strcasecmp(fext, ".png") == 0 || strcasecmp(fext, ".jpg") == 0) + rops = &engineResImage; + else + if (strcasecmp(fext, ".xm") == 0 || strcasecmp(fext, ".jmod") == 0) + rops = &engineResModule; + } + + res->rops = rops; + + return DMERR_OK; +} + + +void *engineGetResource(const char *name) +{ + DMResource *res = dmres_find(name); + if (res != NULL && res->rdata != NULL) + return res->rdata; + else + { + dmError("Could not find resource '%s'.\n", name); + return NULL; + } +} + + +static void engineAudioCallback(void *userdata, Uint8 *stream, int len) +{ + JSSMixer *d = (JSSMixer *) userdata; + + if (d != NULL) + { + jvmRenderAudio(d, stream, len / jvmGetSampleSize(d)); + } +} + + +int main(int argc, char *argv[]) +{ + int err; + BOOL initSDL = FALSE; + SDL_AudioSpec afmt; + + memset(&afmt, 0, sizeof(afmt)); + memset(&frame, 0, sizeof(frame)); + memset(&engine, 0, sizeof(engine)); + + // Pre-initialization + if ((err = demoPreInit(argc, argv)) != DMERR_OK) + goto error_exit; + + // Initialize resource subsystem + dmPrint(1, "Initializing resources subsystem.\n"); + if ((err = dmres_init("orvellys.dat", NULL, DRF_USE_PACK | DRF_PRELOAD_RES, engineClassifier)) != DMERR_OK) + { + dmError("Could not initialize resource manager: %d, %s.\n", err, dmErrorStr(err)); + goto error_exit; + } + + // Initialize SDL components + 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 JSS + jssInit(); + + afmt.freq = 44100; + afmt.format = AUDIO_S16SYS; + afmt.channels = 2; + afmt.samples = 16*1024; + + dmPrint(1, "Initializing miniJSS mixer with: %d, %d, %d\n", + JSS_AUDIO_S16, afmt.channels, afmt.freq); + + if ((engine.dev = jvmInit(JSS_AUDIO_S16, afmt.channels, afmt.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; + } + + // Initialize SDL audio + dmPrint(1, "Trying to init SDL audio with: %d, %d, %d\n", + afmt.format, afmt.channels, afmt.freq); + + afmt.callback = engineAudioCallback; + afmt.userdata = (void *) engine.dev; + + if (SDL_OpenAudio(&afmt, NULL) < 0) + { + dmError("Couldn't open audio: %s\n", SDL_GetError()); + goto error_exit; + } + + // Initialize SDL video + dmPrint(1, "Initializing SDL video %d x %d x %dbpp, flags=0x%08x\n", + engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, engine.optVFlags); + + 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()); + goto error_exit; + } + + SDL_ShowCursor(SDL_DISABLE); + SDL_WM_SetCaption(dmProgDesc, dmProgName); + + + // Load resources + if ((err = engineLoadResources()) != DMERR_OK) + { + dmError("Error loading resources, %d: %s.\n", + err, dmErrorStr(err)); + goto error_exit; + } + + // Final initializations + if ((err = demoGlobalInit()) != DMERR_OK) + goto error_exit; + + 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; + + default: + break; + } + + break; + + case SDL_VIDEOEXPOSE: + break; + + case SDL_QUIT: + engine.exitFlag = TRUE; + break; + } + + // Draw frame + frame.startTime = SDL_GetTicks(); + + if (SDL_MUSTLOCK(engine.screen) != 0 && SDL_LockSurface(engine.screen) != 0) + { + dmError("Can't lock surface.\n"); + goto error_exit; + } + + // Call main tick + if ((err = demoMainTick()) != DMERR_OK) + goto error_exit; + + // Flip screen + if (SDL_MUSTLOCK(engine.screen) != 0) + SDL_UnlockSurface(engine.screen); + + SDL_Flip(engine.screen); + SDL_Delay(20); + + // Get frame time, etc + frame.endTime = SDL_GetTicks(); + engine.currFrame++; + engine.totalFrameTime += frame.endTime - frame.startTime; + } + + // Print benchmark results + engine.endTime = SDL_GetTicks(); + dmPrint(1, "%d frames in %d ms, fps = %1.3f\n", + engine.currFrame, engine.endTime - engine.startTime, + (float) (engine.currFrame * 1000.0f) / (float) engine.totalFrameTime); + + +error_exit: + + dmPrint(1, "Shutting down.\n"); + SDL_ShowCursor(SDL_ENABLE); + SDL_PauseAudio(1); + + if (engine.screen) + SDL_FreeSurface(engine.screen); + + SDL_LockAudio(); + jmpClose(engine.plr); + jvmClose(engine.dev); + jssClose(); + SDL_UnlockAudio(); + + dmres_close(); + + if (initSDL) + SDL_Quit(); + + demoFinish(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmsimple.h Sat Sep 29 16:59:46 2012 +0300 @@ -0,0 +1,64 @@ +#ifndef DMSIMPLE_H +#define DMSIMPLE_H + +#include "dmlib.h" +#include "dmargs.h" +#include "dmres.h" +#include "dmimage.h" + +#include "jss.h" +#include "jssmod.h" +#include "jssmix.h" +#include "jssplr.h" + + +typedef struct +{ + int currFrame, endTime, startTime, totalFrameTime, debugTime; + BOOL pauseFlag, exitFlag; + SDL_Surface *screen; + SDL_Event event; + + int optScrWidth, optScrHeight, optVFlags, optBitDepth; + + JSSMixer *dev; + JSSPlayer *plr; + +} DMEngineData; + + +typedef struct +{ + int currFrame, endTime, startTime; +} DMFrameData; + + +extern DMEngineData engine; +extern DMFrameData frame; + + +#define engineGetResImage(x, name) \ + do { \ + if ((x = (SDL_Surface *) engineGetResource(name)) == NULL) \ + return DMERR_INIT_FAIL; \ + } while (0) + +#define engineGetResModule(x, name) \ + do { \ + if ((x = (JSSModule *) engineGetResource(name)) == NULL) \ + return DMERR_INIT_FAIL; \ + } while (0) + + +void * engineGetResource(const char *name); +int engineGetTime(int t); +int engineGetTimeDTi(); +int engineGetTick(); +float engineGetTimeDT(); + +int demoGlobalInit(); +int demoPreInit(); +int demoMainTick(); +void demoFinish(); + +#endif // DMSIMPLE_H