diff dmsimple.c @ 32:d1a6833a5d67

Added a simple demo engine core.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 29 Sep 2012 16:59:46 +0300
parents
children a239b7d4e13b
line wrap: on
line diff
--- /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;
+}