changeset 21:ea93b1d5c894

Use the dmsimple demo engine "framework".
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 29 Sep 2012 17:00:01 +0300
parents 67ee1ae6185e
children af6fad875a28
files krapula.c
diffstat 1 files changed, 287 insertions(+), 652 deletions(-) [+]
line wrap: on
line diff
--- a/krapula.c	Sat Sep 29 13:36:05 2012 +0300
+++ b/krapula.c	Sat Sep 29 17:00:01 2012 +0300
@@ -1,60 +1,17 @@
-#include "dmlib.h"
-#include "dmargs.h"
+#include "dmsimple.h"
 #include "dmvecmat.h"
-#include "dmres.h"
-#include "dmimage.h"
-
-#include "jss.h"
-#include "jssmod.h"
-#include "jssmix.h"
-#include "jssplr.h"
 
 #include <math.h>
 
+
 #define DM_COLORS (256)
 
 
-typedef struct
-{
-    int x, y;
-} DMCoords;
-
-
-typedef struct
-{
-    int x, y;
-    char *filename;
-    SDL_Surface *img;
-} DMCredits;
-
-
-typedef struct
+DMOptArg optList[] =
 {
-    int currFrame, endTime, startTime, totalFrameTime;
-    BOOL pauseFlag, exitFlag;
-    SDL_Surface *screen;
-    SDL_Event event;
-} DMEngineData;
-
-
-typedef struct
-{
-    int currFrame, endTime, startTime;
-} DMFrameData;
-
-
-
-
-int optVFlags = SDL_SWSURFACE | SDL_HWPALETTE;
-int optScrWidth = 640, optScrHeight = 480;
-int optBenchmarkLen = 20;
-
-
-DMOptArg optList[] = {
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 2, 'v', "verbose",    "Be more verbose", OPT_NONE },
     { 3, 'f', "fs",         "Fullscreen", OPT_NONE },
-//    { 5, 's', "size",       "Screen resolution -s 640x480", OPT_ARGREQ },
 };
 
 const int optListN = sizeof(optList) / sizeof(optList[0]);
@@ -81,28 +38,7 @@
         break;
     
     case 3:
-        optVFlags |= SDL_FULLSCREEN;
-        break;
-
-    case 5:
-        {
-            int w, h;
-            if (sscanf(optArg, "%dx%d", &w, &h) == 2)
-            {
-                if (w < 320 || h < 200 || w > 1024 || h > 768)
-                {
-                    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;
-            }
-        }
+        engine.optVFlags |= SDL_FULLSCREEN;
         break;
 
     default:
@@ -114,6 +50,8 @@
 }
 
 
+
+
 void dmMakePalette(SDL_Surface *scr)
 {
     SDL_Color pal[DM_COLORS];
@@ -400,23 +338,23 @@
 }
 
 
-void engineAudioCallback(void *userdata, Uint8 *stream, int len)
-{
-    JSSMixer *d = (JSSMixer *) userdata;
-
-    if (d != NULL)
-    {
-        jvmRenderAudio(d, stream, len / jvmGetSampleSize(d));
-    }
-}
-
-#define DEBUG 0
-
 #define CREDITS_SPEED 1000
 #define CREDITS_RAND  4
 
