view demo.c @ 3:37b33851cfbb

Joo.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 22 May 2015 01:39:04 +0300
parents 496b9ab9238c
children dcec61df1633
line wrap: on
line source

#include "dmengine.h"
#include "dmtext.h"
#include "dmfft.h"
#include "dmvecmat.h"
#include <math.h>

static int demoInit(DMEngineData *engine);
static void demoShutdown(DMEngineData *engine);
static int demoRender(DMEngineData *engine);


int demoPreInit(DMEngineData *engine)
{
    dmInitProg("bussi",
        "Bussi by AnCiat ProDucTionz",
        "0", "ENGINE INITTIALISSSIZING!!!!!", NULL);

    engine->optPackFilename  = "bussi.dat";
    engine->optDataPath      = NULL;
    engine->optResFlags      = DRF_USE_PACK | DRF_PRELOAD_RES | DRF_USE_STDIO;

    engine->optAudioSetup    = DM_ASETUP_JSS;

    engine->optVidSetup      = DM_VSETUP_ASPECT;
    engine->optVidWidth      = 640;
    engine->optVidHeight     = 480;
    engine->optVidDepth      = 32;
    engine->optVFlags        = SDL_SWSURFACE;

    engine->demoInit = demoInit;
    engine->demoRender = demoRender;
    engine->demoShutdown = demoShutdown;

    return DMERR_OK;
}


#define FFT_SIZE 128
DMFFTContext fft;


static int demoInit(DMEngineData *engine)
{
    int i;
    JSSModule *mod = NULL;

    dmInitializeFFT(&fft, FFT_SIZE);

    engineGetResModule(engine, mod, "pas2.xm");

    if ((i = jssConvertModuleForPlaying(mod)) != DMERR_OK)
    {
        dmErrorMsg("Could not convert module for playing, %d: %s\n",
            i, dmErrorStr(i));
        return DMERR_INIT_FAIL;
    }
    
    jvmSetCallback(engine->jssDev, jmpExec, engine->jssPlr);
    jmpSetModule(engine->jssPlr, mod);
    jmpPlayOrder(engine->jssPlr, 0);
    jvmSetGlobalVol(engine->jssDev, 55);

    // Jne
    srand(15);

    return DMERR_OK;
}


static void demoShutdown(DMEngineData *engine)
{
    (void) engine;
    dmEndFFT(&fft);
}


static inline float dmCX(DMEngineData *engine, const float x)
{
    return (x * engine->screen->w);
}


static inline float dmCY(DMEngineData *engine, const float y)
{
    return (y * engine->screen->h);
}


static inline float dmQX(DMEngineData *engine, SDL_Surface *img, const float x)
{
    return engine->optVidNative ? (img->w * x) : (img->w * engine->screen->w * x) / 640.0f;
}


static inline float dmQY(DMEngineData *engine, SDL_Surface *img, const float y)
{
    return engine->optVidNative ? (img->h * y) : (img->h * engine->screen->h * y) / 480.0f;
}


#define DM_RADIAL_BLUR(YC, XC) \
        DMVector p1 = { xc, yc, 0, 0 }, p2 = { cx, cy, 0, 0 }, v; \
        dm_vector_sub_r(&v, &p2, &p1); \
        dm_vector_scale(&v, scale); \
        dm_vector_add(&v, &p1); \
        if (v.y YC || v.x XC) continue; \
        DMColor *dp = pix + xc, \
                 *q = ((DMColor *)img->pixels) + ((int)(v.y) * pitch) + (int)v.x; \
        dp->r = (q->r + dp->r) / 2; \
        dp->g = (q->g + dp->g) / 2; \
        dp->b = (q->b + dp->b) / 2;



void dmRadialBlur(SDL_Surface *img, const int cx, const int cy, const DMFloat scale)
{
    const int pitch = img->pitch / sizeof(DMColor);
    int xc, yc;

#pragma omp parallel private(yc, xc) shared(img)
    {
#pragma omp sections nowait
        {
#pragma omp section
            for (yc = cy; yc >= 0; yc--)
            {
                DMColor *pix = ((DMColor *)img->pixels) + yc * pitch;
                for (xc = cx + 1; xc < img->w; xc++)
                {
                    DM_RADIAL_BLUR(< 0, >= img->w)
                }
            }

#pragma omp section
            for (yc = cy; yc >= 0; yc--)
            {
                DMColor *pix = ((DMColor *)img->pixels) + yc * pitch;
                for (xc = cx; xc > 0; xc--)
                {
                    DM_RADIAL_BLUR(< 0, < 0)
                }    
            }

#pragma omp section
            for (yc = cy + 1; yc < img->h; yc++)
            {
                DMColor *pix = ((DMColor *)img->pixels) + yc * pitch;
                for (xc = cx; xc > 0; xc--)
                {
                    DM_RADIAL_BLUR(>= img->h, < 0)
                }    
            }

#pragma omp section
            for (yc = cy + 1; yc < img->h; yc++)
            {
                DMColor *pix = ((DMColor *)img->pixels) + yc * pitch;
                for (xc = cx + 1; xc < img->w; xc++)
                {
                    DM_RADIAL_BLUR(>= img->h, >= img->w)
                }    
            }
        }
    }
}



