# HG changeset patch # User Matti Hamalainen # Date 1475473891 -10800 # Node ID 1e1d256a55b37fc21213869ff2b8c996811e40f0 # Parent 72d1b5dd22e54132cab7375d84a02a37b9e2750e Rename main code file. diff -r 72d1b5dd22e5 -r 1e1d256a55b3 demo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo.c Mon Oct 03 08:51:31 2016 +0300 @@ -0,0 +1,698 @@ +#include "dmengine.h" +#include "dmvecmat.h" +#include "dmperlin.h" +#include + +static int demoInit(); +static void demoShutdown(); +static void demoQuit(); +static int demoRender(); + +static DMPerlinContext perlinCtx; + +#define DM_COLORS (256) + +void dmMakePalette(SDL_Surface *scr) +{ + SDL_Color pal[DM_COLORS]; + int n; + + for (n = 0; n < 256; n++) + { + pal[n].r = n; + pal[n].g = n; + pal[n].b = n; + } + + SDL_SetColors(scr, pal, 0, DM_COLORS); +} + + +#define QWIDTH 256 +#define QHEIGHT 160 + +typedef Uint8 DMBlockMap[QHEIGHT][QWIDTH]; + + +void dmMakeBumpMap(DMBlockMap map, DMFloat q, DMFloat m) +{ + int x, y; + for (y = 0; y < QHEIGHT; y++) + { + for (x = 0; x < QWIDTH; x++) + { + DMFloat f = 0.40f + dmPerlinNoise2D(&perlinCtx, x, y, 1.1f, q, 2); + map[y][x] = (int) (dmClamp10(f) * m); + } + } +} + + +void dmShadowTraceHeightMap(DMBlockMap lightMap, DMBlockMap pheightMap, DMVector *light) +{ + int i, j; + + for (j = 0; j < QHEIGHT; j++) + for (i = 0; i < QWIDTH; i++) + { + DMVector vr, vl, va; + DMFloat vrayLen, vfactor; + int vlen; + BOOL wasHit; + + /* Perform shadow occlusion via simplistic raytracing */ + vr.x = i; + vr.y = j; + vr.z = light->z; // - 10.0; +// vr.z = pheightMap[j][i]; + + /* Calculate light vector vector */ + dm_vector_sub_r(&vl, &vr, light); + vrayLen = dm_vector_length(&vl); + +#if 1 + dm_vector_copy(&va, &vl); + dm_vector_normalize(&va); + dm_vector_scale(&va, 0.6f); + dm_vector_copy(&vr, light); + + vlen = 0; + wasHit = FALSE; + do + { + float h; + + /* If ray is inside the heightmap, get value */ + if (vr.x >= 0 && vr.y >= 0 && vr.x < QWIDTH && vr.y < QHEIGHT) + h = pheightMap[(int) vr.y][(int) vr.x]; + else + break; + + /* Check for hits */ + if (h > vr.z) + wasHit = TRUE; + else + { + /* Move forwards */ + dm_vector_add(&vr, &va); + vlen++; + } + } + while (!wasHit && vlen <= vrayLen); + + /* Check if the ray hit something, e.g. is this point occluded? */ + if (wasHit && vlen < vrayLen) + { + vfactor = vlen * 0.01; + } + else + vfactor = vlen * 0.02; +#endif + +#if 1 + { + /* Calculate light's intensity based on the angle it "hits" + * + * 1) Calculate the vectors that form the imaginary "plane" + * 2) Cross-product -> normal vector of the plane + * 2) Normalize the normal vector + * 3) Calculate light vector's hit angle by dot product + */ + DMVector v1, v2; + DMFloat c; + + v1.x = 2.0f; + v1.y = 0.0f; + v1.z = (DMFloat) (pheightMap[j][i] - pheightMap[j][i + 1]); + + v2.x = 0.0f; + v2.y = 2.0f; + v2.z = (DMFloat) (pheightMap[j][i] - pheightMap[j + 1][i]); + + dm_vector_cross(&vr, &v1, &v2); + dm_vector_normalize(&vr); + dm_vector_normalize(&vl); + c = dm_vector_dot(&vl, &vr); + + vrayLen = 255 - (vrayLen * 0.1) * vrayLen + (c * 128.0f) + (vfactor * vfactor * 1255); + } +#else + vrayLen = 255 - vrayLen * vrayLen * (vfactor * vfactor); + if (vrayLen < 0) vrayLen = 0; + vrayLen += pheightMap[j][i]; +#endif + + /* Clip result */ + if (vrayLen < 0) + vrayLen = 0; + else if (vrayLen > 255.0f) + vrayLen = 255.0f; + + lightMap[j][i] = vrayLen; + } +} + + +void dmShadowTraceHeightMap2(DMBlockMap lightMap, DMBlockMap pheightMap, DMVector *light) +{ + int i, j; + + light->z = 150; + + for (j = 0; j < QHEIGHT; j++) + for (i = 0; i < QWIDTH; i++) + { + DMVector vr, vl, va; + DMFloat vrayLen, vfactor; + int vlen; + BOOL wasHit; + + /* Perform shadow occlusion via simplistic raytracing */ + vr.x = i; + vr.y = j; + vr.z = 200; //light->z; // - 10.0; + + /* Calculate light vector vector */ + dm_vector_sub_r(&vl, &vr, light); + vrayLen = dm_vector_length(&vl); + +#if 1 + dm_vector_copy(&va, &vl); + dm_vector_normalize(&va); + dm_vector_copy(&vr, light); + + vlen = 0; + wasHit = FALSE; + do + { + float h; + + /* If ray is inside the heightmap, get value */ + if (vr.x >= 0 && vr.y >= 0 && vr.x < QWIDTH && vr.y < QHEIGHT) + h = pheightMap[(int) vr.y][(int) vr.x]; + else + break; + + /* Check for hits */ + if (h > vr.z) + wasHit = TRUE; + else + { + /* Move forwards */ + dm_vector_add(&vr, &va); + vlen++; + } + } + while (!wasHit && vlen <= vrayLen); + + /* Check if the ray hit something, e.g. is this point occluded? */ + if (wasHit && vlen < vrayLen) + { + vfactor = vlen * 0.05; + } + else + vfactor = vlen * 0.001; +#endif + +#if 0 + { + /* Calculate light's intensity based on the angle it "hits" + * + * 1) Calculate the vectors that form the imaginary "plane" + * 2) Cross-product -> normal vector of the plane + * 2) Normalize the normal vector + * 3) Calculate light vector's hit angle by dot product + */ + DMVector v1, v2; + DMFloat c; + + v1.x = 2.0f; + v1.y = 0.0f; + v1.z = (DMFloat) (pheightMap[j][i] - pheightMap[j][i + 1]); + + v2.x = 0.0f; + v2.y = 2.0f; + v2.z = (DMFloat) (pheightMap[j][i] - pheightMap[j + 1][i]); + + dm_vector_cross(&vr, &v1, &v2); + dm_vector_normalize(&vr); + dm_vector_normalize(&vl); + c = dm_vector_dot(&vl, &vr); + + vrayLen = 255 - (vrayLen * 0.1) * vrayLen + (c * 128.0f) + (vfactor * vfactor * 1255); + } +#else + vrayLen = 255 - vrayLen * vrayLen * (vfactor * vfactor); + if (vrayLen < 0) vrayLen = 0; + vrayLen -= pheightMap[j][i]; +#endif + + /* Clip result */ + if (vrayLen < 0) + vrayLen = 0; + else if (vrayLen > 255.0f) + vrayLen = 255.0f; + + lightMap[j][i] = vrayLen; + } +} + + +#define CREDITS_SPEED 1000 +#define CREDITS_RAND 4 + +typedef struct +{ + int x, y; +} DMCoords; + + +typedef struct +{ + int x, y; + char *filename; + SDL_Surface *img; +} DMCredits; + + + +static const DMCoords randomCoords[] = +{ + { -300, -430 }, + { 700, -550 }, + { -200, 600 }, + { 700, 600 } +}; +const int nrandomCoords = sizeof(randomCoords) / sizeof(randomCoords[0]); + + +static DMCredits credits[] = +{ + { 91, 223, "g4014.png", NULL }, + { 151, 250, "g4026.png", NULL }, + { 217, 227, "g4020.png", NULL }, + { 173, 268, "g4032.png", NULL }, + { 115, 359, "g4038.png", NULL }, + + { 437, 130, "g4062.png", NULL }, + { 457, 102, "g4068.png", NULL }, + { 450, 210, "g4056.png", NULL }, + + { 420, 320, "g4044.png", NULL }, + { 486, 381, "g4050.png", NULL }, +}; + +const int ncredits = sizeof(credits) / sizeof(credits[0]); + + +#define NOSFE_MIN 1 +#define NOSFE_MAX 269 + +SDL_Surface *bmap; +SDL_Surface *nosfe[NOSFE_MAX - NOSFE_MIN + 1]; + + +int demoPreInit(DMEngineData *engine) +{ + dmInitProg("krapula", + "Lauantai Aamun Krapula", + "0.2", "(c) 2012 Anciat Prodz & TNSP", "PENIS."); + + engine->optPackFilename = "orvellys.dat"; + engine->optDataPath = NULL; + engine->optResFlags = DRF_USE_PACK | DRF_PRELOAD_RES; + + engine->optAudioSetup = DM_ASETUP_JSS; + engine->optAfmt.freq = 44100; + engine->optAfmt.format = AUDIO_S16SYS; + engine->optAfmt.channels = 2; + + 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; + engine->demoQuit = demoQuit; + + return DMERR_OK; +} + + +static int demoInit(DMEngineData *engine) +{ + int i; + + // Initialize effect stuff + dmPerlinInit(&perlinCtx, 1234); + + for (i = 0; i < NOSFE_MAX; i++) + { + char fname[32]; + snprintf(fname, sizeof(fname), "%08d.jpg", NOSFE_MIN + i); + engineGetResImage(engine, nosfe[i], fname); + } + + for (i = 0; i < ncredits; i++) + engineGetResImage(engine, credits[i].img, credits[i].filename); + + bmap = SDL_CreateRGBSurface(SDL_SWSURFACE, QWIDTH, QHEIGHT, 8, 0, 0, 0, 0); + + + // Initialize music player + JSSModule *mod = NULL; + engineGetResModule(engine, mod, "krapula.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); + + return DMERR_OK; +} + + +static void demoShutdown(DMEngineData *engine) +{ + (void) engine; + SDL_FreeSurface(bmap); +} + + +static void demoQuit() +{ + dmPrint(0, "Krapulassa on kivaa.\n"); +} + + +static int demoRender(DMEngineData *engine) +{ + float t = engineGetTimeDT(engine); + + if (t < 5) + { + // + // Anciat prodz logo + // + int dt = engineGetTime(engine, 0); + static SDL_Surface *anciat; + static DMLerpContext lerpX, lerpY, lerpD; + static DMScaledBlitFunc nblit; + DMVector light; + static BOOL nollattu = FALSE; + if (!nollattu) + { + engineGetResImage(engine, 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; + } + + 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) + { + // + // Demo "logo" texts + // + int dt = engineGetTime(engine, 5); + static SDL_Surface *logobg, *logolayer1, *logolayer2; + static DMScaledBlitFunc nblit, kblit; + static DMLerpContext lerpD; + static BOOL nollattu = FALSE; + + if (!nollattu) + { + engineGetResImage(engine, logobg, "logobg.png"); + engineGetResImage(engine, logolayer1, "logolayer1.png"); + engineGetResImage(engine, 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 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); + } + else + if (t < 20) + { + // + // "Gaytracing" + // + int dt = engineGetTime(engine, 10); + static SDL_Surface *gay, *logobg; + static DMLerpContext lerpX, lerpY, lerpD; + static DMScaledBlitFunc nblit, kblit; + static BOOL nollattu = FALSE; + DMVector light; + DMBlockMap heightMap; + + if (!nollattu) + { + engineGetResImage(engine, gay, "gay.png"); + engineGetResImage(engine, 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; + } + + 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); + + 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); + } + } + else + if (t < 45) + { + // + // Nosfe video/animation + credits + // + 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(engine, 20) * 15 / 1000; + if (!nollattu) + { + engineGetResImage(engine, 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(engine, 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(engine, 30); + int creditTime = engineGetTime(engine, 0) - creditStartTime; + float zscale; + if ( ( (qtime / (CREDITS_SPEED + 500)) % 2) == 0 && currState == -1) + stateChange = TRUE; + + if (stateChange && currCredit < ncredits) + { + stateChange = FALSE; + switch (currState) + { + case 0: + { + int qt = (qtime / 100) % nrandomCoords; + creditStartTime = engineGetTime(engine, 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); + + currState = -1; + break; + + default: + currCredit++; + currState = 0; + stateChange = TRUE; + break; + } + } + + + if (currCredit > 0) + { + int zk = cos(engineGetTime(engine, 0) / 250.0f) * 25; + kblit(ruutu, -zk, -zk, engine->screen->w + zk*2, engine->screen->h + zk*2, engine->screen); + } + + if (currState == 1) + { + if (creditTime >= CREDITS_SPEED) + { + creditTime = CREDITS_SPEED; + 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); + } + } + + } + else + if (t < 60) + { + // + // Greetings + // + int dt = engineGetTime(engine, 45); + static SDL_Surface *logobg, *greets; + static DMScaledBlitFunc nblit, kblit; + static DMLerpContext lerpD; + static BOOL nollattu = FALSE; + + if (!nollattu) + { + engineGetResImage(engine, logobg, "logobg.png"); + engineGetResImage(engine, 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; + } + + 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; + + + // + // Flash/fade thingy + // + { + static SDL_Surface *feidi; + static int fadeStartTime; + static BOOL fadeActive, nollattu = FALSE; + static DMLerpContext fadeLerp; + BOOL hit; + int ch; + + if (!nollattu) + { + engineGetResImage(engine, feidi, "feidi.png"); + dmLerpInit(&fadeLerp, 255, 0, 250); + nollattu = TRUE; + } + + JSS_LOCK(engine->jssPlr); + for (hit = FALSE, ch = 0; ch < 6; ch++) + if (engine->jssPlr->channels[ch].nextInstrument == 0) + { + hit = TRUE; + break; + } + JSS_UNLOCK(engine->jssPlr); + + if (hit && !fadeActive) + { + fadeActive = TRUE; + fadeStartTime = engineGetTime(engine, 0); + } + if (fadeActive) + { + int fadeTime = engineGetTime(engine, 0) - fadeStartTime; + if (fadeTime < 250) + { + dmScaledBlitSurface32to32TransparentGA(feidi, + 0, 0, engine->screen->w, engine->screen->h, engine->screen, + dmLerpSCurve(&fadeLerp, fadeTime)); + } + else + fadeActive = FALSE; + } + } + + return DMERR_OK; +} diff -r 72d1b5dd22e5 -r 1e1d256a55b3 krapula.c --- a/krapula.c Mon Mar 02 04:51:18 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,698 +0,0 @@ -#include "dmengine.h" -#include "dmvecmat.h" -#include "dmperlin.h" -#include - -static int demoInit(); -static void demoShutdown(); -static void demoQuit(); -static int demoRender(); - -static DMPerlinContext perlinCtx; - -#define DM_COLORS (256) - -void dmMakePalette(SDL_Surface *scr) -{ - SDL_Color pal[DM_COLORS]; - int n; - - for (n = 0; n < 256; n++) - { - pal[n].r = n; - pal[n].g = n; - pal[n].b = n; - } - - SDL_SetColors(scr, pal, 0, DM_COLORS); -} - - -#define QWIDTH 256 -#define QHEIGHT 160 - -typedef Uint8 DMBlockMap[QHEIGHT][QWIDTH]; - - -void dmMakeBumpMap(DMBlockMap map, DMFloat q, DMFloat m) -{ - int x, y; - for (y = 0; y < QHEIGHT; y++) - { - for (x = 0; x < QWIDTH; x++) - { - DMFloat f = 0.40f + dmPerlinNoise2D(&perlinCtx, x, y, 1.1f, q, 2); - map[y][x] = (int) (dmClamp10(f) * m); - } - } -} - - -void dmShadowTraceHeightMap(DMBlockMap lightMap, DMBlockMap pheightMap, DMVector *light) -{ - int i, j; - - for (j = 0; j < QHEIGHT; j++) - for (i = 0; i < QWIDTH; i++) - { - DMVector vr, vl, va; - DMFloat vrayLen, vfactor; - int vlen; - BOOL wasHit; - - /* Perform shadow occlusion via simplistic raytracing */ - vr.x = i; - vr.y = j; - vr.z = light->z; // - 10.0; -// vr.z = pheightMap[j][i]; - - /* Calculate light vector vector */ - dm_vector_sub_r(&vl, &vr, light); - vrayLen = dm_vector_length(&vl); - -#if 1 - dm_vector_copy(&va, &vl); - dm_vector_normalize(&va); - dm_vector_scale(&va, 0.6f); - dm_vector_copy(&vr, light); - - vlen = 0; - wasHit = FALSE; - do - { - float h; - - /* If ray is inside the heightmap, get value */ - if (vr.x >= 0 && vr.y >= 0 && vr.x < QWIDTH && vr.y < QHEIGHT) - h = pheightMap[(int) vr.y][(int) vr.x]; - else - break; - - /* Check for hits */ - if (h > vr.z) - wasHit = TRUE; - else - { - /* Move forwards */ - dm_vector_add(&vr, &va); - vlen++; - } - } - while (!wasHit && vlen <= vrayLen); - - /* Check if the ray hit something, e.g. is this point occluded? */ - if (wasHit && vlen < vrayLen) - { - vfactor = vlen * 0.01; - } - else - vfactor = vlen * 0.02; -#endif - -#if 1 - { - /* Calculate light's intensity based on the angle it "hits" - * - * 1) Calculate the vectors that form the imaginary "plane" - * 2) Cross-product -> normal vector of the plane - * 2) Normalize the normal vector - * 3) Calculate light vector's hit angle by dot product - */ - DMVector v1, v2; - DMFloat c; - - v1.x = 2.0f; - v1.y = 0.0f; - v1.z = (DMFloat) (pheightMap[j][i] - pheightMap[j][i + 1]); - - v2.x = 0.0f; - v2.y = 2.0f; - v2.z = (DMFloat) (pheightMap[j][i] - pheightMap[j + 1][i]); - - dm_vector_cross(&vr, &v1, &v2); - dm_vector_normalize(&vr); - dm_vector_normalize(&vl); - c = dm_vector_dot(&vl, &vr); - - vrayLen = 255 - (vrayLen * 0.1) * vrayLen + (c * 128.0f) + (vfactor * vfactor * 1255); - } -#else - vrayLen = 255 - vrayLen * vrayLen * (vfactor * vfactor); - if (vrayLen < 0) vrayLen = 0; - vrayLen += pheightMap[j][i]; -#endif - - /* Clip result */ - if (vrayLen < 0) - vrayLen = 0; - else if (vrayLen > 255.0f) - vrayLen = 255.0f; - - lightMap[j][i] = vrayLen; - } -} - - -void dmShadowTraceHeightMap2(DMBlockMap lightMap, DMBlockMap pheightMap, DMVector *light) -{ - int i, j; - - light->z = 150; - - for (j = 0; j < QHEIGHT; j++) - for (i = 0; i < QWIDTH; i++) - { - DMVector vr, vl, va; - DMFloat vrayLen, vfactor; - int vlen; - BOOL wasHit; - - /* Perform shadow occlusion via simplistic raytracing */ - vr.x = i; - vr.y = j; - vr.z = 200; //light->z; // - 10.0; - - /* Calculate light vector vector */ - dm_vector_sub_r(&vl, &vr, light); - vrayLen = dm_vector_length(&vl); - -#if 1 - dm_vector_copy(&va, &vl); - dm_vector_normalize(&va); - dm_vector_copy(&vr, light); - - vlen = 0; - wasHit = FALSE; - do - { - float h; - - /* If ray is inside the heightmap, get value */ - if (vr.x >= 0 && vr.y >= 0 && vr.x < QWIDTH && vr.y < QHEIGHT) - h = pheightMap[(int) vr.y][(int) vr.x]; - else - break; - - /* Check for hits */ - if (h > vr.z) - wasHit = TRUE; - else - { - /* Move forwards */ - dm_vector_add(&vr, &va); - vlen++; - } - } - while (!wasHit && vlen <= vrayLen); - - /* Check if the ray hit something, e.g. is this point occluded? */ - if (wasHit && vlen < vrayLen) - { - vfactor = vlen * 0.05; - } - else - vfactor = vlen * 0.001; -#endif - -#if 0 - { - /* Calculate light's intensity based on the angle it "hits" - * - * 1) Calculate the vectors that form the imaginary "plane" - * 2) Cross-product -> normal vector of the plane - * 2) Normalize the normal vector - * 3) Calculate light vector's hit angle by dot product - */ - DMVector v1, v2; - DMFloat c; - - v1.x = 2.0f; - v1.y = 0.0f; - v1.z = (DMFloat) (pheightMap[j][i] - pheightMap[j][i + 1]); - - v2.x = 0.0f; - v2.y = 2.0f; - v2.z = (DMFloat) (pheightMap[j][i] - pheightMap[j + 1][i]); - - dm_vector_cross(&vr, &v1, &v2); - dm_vector_normalize(&vr); - dm_vector_normalize(&vl); - c = dm_vector_dot(&vl, &vr); - - vrayLen = 255 - (vrayLen * 0.1) * vrayLen + (c * 128.0f) + (vfactor * vfactor * 1255); - } -#else - vrayLen = 255 - vrayLen * vrayLen * (vfactor * vfactor); - if (vrayLen < 0) vrayLen = 0; - vrayLen -= pheightMap[j][i]; -#endif - - /* Clip result */ - if (vrayLen < 0) - vrayLen = 0; - else if (vrayLen > 255.0f) - vrayLen = 255.0f; - - lightMap[j][i] = vrayLen; - } -} - - -#define CREDITS_SPEED 1000 -#define CREDITS_RAND 4 - -typedef struct -{ - int x, y; -} DMCoords; - - -typedef struct -{ - int x, y; - char *filename; - SDL_Surface *img; -} DMCredits; - - - -static const DMCoords randomCoords[] = -{ - { -300, -430 }, - { 700, -550 }, - { -200, 600 }, - { 700, 600 } -}; -const int nrandomCoords = sizeof(randomCoords) / sizeof(randomCoords[0]); - - -static DMCredits credits[] = -{ - { 91, 223, "g4014.png", NULL }, - { 151, 250, "g4026.png", NULL }, - { 217, 227, "g4020.png", NULL }, - { 173, 268, "g4032.png", NULL }, - { 115, 359, "g4038.png", NULL }, - - { 437, 130, "g4062.png", NULL }, - { 457, 102, "g4068.png", NULL }, - { 450, 210, "g4056.png", NULL }, - - { 420, 320, "g4044.png", NULL }, - { 486, 381, "g4050.png", NULL }, -}; - -const int ncredits = sizeof(credits) / sizeof(credits[0]); - - -#define NOSFE_MIN 1 -#define NOSFE_MAX 269 - -SDL_Surface *bmap; -SDL_Surface *nosfe[NOSFE_MAX - NOSFE_MIN + 1]; - - -int demoPreInit(DMEngineData *engine) -{ - dmInitProg("krapula", - "Lauantai Aamun Krapula", - "0.2", "(c) 2012 Anciat Prodz & TNSP", "PENIS."); - - engine->optPackFilename = "orvellys.dat"; - engine->optDataPath = NULL; - engine->optResFlags = DRF_USE_PACK | DRF_PRELOAD_RES; - - engine->optAudioSetup = DM_ASETUP_JSS; - engine->optAfmt.freq = 44100; - engine->optAfmt.format = AUDIO_S16SYS; - engine->optAfmt.channels = 2; - - 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; - engine->demoQuit = demoQuit; - - return DMERR_OK; -} - - -static int demoInit(DMEngineData *engine) -{ - int i; - - // Initialize effect stuff - dmPerlinInit(&perlinCtx, 1234); - - for (i = 0; i < NOSFE_MAX; i++) - { - char fname[32]; - snprintf(fname, sizeof(fname), "%08d.jpg", NOSFE_MIN + i); - engineGetResImage(engine, nosfe[i], fname); - } - - for (i = 0; i < ncredits; i++) - engineGetResImage(engine, credits[i].img, credits[i].filename); - - bmap = SDL_CreateRGBSurface(SDL_SWSURFACE, QWIDTH, QHEIGHT, 8, 0, 0, 0, 0); - - - // Initialize music player - JSSModule *mod = NULL; - engineGetResModule(engine, mod, "krapula.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); - - return DMERR_OK; -} - - -static void demoShutdown(DMEngineData *engine) -{ - (void) engine; - SDL_FreeSurface(bmap); -} - - -static void demoQuit() -{ - dmPrint(0, "Krapulassa on kivaa.\n"); -} - - -static int demoRender(DMEngineData *engine) -{ - float t = engineGetTimeDT(engine); - - if (t < 5) - { - // - // Anciat prodz logo - // - int dt = engineGetTime(engine, 0); - static SDL_Surface *anciat; - static DMLerpContext lerpX, lerpY, lerpD; - static DMScaledBlitFunc nblit; - DMVector light; - static BOOL nollattu = FALSE; - if (!nollattu) - { - engineGetResImage(engine, 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; - } - - 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) - { - // - // Demo "logo" texts - // - int dt = engineGetTime(engine, 5); - static SDL_Surface *logobg, *logolayer1, *logolayer2; - static DMScaledBlitFunc nblit, kblit; - static DMLerpContext lerpD; - static BOOL nollattu = FALSE; - - if (!nollattu) - { - engineGetResImage(engine, logobg, "logobg.png"); - engineGetResImage(engine, logolayer1, "logolayer1.png"); - engineGetResImage(engine, 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 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); - } - else - if (t < 20) - { - // - // "Gaytracing" - // - int dt = engineGetTime(engine, 10); - static SDL_Surface *gay, *logobg; - static DMLerpContext lerpX, lerpY, lerpD; - static DMScaledBlitFunc nblit, kblit; - static BOOL nollattu = FALSE; - DMVector light; - DMBlockMap heightMap; - - if (!nollattu) - { - engineGetResImage(engine, gay, "gay.png"); - engineGetResImage(engine, 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; - } - - 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); - - 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); - } - } - else - if (t < 45) - { - // - // Nosfe video/animation + credits - // - 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(engine, 20) * 15 / 1000; - if (!nollattu) - { - engineGetResImage(engine, 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(engine, 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(engine, 30); - int creditTime = engineGetTime(engine, 0) - creditStartTime; - float zscale; - if ( ( (qtime / (CREDITS_SPEED + 500)) % 2) == 0 && currState == -1) - stateChange = TRUE; - - if (stateChange && currCredit < ncredits) - { - stateChange = FALSE; - switch (currState) - { - case 0: - { - int qt = (qtime / 100) % nrandomCoords; - creditStartTime = engineGetTime(engine, 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); - - currState = -1; - break; - - default: - currCredit++; - currState = 0; - stateChange = TRUE; - break; - } - } - - - if (currCredit > 0) - { - int zk = cos(engineGetTime(engine, 0) / 250.0f) * 25; - kblit(ruutu, -zk, -zk, engine->screen->w + zk*2, engine->screen->h + zk*2, engine->screen); - } - - if (currState == 1) - { - if (creditTime >= CREDITS_SPEED) - { - creditTime = CREDITS_SPEED; - 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); - } - } - - } - else - if (t < 60) - { - // - // Greetings - // - int dt = engineGetTime(engine, 45); - static SDL_Surface *logobg, *greets; - static DMScaledBlitFunc nblit, kblit; - static DMLerpContext lerpD; - static BOOL nollattu = FALSE; - - if (!nollattu) - { - engineGetResImage(engine, logobg, "logobg.png"); - engineGetResImage(engine, 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; - } - - 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; - - - // - // Flash/fade thingy - // - { - static SDL_Surface *feidi; - static int fadeStartTime; - static BOOL fadeActive, nollattu = FALSE; - static DMLerpContext fadeLerp; - BOOL hit; - int ch; - - if (!nollattu) - { - engineGetResImage(engine, feidi, "feidi.png"); - dmLerpInit(&fadeLerp, 255, 0, 250); - nollattu = TRUE; - } - - JSS_LOCK(engine->jssPlr); - for (hit = FALSE, ch = 0; ch < 6; ch++) - if (engine->jssPlr->channels[ch].nextInstrument == 0) - { - hit = TRUE; - break; - } - JSS_UNLOCK(engine->jssPlr); - - if (hit && !fadeActive) - { - fadeActive = TRUE; - fadeStartTime = engineGetTime(engine, 0); - } - if (fadeActive) - { - int fadeTime = engineGetTime(engine, 0) - fadeStartTime; - if (fadeTime < 250) - { - dmScaledBlitSurface32to32TransparentGA(feidi, - 0, 0, engine->screen->w, engine->screen->h, engine->screen, - dmLerpSCurve(&fadeLerp, fadeTime)); - } - else - fadeActive = FALSE; - } - } - - return DMERR_OK; -}