-#define NOSFE_MIN     1
-#define NOSFE_MAX     269
+typedef struct
+{
+    int x, y;
+} DMCoords;
+
+
+typedef struct
+{
+    int x, y;
+    char *filename;
+    SDL_Surface *img;
+} DMCredits;
+
+
 
 static const DMCoords randomCoords[] =
 {
@@ -447,655 +385,352 @@
 const int ncredits = sizeof(credits) / sizeof(credits[0]);
 
 
-
-
-DMEngineData engine;
-DMFrameData frame;
-
-int engineGetTick()
-{
-    return (frame.startTime - engine.startTime) + DEBUG * 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;
-}
-
-
-int dmScaledBlitSurface32to32TransparentX(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst);
-
+#define NOSFE_MIN     1
+#define NOSFE_MAX     269
 
-int engineResImageLoad(DMResource *res)
-{
-    SDL_Surface *img = dmLoadImage(res);
-    if (res != NULL)
-    {
-        res->rdata = img;
-        return DMERR_OK;
-    }
-    else
-        return dmferror(res);
-}
-
-void engineResImageFree(DMResource *res)
-{
-    SDL_FreeSurface((SDL_Surface *)res->rdata);
-}
-
-int engineResModuleLoad(DMResource *res)
-{
-    return jssLoadXM(res, (JSSModule **) &(res->rdata));
-}
-
-void engineResModuleFree(DMResource *res)
-{
-    jssFreeModule((JSSModule *) res->rdata);
-}
-
-
-static DMResourceDataOps engineResImage =
-{
-    engineResImageLoad,
-    engineResImageFree
-};
-
-static DMResourceDataOps engineResModule =
-{
-    engineResModuleLoad,
-    engineResModuleFree
-};
+SDL_Surface *bmap;
+SDL_Surface *nosfe[NOSFE_MAX - NOSFE_MIN + 1];
 
 
-int engineClassifier(DMResource *res)
+int demoPreInit(int argc, char *argv[])
 {
-    DMResourceDataOps *rops = NULL;
-    char *fext;
+    dmInitProg("krapula", "Lauantai Aamun Krapula", "0.2", "(c) 2012 Anciat Prodz & TNSP", "PENIS.");
 
-    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;
-    }
-}
-
-
-#define engineGetResImage(name) (SDL_Surface *) engineGetResource(name)
-#define engineGetResModule(name) (JSSModule *) engineGetResource(name)
+    engine.optScrWidth  = 640;
+    engine.optScrHeight = 480;
+    engine.optBitDepth  = 32;
+    engine.optVFlags    = SDL_SWSURFACE | SDL_HWPALETTE;
 
 
-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 main(int argc, char *argv[])
-{
-    BOOL initSDL = FALSE;
-    JSSModule *mod = NULL;
-    JSSMixer *dev = NULL;
-    JSSPlayer *plr = NULL;
-    int err, i;
-    SDL_AudioSpec afmt;
-
-    memset(&afmt, 0, sizeof(afmt));
-    memset(&frame, 0, sizeof(frame));
-    memset(&engine, 0, sizeof(engine));
-
-    dmInitProg("krapula", "Lauantai Aamun Krapula", "0.2", "(c) 2012 Anciat Prodz & TNSP", "PENIS.");
     if (!dmArgsProcess(argc, argv, optList, optListN,
         argHandleOpt, NULL, FALSE))
-        exit(1);
+        return DMERR_INIT_FAIL;
 
     dmPrint(0, "%s\n", dmProgDesc);
     dmPrint(0, "%s\n", dmProgAuthor);
     dmPrint(0, "TNSP PIERUPASKA engine 2012 'passeli professional' loading.\n");
 
-    // 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;
+    return DMERR_OK;
+}
 
 
-    // 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 ((dev = jvmInit(JSS_AUDIO_S16, afmt.channels, afmt.freq, JMIX_AUTO)) == NULL)
-    {
-        dmError("jvmInit() returned NULL, voi perkele.\n");
-        goto error_exit;
-    }
-
-    if ((plr = jmpInit(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 *) 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 - %08x flags\n",
-        optScrWidth, optScrHeight, 32, optVFlags);
-
-    engine.screen = SDL_SetVideoMode(optScrWidth, optScrHeight, 32, 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
-    err = engineLoadResources();
-    if (err != DMERR_OK)
-    {
-        dmError("Error loading resources, %d: %s.\n",
-            err, dmErrorStr(err));
-        goto error_exit;
-    }
+int demoGlobalInit()
+{
+    int i;
 
     // Initialize effect stuff
     dmPerlinInit();
-    SDL_Surface *nosfe[NOSFE_MAX - NOSFE_MIN + 1];
+
     for (i = 0; i < NOSFE_MAX; i++)
     {
-        char fname[64];
+        char fname[32];
         snprintf(fname, sizeof(fname), "%08d.jpg", NOSFE_MIN + i);
-        nosfe[i] = engineGetResImage(fname);
+        engineGetResImage(nosfe[i], fname);
     }
 
     for (i = 0; i < ncredits; i++)
-        credits[i].img = engineGetResImage(credits[i].filename);
+        engineGetResImage(credits[i].img, credits[i].filename);
 
-    SDL_Surface *bmap = SDL_CreateRGBSurface(SDL_SWSURFACE, QWIDTH, QHEIGHT, 8, 0, 0, 0, 0);
+    bmap = SDL_CreateRGBSurface(SDL_SWSURFACE, QWIDTH, QHEIGHT, 8, 0, 0, 0, 0);
 
 
     // Initialize music player
-    jvmSetCallback(dev, jmpExec, plr);
-    jmpSetModule(plr, engineGetResModule("krapula.xm"));
-    jmpPlayOrder(plr, 0);
-    jvmSetGlobalVol(dev, 55);
+    JSSModule *mod = NULL;
+    engineGetResModule(mod, "krapula.xm");
+    jvmSetCallback(engine.dev, jmpExec, engine.plr);
+    jmpSetModule(engine.plr, mod);
+    jmpPlayOrder(engine.plr, 0);
+    jvmSetGlobalVol(engine.dev, 55);
     SDL_PauseAudio(0);
 
+    return DMERR_OK;
+}
+
 
-    engine.startTime = SDL_GetTicks();
+int demoMainTick()
+{
+    float t = engineGetTimeDT();
 
-    while (!engine.exitFlag)
+    if (t < 5)
     {
-        while (SDL_PollEvent(&engine.event))
-        switch (engine.event.type)
+        int dt = engineGetTime(0);
+        static SDL_Surface *anciat;
+        static DMLerpContext lerpX, lerpY, lerpD;
+        static DMScaledBlitFunc nblit;
+        DMVector light;
+        static BOOL nollattu = FALSE;
+        if (!nollattu)
         {
-            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;
+            engineGetResImage(anciat, "anciat.png");
+            nblit = dmGetScaledBlitFunc(bmap->format, engine.screen->format, DMD_NONE);
+            dmMakePalette(bmap);
+            dmLerpInit(&lerpX, 0, QWIDTH, 5000);
+            dmLerpInit(&lerpY, QHEIGHT * 0.25, QHEIGHT * 0.75, 5000);
+            dmLerpInit(&lerpD, 0.04, 0.08, 5000);
+            nollattu = TRUE;
         }
 
-        // Draw frame
-        frame.startTime = SDL_GetTicks();
+        light.x = dmLerpSCurve(&lerpX, dt);
+        light.y = dmLerp1(&lerpY, dt);
+        light.z = 128;
 
-        if (SDL_MUSTLOCK(engine.screen) != 0 && SDL_LockSurface(engine.screen) != 0)
+        dmShadowTraceHeightMap2(bmap->pixels, anciat->pixels, &light);
+        nblit(bmap, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
+    }
+    else
+    if (t < 10)
+    {
+        int dt = engineGetTime(5);
+        static SDL_Surface *logobg, *logolayer1, *logolayer2;
+        static DMScaledBlitFunc nblit, kblit;
+        static DMLerpContext lerpD;
+        static BOOL nollattu = FALSE;
+
+        if (!nollattu)
         {
-            dmError("Can't lock surface.\n");
-            goto error_exit;
+            engineGetResImage(logobg, "logobg.png");
+            engineGetResImage(logolayer1, "logolayer1.png");
+            engineGetResImage(logolayer2, "logolayer2.png");
+
+            nblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_TRANSPARENT);
+            kblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_NONE);
+            dmLerpInit(&lerpD, 0.01, 500, 10000);
+            nollattu = TRUE;
         }
 
-        float t = engineGetTimeDT();
+        float q = dmLerpSCurve(&lerpD, dt);
+        float t = sin((float) dt / 150.0f);
+        int x = t * 25.0f + q, y = t * 35.0f + q*2.0f,
+            w = t * 70.0f + q, h = t * 40.0f + q*2.0f;
 
-        if (t < 5)
-        {
-            SDL_Surface *anciat;
-            int dt = engineGetTime(0);
-            static DMLerpContext lerpX, lerpY, lerpD;
-            static DMScaledBlitFunc nblit;
-            DMVector light;
-            static BOOL nollattu = FALSE;
-            if (!nollattu)
-            {
-                anciat = engineGetResImage("anciat.png");
-                nblit = dmGetScaledBlitFunc(bmap->format, engine.screen->format, DMD_NONE);
-                dmMakePalette(bmap);
-                dmLerpInit(&lerpX, 0, QWIDTH, 5000);
-                dmLerpInit(&lerpY, QHEIGHT * 0.25, QHEIGHT * 0.75, 5000);
-                dmLerpInit(&lerpD, 0.04, 0.08, 5000);
-                nollattu = TRUE;
-            }
+        float t2 = sin((float) dt / 150.0f + 0.2f);
+        int x2 = t2 * 25.0f + q, y2 = t * 35.0f + q*2.0f,
+            w2 = t2 * 70.0f + q, h2 = t * 40.0f + q*2.0f;
 
-            light.x = dmLerpSCurve(&lerpX, dt);
-            light.y = dmLerp1(&lerpY, dt);
-            light.z = 128;
-
-            dmShadowTraceHeightMap2(bmap->pixels, anciat->pixels, &light);
-            nblit(bmap, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
-        }
-        else
-        if (t < 10)
-        {
-            SDL_Surface *logobg, *logolayer1, *logolayer2;
-            int dt = engineGetTime(5);
-            static DMScaledBlitFunc nblit, kblit;
-            static DMLerpContext lerpD;
-            static BOOL nollattu = FALSE;
-
-            if (!nollattu)
-            {
-                logobg = engineGetResImage("logobg.png");
-                logolayer1 = engineGetResImage("logolayer1.png");
-                logolayer2 = engineGetResImage("logolayer2.png");
-
-                nblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_TRANSPARENT);
-                kblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_NONE);
-                dmLerpInit(&lerpD, 0.01, 500, 10000);
-                nollattu = TRUE;
-            }
+        kblit(logobg, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
+        nblit(logolayer1, -x, -y, engine.screen->w+w, engine.screen->h+h, engine.screen);
+        nblit(logolayer2, -x2, -y2, engine.screen->w+w2, engine.screen->h+h2, engine.screen);
+    }
+    else
+    if (t < 20)
+    {
+        int dt = engineGetTime(10);
+        static SDL_Surface *gay, *logobg;
+        static DMLerpContext lerpX, lerpY, lerpD;
+        static DMScaledBlitFunc nblit, kblit;
+        static BOOL nollattu = FALSE;
+        DMVector light;
+        DMBlockMap heightMap;
 
-            float q = dmLerpSCurve(&lerpD, dt);
-            float t = sin((float) dt / 150.0f);
-            int x = t * 25.0f + q, y = t * 35.0f + q*2.0f,
-                w = t * 70.0f + q, h = t * 40.0f + q*2.0f;
-
-            float t2 = sin((float) dt / 150.0f + 0.2f);
-            int x2 = t2 * 25.0f + q, y2 = t * 35.0f + q*2.0f,
-                w2 = t2 * 70.0f + q, h2 = t * 40.0f + q*2.0f;
-
-            kblit(logobg, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
-            nblit(logolayer1, -x, -y, engine.screen->w+w, engine.screen->h+h, engine.screen);
-            nblit(logolayer2, -x2, -y2, engine.screen->w+w2, engine.screen->h+h2, engine.screen);
+        if (!nollattu)
+        {
+            engineGetResImage(gay, "gay.png");
+            engineGetResImage(logobg, "logobg.png");
+            nblit = dmGetScaledBlitFunc(bmap->format, engine.screen->format, DMD_NONE);
+            kblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_TRANSPARENT);
+            dmMakePalette(bmap);
+            dmLerpInit(&lerpX, QWIDTH, 0, 10000);
+            dmLerpInit(&lerpY, QHEIGHT * 0.25, QHEIGHT * 0.75, 10000);
+            dmLerpInit(&lerpD, 0.04, 0.08, 10000);
+            nollattu = TRUE;
         }
-        else
-        if (t < 20)
-        {
-            SDL_Surface *gay, *logobg;
-            int dt = engineGetTime(10);
-            static DMLerpContext lerpX, lerpY, lerpD;
-            static DMScaledBlitFunc nblit, kblit;
-            static BOOL nollattu = FALSE;
-            DMVector light;
-            DMBlockMap heightMap;
 
-            if (!nollattu)
-            {
-                gay = engineGetResImage("gay.png");
-                logobg = engineGetResImage("logobg.png");
-                nblit = dmGetScaledBlitFunc(bmap->format, engine.screen->format, DMD_NONE);
-                kblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_TRANSPARENT);
-                dmMakePalette(bmap);
-                dmLerpInit(&lerpX, QWIDTH, 0, 10000);
-                dmLerpInit(&lerpY, QHEIGHT * 0.25, QHEIGHT * 0.75, 10000);
-                dmLerpInit(&lerpD, 0.04, 0.08, 10000);
-                nollattu = TRUE;
-            }
+        light.x = dmLerpSCurve(&lerpX, dt);
+        light.y = QHEIGHT * 0.5 + sin(dmLerp1(&lerpY, dt)) * 0.5;
+        light.z = 128;
+
+        dmMakeBumpMap(heightMap, dmLerpSCurve(&lerpD, dt), 254);
 
-            light.x = dmLerpSCurve(&lerpX, dt);
-            light.y = QHEIGHT * 0.5 + sin(dmLerp1(&lerpY, dt)) * 0.5;
-            light.z = 128;
+        dmShadowTraceHeightMap(bmap->pixels, heightMap, &light);
 
-            dmMakeBumpMap(heightMap, dmLerpSCurve(&lerpD, dt), 254);
+        nblit(bmap, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
 
-            dmShadowTraceHeightMap(bmap->pixels, heightMap, &light);
-
-            nblit(bmap, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
-
-            if ((dt / 100) % 10 < 5)
-            {
-                kblit(gay, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
-            }
+        if ((dt / 100) % 10 < 5)
+        {
+            kblit(gay, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
         }
-        else
-        if (t < 45)
+    }
+    else
+    if (t < 45)
+    {
+        static SDL_Surface *ruutu;
+        static int currState, currCredit, creditStartTime;
+        static DMLerpContext lerpX, lerpY, lerpZ;
+        static DMScaledBlitFunc nblit, kblit;
+        static BOOL stateChange, nollattu = FALSE;
+        int currFrame = engineGetTime(20) * 15 / 1000;
+        if (!nollattu)
         {
-            static SDL_Surface *ruutu;
-            static int currState, currCredit, creditStartTime;
-            static DMLerpContext lerpX, lerpY, lerpZ;
-            static DMScaledBlitFunc nblit, kblit;
-            static BOOL stateChange, nollattu = FALSE;
-            int currFrame = engineGetTime(20) * 15 / 1000;
-            if (!nollattu)
-            {
-                ruutu = engineGetResImage("ruutu.png");
-                dmClearSurface(ruutu, dmMapRGBA(ruutu, 0,0,0,0));
-                nblit = dmGetScaledBlitFunc(nosfe[0]->format, engine.screen->format, DMD_NONE);
-                kblit = dmGetScaledBlitFunc(credits[0].img->format, engine.screen->format, DMD_TRANSPARENT);
-                currCredit = -1;
-                currState = -1;
+            engineGetResImage(ruutu, "ruutu.png");
+            dmClearSurface(ruutu, dmMapRGBA(ruutu, 0,0,0,0));
+            nblit = dmGetScaledBlitFunc(nosfe[0]->format, engine.screen->format, DMD_NONE);
+            kblit = dmGetScaledBlitFunc(credits[0].img->format, engine.screen->format, DMD_TRANSPARENT);
+            currCredit = -1;
+            currState = -1;
+            stateChange = TRUE;
+            nollattu = TRUE;
+        }
+
+        float gt = 1.0f + sin(engineGetTime(0) / 250.0f);
+        int g1 = gt * 25.0f, g2 = gt * 50.0f;
+        
+        nblit(nosfe[currFrame % NOSFE_MAX], -g1, -g1, engine.screen->w+g2, engine.screen->h+g2, engine.screen);
+
+        if (t >= 30)
+        {
+            int qtime = engineGetTime(30);
+            int creditTime = (engineGetTime(0) - creditStartTime);
+            float zscale;
+            if ( ( (qtime / (CREDITS_SPEED + 500)) % 2) == 0 && currState == -1)
                 stateChange = TRUE;
-                nollattu = TRUE;
-            }
 
-            float gt = 1.0f + sin(engineGetTime(0) / 250.0f);
-            int g1 = gt * 25.0f, g2 = gt * 50.0f;
-            
-            nblit(nosfe[currFrame % NOSFE_MAX], -g1, -g1, engine.screen->w+g2, engine.screen->h+g2, engine.screen);
-
-            if (t >= 30)
+            if (stateChange && currCredit < ncredits)
             {
-                int qtime = engineGetTime(30);
-                int creditTime = (engineGetTime(0) - creditStartTime);
-                float zscale;
-                if ( ( (qtime / (CREDITS_SPEED + 500)) % 2) == 0 && currState == -1)
-                    stateChange = TRUE;
-
-                if (stateChange && currCredit < ncredits)
+                stateChange = FALSE;
+                switch (currState)
                 {
-//                    fprintf(stderr, "[%6d] stateChange: st=%d, credit=%d\n", creditTime, currState, currCredit);
-                    stateChange = FALSE;
-                    switch (currState)
-                    {
-                        case 0:
-                            {
-                            int qt = (qtime / 100) % nrandomCoords;
-                            creditStartTime = engineGetTime(0);
-                            creditTime = 0;
-                            dmLerpInit(&lerpX, randomCoords[qt].x, credits[currCredit].x - 50, CREDITS_SPEED);
-                            dmLerpInit(&lerpY, randomCoords[qt].y, credits[currCredit].y - 50, CREDITS_SPEED);
-                            dmLerpInit(&lerpZ, 5.0f, 0.0f, CREDITS_SPEED);
-                            currState = 1;
-                            }
-                            break;
+                    case 0:
+                        {
+                        int qt = (qtime / 100) % nrandomCoords;
+                        creditStartTime = engineGetTime(0);
+                        creditTime = 0;
+                        dmLerpInit(&lerpX, randomCoords[qt].x, credits[currCredit].x - 50, CREDITS_SPEED);
+                        dmLerpInit(&lerpY, randomCoords[qt].y, credits[currCredit].y - 50, CREDITS_SPEED);
+                        dmLerpInit(&lerpZ, 5.0f, 0.0f, CREDITS_SPEED);
+                        currState = 1;
+                        }
+                        break;
 
-                        case 2:
-                            if (creditTime >= CREDITS_SPEED)
-                                creditTime = CREDITS_SPEED - 1;
-
-                            zscale = dmLerpSCurve(&lerpZ, creditTime);
-                            dmScaledBlitSurface32to32TransparentX(
-                                credits[currCredit].img,
-                                dmLerpSCurve(&lerpX, creditTime) - (zscale * credits[currCredit].img->w),
-                                dmLerpSCurve(&lerpY, creditTime) - (zscale * credits[currCredit].img->h),
-                                credits[currCredit].img->w * (1.0f + zscale),
-                                credits[currCredit].img->h * (1.0f + zscale),
-                                ruutu);
+                    case 2:
+                        if (creditTime >= CREDITS_SPEED)
+                            creditTime = CREDITS_SPEED - 1;
 
-                            currState = -1;
-                            break;
-                        
-                        default:
-                            currCredit++;
-                            currState = 0;
-                            stateChange = TRUE;
-                            break;
-                    }
-
-//                    fprintf(stderr, "[%6d] changed: st=%d, credit=%d, chg=%d\n", creditTime, currState, currCredit, stateChange);
-                }
-                
+                        zscale = dmLerpSCurve(&lerpZ, creditTime);
+                        dmScaledBlitSurface32to32TransparentX(
+                            credits[currCredit].img,
+                            dmLerpSCurve(&lerpX, creditTime) - (zscale * credits[currCredit].img->w),
+                            dmLerpSCurve(&lerpY, creditTime) - (zscale * credits[currCredit].img->h),
+                            credits[currCredit].img->w * (1.0f + zscale),
+                            credits[currCredit].img->h * (1.0f + zscale),
+                            ruutu);
 
-                if (currCredit > 0)
-                {
-                    kblit(ruutu, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
-                }
-
-                if (currState == 1)
-                {
-                    if (creditTime >= CREDITS_SPEED)
-                    {
-                        creditTime = CREDITS_SPEED;
+                        currState = -1;
+                        break;
+                    
+                    default:
+                        currCredit++;
+                        currState = 0;
                         stateChange = TRUE;
-                        currState = 2;
-                    }
-
-                    zscale = dmLerpSCurve(&lerpZ, creditTime);
-                    kblit(credits[currCredit].img,
-                        dmLerpSCurve(&lerpX, creditTime) - (zscale * credits[currCredit].img->w),
-                        dmLerpSCurve(&lerpY, creditTime) - (zscale * credits[currCredit].img->h),
-                        credits[currCredit].img->w * (1.0f + zscale),
-                        credits[currCredit].img->h * (1.0f + zscale),
-                        engine.screen);
+                        break;
                 }
             }
             
-        }
-        else
-        if (t < 60)
-        {
-            SDL_Surface *logobg, *greets;
-            int dt = engineGetTime(45);
-            static DMScaledBlitFunc nblit, kblit;
-            static DMLerpContext lerpD;
-            static BOOL nollattu = FALSE;
 
-            if (!nollattu)
+            if (currCredit > 0)
             {
-                logobg = engineGetResImage("logobg.png");
-                greets = engineGetResImage("greetings.png");
-                nblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_TRANSPARENT);
-                kblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_NONE);
-                dmLerpInit(&lerpD, 0.01, 500, 10000);
-                nollattu = TRUE;
-            }
-
-            float q = dmLerpSCurve(&lerpD, dt);
-            float t = sin((float) dt / 150.0f),
-                  j = (1.0 + t) * 15;
-            int x = t * 25.0f + q, y = t * 35.0f + q,
-                w = t * 70.0f + q*2.0f, h = t * 40.0f + q*2.0f;
-
-            kblit(logobg, -j, -j, engine.screen->w+j*2.0f, engine.screen->h+j*2.0f, engine.screen);
-            nblit(greets, -x, -y, engine.screen->w+w, engine.screen->h+h, engine.screen);
-        }
-        else
-            engine.exitFlag = TRUE;
-
-        {
-            static SDL_Surface *feidi;
-            static int fadeStartTime;
-            static BOOL fadeActive, nollattu = FALSE;
-            static DMLerpContext fadeLerp;
-            BOOL hit;
-            int ch;
-
-            if (!nollattu)
-            {
-                feidi = engineGetResImage("feidi.png");
-                dmLerpInit(&fadeLerp, 255, 0, 250);
-                nollattu = TRUE;
+                kblit(ruutu, 0, 0, engine.screen->w, engine.screen->h, engine.screen);
             }
 
-            JSS_LOCK(plr);
-            for (hit = FALSE, ch = 0; ch < 6; ch++)
-            if (plr->iCExtInstrumentN[ch] == 0)
-            {
-                hit = TRUE;
-                break;
-            }
-            JSS_UNLOCK(plr);
-
-            if (hit && !fadeActive)
+            if (currState == 1)
             {
-                fadeActive = TRUE;
-                fadeStartTime = engineGetTime(0);
-            }
-            if (fadeActive)
-            {
-                int fadeTime = engineGetTime(0) - fadeStartTime;
-                if (fadeTime < 250)
+                if (creditTime >= CREDITS_SPEED)
                 {
-                    dmScaledBlitSurface32to32TransparentGA(feidi,
-                        0, 0, engine.screen->w, engine.screen->h, engine.screen,
-                        dmLerpSCurve(&fadeLerp, fadeTime));
+                    creditTime = CREDITS_SPEED;
+                    stateChange = TRUE;
+                    currState = 2;
                 }
-                else
-                    fadeActive = FALSE;
+
+                zscale = dmLerpSCurve(&lerpZ, creditTime);
+                kblit(credits[currCredit].img,
+                    dmLerpSCurve(&lerpX, creditTime) - (zscale * credits[currCredit].img->w),
+                    dmLerpSCurve(&lerpY, creditTime) - (zscale * credits[currCredit].img->h),
+                    credits[currCredit].img->w * (1.0f + zscale),
+                    credits[currCredit].img->h * (1.0f + zscale),
+                    engine.screen);
             }
         }
+        
+    }
+    else
+    if (t < 60)
+    {
+        int dt = engineGetTime(45);
+        static SDL_Surface *logobg, *greets;
+        static DMScaledBlitFunc nblit, kblit;
+        static DMLerpContext lerpD;
+        static BOOL nollattu = FALSE;
+
+        if (!nollattu)
+        {
+            engineGetResImage(logobg, "logobg.png");
+            engineGetResImage(greets, "greetings.png");
+            nblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_TRANSPARENT);
+            kblit = dmGetScaledBlitFunc(logobg->format, engine.screen->format, DMD_NONE);
+            dmLerpInit(&lerpD, 0.01, 500, 10000);
+            nollattu = TRUE;
+        }
 
-        // Flip screen
-        if (SDL_MUSTLOCK(engine.screen) != 0)
-            SDL_UnlockSurface(engine.screen);
-
-        SDL_Flip(engine.screen);
-        SDL_Delay(20);
+        float q = dmLerpSCurve(&lerpD, dt);
+        float t = sin((float) dt / 150.0f),
+              j = (1.0 + t) * 15;
+        int x = t * 25.0f + q, y = t * 35.0f + q,
+            w = t * 70.0f + q*2.0f, h = t * 40.0f + q*2.0f;
 
-        // Get frame time, etc
-        frame.endTime = SDL_GetTicks();
-        engine.currFrame++;
-        engine.totalFrameTime += frame.endTime - frame.startTime;
+        kblit(logobg, -j, -j, engine.screen->w+j*2.0f, engine.screen->h+j*2.0f, engine.screen);
+        nblit(greets, -x, -y, engine.screen->w+w, engine.screen->h+h, engine.screen);
     }
-
-    // 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);
+    else
+        engine.exitFlag = TRUE;
 
 
-error_exit:
-    dmPrint(1, "Shutting down.\n");
-    SDL_ShowCursor(SDL_ENABLE);
-    SDL_PauseAudio(1);
+    {
+        static SDL_Surface *feidi;
+        static int fadeStartTime;
+        static BOOL fadeActive, nollattu = FALSE;
+        static DMLerpContext fadeLerp;
+        BOOL hit;
+        int ch;
 
-    if (engine.screen)
-        SDL_FreeSurface(engine.screen);
+        if (!nollattu)
+        {
+            engineGetResImage(feidi, "feidi.png");
+            dmLerpInit(&fadeLerp, 255, 0, 250);
+            nollattu = TRUE;
+        }
+
+        JSS_LOCK(engine.plr);
+        for (hit = FALSE, ch = 0; ch < 6; ch++)
+        if (engine.plr->iCExtInstrumentN[ch] == 0)
+        {
+            hit = TRUE;
+            break;
+        }
+        JSS_UNLOCK(engine.plr);
 
-    SDL_LockAudio();
-    jmpClose(plr);
-    jvmClose(dev);
-    jssFreeModule(mod);
-    jssClose();
-    SDL_UnlockAudio();
+        if (hit && !fadeActive)
+        {
+            fadeActive = TRUE;
+            fadeStartTime = engineGetTime(0);
+        }
+        if (fadeActive)
+        {
+            int fadeTime = engineGetTime(0) - fadeStartTime;
+            if (fadeTime < 250)
+            {
+                dmScaledBlitSurface32to32TransparentGA(feidi,
+                    0, 0, engine.screen->w, engine.screen->h, engine.screen,
+                    dmLerpSCurve(&fadeLerp, fadeTime));
+            }
+            else
+                fadeActive = FALSE;
+        }
+    }
 
-    dmres_close();    
+    return DMERR_OK;
+}
 
-    if (initSDL)
-        SDL_Quit();
 
-    dmPrint(0, "SDL on muuten melko paska kirjasto.\n");
-    
-    return 0;
+void demoFinish()
+{
+    dmPrint(0, "Krapulassa on kivaa.\n");
 }