mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-25 16:08:04 +03:00
Instead of hardcoding "dDEMO.alk" / "tDEMO.alk", use the actual filename stored in nact->files.alk[0] from the directory scan. This fixes loading failures on case-sensitive filesystems where the actual file may be named "dDemo.alk" or "tDemo.alk". Also update gameresource.c to store .alk files without a numeric suffix at index 0 (these games have only one .alk file).
964 lines
32 KiB
C
964 lines
32 KiB
C
#include "config.h"
|
||
|
||
#include <stdio.h>
|
||
#include <math.h>
|
||
#include <SDL.h>
|
||
|
||
#include "portab.h"
|
||
#include "system.h"
|
||
#include "xsystem35.h"
|
||
#include "modules.h"
|
||
#include "nact.h"
|
||
#include "input.h"
|
||
#include "music.h"
|
||
#include "alk.h"
|
||
#include "cg.h"
|
||
#include "gfx.h"
|
||
#include "gfx_private.h"
|
||
|
||
// Perspective projection parameters
|
||
#define PROJ_SCALE_X 1.2993f // cot(30°) / (4/3)
|
||
#define PROJ_SCALE_Y 1.7321f // cot(30°) = √3
|
||
#define PROJ_W_DENOM 0.5000625f
|
||
|
||
static inline float lerpf(float a, float b, float t) { return a + (b - a) * t; }
|
||
|
||
static void render_quad(SDL_Texture *tex, SDL_Vertex verts[4]) {
|
||
static const int indices[] = {0, 1, 2, 0, 2, 3};
|
||
SDL_RenderGeometry(gfx_renderer, tex, verts, 4, indices, 6);
|
||
}
|
||
|
||
static void fade_overlay(Uint8 r, Uint8 g, Uint8 b, Uint8 alpha) {
|
||
SDL_SetRenderDrawBlendMode(gfx_renderer, SDL_BLENDMODE_BLEND);
|
||
SDL_SetRenderDrawColor(gfx_renderer, r, g, b, alpha);
|
||
SDL_RenderFillRect(gfx_renderer, NULL);
|
||
}
|
||
|
||
#define NR_SCENES 13
|
||
|
||
static const int scene_duration[] = {
|
||
5400,
|
||
4752,
|
||
24963,
|
||
4000,
|
||
20000,
|
||
4000,
|
||
21000,
|
||
4000,
|
||
6402,
|
||
4000,
|
||
10370,
|
||
31613,
|
||
10338,
|
||
};
|
||
|
||
#define NR_TEXTURES 86
|
||
|
||
static struct {
|
||
bool loop;
|
||
bool key_cancel;
|
||
SDL_Texture *images[NR_TEXTURES];
|
||
} dd;
|
||
|
||
// For each corner, if a coordinate is out of [0, view_w-1] x [0, view_h-1],
|
||
// shift all other corners by the overshoot amount, then hard-clamp everything
|
||
// to the screen boundary.
|
||
static void clamp_rect_to_screen(int xs[4], int ys[4]) {
|
||
for (int i = 0; i < 4; i++) {
|
||
if (xs[i] < 0) {
|
||
for (int j = 0; j < 4; j++) if (j != i) xs[j] -= xs[i];
|
||
xs[i] = 0;
|
||
}
|
||
if (ys[i] < 0) {
|
||
for (int j = 0; j < 4; j++) if (j != i) ys[j] -= ys[i];
|
||
ys[i] = 0;
|
||
}
|
||
if (xs[i] >= view_w - 1) {
|
||
for (int j = 0; j < 4; j++) if (j != i) xs[j] += (view_w - 1 - xs[i]);
|
||
xs[i] = view_w - 1;
|
||
}
|
||
if (ys[i] >= view_h - 1) {
|
||
for (int j = 0; j < 4; j++) if (j != i) ys[j] += (view_h - 1 - ys[i]);
|
||
ys[i] = view_h - 1;
|
||
}
|
||
}
|
||
for (int i = 0; i < 4; i++) {
|
||
if (xs[i] < 0) xs[i] = 0;
|
||
if (xs[i] >= view_w) xs[i] = view_w - 1;
|
||
if (ys[i] < 0) ys[i] = 0;
|
||
if (ys[i] >= view_h) ys[i] = view_h - 1;
|
||
}
|
||
}
|
||
|
||
static void Init() {
|
||
int p1 = getCaliValue();
|
||
int p2 = getCaliValue();
|
||
int p3 = getCaliValue();
|
||
int *var = getCaliVariable();
|
||
|
||
if (!nact->files.alk[0]) {
|
||
WARNING("dDEMO.alk not found");
|
||
return;
|
||
}
|
||
alk_t *alk = alk_new(nact->files.alk[0]); // dDEMO.alk
|
||
if (!alk) {
|
||
WARNING("Cannot open %s", nact->files.alk[0]);
|
||
*var = 0;
|
||
return;
|
||
}
|
||
if (alk->datanum < NR_TEXTURES) {
|
||
WARNING("dDEMO.alk has %d entries, expected %d", alk->datanum, NR_TEXTURES);
|
||
alk_free(alk);
|
||
*var = 0;
|
||
return;
|
||
}
|
||
for (int i = 0; i < NR_TEXTURES; i++) {
|
||
bool load_as_alpha_map = i < 18 || i > 60;
|
||
SDL_Surface *sf = cg_load_as_sdlsurface_from_data(alk->entries[i].data, alk->entries[i].size, false, load_as_alpha_map);
|
||
if (!sf) {
|
||
WARNING("failed to load image %d in dDEMO.alk", i);
|
||
dd.images[i] = NULL;
|
||
continue;
|
||
}
|
||
dd.images[i] = SDL_CreateTextureFromSurface(gfx_renderer, sf);
|
||
SDL_FreeSurface(sf);
|
||
}
|
||
*var = 1;
|
||
TRACE("dDemo.Init %d,%d,%d,%p:", p1, p2, p3, var);
|
||
}
|
||
|
||
static void SetKeyCancelFlag() {
|
||
int cancelflag = getCaliValue();
|
||
dd.key_cancel = cancelflag != 0;
|
||
TRACE("dDemo.SetKeyCancelFlag %d:", cancelflag);
|
||
}
|
||
|
||
static void SetLoopFlag() {
|
||
int loopflag = getCaliValue();
|
||
dd.loop = loopflag != 0;
|
||
TRACE("dDemo.SetLoopFlag %d:", loopflag);
|
||
}
|
||
|
||
static void render_affine_bg(SDL_Texture *scroll_bg, int elapsed, int duration,
|
||
float angle_deg, float scale, int offset_x, int offset_y) {
|
||
if (!scroll_bg) return;
|
||
|
||
int bg_w, bg_h;
|
||
SDL_QueryTexture(scroll_bg, NULL, NULL, &bg_w, &bg_h);
|
||
|
||
int xs[4], ys[4];
|
||
const float angle = angle_deg * (float)M_PI / 180.0f;
|
||
const float hw = view_w * 0.5f, hh = view_h * 0.5f;
|
||
const float cosA = cosf(angle), sinA = sinf(angle);
|
||
const float cxs[4] = {-hw, hw, hw, -hw};
|
||
const float cys[4] = {-hh, -hh, hh, hh};
|
||
for (int i = 0; i < 4; i++) {
|
||
xs[i] = (int)((cosA * cxs[i] - sinA * cys[i]) * scale + hw) + offset_x;
|
||
ys[i] = (int)((sinA * cxs[i] + cosA * cys[i]) * scale + hh) + offset_y;
|
||
}
|
||
clamp_rect_to_screen(xs, ys);
|
||
|
||
float t = (float)elapsed / (float)duration;
|
||
float w = (float)view_w, h = (float)view_h;
|
||
|
||
float uv[4][2];
|
||
uv[0][0] = 0.0f;
|
||
uv[0][1] = lerpf(0.0f, (float)ys[0], t);
|
||
uv[1][0] = lerpf(w - 1.0f, (float)xs[1], t);
|
||
uv[1][1] = lerpf(0.0f, (float)ys[1], t);
|
||
uv[2][0] = lerpf(w - 1.0f, (float)xs[2], t);
|
||
uv[2][1] = lerpf(h - 1.0f, (float)ys[2], t);
|
||
uv[3][0] = lerpf(0.0f, (float)xs[3], t);
|
||
uv[3][1] = lerpf(h - 1.0f, (float)ys[3], t);
|
||
|
||
for (int i = 0; i < 4; i++) {
|
||
uv[i][0] /= (float)bg_w;
|
||
uv[i][1] /= (float)bg_h;
|
||
}
|
||
|
||
SDL_Vertex verts[4];
|
||
static int y_toggle = 0;
|
||
|
||
// Pass 1: Forward mapping layer
|
||
for (int i = 0; i < 4; i++) {
|
||
verts[i].position.x = (i == 1 || i == 2) ? w : 0;
|
||
verts[i].position.y = (i == 2 || i == 3) ? h : (float)y_toggle;
|
||
verts[i].color = (SDL_Color){255, 255, 255, 255};
|
||
verts[i].tex_coord.x = uv[i][0];
|
||
verts[i].tex_coord.y = uv[i][1];
|
||
}
|
||
SDL_SetTextureBlendMode(scroll_bg, SDL_BLENDMODE_NONE);
|
||
render_quad(scroll_bg, verts);
|
||
|
||
// Pass 2: 180° rotated mapping layer
|
||
y_toggle = (y_toggle + 1) & 1;
|
||
for (int i = 0; i < 4; i++) {
|
||
verts[i].position.y = (i == 2 || i == 3) ? h : (float)y_toggle;
|
||
verts[i].color = (SDL_Color){255, 255, 255, 128};
|
||
}
|
||
// Swap mapping: TL<->BR, TR<->BL for 180° rotation effect
|
||
verts[0].tex_coord.x = uv[2][0]; verts[0].tex_coord.y = uv[2][1];
|
||
verts[1].tex_coord.x = uv[3][0]; verts[1].tex_coord.y = uv[3][1];
|
||
verts[2].tex_coord.x = uv[0][0]; verts[2].tex_coord.y = uv[0][1];
|
||
verts[3].tex_coord.x = uv[1][0]; verts[3].tex_coord.y = uv[1][1];
|
||
|
||
SDL_SetTextureBlendMode(scroll_bg, SDL_BLENDMODE_BLEND);
|
||
render_quad(scroll_bg, verts);
|
||
}
|
||
|
||
static void render_scene0(int elapsed) {
|
||
SDL_Texture *scroll_bg = dd.images[79];
|
||
SDL_Texture *sprite = dd.images[77];
|
||
if (!sprite) return;
|
||
|
||
int spr_w, spr_h;
|
||
SDL_QueryTexture(sprite, NULL, NULL, &spr_w, &spr_h);
|
||
const int slide_end = 4700;
|
||
const int duration = scene_duration[0]; // 5400
|
||
|
||
// --- Background: DrawAffineSurfaceAlpha50 x2 (alpha=50%) ---
|
||
// Source coordinates are linear-interpolated between identity and a transformed state.
|
||
// Two layers (identity and 180° rotated) are blended together.
|
||
render_affine_bg(scroll_bg, elapsed, duration, 40.0f, 0.55f, -20, 100);
|
||
|
||
// --- Sprite and UI elements ---
|
||
// 2. Sprite (ALK 77) with 3-echo horizontal slide-in.
|
||
// Each copy starts wider/further left and converges to the final position.
|
||
SDL_SetTextureBlendMode(sprite, SDL_BLENDMODE_BLEND);
|
||
int dest_y = (view_h - spr_h) / 2;
|
||
if (elapsed < slide_end) {
|
||
SDL_SetTextureAlphaMod(sprite, 0x80);
|
||
const int a0_vals[] = {640, 480, 320};
|
||
for (int i = 0; i < 3; i++) {
|
||
int a0 = a0_vals[i];
|
||
int dest_w = a0 - ((a0 - spr_w) * elapsed) / slide_end;
|
||
if (dest_w <= 0) continue;
|
||
SDL_Rect dst = {view_w - 2 * dest_w, dest_y, dest_w, spr_h};
|
||
SDL_RenderCopy(gfx_renderer, sprite, NULL, &dst);
|
||
}
|
||
} else {
|
||
SDL_SetTextureAlphaMod(sprite, 0xd0);
|
||
SDL_Rect dst = {view_w - 2 * spr_w, dest_y, spr_w, spr_h};
|
||
SDL_RenderCopy(gfx_renderer, sprite, NULL, &dst);
|
||
}
|
||
|
||
// 3. Horizontal accent line (grows rightward over 4700ms)
|
||
int line_w = elapsed < slide_end ? 639 * elapsed / slide_end + 1 : 640;
|
||
SDL_SetRenderDrawBlendMode(gfx_renderer, SDL_BLENDMODE_NONE);
|
||
SDL_SetRenderDrawColor(gfx_renderer, 0xc0, 0xc0, 0xc0, 0xff);
|
||
SDL_Rect hline = {0, (spr_h + view_h) / 2 - 4, line_w, 2};
|
||
SDL_RenderFillRect(gfx_renderer, &hline);
|
||
|
||
// 4. Vertical accent line (right edge of sprite, grows downward)
|
||
int line_h = elapsed < slide_end ? 479 * elapsed / slide_end + 1 : 480;
|
||
SDL_Rect vline = {view_w - spr_w, 0, 2, line_h};
|
||
SDL_RenderFillRect(gfx_renderer, &vline);
|
||
}
|
||
|
||
static void render_scene1(int elapsed) {
|
||
SDL_Texture *scroll_bg = dd.images[78];
|
||
SDL_Texture *sprite = dd.images[76];
|
||
if (!sprite) return;
|
||
|
||
int spr_w, spr_h;
|
||
SDL_QueryTexture(sprite, NULL, NULL, &spr_w, &spr_h);
|
||
const int duration = scene_duration[1]; // 4752
|
||
|
||
// --- Background: DrawAffineSurfaceAlpha50 x2 (alpha=50%) ---
|
||
render_affine_bg(scroll_bg, elapsed, duration, -45.0f, 0.1f, 0, 200);
|
||
|
||
// Foreground (ALK 76): centered, fades in over first 3000ms.
|
||
// graph_BlendAlphaMapColorAlpha (alpha 0->255) for elapsed < 3000,
|
||
// graph_BlendAlphaMapColor (full opacity) for elapsed >= 3000.
|
||
{
|
||
int alpha = elapsed < 3000 ? (elapsed * 255) / 3000 : 255;
|
||
SDL_SetTextureBlendMode(sprite, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(sprite, (Uint8)alpha);
|
||
SDL_Rect dst = {(view_w - spr_w) / 2, (view_h - spr_h) / 2, spr_w, spr_h};
|
||
SDL_RenderCopy(gfx_renderer, sprite, NULL, &dst);
|
||
}
|
||
|
||
// Fade to black: graph_FillAlphaColor(0,0,0), starts at 4000ms.
|
||
if (elapsed > 4000) {
|
||
int fade_alpha = ((elapsed - 4000) * 255) / (duration - 4000);
|
||
fade_overlay(0, 0, 0, (Uint8)SDL_min(fade_alpha, 255));
|
||
}
|
||
}
|
||
|
||
// 3D rendering for render_scene2_4_6.
|
||
//
|
||
// Background quad (model space, XY plane):
|
||
// v0=(-1, -0.73446, 0) v1=(+1, -0.73446, 0)
|
||
// v2=(+1, +0.73446, 0) v3=(-1, +0.73446, 0)
|
||
// Object border quad (slightly oversized):
|
||
// v0=(-1.00885, -0.74655, 0) ... v3=(-1.00885, +0.74655, 0)
|
||
//
|
||
// Animation phases (phaseDuration = (sceneDuration - 1000) / 8):
|
||
// Phase 0 [0..1pd): approach from Z=-9 to Z=-3.75, Y-rot -90°→0°, tex1
|
||
// Phase 1 [1..3pd): static at Z=-3.75, rot=0°, tex1
|
||
// Phase 2 [3..4pd): recede from Z=-3.75 to Z=-9, Y-rot 0°→90°, tex1
|
||
// Phase 3 [4..5pd): approach from Z=-9 to Z=-3.75, Y-rot -90°→0°, tex2
|
||
// Phase 4 [5..7pd): static at Z=-3.75, rot=0°, tex2
|
||
// Phase 5 [7..8pd): recede from Z=-3.75 to Z=-9, Y-rot 0°→90°, tex2
|
||
//
|
||
// All phases also have an X-swing: tx = sin(π*t) * swing_amp
|
||
// approach swing_amp = -1.5, recede = +1.5
|
||
//
|
||
// Projection: same parameters as render_scene12_3d.
|
||
static void render_scene_2_4_6_3d(int elapsed, int phase_dur, SDL_Texture *tex1, SDL_Texture *tex2) {
|
||
static const float bg_mv[4][3] = {
|
||
{-1.00000f, -0.73446f, 0.0f},
|
||
{+1.00000f, -0.73446f, 0.0f},
|
||
{+1.00000f, +0.73446f, 0.0f},
|
||
{-1.00000f, +0.73446f, 0.0f},
|
||
};
|
||
static const float obj_mv[4][3] = {
|
||
{-1.00885f, -0.74655f, 0.0f},
|
||
{+1.00885f, -0.74655f, 0.0f},
|
||
{+1.00885f, +0.74655f, 0.0f},
|
||
{-1.00885f, +0.74655f, 0.0f},
|
||
};
|
||
static const float muv[4][2] = {
|
||
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
|
||
};
|
||
|
||
float tx, tz, rot_y_deg;
|
||
SDL_Texture *tex;
|
||
|
||
if (elapsed < phase_dur) {
|
||
// Phase 0: approach with X-swing, tex1
|
||
float t = (float)elapsed / (float)phase_dur;
|
||
tx = sinf(t * (float)M_PI) * (-1.5f);
|
||
tz = lerpf(-9.0f, -3.75f, t);
|
||
rot_y_deg = lerpf(-90.0f, 0.0f, t);
|
||
tex = tex1;
|
||
} else if (elapsed < phase_dur * 3) {
|
||
// Phase 1: static, tex1
|
||
tx = 0.0f; tz = -3.75f; rot_y_deg = 0.0f;
|
||
tex = tex1;
|
||
} else if (elapsed < phase_dur * 4) {
|
||
// Phase 2: recede with X-swing, tex1
|
||
float t = (float)(elapsed - phase_dur * 3) / (float)phase_dur;
|
||
tx = sinf(t * (float)M_PI) * 1.5f;
|
||
tz = lerpf(-3.75f, -9.0f, t);
|
||
rot_y_deg = lerpf(0.0f, 90.0f, t);
|
||
tex = tex1;
|
||
} else if (elapsed < phase_dur * 5) {
|
||
// Phase 3: approach with X-swing, tex2
|
||
float t = (float)(elapsed - phase_dur * 4) / (float)phase_dur;
|
||
tx = sinf(t * (float)M_PI) * (-1.5f);
|
||
tz = lerpf(-9.0f, -3.75f, t);
|
||
rot_y_deg = lerpf(-90.0f, 0.0f, t);
|
||
tex = tex2;
|
||
} else if (elapsed < phase_dur * 7) {
|
||
// Phase 4: static, tex2
|
||
tx = 0.0f; tz = -3.75f; rot_y_deg = 0.0f;
|
||
tex = tex2;
|
||
} else if (elapsed < phase_dur * 8) {
|
||
// Phase 5: recede with X-swing, tex2
|
||
float t = (float)(elapsed - phase_dur * 7) / (float)phase_dur;
|
||
tx = sinf(t * (float)M_PI) * 1.5f;
|
||
tz = lerpf(-3.75f, -9.0f, t);
|
||
rot_y_deg = lerpf(0.0f, 90.0f, t);
|
||
tex = tex2;
|
||
} else {
|
||
return;
|
||
}
|
||
|
||
if (!tex) return;
|
||
|
||
float angle_rad = rot_y_deg * (float)M_PI / 180.0f;
|
||
float cos_a = cosf(angle_rad);
|
||
float sin_a = sinf(angle_rad);
|
||
|
||
const float half_w = (float)view_w * 0.5f;
|
||
const float half_h = (float)view_h * 0.5f;
|
||
|
||
SDL_Vertex bg_verts[4], obj_verts[4];
|
||
for (int i = 0; i < 4; i++) {
|
||
for (int pass = 0; pass < 2; pass++) {
|
||
const float (*mv)[3] = (pass == 0) ? bg_mv : obj_mv;
|
||
SDL_Vertex *v = (pass == 0) ? &bg_verts[i] : &obj_verts[i];
|
||
float rx = cos_a * mv[i][0] + sin_a * mv[i][2];
|
||
float ry = mv[i][1];
|
||
float rz = -sin_a * mv[i][0] + cos_a * mv[i][2];
|
||
float wx = rx + tx;
|
||
float wy = ry;
|
||
float wz = rz + tz;
|
||
float w = -wz * PROJ_W_DENOM;
|
||
if (w <= 0.0f) w = 1e-5f;
|
||
v->position.x = (wx * PROJ_SCALE_X / w + 1.0f) * half_w;
|
||
v->position.y = (wy * PROJ_SCALE_Y / w + 1.0f) * half_h;
|
||
v->tex_coord.x = muv[i][0];
|
||
v->tex_coord.y = muv[i][1];
|
||
}
|
||
}
|
||
|
||
// Object border quad: solid color RGB(244,221,181) = BGR(0xb5,0xdd,0xf4),
|
||
// drawn first as a backdrop. The bg quad drawn on top leaves only the thin
|
||
// border ring visible.
|
||
for (int i = 0; i < 4; i++) obj_verts[i].color = (SDL_Color){0xf4, 0xdd, 0xb5, 0xff};
|
||
SDL_SetRenderDrawBlendMode(gfx_renderer, SDL_BLENDMODE_NONE);
|
||
render_quad(NULL, obj_verts);
|
||
|
||
// Background quad: textured, opaque, drawn on top (covers center of border quad)
|
||
for (int i = 0; i < 4; i++) bg_verts[i].color = (SDL_Color){255, 255, 255, 255};
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE);
|
||
render_quad(tex, bg_verts);
|
||
}
|
||
|
||
// Scenes 2, 4, and 6 share the same structure:
|
||
// - Fixed background (ALK[9]) full-screen blit
|
||
// - 3D quad animation (see render_scene_2_4_6_3d above)
|
||
// - Sprite + shadow scroll linearly left-to-right over the full scene duration
|
||
//
|
||
// sprite_idx: ALK index of the scrolling sprite (shadow is at sprite_idx + 73)
|
||
// tex1_idx: ALK index of the 3D quad texture for phases 0-2
|
||
// tex2_idx: ALK index of the 3D quad texture for phases 3-5
|
||
static void render_scene_2_4_6(int elapsed, int scene_idx, int sprite_idx, int tex1_idx, int tex2_idx) {
|
||
const int duration = scene_duration[scene_idx];
|
||
SDL_Texture *bg = dd.images[9];
|
||
SDL_Texture *sprite = dd.images[sprite_idx];
|
||
SDL_Texture *sprite_shadow = dd.images[sprite_idx + 73];
|
||
|
||
// 1. Background: full-screen blit, no blending
|
||
if (bg) {
|
||
SDL_SetTextureBlendMode(bg, SDL_BLENDMODE_NONE);
|
||
SDL_SetTextureColorMod(bg, 0xff, 0xff, 0xff);
|
||
SDL_RenderCopy(gfx_renderer, bg, NULL, NULL);
|
||
}
|
||
|
||
// 2. 3D rotating quad animation (8-phase timing)
|
||
{
|
||
int phase_dur = (duration - 1000) / 8;
|
||
SDL_Texture *tex1 = dd.images[tex1_idx];
|
||
SDL_Texture *tex2 = dd.images[tex2_idx];
|
||
render_scene_2_4_6_3d(elapsed, phase_dur, tex1, tex2);
|
||
}
|
||
|
||
// 3. Scrolling sprite: x moves from -sprite_w (off-screen left) to view_w (off-screen right)
|
||
int sprite_w = 0, sprite_h = 0;
|
||
if (sprite)
|
||
SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
|
||
int x = sprite_w ? ((sprite_w + view_w) * elapsed) / duration - sprite_w : 0;
|
||
|
||
// Shadow drawn first (color-modded to black), sprite on top (full color)
|
||
if (sprite_shadow) {
|
||
int sw, sh;
|
||
SDL_QueryTexture(sprite_shadow, NULL, NULL, &sw, &sh);
|
||
SDL_SetTextureBlendMode(sprite_shadow, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureColorMod(sprite_shadow, 0, 0, 0);
|
||
SDL_Rect dst = {x, 0, sw, sh};
|
||
SDL_RenderCopy(gfx_renderer, sprite_shadow, NULL, &dst);
|
||
}
|
||
if (sprite) {
|
||
SDL_SetTextureBlendMode(sprite, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureColorMod(sprite, 0xff, 0xff, 0xff);
|
||
SDL_Rect dst = {x, 0, sprite_w, sprite_h};
|
||
SDL_RenderCopy(gfx_renderer, sprite, NULL, &dst);
|
||
}
|
||
}
|
||
|
||
// Scenes 3, 5, 7, and 9 share the same structure:
|
||
// - Main image (image_idx) fades in and out over 4 seconds
|
||
// - ALK[9] overlay drawn at 50% alpha with an animated quad-warp throughout
|
||
//
|
||
// Timing of main image:
|
||
// 0–250ms: black (no image)
|
||
// 250–1000ms: fade in (alpha 0→255)
|
||
// 1000–3000ms: full opacity
|
||
// 3000–4000ms: fade out (alpha 255→0)
|
||
//
|
||
// Overlay quad-warp: source corners rotate clockwise along image edges over the full duration.
|
||
// At t=0: source = full image (no warp).
|
||
// At t=1: each corner has shifted 1/3 of its edge length, creating a rotation-like distortion.
|
||
static void render_scene_3_5_7_9(int elapsed, int image_idx) {
|
||
SDL_Texture *main_img = dd.images[image_idx];
|
||
SDL_Texture *overlay = dd.images[9];
|
||
|
||
if (main_img) {
|
||
int alpha;
|
||
if (elapsed < 250)
|
||
alpha = 0;
|
||
else if (elapsed < 1000)
|
||
alpha = ((elapsed - 250) * 255) / 750;
|
||
else if (elapsed < 3000)
|
||
alpha = 255;
|
||
else
|
||
alpha = ((4000 - elapsed) * 255) / 1000;
|
||
alpha = SDL_max(0, SDL_min(255, alpha));
|
||
if (alpha > 0) {
|
||
SDL_SetTextureBlendMode(main_img, alpha < 255 ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
|
||
SDL_SetTextureAlphaMod(main_img, (Uint8)alpha);
|
||
SDL_RenderCopy(gfx_renderer, main_img, NULL, NULL);
|
||
}
|
||
}
|
||
|
||
// Overlay: 50% alpha blend with animated quad-warp.
|
||
// UV corner positions (normalized): corners shift by t/3 along each edge.
|
||
if (overlay) {
|
||
float t3 = (float)elapsed / (4000.0f * 3.0f); // 0 → 1/3
|
||
float w = (float)view_w, h = (float)view_h;
|
||
SDL_Vertex verts[4] = {
|
||
/* TL */ {{0.f, 0.f}, {255, 255, 255, 128}, {t3, 0.f }},
|
||
/* TR */ {{w, 0.f}, {255, 255, 255, 128}, {1.0f, t3 }},
|
||
/* BR */ {{w, h }, {255, 255, 255, 128}, {1.0f - t3, 1.0f }},
|
||
/* BL */ {{0.f, h }, {255, 255, 255, 128}, {0.f, 1.0f-t3}},
|
||
};
|
||
SDL_SetTextureBlendMode(overlay, SDL_BLENDMODE_BLEND);
|
||
render_quad(overlay, verts);
|
||
}
|
||
}
|
||
|
||
// Scene 8 is a slideshow of 6 images (ALK 80–85) with crossfade transitions.
|
||
// Total duration (scene_duration[8] = 6402ms) is divided into 7 equal segments:
|
||
// Segment 1: fade in image[0] (black → full)
|
||
// Segments 2–6: crossfade image[i-1] → image[i]
|
||
// Segment 7: hold image[5] at full opacity
|
||
static void render_scene8(int elapsed) {
|
||
const int duration = scene_duration[8];
|
||
const int seg = duration / 7;
|
||
|
||
SDL_Texture **imgs = dd.images + 80; // ALK[80..85]
|
||
|
||
if (elapsed < seg) {
|
||
// Segment 1: fade in image[0] from black
|
||
int alpha = seg > 0 ? (elapsed * 255) / seg : 255;
|
||
if (imgs[0]) {
|
||
SDL_SetTextureBlendMode(imgs[0], SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(imgs[0], (Uint8)SDL_min(alpha, 255));
|
||
SDL_RenderCopy(gfx_renderer, imgs[0], NULL, NULL);
|
||
}
|
||
} else if (elapsed < 6 * seg) {
|
||
// Segments 2–6: crossfade image[idx] → image[idx+1]
|
||
int idx = elapsed / seg - 1; // 0..4
|
||
int alpha = ((elapsed - (idx + 1) * seg) * 255) / seg;
|
||
if (imgs[idx]) {
|
||
SDL_SetTextureBlendMode(imgs[idx], SDL_BLENDMODE_NONE);
|
||
SDL_SetTextureAlphaMod(imgs[idx], 255);
|
||
SDL_RenderCopy(gfx_renderer, imgs[idx], NULL, NULL);
|
||
}
|
||
if (imgs[idx + 1]) {
|
||
SDL_SetTextureBlendMode(imgs[idx + 1], SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(imgs[idx + 1], (Uint8)SDL_min(alpha, 255));
|
||
SDL_RenderCopy(gfx_renderer, imgs[idx + 1], NULL, NULL);
|
||
}
|
||
} else {
|
||
// Segment 7: hold image[5] at full opacity
|
||
if (imgs[5]) {
|
||
SDL_SetTextureBlendMode(imgs[5], SDL_BLENDMODE_NONE);
|
||
SDL_SetTextureAlphaMod(imgs[5], 255);
|
||
SDL_RenderCopy(gfx_renderer, imgs[5], NULL, NULL);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Scene 10 is a 10.37s animation with 3 phases:
|
||
// images[18..31]: surfaces1, 14 animation frames (type A)
|
||
// images[32..59]: surfaces2, 28 animation frames (type B/C pairs per slot)
|
||
// images[10]: surface3, static full-screen image for zoom/fade
|
||
//
|
||
// Phase 1 (0–6453ms): slideshow of 14 frames × 461ms each.
|
||
// Within each frame, 3 sub-images are shown in sequence:
|
||
// 0–152ms: images[18+frame] (surfaces1[frame])
|
||
// 153–306ms: images[32+frame*2] (surfaces2[frame*2])
|
||
// 307–460ms: images[32+frame*2+1] (surfaces2[frame*2+1])
|
||
//
|
||
// Phase 2 (6454–9609ms): ZoomBlend – images[10] zooms in from a tiny
|
||
// bottom-centered region (16 × view_h/4) to full screen with pow(4) ease-in.
|
||
//
|
||
// Phase 3 (9610–10370ms): images[10] fades out to black (alpha 255→0).
|
||
static void render_scene10(int elapsed) {
|
||
const int duration = scene_duration[10];
|
||
SDL_Texture *surface3 = dd.images[10];
|
||
|
||
if (elapsed < 6454) {
|
||
// Phase 1: frame animation
|
||
int frame = elapsed / 461;
|
||
int phase = elapsed % 461;
|
||
int idx;
|
||
if (phase < 153)
|
||
idx = 18 + frame;
|
||
else if (phase < 307)
|
||
idx = 32 + frame * 2;
|
||
else
|
||
idx = 32 + frame * 2 + 1;
|
||
SDL_Texture *tex = dd.images[idx];
|
||
if (tex) {
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE);
|
||
SDL_SetTextureAlphaMod(tex, 255);
|
||
SDL_SetTextureColorMod(tex, 255, 255, 255);
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, NULL);
|
||
}
|
||
} else if (elapsed < 9610) {
|
||
// Phase 2: zoom in
|
||
int h4 = view_h / 4;
|
||
float progress = 1.0f - (float)(elapsed - 6454) / (float)(9610 - 6454);
|
||
float ease = powf(progress, 4.0f);
|
||
float src_w = lerpf((float)view_w, 16.0f, ease);
|
||
float src_h = lerpf((float)view_h, (float)h4, ease);
|
||
SDL_Rect src_rect = {
|
||
(int)((view_w - src_w) * 0.5f),
|
||
(int)(view_h - src_h),
|
||
(int)src_w,
|
||
(int)src_h,
|
||
};
|
||
if (surface3) {
|
||
SDL_SetTextureBlendMode(surface3, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(surface3, 255);
|
||
SDL_SetTextureColorMod(surface3, 255, 255, 255);
|
||
SDL_RenderCopy(gfx_renderer, surface3, &src_rect, NULL);
|
||
}
|
||
} else {
|
||
// Phase 3: fade out to black
|
||
int blend_alpha = (elapsed - 9610) * 255 / (duration - 9610);
|
||
int combined = 255 - SDL_min(blend_alpha, 255);
|
||
if (surface3) {
|
||
SDL_SetTextureBlendMode(surface3,
|
||
combined < 255 ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
|
||
SDL_SetTextureAlphaMod(surface3, (Uint8)combined);
|
||
SDL_SetTextureColorMod(surface3, 255, 255, 255);
|
||
SDL_RenderCopy(gfx_renderer, surface3, NULL, NULL);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Scene 11 is a complex layered animation with 8 segments over 31.6s:
|
||
// Background (ALK 60) scrolls upward over the full scene duration.
|
||
// The scene duration (31613ms) is divided into 8 equal segments (~3951ms each):
|
||
// Segment 0: background only
|
||
// Segments 1, 3, 5: one of 3 images (ALK 63, 62, 61) slides top-to-bottom at 50% alpha
|
||
// Segments 2, 4, 6: one of 3 overlay images (ALK 69, 70, 71) pingpong-fades in/out
|
||
// Segment 7: white fade out
|
||
static void render_scene11(int elapsed) {
|
||
const int duration = scene_duration[11]; // 31613
|
||
const int unit = duration / 8; // ~3951
|
||
|
||
SDL_Texture *bg = dd.images[60];
|
||
// Slide images (alpha maps, drawn at 50% alpha, pass top-to-bottom)
|
||
SDL_Texture **slide = dd.images + 61; // ALK[61..63]
|
||
// Overlay images (alpha maps, pingpong blend)
|
||
SDL_Texture **overlay = dd.images + 69; // ALK[69..71]
|
||
|
||
// Background: scrolls from bottom to top of source image over full duration.
|
||
// srcY = (bg_h - view_h) * (duration - elapsed) / duration
|
||
if (bg) {
|
||
int bg_w, bg_h;
|
||
SDL_QueryTexture(bg, NULL, NULL, &bg_w, &bg_h);
|
||
int scroll = (int)((long long)(bg_h - view_h) * elapsed / duration);
|
||
int src_y = SDL_max(0, (bg_h - view_h) - scroll);
|
||
SDL_Rect src = {0, src_y, SDL_min(view_w, bg_w), view_h};
|
||
SDL_SetTextureBlendMode(bg, SDL_BLENDMODE_NONE);
|
||
SDL_RenderCopy(gfx_renderer, bg, &src, NULL);
|
||
}
|
||
|
||
if (elapsed < unit) {
|
||
// Segment 0: background only, nothing extra
|
||
} else if (elapsed < unit * 2) {
|
||
// Segment 1: slide[2] (ALK 63) passes top-to-bottom at 50% alpha
|
||
SDL_Texture *tex = slide[2];
|
||
if (tex) {
|
||
int tw, th;
|
||
SDL_QueryTexture(tex, NULL, NULL, &tw, &th);
|
||
int y = (int)((long long)(th + view_h) * (elapsed - unit) / unit) - th;
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(tex, 0x80);
|
||
SDL_Rect dst = {(view_w - tw) / 2, y, tw, th};
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, &dst);
|
||
}
|
||
} else if (elapsed < unit * 3) {
|
||
// Segment 2: overlay[0] (ALK 69) pingpong fade
|
||
SDL_Texture *tex = overlay[0];
|
||
if (tex) {
|
||
int t2 = elapsed % unit;
|
||
if (t2 >= unit / 2) t2 = unit - t2;
|
||
int alpha = (t2 * 255) / (unit / 2);
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(tex, (Uint8)SDL_min(alpha, 255));
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, NULL);
|
||
}
|
||
} else if (elapsed < unit * 4) {
|
||
// Segment 3: slide[1] (ALK 62) passes top-to-bottom at 50% alpha
|
||
SDL_Texture *tex = slide[1];
|
||
if (tex) {
|
||
int tw, th;
|
||
SDL_QueryTexture(tex, NULL, NULL, &tw, &th);
|
||
int y = (int)((long long)(th + view_h) * (elapsed - unit * 3) / unit) - th;
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(tex, 0x80);
|
||
SDL_Rect dst = {(view_w - tw) / 2, y, tw, th};
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, &dst);
|
||
}
|
||
} else if (elapsed < unit * 5) {
|
||
// Segment 4: overlay[1] (ALK 70) pingpong fade
|
||
SDL_Texture *tex = overlay[1];
|
||
if (tex) {
|
||
int t2 = elapsed % unit;
|
||
if (t2 >= unit / 2) t2 = unit - t2;
|
||
int alpha = (t2 * 255) / (unit / 2);
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(tex, (Uint8)SDL_min(alpha, 255));
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, NULL);
|
||
}
|
||
} else if (elapsed < unit * 6) {
|
||
// Segment 5: slide[0] (ALK 61) passes top-to-bottom at 50% alpha
|
||
SDL_Texture *tex = slide[0];
|
||
if (tex) {
|
||
int tw, th;
|
||
SDL_QueryTexture(tex, NULL, NULL, &tw, &th);
|
||
int y = (int)((long long)(th + view_h) * (elapsed - unit * 5) / unit) - th;
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(tex, 0x80);
|
||
SDL_Rect dst = {(view_w - tw) / 2, y, tw, th};
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, &dst);
|
||
}
|
||
} else if (elapsed < unit * 7) {
|
||
// Segment 6: overlay[2] (ALK 71) pingpong fade
|
||
SDL_Texture *tex = overlay[2];
|
||
if (tex) {
|
||
int t2 = elapsed % unit;
|
||
if (t2 >= unit / 2) t2 = unit - t2;
|
||
int alpha = (t2 * 255) / (unit / 2);
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(tex, (Uint8)SDL_min(alpha, 255));
|
||
SDL_RenderCopy(gfx_renderer, tex, NULL, NULL);
|
||
}
|
||
} else {
|
||
// Segment 7: white fade out
|
||
int fade_alpha = (duration > unit * 7)
|
||
? ((elapsed - unit * 7) * 255) / (duration - unit * 7)
|
||
: 255;
|
||
fade_overlay(0xff, 0xff, 0xff, (Uint8)SDL_min(fade_alpha, 255));
|
||
}
|
||
}
|
||
|
||
// Scene 12 is a complex 10.37s animation with multiple layers and a 3D spinning quad:
|
||
// ALK[64]: background image A
|
||
// ALK[65]: background image B
|
||
// ALK[66]: overlay image
|
||
// ALK[67]: 3D quad texture
|
||
//
|
||
// Timeline (relative to scene start):
|
||
// 0–2076ms: fade in bg_a from white (white overlay 255→0)
|
||
// 2076–2226ms: bg_a static
|
||
// 2226–3826ms: crossfade bg_a → bg_b
|
||
// 3826–3976ms: bg_b static
|
||
// 3976–7803ms: bg_b wave distortion (TODO) + bg_b at α=0xB0 + fade to white
|
||
// 7803–9397ms: white bg + 3D rotating quad + overlay fade in (0→255)
|
||
// 9397–10338ms: overlay static
|
||
//
|
||
// 3D rendering (7803–9397ms):
|
||
// A rhombus-shaped textured quad in the XY plane at z=-2.4 (world space),
|
||
// spinning around the Y axis (2 full rotations over 1594ms).
|
||
// Projection: vertical FoV=60°, aspect=4:3, near=0.25, far=2000.
|
||
// Vertex positions (model space):
|
||
// v0=(0, -0.51524, 0) UV:(0,0)
|
||
// v1=(0.28806, 0.22720, 0) UV:(1,0)
|
||
// v2=(0, 0.51524, 0) UV:(1,1)
|
||
// v3=(-0.28806, -0.22720, 0) UV:(0,1)
|
||
static void render_scene12_3d(int elapsed) {
|
||
SDL_Texture *tex = dd.images[67];
|
||
if (!tex) return;
|
||
|
||
// Model-space vertices (x, y, z) forming a rhombus in the XY plane.
|
||
static const float mv[4][3] = {
|
||
{ 0.00000f, -0.51524f, 0.0f }, // v0
|
||
{ 0.28806f, 0.22720f, 0.0f }, // v1
|
||
{ 0.00000f, 0.51524f, 0.0f }, // v2
|
||
{ -0.28806f, -0.22720f, 0.0f }, // v3
|
||
};
|
||
// Normalized texture UV per vertex
|
||
static const float muv[4][2] = {
|
||
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
|
||
};
|
||
|
||
// Y-rotation: 2 full rotations over the 1594ms 3D phase.
|
||
float t = (float)(elapsed - 7803);
|
||
float angle = t * (4.0f * (float)M_PI / 1594.0f);
|
||
float cos_a = cosf(angle);
|
||
float sin_a = sinf(angle);
|
||
|
||
// Perspective projection parameters: see PROJ_SCALE_X/Y, PROJ_W_DENOM
|
||
const float half_w = (float)view_w * 0.5f;
|
||
const float half_h = (float)view_h * 0.5f;
|
||
|
||
SDL_Vertex verts[4];
|
||
for (int i = 0; i < 4; i++) {
|
||
// World transform: Y-rotate first, then translate(+0.01, 0, -2.4).
|
||
float rx = cos_a * mv[i][0] + sin_a * mv[i][2];
|
||
float ry = mv[i][1];
|
||
float rz = -sin_a * mv[i][0] + cos_a * mv[i][2];
|
||
float wx = rx + 0.01f;
|
||
float wy = ry;
|
||
float wz = rz - 2.4f;
|
||
|
||
// Perspective divide: w = -wz * PROJ_W_DENOM (wz is negative → w positive)
|
||
float w = -wz * PROJ_W_DENOM;
|
||
if (w <= 0.0f) w = 1e-5f;
|
||
|
||
// NDC → screen
|
||
verts[i].position.x = (wx * PROJ_SCALE_X / w + 1.0f) * half_w;
|
||
verts[i].position.y = (wy * PROJ_SCALE_Y / w + 1.0f) * half_h;
|
||
verts[i].color = (SDL_Color){255, 255, 255, 255};
|
||
verts[i].tex_coord.x = muv[i][0];
|
||
verts[i].tex_coord.y = muv[i][1];
|
||
}
|
||
|
||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE);
|
||
render_quad(tex, verts);
|
||
}
|
||
|
||
static void render_scene12(int elapsed) {
|
||
SDL_Texture *bg_a = dd.images[64];
|
||
SDL_Texture *bg_b = dd.images[65];
|
||
SDL_Texture *overlay = dd.images[66];
|
||
|
||
if (elapsed < 2076) {
|
||
// 0–2076ms: bg_a with white fade-in overlay
|
||
if (bg_a) {
|
||
SDL_SetTextureBlendMode(bg_a, SDL_BLENDMODE_NONE);
|
||
SDL_RenderCopy(gfx_renderer, bg_a, NULL, NULL);
|
||
}
|
||
int white_alpha = 0xff - (elapsed * 0xff) / 2076;
|
||
fade_overlay(0xff, 0xff, 0xff, (Uint8)white_alpha);
|
||
} else if (elapsed < 2226) {
|
||
// 2076–2226ms: bg_a static
|
||
if (bg_a) {
|
||
SDL_SetTextureBlendMode(bg_a, SDL_BLENDMODE_NONE);
|
||
SDL_RenderCopy(gfx_renderer, bg_a, NULL, NULL);
|
||
}
|
||
} else if (elapsed < 3826) {
|
||
// 2226–3826ms: crossfade bg_a → bg_b
|
||
if (bg_a) {
|
||
SDL_SetTextureBlendMode(bg_a, SDL_BLENDMODE_NONE);
|
||
SDL_RenderCopy(gfx_renderer, bg_a, NULL, NULL);
|
||
}
|
||
if (bg_b) {
|
||
int alpha = ((elapsed - 2226) * 0xff) / 1600;
|
||
SDL_SetTextureBlendMode(bg_b, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(bg_b, (Uint8)SDL_min(alpha, 0xff));
|
||
SDL_RenderCopy(gfx_renderer, bg_b, NULL, NULL);
|
||
}
|
||
} else if (elapsed < 3976) {
|
||
// 3826–3976ms: bg_b static
|
||
if (bg_b) {
|
||
SDL_SetTextureBlendMode(bg_b, SDL_BLENDMODE_NONE);
|
||
SDL_RenderCopy(gfx_renderer, bg_b, NULL, NULL);
|
||
}
|
||
} else if (elapsed < 7803) {
|
||
// 3976–7803ms: TODO wave distortion on bg_b; for now just show bg_b,
|
||
// then fade to white
|
||
if (bg_b) {
|
||
SDL_SetTextureBlendMode(bg_b, SDL_BLENDMODE_BLEND);
|
||
SDL_RenderCopy(gfx_renderer, bg_b, NULL, NULL);
|
||
}
|
||
int white_alpha = ((elapsed - 3976) * 0xff) / 3827;
|
||
fade_overlay(0xff, 0xff, 0xff, (Uint8)SDL_min(white_alpha, 0xff));
|
||
} else if (elapsed < 9397) {
|
||
// 7803–9397ms: white bg + 3D rotating quad + overlay fade-in
|
||
SDL_SetRenderDrawBlendMode(gfx_renderer, SDL_BLENDMODE_NONE);
|
||
SDL_SetRenderDrawColor(gfx_renderer, 0xff, 0xff, 0xff, 0xff);
|
||
SDL_RenderFillRect(gfx_renderer, NULL);
|
||
render_scene12_3d(elapsed);
|
||
if (overlay) {
|
||
int alpha = ((elapsed - 7803) * 0xff) / 1594;
|
||
SDL_SetTextureBlendMode(overlay, SDL_BLENDMODE_BLEND);
|
||
SDL_SetTextureAlphaMod(overlay, (Uint8)SDL_min(alpha, 0xff));
|
||
SDL_RenderCopy(gfx_renderer, overlay, NULL, NULL);
|
||
}
|
||
} else {
|
||
// 9397–10338ms: overlay static
|
||
if (overlay) {
|
||
SDL_SetTextureBlendMode(overlay, SDL_BLENDMODE_NONE);
|
||
SDL_RenderCopy(gfx_renderer, overlay, NULL, NULL);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void Run() {
|
||
TRACE("dDemo.Run:");
|
||
|
||
muscd_start(13, 1);
|
||
uint32_t start = sys_get_ticks();
|
||
int current_scene = 0;
|
||
while (!nact->is_quit && !(sys_getInputInfo() && dd.key_cancel)) {
|
||
uint32_t now = sys_get_ticks();
|
||
if (current_scene < NR_SCENES && now - start >= (uint32_t)scene_duration[current_scene]) {
|
||
current_scene++;
|
||
if (current_scene < NR_SCENES) {
|
||
start = now;
|
||
} else if (dd.loop) {
|
||
muscd_stop();
|
||
current_scene = 0;
|
||
start = now;
|
||
muscd_start(13, 1);
|
||
}
|
||
}
|
||
if (current_scene >= NR_SCENES) {
|
||
break;
|
||
}
|
||
SDL_SetRenderDrawColor(gfx_renderer, 0, 0, 0, 255);
|
||
SDL_RenderClear(gfx_renderer);
|
||
switch (current_scene) {
|
||
case 0:
|
||
render_scene0(now - start);
|
||
break;
|
||
case 1:
|
||
render_scene1(now - start);
|
||
break;
|
||
case 2:
|
||
render_scene_2_4_6(now - start, 2, 0, 3, 4);
|
||
break;
|
||
case 3:
|
||
render_scene_3_5_7_9(now - start, 11);
|
||
break;
|
||
case 4:
|
||
render_scene_2_4_6(now - start, 4, 1, 5, 6);
|
||
break;
|
||
case 5:
|
||
render_scene_3_5_7_9(now - start, 12);
|
||
break;
|
||
case 6:
|
||
render_scene_2_4_6(now - start, 6, 2, 7, 8);
|
||
break;
|
||
case 7:
|
||
render_scene_3_5_7_9(now - start, 13);
|
||
break;
|
||
case 8:
|
||
render_scene8(now - start);
|
||
break;
|
||
case 9:
|
||
render_scene_3_5_7_9(now - start, 14);
|
||
break;
|
||
case 10:
|
||
render_scene10(now - start);
|
||
break;
|
||
case 11:
|
||
render_scene11(now - start);
|
||
break;
|
||
case 12:
|
||
render_scene12(now - start);
|
||
break;
|
||
}
|
||
SDL_RenderPresent(gfx_renderer);
|
||
sys_wait_vsync();
|
||
}
|
||
|
||
muscd_stop();
|
||
|
||
for (int i = 0; i < NR_TEXTURES; i++) {
|
||
if (dd.images[i])
|
||
SDL_DestroyTexture(dd.images[i]);
|
||
dd.images[i] = NULL;
|
||
}
|
||
}
|
||
|
||
static const ModuleFunc functions[] = {
|
||
{"Init", Init},
|
||
{"Run", Run},
|
||
{"SetKeyCancelFlag", SetKeyCancelFlag},
|
||
{"SetLoopFlag", SetLoopFlag},
|
||
};
|
||
|
||
const Module module_dDemo = {"dDemo", functions, sizeof(functions) / sizeof(ModuleFunc)};
|