Mercurial > hg > demos > bussi
view demo.c @ 37:dc514b8d8cdd default tip
s/EXEEXT/BINEXT/g
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 05 Dec 2019 18:22:11 +0200 |
parents | 0b74381be601 |
children |
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->optResFlags = DRF_USE_PACK | DRF_PRELOAD_RES #ifdef DM_USE_STDIO | DRF_USE_STDIO #endif ; engine->optAudioSetup = DM_ASETUP_JSS; engine->optVidSetup = DM_VSETUP_ASPECT; engine->optVidWidth = 640; engine->optVidHeight = 480; engine->optVidDepth = 32; engine->demoInit = demoInit; engine->demoRender = demoRender; engine->demoShutdown = demoShutdown; return DMERR_OK; } #define FFT_SIZE 128 DMFFTContext fft; DMResource *teksti = NULL; DMBitmapFont *font = NULL; typedef struct { int layer; int freq; int max; float ypos; float speed; char *filename; SDL_Surface *img; int count; } DMItemDef; typedef struct { BOOL enabled; float xtime, xpos, ypos; DMItemDef *ref; } DMFooItemDef; static DMItemDef items[] = { { 0, 3, 1, 0.53, 0.2, "viitta.png", NULL, 0 }, { 0, 1, 3, -0.2, 0.05, "pilvi.png", NULL, 0 }, { 0, 1, 3, 0.28 , 0.1 , "puu_pv_2.png", NULL, 0 }, { 1, 9, 2, 0.25 , 0.8 , "puu_pv_1.png", NULL, 0 }, }; static const int nitems = sizeof(items) / sizeof(items[0]); static int demoInit(DMEngineData *engine) { int i; JSSModule *mod = NULL; SDL_Color pal[DMFONT_NPALETTE]; DMResource *tmp; // FFT init dmInitializeFFT(&fft, FFT_SIZE); // Skrolliteksti if ((teksti = engineFindResource(engine, "skrolli.txt")) == NULL) return DMERR_INIT_FAIL; // Skrollerin fontti if ((tmp = engineFindResource(engine, "fontti.dmf")) == NULL) return DMERR_INIT_FAIL; if ((i = dmLoadBitmapFont(tmp, &font)) != DMERR_OK) return i; for (i = 0; i < DMFONT_NPALETTE; i++) { pal[i].r = pal[i].g = pal[i].b = i * 8; pal[i].a = i > 0 ? 255 : 0; } dmSetBitmapFontPalette(font, pal, 0, DMFONT_NPALETTE); // Musa 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); // Osa kuvadatasta for (i = 0; i < nitems; i++) engineGetResImage(engine, items[i].img, items[i].filename); // Jne srand(15); return DMERR_OK; } static void demoShutdown(DMEngineData *engine) { (void) engine; dmEndFFT(&fft); dmFreeBitmapFont(font); } static inline float dmCX(DMEngineData *engine, const float x) { return (x * engine->screen->w); } static inline float dmCY(const DMEngineData *engine, const float y) { return (y * engine->screen->h); } static inline float dmQX(const DMEngineData *engine, const SDL_Surface *img, const float x) { return engine->optVidNative ? (img->w * x) : (img->w * engine->screen->w * x) / 640.0f; } static inline float dmQY(const DMEngineData *engine, const 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 my_toupper(int ch) { switch (ch) { case 0xe4: return 142; case 0xf6: return 153; default: if (ch >= 'a' && ch <= 'z') return ch - 'a' + 'A'; else return ch; } } static DMItemDef * dmGetItem(int t) { int i; for (i = 0; i < nitems; i++) { DMItemDef *def = &items[i]; if (t % def->freq == 0 && def->count <= def->max) return def; } return NULL; } static void dmRenderItems(DMEngineData *engine, DMScaledBlitFunc ablit, DMFooItemDef *mitems, const int nmitems, const int layer) { int i; for (i = 0; i < nmitems; i++) { DMFooItemDef *item = &mitems[i]; if (item->enabled && item->ref->layer == layer) { ablit(item->ref->img, dmCX(engine, item->xpos), dmCY(engine, item->ypos), dmQX(engine, item->ref->img, 1), dmQY(engine, item->ref->img, 1), engine->screen); } } } 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, *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, 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) % (int) dmQX(engine, tausta, 1)), x2 = x1 + dmQX(engine, tausta, 1); cblit(tausta, x1, 0, dmQX(engine, tausta, 1), dmQY(engine, tausta, 1), engine->screen); cblit(tausta, x2, 0, dmQX(engine, tausta, 1), dmQY(engine, tausta, 1), engine->screen); float qm = sin(t * 0.1 + fftPow * 5) * 0.05, qm2 = qm * 10; ablit(aurinko, dmCX(engine, 0.8 - dmLerpSCurveClamp(&fadeLerp3, engineGetTime(engine, 0) * 0.01) * 0.3 - qm), dmCY(engine, 0.05 - qm), dmQX(engine, aurinko, 1 + qm2), dmQY(engine, aurinko, 1 + qm2), engine->screen); // Puut ym. liikennejutut #define DM_MAX_MITEMS 16 static DMFooItemDef mitems[DM_MAX_MITEMS]; if (t > 6) { float dt = (t - 6); static BOOL nollattu = FALSE; int i; if (!nollattu) { memset(mitems, 0, sizeof(mitems)); nollattu = TRUE; } for (i = 0; i < DM_MAX_MITEMS; i++) { DMFooItemDef *item = &mitems[i]; if (!item->enabled && (item->ref = dmGetItem((int) t * 10 + 1)) != NULL) { item->enabled = TRUE; item->ref->count++; item->xtime = dt; item->ypos = item->ref->ypos + sin(dt) * 0.001f; } } for (i = 0; i < DM_MAX_MITEMS; i++) { DMFooItemDef *item = &mitems[i]; if (item->enabled) { float xpos = (dt - item->xtime) * item->ref->speed; if (xpos > 1.5) { item->enabled = FALSE; item->ref->count--; } else item->xpos = 1 - xpos; } } } dmRenderItems(engine, ablit, mitems, DM_MAX_MITEMS, 0); // Bussi ajaa sisään if (t > 14) { float dt = engineGetTime(engine, 14), ajelu = dmLerpSCurveClamp(&fadeLerp3, dt), xc = dmCX(engine, -1 + ajelu), yc = dmCY(engine, 0.38 + 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); } dmRenderItems(engine, ablit, mitems, DM_MAX_MITEMS, 1); } // // 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); } // // Skrolleri // if (t > 3) { int tt = engineGetTime(engine, 2); static DMScaledBlitFunc cblit, qblit; static BOOL nollattu = FALSE; if (!nollattu) { cblit = dmGetScaledBlitFunc(font->glyphs->format, engine->screen->format, DMD_TRANSPARENT); qblit = dmGetScaledBlitFunc(font->glyphs->format, engine->screen->format, DMD_SATURATE); } size_t txtLen = teksti->rawSize - 1; Uint8 *txtData = teksti->rawData; int fwidth = font->width * 2 + 2; int xc, offs, scrollTime = tt / 10, // v-- bug scrWidth = engine->screen->w / (dmQX(engine, font->glyphs, 1) + dmCX(engine, 0.001)); for (xc = offs = 0; offs < scrWidth; offs++) { const int ch = txtData[((scrollTime / fwidth) + offs) % txtLen]; SDL_Surface glyph; dmGetBMGlyph(&glyph, font, my_toupper(ch)); float mt = (offs * 20 + tt) / 100.0f; int dx = xc - (scrollTime % fwidth), dy = dmCY(engine, 0.8 + sin(mt) * 0.05), dw = glyph.w * 2 * (1.0f + sin(mt) * 0.1f), dh = glyph.h * 2 * (1.0f + cos(mt) * 0.2f); cblit(&glyph, dx+1, dy+1, dw+1, dh+1, engine->screen); qblit(&glyph, dx, dy, dw, dh, engine->screen); xc += fwidth; } } // // Alku- ja Loppufeidi // { static DMLerpContext fadeLerp, fadeLerp2; static SDL_Surface *feidi = NULL; static BOOL nollattu = FALSE; if (!nollattu) { engineGetResImage(engine, feidi, "feidi.png"); dmLerpInit(&fadeLerp, 255, 0, 3000); dmLerpInit(&fadeLerp2, 0, 255, 5000); } int fadeVal = -1; if (t < 5) fadeVal = dmLerpSCurveClamp(&fadeLerp, engineGetTime(engine, 0)); else if (t > 70) fadeVal = dmLerpSCurveClamp(&fadeLerp2, engineGetTime(engine, 70)); if (fadeVal >= 0) { dmScaledBlitSurface32to32TransparentGA(feidi, 0, 0, dmQX(engine, feidi, 1), dmQY(engine, feidi, 1), engine->screen, fadeVal); } } // // Maskaus // { static DMScaledBlitFunc cblit = NULL; static SDL_Surface *maski = NULL; static BOOL nollattu = FALSE; if (!nollattu) { engineGetResImage(engine, maski, "maski.png"); cblit = dmGetScaledBlitFunc(maski->format, engine->screen->format, DMD_TRANSPARENT); } cblit(maski, 0, 0, dmQX(engine, maski, 1), dmQY(engine, maski, 1), engine->screen); } if (t > 75) return 1; else return DMERR_OK; }