static int demoRender(DMEngineData *engine)
{
    float t = engineGetTimeDT(engine);
    

    //
    // Do FFT
    //
    DMFFTType fftPow = 0;
    BOOL fftOK = FALSE;
    static DMFFTType fftAmp[FFT_SIZE / 2];
    static DMFFTType fftData[FFT_SIZE];

    dmMutexLock(engine->audioStreamMutex);
    if (engine->audioStreamBuf != 0 && engine->audioStreamLen > FFT_SIZE)
    {
        int i;
        Sint16 *buf = (Sint16 *) engine->audioStreamBuf;
        for (i = 0; i < FFT_SIZE; i++)
        {
            fftData[i] = *buf;
            buf += 2;
        }
        fftOK = TRUE;
    }
    dmMutexUnlock(engine->audioStreamMutex);

    if (fftOK)
    {
        dmRealFFT(&fft, fftData);
        dmConvertFFTtoPowerAndSum(&fft, fftData, fftAmp, 1.0, &fftPow, 0.00004f);
    }


    //
    // Taustaskrolli
    //
    {
        static SDL_Surface *tausta = NULL,
                *aurinko = NULL,
                *puu1 = NULL,
                *puu2 = NULL,
                *bussi = NULL,
                *rengas = NULL;

        static DMScaledBlitFunc cblit = NULL, ablit = NULL;
        static BOOL nollattu = FALSE;
        static DMLerpContext fadeLerp, fadeLerp2, fadeLerp3;

        if (!nollattu)
        {
            dmLerpInit(&fadeLerp, 0, 255, 3000);
            dmLerpInit(&fadeLerp2, 0, 255, 4000);
            dmLerpInit(&fadeLerp3, 0, 1.2, 3000);
            engineGetResImage(engine, tausta, "tausta_pv.png");
            engineGetResImage(engine, aurinko, "aurinko.png");
            engineGetResImage(engine, puu1, "puu_pv_1.png");
            engineGetResImage(engine, puu2, "puu_pv_2.png");
            engineGetResImage(engine, bussi, "auto.png");
            engineGetResImage(engine, rengas, "rengas.png");
            cblit = dmGetScaledBlitFunc(tausta->format, engine->screen->format, DMD_NONE);
            ablit = dmGetScaledBlitFunc(bussi->format, engine->screen->format, DMD_TRANSPARENT);
        }

        int x1 = - ((int)dmQX(engine, tausta, t * 0.2) % tausta->w),
            x2 = x1 + tausta->w;

        int fadeVal;
        if (t < 3 || t > 64)
        {
            if (t < 3)
                fadeVal = dmLerpSCurveClamp(&fadeLerp, engineGetTime(engine, 0));
            else
                fadeVal = dmLerpSCurveClamp(&fadeLerp2, engineGetTime(engine, 64));

            dmClearSurface(engine->screen, dmMapRGB(engine->screen, 0,0,0));
            dmScaledBlitSurface32to32TransparentGA(tausta, x1, 0, tausta->w, tausta->h, engine->screen, fadeVal);
            dmScaledBlitSurface32to32TransparentGA(tausta, x2, 0, tausta->w, tausta->h, engine->screen, fadeVal);
        }
        else
        {
            fadeVal = 255;
            cblit(tausta, x1, 0, tausta->w, tausta->h, engine->screen);
            cblit(tausta, x2, 0, tausta->w, tausta->h, engine->screen);
        }

        float qm = sin(t * 0.1 + fftPow * 5) * 15, qm2 = qm*2;
        dmScaledBlitSurface32to32TransparentGA(aurinko,
            dmCX(engine, 0.8 - dmLerpSCurveClamp(&fadeLerp3, engineGetTime(engine, 0) * 0.01) * 0.3 ) - qm,
            dmCY(engine, 0.05) - qm,
            aurinko->w + qm2, aurinko->h + qm2,
            engine->screen, fadeVal);

        
        // Bussi ajaa sisään
        if (t > 4)
        {
            float
                dt = engineGetTime(engine, 4),
                ajelu = dmLerpSCurveClamp(&fadeLerp3, dt),
                xc = dmCX(engine, -1 + ajelu),
                yc = dmCY(engine, 0.35 + sin(t * 10) * 0.005),
                yc2 = yc + dmQY(engine, bussi, 0.7) + dmCY(engine, sin(t * 20) * 0.001);
            
            ablit(rengas, xc + dmQX(engine, bussi, 0.07), yc2, dmQX(engine, rengas, 1), dmQY(engine, rengas, 1), engine->screen);
            ablit(rengas, xc + dmQX(engine, bussi, 0.80), yc2, dmQX(engine, rengas, 1), dmQY(engine, rengas, 1), engine->screen);
            ablit(bussi, xc, yc, dmQX(engine, bussi, 1), dmQY(engine, bussi, 1), engine->screen);
        }
    }

    //
    // AP logo
    //
    if (t > 4 && t < 8)
    {
        int dt = engineGetTime(engine, 4);
        static DMLerpContext fadeLerp;
        static SDL_Surface *logo = NULL;
        static BOOL nollattu = FALSE;
        if (!nollattu)
        {
            dmLerpInit(&fadeLerp, 0, 255, 1000);
            engineGetResImage(engine, logo, "ap.png");
            nollattu = TRUE;
        }

        int fadeVal;
        if (dt < 1000)
            fadeVal = dmLerpSCurveClamp(&fadeLerp, dt);
        else
        if (dt > 3000)
            fadeVal = 255 - dmLerpSCurveClamp(&fadeLerp, dt - 3000);
        else
            fadeVal = 255;

        dmScaledBlitSurface32to32TransparentGA(logo,
            dmQX(engine, logo, 0.2),
            dmQY(engine, logo, 0.3),
            dmQX(engine, logo, 1),
            dmQY(engine, logo, 1),
            engine->screen, fadeVal);
    }

    //
    // BUSSI logo
    //
    if (t > 10 && t < 14)
    {
        int dt = engineGetTime(engine, 10);
        static DMLerpContext fadeLerp;
        static SDL_Surface *logo = NULL, *logo2 = NULL;
        static BOOL nollattu = FALSE;
        if (!nollattu)
        {
            dmLerpInit(&fadeLerp, 0, 255, 1000);
            engineGetResImage(engine, logo, "bussi_logo.png");
            engineGetResImage(engine, logo2, "dosa.png");
            nollattu = TRUE;
        }

        int fadeVal, fadeVal2;
        if (dt < 1000)
            fadeVal = dmLerpSCurveClamp(&fadeLerp, dt);
        else
        if (dt > 3000)
            fadeVal = 255 - dmLerpSCurveClamp(&fadeLerp, dt - 3000);
        else
            fadeVal = 255;

        if (dt > 1000)
        {
            if (dt < 2000)
                fadeVal2 = dmLerpSCurveClamp(&fadeLerp, dt - 1000);
            else
            if (dt > 3000)
                fadeVal2 = 255 - dmLerpSCurveClamp(&fadeLerp, dt - 3000);
            else
                fadeVal2 = 255;
        }
        else
            fadeVal2 = 0;

        dmScaledBlitSurface32to32TransparentGA(logo,
            dmCX(engine, 0.10),
            dmCY(engine, 0.2),
            dmQX(engine, logo, 1),
            dmQY(engine, logo, 1),
            engine->screen, fadeVal);

        dmScaledBlitSurface32to32TransparentGA(logo2,
            dmCX(engine, 0.6),
            dmCY(engine, 0.6),
            dmQX(engine, logo2, 1),
            dmQY(engine, logo2, 1),
            engine->screen, fadeVal2);
    }


    {
        static DMScaledBlitFunc cblit = NULL;
        static SDL_Surface *maski = NULL;
        static BOOL nollattu = FALSE;

        if (!nollattu)
        {
            engineGetResImage(engine, maski, "maze.png");
            cblit = dmGetScaledBlitFunc(maski->format, engine->screen->format, DMD_TRANSPARENT);
        }

        cblit(maski,
            0, 0,
            dmQX(engine, maski, 1),
            dmQY(engine, maski, 1),
            engine->screen);
    }

    return DMERR_OK;
}