Compare commits

..
Author SHA1 Message Date
kichikuou 18af9be92d Route effect and dDemo rendering through gfx_updateScreen()
Effects and dDemo now register a redraw handler instead of presenting
frames themselves, so the current frame can be redrawn at any time
(e.g. on window expose) and the modal overlay is drawn during them.
2026-10-10 09:02:52 +09:00
kichikuou 82c8b76a58 Fix missing equipment gauges in Rance 5D
This fixes #83.

**CG_GRAPH checks the source CG's type before drawing, but
SACT.CG_QueryType only checked CGs already loaded into memory. The gauge
images had not been loaded yet, so they were reported as unused.

Check the ALD link table for unloaded CGs, then load them when querying
their dimensions.
2026-09-23 07:51:47 +09:00
6 changed files with 199 additions and 190 deletions
+57 -48
View File
@@ -58,6 +58,9 @@ static struct {
bool loop; bool loop;
bool key_cancel; bool key_cancel;
SDL_Texture *images[NR_TEXTURES]; SDL_Texture *images[NR_TEXTURES];
// State of the current frame, drawn by redraw().
int scene;
int elapsed;
} dd; } dd;
// For each corner, if a coordinate is out of [0, view_w-1] x [0, view_h-1], // For each corner, if a coordinate is out of [0, view_w-1] x [0, view_h-1],
@@ -177,12 +180,11 @@ static void render_affine_bg(SDL_Texture *scroll_bg, int elapsed, int duration,
} }
SDL_Vertex verts[4]; SDL_Vertex verts[4];
static int y_toggle = 0;
// Pass 1: Forward mapping layer // Pass 1: Forward mapping layer
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
verts[i].position.x = (i == 1 || i == 2) ? w : 0; verts[i].position.x = (i == 1 || i == 2) ? w : 0;
verts[i].position.y = (i == 2 || i == 3) ? h : (float)y_toggle; verts[i].position.y = (i == 2 || i == 3) ? h : 0;
verts[i].color = (SDL_Color){255, 255, 255, 255}; verts[i].color = (SDL_Color){255, 255, 255, 255};
verts[i].tex_coord.x = uv[i][0]; verts[i].tex_coord.x = uv[i][0];
verts[i].tex_coord.y = uv[i][1]; verts[i].tex_coord.y = uv[i][1];
@@ -191,9 +193,7 @@ static void render_affine_bg(SDL_Texture *scroll_bg, int elapsed, int duration,
render_quad(scroll_bg, verts); render_quad(scroll_bg, verts);
// Pass 2: 180° rotated mapping layer // Pass 2: 180° rotated mapping layer
y_toggle = (y_toggle + 1) & 1;
for (int i = 0; i < 4; i++) { 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}; verts[i].color = (SDL_Color){255, 255, 255, 128};
} }
// Swap mapping: TL<->BR, TR<->BL for 180° rotation effect // Swap mapping: TL<->BR, TR<->BL for 180° rotation effect
@@ -875,12 +875,61 @@ static void render_scene12(int elapsed) {
} }
} }
static void redraw(void *arg) {
SDL_SetRenderDrawColor(gfx_renderer, 0, 0, 0, 255);
SDL_RenderClear(gfx_renderer);
switch (dd.scene) {
case 0:
render_scene0(dd.elapsed);
break;
case 1:
render_scene1(dd.elapsed);
break;
case 2:
render_scene_2_4_6(dd.elapsed, 2, 0, 3, 4);
break;
case 3:
render_scene_3_5_7_9(dd.elapsed, 11);
break;
case 4:
render_scene_2_4_6(dd.elapsed, 4, 1, 5, 6);
break;
case 5:
render_scene_3_5_7_9(dd.elapsed, 12);
break;
case 6:
render_scene_2_4_6(dd.elapsed, 6, 2, 7, 8);
break;
case 7:
render_scene_3_5_7_9(dd.elapsed, 13);
break;
case 8:
render_scene8(dd.elapsed);
break;
case 9:
render_scene_3_5_7_9(dd.elapsed, 14);
break;
case 10:
render_scene10(dd.elapsed);
break;
case 11:
render_scene11(dd.elapsed);
break;
case 12:
render_scene12(dd.elapsed);
break;
}
}
static void Run() { static void Run() {
TRACE("dDemo.Run:"); TRACE("dDemo.Run:");
muscd_start(13, 1); muscd_start(13, 1);
uint32_t start = sys_get_ticks(); uint32_t start = sys_get_ticks();
int current_scene = 0; int current_scene = 0;
dd.scene = 0;
dd.elapsed = 0;
gfx_setRedrawHandler(redraw, NULL);
while (!nact->is_quit && !(sys_getInputInfo() && dd.key_cancel)) { while (!nact->is_quit && !(sys_getInputInfo() && dd.key_cancel)) {
uint32_t now = sys_get_ticks(); uint32_t now = sys_get_ticks();
if (current_scene < NR_SCENES && now - start >= (uint32_t)scene_duration[current_scene]) { if (current_scene < NR_SCENES && now - start >= (uint32_t)scene_duration[current_scene]) {
@@ -897,53 +946,13 @@ static void Run() {
if (current_scene >= NR_SCENES) { if (current_scene >= NR_SCENES) {
break; break;
} }
SDL_SetRenderDrawColor(gfx_renderer, 0, 0, 0, 255); dd.scene = current_scene;
SDL_RenderClear(gfx_renderer); dd.elapsed = now - start;
switch (current_scene) { gfx_requestRedraw();
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(); sys_wait_vsync();
} }
gfx_setRedrawHandler(NULL, NULL);
muscd_stop(); muscd_stop();
for (int i = 0; i < NR_TEXTURES; i++) { for (int i = 0; i < NR_TEXTURES; i++) {
+15 -11
View File
@@ -35,6 +35,7 @@
#include "ags.h" #include "ags.h"
#include "variable.h" #include "variable.h"
#include "sactcg.h" #include "sactcg.h"
#include "ald_manager.h"
#include "cg.h" #include "cg.h"
#include "gfx.h" #include "gfx.h"
@@ -328,24 +329,27 @@ void scg_free(int no) {
// CGの種類を取得 // CGの種類を取得
int scg_querytype(int wNumCG) { int scg_querytype(int wNumCG) {
if (wNumCG >= (CGMAX -1)) return CG_NOTUSED; if (wNumCG >= (CGMAX -1)) return CG_NOTUSED;
if (!cg_store || !cg_store[wNumCG]) return CG_NOTUSED; if (cg_store && cg_store[wNumCG])
return cg_store[wNumCG]->type; return cg_store[wNumCG]->type;
// Linked CGs are valid even before they are loaded into cg_store.
return ald_is_linked(DRIFILE_CG, wNumCG - 1) ? CG_LINKED : CG_NOTUSED;
} }
// CGの大きさを取得 // CGの大きさを取得
bool scg_querysize(int wNumCG, vmvar_t *w, vmvar_t *h) { bool scg_querysize(int wNumCG, vmvar_t *w, vmvar_t *h) {
if (wNumCG >= (CGMAX -1)) goto errexit;
if (!cg_store || !cg_store[wNumCG]) goto errexit;
if (cg_store[wNumCG]->sf == NULL) goto errexit;
*w = cg_store[wNumCG]->sf->w;
*h = cg_store[wNumCG]->sf->h;
return true;
errexit:
*w = *h = 0; *w = *h = 0;
if (wNumCG >= (CGMAX - 1))
return false; return false;
cginfo_t *cg = cg_store ? cg_store[wNumCG] : NULL;
if (!cg && ald_is_linked(DRIFILE_CG, wNumCG - 1))
cg = scg_get(wNumCG);
if (!cg || !cg->sf)
return false;
*w = cg->sf->w;
*h = cg->sf->h;
return true;
} }
// CGのBPPを取得 // CGのBPPを取得
+112 -120
View File
@@ -173,14 +173,19 @@ static int render_effect_texture(EffectTexture *t, const SDL_Rect* srcrect, cons
} }
struct effect { struct effect {
void (*step)(struct effect *this, float progress); void (*draw)(struct effect *this, float progress);
// Optional. Advances the per-frame state, called once per effect_step().
void (*update)(struct effect *this, float progress);
void (*finish)(struct effect *this); void (*finish)(struct effect *this);
enum effect_type type; enum effect_type type;
SDL_Rect dst_rect; SDL_Rect dst_rect;
bool is_fullscreen; bool is_fullscreen;
EffectTexture *tx_old, *tx_new; EffectTexture *tx_old, *tx_new;
float progress;
}; };
static void effect_redraw(void *arg);
static void eff_init(struct effect *eff, SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static void eff_init(struct effect *eff, SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
eff->type = type; eff->type = type;
eff->dst_rect = *rect; eff->dst_rect = *rect;
@@ -191,17 +196,22 @@ static void eff_init(struct effect *eff, SDL_Rect *rect, EffectTexture *old, Eff
if (!eff->is_fullscreen) if (!eff->is_fullscreen)
gfx_updateScreen(); // Flush pending display changes. gfx_updateScreen(); // Flush pending display changes.
gfx_setEffectRunning(true); gfx_setRedrawHandler(effect_redraw, eff);
} }
static void draw_final_frame(struct effect *eff, float progress) {
render_effect_texture(eff->tx_new, NULL, &eff->dst_rect);
}
// If present is true, tx_new is displayed as the final frame. Otherwise the
// frame at progress 1.0 is left on the screen.
static void eff_finish(struct effect *eff, bool present) { static void eff_finish(struct effect *eff, bool present) {
if (present) { if (present) {
SDL_RenderClear(gfx_renderer); eff->draw = draw_final_frame;
if (!eff->is_fullscreen) gfx_requestRedraw();
SDL_RenderCopy(gfx_renderer, gfx_texture, NULL, NULL);
render_effect_texture(eff->tx_new, NULL, &eff->dst_rect);
SDL_RenderPresent(gfx_renderer);
} }
gfx_updateScreen(); // Make sure the last frame is displayed.
gfx_setRedrawHandler(NULL, NULL);
destroy_effect_texture(eff->tx_old); destroy_effect_texture(eff->tx_old);
destroy_effect_texture(eff->tx_new); destroy_effect_texture(eff->tx_new);
} }
@@ -230,7 +240,7 @@ static inline void move_rect(SDL_Rect *r, int off_x, int off_y) {
// EFFECT_CROSSFADE // EFFECT_CROSSFADE
static void crossfade_step(struct effect *eff, float progress); static void crossfade_draw(struct effect *eff, float progress);
static void crossfade_free(struct effect *eff); static void crossfade_free(struct effect *eff);
static struct effect *crossfade_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new) { static struct effect *crossfade_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new) {
@@ -238,19 +248,18 @@ static struct effect *crossfade_new(SDL_Rect *rect, EffectTexture *old, EffectTe
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, EFFECT_CROSSFADE); eff_init(eff, rect, old, new, EFFECT_CROSSFADE);
eff->step = crossfade_step; eff->draw = crossfade_draw;
eff->finish = crossfade_free; eff->finish = crossfade_free;
return eff; return eff;
} }
static void crossfade_step(struct effect *eff, float progress) { static void crossfade_draw(struct effect *eff, float progress) {
render_effect_texture(eff->tx_old, NULL, &eff->dst_rect); render_effect_texture(eff->tx_old, NULL, &eff->dst_rect);
SDL_SetTextureBlendMode(eff->tx_new->tx, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(eff->tx_new->tx, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(eff->tx_new->tx, progress * 255); SDL_SetTextureAlphaMod(eff->tx_new->tx, progress * 255);
render_effect_texture(eff->tx_new, NULL, &eff->dst_rect); render_effect_texture(eff->tx_new, NULL, &eff->dst_rect);
SDL_SetTextureAlphaMod(eff->tx_new->tx, 255); SDL_SetTextureAlphaMod(eff->tx_new->tx, 255);
SDL_SetTextureBlendMode(eff->tx_new->tx, SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(eff->tx_new->tx, SDL_BLENDMODE_NONE);
SDL_RenderPresent(gfx_renderer);
} }
static void crossfade_free(struct effect *eff) { static void crossfade_free(struct effect *eff) {
@@ -265,7 +274,7 @@ static struct effect *fallback_effect_new(SDL_Rect *rect, EffectTexture *old, Ef
// EFFECT_CROSSFADE_{UP,DOWN,LR,RL} // EFFECT_CROSSFADE_{UP,DOWN,LR,RL}
static void crossfade_animation_step(struct effect *eff, float progress); static void crossfade_animation_draw(struct effect *eff, float progress);
static void crossfade_animation_free(struct effect *eff); static void crossfade_animation_free(struct effect *eff);
static struct effect *crossfade_animation_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *crossfade_animation_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -273,12 +282,12 @@ static struct effect *crossfade_animation_new(SDL_Rect *rect, EffectTexture *old
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = crossfade_animation_step; eff->draw = crossfade_animation_draw;
eff->finish = crossfade_animation_free; eff->finish = crossfade_animation_free;
return eff; return eff;
} }
static void crossfade_animation_step_sub(SDL_Rect *rect, EffectTexture *tx, int tx_x, int tx_y, float progress, int band_width, bool lr, bool flip) { static void crossfade_animation_draw_sub(SDL_Rect *rect, EffectTexture *tx, int tx_x, int tx_y, float progress, int band_width, bool lr, bool flip) {
int maxstep = (lr ? rect->w : rect->h) + band_width; int maxstep = (lr ? rect->w : rect->h) + band_width;
int band_top = maxstep * progress - band_width; int band_top = maxstep * progress - band_width;
if (band_top > 0) { if (band_top > 0) {
@@ -324,31 +333,31 @@ static void crossfade_animation_step_sub(SDL_Rect *rect, EffectTexture *tx, int
SDL_SetTextureBlendMode(tx->tx, SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(tx->tx, SDL_BLENDMODE_NONE);
} }
static void crossfade_animation_step(struct effect *eff, float progress) { static void crossfade_animation_draw(struct effect *eff, float progress) {
render_effect_texture(eff->tx_old, NULL, &eff->dst_rect); render_effect_texture(eff->tx_old, NULL, &eff->dst_rect);
switch (eff->type) { switch (eff->type) {
case EFFECT_CROSSFADE_DOWN: case EFFECT_CROSSFADE_DOWN:
crossfade_animation_step_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, false, false); crossfade_animation_draw_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, false, false);
break; break;
case EFFECT_CROSSFADE_UP: case EFFECT_CROSSFADE_UP:
crossfade_animation_step_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, false, true); crossfade_animation_draw_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, false, true);
break; break;
case EFFECT_CROSSFADE_LR: case EFFECT_CROSSFADE_LR:
crossfade_animation_step_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, true, false); crossfade_animation_draw_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, true, false);
break; break;
case EFFECT_CROSSFADE_RL: case EFFECT_CROSSFADE_RL:
crossfade_animation_step_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, true, true); crossfade_animation_draw_sub(&eff->dst_rect, eff->tx_new, 0, 0, progress, 254, true, true);
break; break;
case EFFECT_CROSSFADE_UP_DOWN: case EFFECT_CROSSFADE_UP_DOWN:
{ {
SDL_Rect dr = eff->dst_rect; SDL_Rect dr = eff->dst_rect;
int th = dr.h /= 2; int th = dr.h /= 2;
dr.h = th; dr.h = th;
crossfade_animation_step_sub(&dr, eff->tx_new, 0, 0, progress, 127, false, true); crossfade_animation_draw_sub(&dr, eff->tx_new, 0, 0, progress, 127, false, true);
dr.y += th; dr.y += th;
dr.h = eff->dst_rect.h - th; dr.h = eff->dst_rect.h - th;
crossfade_animation_step_sub(&dr, eff->tx_new, 0, th, progress, 127, false, false); crossfade_animation_draw_sub(&dr, eff->tx_new, 0, th, progress, 127, false, false);
} }
break; break;
case EFFECT_CROSSFADE_LR_RL: case EFFECT_CROSSFADE_LR_RL:
@@ -356,17 +365,15 @@ static void crossfade_animation_step(struct effect *eff, float progress) {
SDL_Rect dr = eff->dst_rect; SDL_Rect dr = eff->dst_rect;
int lw = dr.w /= 2; int lw = dr.w /= 2;
dr.w = lw; dr.w = lw;
crossfade_animation_step_sub(&dr, eff->tx_new, 0, 0, progress, 127, true, true); crossfade_animation_draw_sub(&dr, eff->tx_new, 0, 0, progress, 127, true, true);
dr.x += lw; dr.x += lw;
dr.w = eff->dst_rect.w - lw; dr.w = eff->dst_rect.w - lw;
crossfade_animation_step_sub(&dr, eff->tx_new, lw, 0, progress, 127, true, false); crossfade_animation_draw_sub(&dr, eff->tx_new, lw, 0, progress, 127, true, false);
} }
break; break;
default: default:
assert(!"Cannot happen"); assert(!"Cannot happen");
} }
SDL_RenderPresent(gfx_renderer);
} }
static void crossfade_animation_free(struct effect *eff) { static void crossfade_animation_free(struct effect *eff) {
@@ -381,7 +388,7 @@ struct mosaic_effect {
SDL_Texture *tmp_old, *tmp_new, *tx_mosaic; SDL_Texture *tmp_old, *tmp_new, *tx_mosaic;
}; };
static void mosaic_step(struct effect *eff, float progress); static void mosaic_draw(struct effect *eff, float progress);
static void mosaic_free(struct effect *eff); static void mosaic_free(struct effect *eff);
static struct effect *mosaic_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *mosaic_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -395,7 +402,7 @@ static struct effect *mosaic_new(SDL_Rect *rect, EffectTexture *old, EffectTextu
eff->tmp_old = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); eff->tmp_old = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h);
eff->tmp_new = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); eff->tmp_new = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h);
eff->tx_mosaic = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); eff->tx_mosaic = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h);
eff->eff.step = mosaic_step; eff->eff.draw = mosaic_draw;
eff->eff.finish = mosaic_free; eff->eff.finish = mosaic_free;
return &eff->eff; return &eff->eff;
} }
@@ -425,7 +432,7 @@ static void mosaic(EffectTexture *src, SDL_Texture *tmp, SDL_Texture *dst, int w
SDL_SetRenderTarget(gfx_renderer, NULL); SDL_SetRenderTarget(gfx_renderer, NULL);
} }
static void mosaic_step(struct effect *eff, float progress) { static void mosaic_draw(struct effect *eff, float progress) {
struct mosaic_effect *this = (struct mosaic_effect *)eff; struct mosaic_effect *this = (struct mosaic_effect *)eff;
if (eff->type == EFFECT_MOSAIC) { if (eff->type == EFFECT_MOSAIC) {
@@ -446,22 +453,20 @@ static void mosaic_step(struct effect *eff, float progress) {
} else { } else {
assert(!"Cannot happen"); assert(!"Cannot happen");
} }
SDL_RenderPresent(gfx_renderer);
} }
static void mosaic_free(struct effect *eff) { static void mosaic_free(struct effect *eff) {
struct mosaic_effect *this = (struct mosaic_effect *)eff; struct mosaic_effect *this = (struct mosaic_effect *)eff;
eff_finish(&this->eff, true);
SDL_DestroyTexture(this->tmp_old); SDL_DestroyTexture(this->tmp_old);
SDL_DestroyTexture(this->tmp_new); SDL_DestroyTexture(this->tmp_new);
SDL_DestroyTexture(this->tx_mosaic); SDL_DestroyTexture(this->tx_mosaic);
eff_finish(&this->eff, true);
free(this); free(this);
} }
// EFFECT_{FADE,WHITE}{OUT,IN} // EFFECT_{FADE,WHITE}{OUT,IN}
static void brightness_step(struct effect *eff, float progress); static void brightness_draw(struct effect *eff, float progress);
static void brightness_free(struct effect *eff); static void brightness_free(struct effect *eff);
static struct effect *brightness_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *brightness_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -469,12 +474,12 @@ static struct effect *brightness_new(SDL_Rect *rect, EffectTexture *old, EffectT
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = brightness_step; eff->draw = brightness_draw;
eff->finish = brightness_free; eff->finish = brightness_free;
return eff; return eff;
} }
static void brightness_step(struct effect *eff, float progress) { static void brightness_draw(struct effect *eff, float progress) {
EffectTexture *texture; EffectTexture *texture;
int color; int color;
int alpha; int alpha;
@@ -518,7 +523,6 @@ static void brightness_step(struct effect *eff, float progress) {
SDL_RenderFillRect(gfx_renderer, &eff->dst_rect); SDL_RenderFillRect(gfx_renderer, &eff->dst_rect);
SDL_SetRenderDrawBlendMode(gfx_renderer, SDL_BLENDMODE_NONE); SDL_SetRenderDrawBlendMode(gfx_renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(gfx_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); SDL_SetRenderDrawColor(gfx_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderPresent(gfx_renderer);
} }
static void brightness_free(struct effect *eff) { static void brightness_free(struct effect *eff) {
@@ -528,7 +532,7 @@ static void brightness_free(struct effect *eff) {
// EFFECT_DITHERING_{FADE,WHITE}{OUT,IN} // EFFECT_DITHERING_{FADE,WHITE}{OUT,IN}
static void dithering_fade_step(struct effect *eff, float progress); static void dithering_fade_draw(struct effect *eff, float progress);
static void dithering_fade_free(struct effect *eff); static void dithering_fade_free(struct effect *eff);
static EffectTexture *create_dither_pattern_texture(int w, int h, int val) { static EffectTexture *create_dither_pattern_texture(int w, int h, int val) {
@@ -582,12 +586,12 @@ static struct effect *dithering_fade_new(SDL_Rect *rect, EffectTexture *old, Eff
default: default:
assert(!"Cannot happen"); assert(!"Cannot happen");
} }
eff->step = dithering_fade_step; eff->draw = dithering_fade_draw;
eff->finish = dithering_fade_free; eff->finish = dithering_fade_free;
return eff; return eff;
} }
static void dithering_fade_step(struct effect *eff, float progress) { static void dithering_fade_draw(struct effect *eff, float progress) {
static const int dither_x[16] = {0,2,2,0,1,3,3,1,1,3,3,1,0,2,2,0}; static const int dither_x[16] = {0,2,2,0,1,3,3,1,1,3,3,1,0,2,2,0};
static const int dither_y[16] = {0,2,0,2,1,3,1,3,0,2,0,2,1,3,1,3}; static const int dither_y[16] = {0,2,0,2,1,3,1,3,0,2,0,2,1,3,1,3};
@@ -604,8 +608,6 @@ static void dithering_fade_step(struct effect *eff, float progress) {
dr.y = eff->dst_rect.y + dither_y[i]; dr.y = eff->dst_rect.y + dither_y[i];
render_effect_texture(eff->tx_new, NULL, &dr); render_effect_texture(eff->tx_new, NULL, &dr);
} }
SDL_RenderPresent(gfx_renderer);
} }
static void dithering_fade_free(struct effect *eff) { static void dithering_fade_free(struct effect *eff) {
@@ -622,7 +624,7 @@ static void dithering_fade_free(struct effect *eff) {
// EFFECT_PAN_IN_* // EFFECT_PAN_IN_*
static void pan_in_step(struct effect *eff, float progress); static void pan_in_draw(struct effect *eff, float progress);
static void pan_in_free(struct effect *eff); static void pan_in_free(struct effect *eff);
static struct effect *pan_in_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *pan_in_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -630,12 +632,12 @@ static struct effect *pan_in_new(SDL_Rect *rect, EffectTexture *old, EffectTextu
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = pan_in_step; eff->draw = pan_in_draw;
eff->finish = pan_in_free; eff->finish = pan_in_free;
return eff; return eff;
} }
static void pan_in_step(struct effect *eff, float progress) { static void pan_in_draw(struct effect *eff, float progress) {
render_effect_texture(eff->tx_old, NULL, &eff->dst_rect); render_effect_texture(eff->tx_old, NULL, &eff->dst_rect);
int h = eff->dst_rect.h * progress; int h = eff->dst_rect.h * progress;
@@ -648,8 +650,6 @@ static void pan_in_step(struct effect *eff, float progress) {
dr.y += eff->dst_rect.h - h; dr.y += eff->dst_rect.h - h;
} }
render_effect_texture(eff->tx_new, &sr, &dr); render_effect_texture(eff->tx_new, &sr, &dr);
SDL_RenderPresent(gfx_renderer);
} }
static void pan_in_free(struct effect *eff) { static void pan_in_free(struct effect *eff) {
@@ -659,7 +659,7 @@ static void pan_in_free(struct effect *eff) {
// EFFECT_SKIP_LINE_* // EFFECT_SKIP_LINE_*
static void skip_line_step(struct effect *eff, float progress); static void skip_line_draw(struct effect *eff, float progress);
static void skip_line_free(struct effect *eff); static void skip_line_free(struct effect *eff);
static struct effect *skip_line_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *skip_line_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -667,12 +667,12 @@ static struct effect *skip_line_new(SDL_Rect *rect, EffectTexture *old, EffectTe
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = skip_line_step; eff->draw = skip_line_draw;
eff->finish = skip_line_free; eff->finish = skip_line_free;
return eff; return eff;
} }
static void skip_line_step(struct effect *eff, float progress) { static void skip_line_draw(struct effect *eff, float progress) {
render_effect_texture(eff->tx_old, NULL, &eff->dst_rect); render_effect_texture(eff->tx_old, NULL, &eff->dst_rect);
if (eff->type == EFFECT_SKIP_LINE_UP_DOWN) { if (eff->type == EFFECT_SKIP_LINE_UP_DOWN) {
@@ -712,8 +712,6 @@ static void skip_line_step(struct effect *eff, float progress) {
render_effect_texture(eff->tx_new, &sr, &dr); render_effect_texture(eff->tx_new, &sr, &dr);
} }
} }
SDL_RenderPresent(gfx_renderer);
} }
static void skip_line_free(struct effect *eff) { static void skip_line_free(struct effect *eff) {
@@ -723,7 +721,7 @@ static void skip_line_free(struct effect *eff) {
// EFFECT_WIPE_* // EFFECT_WIPE_*
static void wipe_step(struct effect *eff, float progress); static void wipe_draw(struct effect *eff, float progress);
static void wipe_free(struct effect *eff); static void wipe_free(struct effect *eff);
static struct effect *wipe_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *wipe_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -731,12 +729,12 @@ static struct effect *wipe_new(SDL_Rect *rect, EffectTexture *old, EffectTexture
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = wipe_step; eff->draw = wipe_draw;
eff->finish = wipe_free; eff->finish = wipe_free;
return eff; return eff;
} }
static void wipe_step(struct effect *eff, float progress) { static void wipe_draw(struct effect *eff, float progress) {
EffectTexture *bg = eff->tx_old; EffectTexture *bg = eff->tx_old;
EffectTexture *fg = eff->tx_new; EffectTexture *fg = eff->tx_new;
if (eff->type == EFFECT_WIPE_RL || if (eff->type == EFFECT_WIPE_RL ||
@@ -786,8 +784,6 @@ static void wipe_step(struct effect *eff, float progress) {
assert(!"Cannot happen"); assert(!"Cannot happen");
} }
render_effect_texture(fg, &sr, &dr); render_effect_texture(fg, &sr, &dr);
SDL_RenderPresent(gfx_renderer);
} }
static void wipe_free(struct effect *eff) { static void wipe_free(struct effect *eff) {
@@ -797,7 +793,7 @@ static void wipe_free(struct effect *eff) {
// EFFECT_CIRCLE_WIPE_* // EFFECT_CIRCLE_WIPE_*
static void circle_wipe_step(struct effect *eff, float progress); static void circle_wipe_draw(struct effect *eff, float progress);
static void circle_wipe_free(struct effect *eff); static void circle_wipe_free(struct effect *eff);
static struct effect *circle_wipe_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *circle_wipe_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -805,12 +801,12 @@ static struct effect *circle_wipe_new(SDL_Rect *rect, EffectTexture *old, Effect
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = circle_wipe_step; eff->draw = circle_wipe_draw;
eff->finish = circle_wipe_free; eff->finish = circle_wipe_free;
return eff; return eff;
} }
static void circle_wipe_step(struct effect *eff, float progress) { static void circle_wipe_draw(struct effect *eff, float progress) {
EffectTexture *bg = eff->tx_old; EffectTexture *bg = eff->tx_old;
EffectTexture *fg = eff->tx_new; EffectTexture *fg = eff->tx_new;
if (eff->type == EFFECT_CIRCLE_WIPE_IN) { if (eff->type == EFFECT_CIRCLE_WIPE_IN) {
@@ -836,8 +832,6 @@ static void circle_wipe_step(struct effect *eff, float progress) {
} }
} }
} }
SDL_RenderPresent(gfx_renderer);
} }
static void circle_wipe_free(struct effect *eff) { static void circle_wipe_free(struct effect *eff) {
@@ -847,7 +841,7 @@ static void circle_wipe_free(struct effect *eff) {
// EFFECT_BLIND_* // EFFECT_BLIND_*
static void blind_step(struct effect *eff, float progress); static void blind_draw(struct effect *eff, float progress);
static void blind_free(struct effect *eff); static void blind_free(struct effect *eff);
static struct effect *blind_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *blind_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -855,12 +849,12 @@ static struct effect *blind_new(SDL_Rect *rect, EffectTexture *old, EffectTextur
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = blind_step; eff->draw = blind_draw;
eff->finish = blind_free; eff->finish = blind_free;
return eff; return eff;
} }
static void blind_vstep(float progress, SDL_Rect *rect, EffectTexture *tx_new, int offset_y, bool flip) { static void blind_vdraw(float progress, SDL_Rect *rect, EffectTexture *tx_new, int offset_y, bool flip) {
const int N = 16; const int N = 16;
int nr_bands = rect->h / N + N - 1; int nr_bands = rect->h / N + N - 1;
@@ -892,23 +886,23 @@ static void blind_vstep(float progress, SDL_Rect *rect, EffectTexture *tx_new, i
} }
} }
static void blind_step(struct effect *eff, float progress) { static void blind_draw(struct effect *eff, float progress) {
const int N = 16; const int N = 16;
render_effect_texture(eff->tx_old, NULL, &eff->dst_rect); render_effect_texture(eff->tx_old, NULL, &eff->dst_rect);
if (eff->type == EFFECT_BLIND_DOWN || eff->type == EFFECT_BLIND_UP || eff->type == EFFECT_BLIND_DOWN_LR) { if (eff->type == EFFECT_BLIND_DOWN || eff->type == EFFECT_BLIND_UP || eff->type == EFFECT_BLIND_DOWN_LR) {
blind_vstep(progress, &eff->dst_rect, eff->tx_new, 0, eff->type == EFFECT_BLIND_UP); blind_vdraw(progress, &eff->dst_rect, eff->tx_new, 0, eff->type == EFFECT_BLIND_UP);
} }
if (eff->type == EFFECT_BLIND_UP_DOWN) { if (eff->type == EFFECT_BLIND_UP_DOWN) {
SDL_Rect top_rect = eff->dst_rect; SDL_Rect top_rect = eff->dst_rect;
top_rect.h = top_rect.h / (N * 2) * N; top_rect.h = top_rect.h / (N * 2) * N;
blind_vstep(progress, &top_rect, eff->tx_new, 0, false); blind_vdraw(progress, &top_rect, eff->tx_new, 0, false);
SDL_Rect bottom_rect = eff->dst_rect; SDL_Rect bottom_rect = eff->dst_rect;
bottom_rect.y += top_rect.h; bottom_rect.y += top_rect.h;
bottom_rect.h -= top_rect.h; bottom_rect.h -= top_rect.h;
blind_vstep(progress, &bottom_rect, eff->tx_new, top_rect.h, true); blind_vdraw(progress, &bottom_rect, eff->tx_new, top_rect.h, true);
} }
if (eff->type == EFFECT_BLIND_LR || eff->type == EFFECT_BLIND_RL || eff->type == EFFECT_BLIND_DOWN_LR) { if (eff->type == EFFECT_BLIND_LR || eff->type == EFFECT_BLIND_RL || eff->type == EFFECT_BLIND_DOWN_LR) {
@@ -938,8 +932,6 @@ static void blind_step(struct effect *eff, float progress) {
render_effect_texture(eff->tx_new, &sr, &dr); render_effect_texture(eff->tx_new, &sr, &dr);
} }
} }
SDL_RenderPresent(gfx_renderer);
} }
static void blind_free(struct effect *eff) { static void blind_free(struct effect *eff) {
@@ -949,7 +941,7 @@ static void blind_free(struct effect *eff) {
// EFFECT_BLEND_* // EFFECT_BLEND_*
static void blend_animation_step(struct effect *eff, float progress); static void blend_animation_draw(struct effect *eff, float progress);
static void blend_animation_free(struct effect *eff); static void blend_animation_free(struct effect *eff);
static struct effect *blend_animation_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *blend_animation_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -957,12 +949,12 @@ static struct effect *blend_animation_new(SDL_Rect *rect, EffectTexture *old, Ef
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = blend_animation_step; eff->draw = blend_animation_draw;
eff->finish = blend_animation_free; eff->finish = blend_animation_free;
return eff; return eff;
} }
static void blend_animation_step(struct effect *eff, float progress) { static void blend_animation_draw(struct effect *eff, float progress) {
const bool lr = eff->type == EFFECT_BLEND_LR_RL; const bool lr = eff->type == EFFECT_BLEND_LR_RL;
EffectTexture *bg, *fg; EffectTexture *bg, *fg;
@@ -999,7 +991,6 @@ static void blend_animation_step(struct effect *eff, float progress) {
SDL_SetTextureAlphaMod(fg->tx, 255); SDL_SetTextureAlphaMod(fg->tx, 255);
SDL_SetTextureBlendMode(fg->tx, SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(fg->tx, SDL_BLENDMODE_NONE);
SDL_RenderPresent(gfx_renderer);
} }
static void blend_animation_free(struct effect *eff) { static void blend_animation_free(struct effect *eff) {
@@ -1017,7 +1008,8 @@ struct zoom_blend_blur_effect {
int index; int index;
}; };
static void zoom_blend_blur_step(struct effect *eff, float progress); static void zoom_blend_blur_update(struct effect *eff, float progress);
static void zoom_blend_blur_draw(struct effect *eff, float progress);
static void zoom_blend_blur_free(struct effect *eff); static void zoom_blend_blur_free(struct effect *eff);
static struct effect *zoom_blend_blur_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new) { static struct effect *zoom_blend_blur_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new) {
@@ -1028,12 +1020,14 @@ static struct effect *zoom_blend_blur_new(SDL_Rect *rect, EffectTexture *old, Ef
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(&eff->eff, rect, old, new, EFFECT_ZOOM_BLEND_BLUR); eff_init(&eff->eff, rect, old, new, EFFECT_ZOOM_BLEND_BLUR);
eff->eff.step = zoom_blend_blur_step; eff->eff.update = zoom_blend_blur_update;
eff->eff.draw = zoom_blend_blur_draw;
eff->eff.finish = zoom_blend_blur_free; eff->eff.finish = zoom_blend_blur_free;
return &eff->eff; return &eff->eff;
} }
static void zoom_blend_blur_step(struct effect *eff, float progress) { // Renders the zoomed image for this frame into the ring buffer of trails.
static void zoom_blend_blur_update(struct effect *eff, float progress) {
struct zoom_blend_blur_effect *this = (struct zoom_blend_blur_effect *)eff; struct zoom_blend_blur_effect *this = (struct zoom_blend_blur_effect *)eff;
if (!this->tx[this->index]) { if (!this->tx[this->index]) {
@@ -1054,6 +1048,10 @@ static void zoom_blend_blur_step(struct effect *eff, float progress) {
SDL_SetRenderTarget(gfx_renderer, NULL); SDL_SetRenderTarget(gfx_renderer, NULL);
this->index = (this->index + 1) % ZOOM_BLEND_BLUR_STEPS; this->index = (this->index + 1) % ZOOM_BLEND_BLUR_STEPS;
}
static void zoom_blend_blur_draw(struct effect *eff, float progress) {
struct zoom_blend_blur_effect *this = (struct zoom_blend_blur_effect *)eff;
SDL_RenderFillRect(gfx_renderer, &eff->dst_rect); SDL_RenderFillRect(gfx_renderer, &eff->dst_rect);
EffectTexture texture_rect = { NULL, { 0, 0, eff->dst_rect.w, eff->dst_rect.h } }; EffectTexture texture_rect = { NULL, { 0, 0, eff->dst_rect.w, eff->dst_rect.h } };
@@ -1066,16 +1064,15 @@ static void zoom_blend_blur_step(struct effect *eff, float progress) {
SDL_SetTextureBlendMode(t->tx, SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(t->tx, SDL_BLENDMODE_NONE);
SDL_SetTextureAlphaMod(t->tx, 255); SDL_SetTextureAlphaMod(t->tx, 255);
} }
SDL_RenderPresent(gfx_renderer);
} }
static void zoom_blend_blur_free(struct effect *eff) { static void zoom_blend_blur_free(struct effect *eff) {
struct zoom_blend_blur_effect *this = (struct zoom_blend_blur_effect *)eff; struct zoom_blend_blur_effect *this = (struct zoom_blend_blur_effect *)eff;
eff_finish(&this->eff, true);
for (int i = 0; i < ZOOM_BLEND_BLUR_STEPS; i++) { for (int i = 0; i < ZOOM_BLEND_BLUR_STEPS; i++) {
if (this->tx[i]) if (this->tx[i])
SDL_DestroyTexture(this->tx[i]); SDL_DestroyTexture(this->tx[i]);
} }
eff_finish(&this->eff, true);
free(this); free(this);
} }
@@ -1089,7 +1086,7 @@ struct linear_blur_effect {
EffectTexture *blurred_new[LINEAR_BLUR_STEPS]; EffectTexture *blurred_new[LINEAR_BLUR_STEPS];
}; };
static void linear_blur_step(struct effect *eff, float progress); static void linear_blur_draw(struct effect *eff, float progress);
static void linear_blur_free(struct effect *eff); static void linear_blur_free(struct effect *eff);
static struct effect *linear_blur_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *linear_blur_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -1100,7 +1097,7 @@ static struct effect *linear_blur_new(SDL_Rect *rect, EffectTexture *old, Effect
if (!lbe) if (!lbe)
NOMEMERR(); NOMEMERR();
eff_init(&lbe->eff, rect, old, new, type); eff_init(&lbe->eff, rect, old, new, type);
lbe->eff.step = linear_blur_step; lbe->eff.draw = linear_blur_draw;
lbe->eff.finish = linear_blur_free; lbe->eff.finish = linear_blur_free;
return &lbe->eff; return &lbe->eff;
} }
@@ -1147,13 +1144,12 @@ static EffectTexture *blur(struct linear_blur_effect *this, EffectTexture *src,
return dst; return dst;
} }
static void linear_blur_step(struct effect *eff, float progress) { static void linear_blur_draw(struct effect *eff, float progress) {
struct linear_blur_effect *this = (struct linear_blur_effect *)eff; struct linear_blur_effect *this = (struct linear_blur_effect *)eff;
int step = progress * LINEAR_BLUR_STEPS * 2; int step = progress * LINEAR_BLUR_STEPS * 2;
if (step == LINEAR_BLUR_STEPS * 2) { if (step == LINEAR_BLUR_STEPS * 2) {
render_effect_texture(eff->tx_new, NULL, NULL); render_effect_texture(eff->tx_new, NULL, NULL);
SDL_RenderPresent(gfx_renderer);
return; return;
} }
@@ -1171,18 +1167,17 @@ static void linear_blur_step(struct effect *eff, float progress) {
SDL_SetTextureBlendMode(new->tx, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(new->tx, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(new->tx, 255 * progress); SDL_SetTextureAlphaMod(new->tx, 255 * progress);
render_effect_texture(new, NULL, &eff->dst_rect); render_effect_texture(new, NULL, &eff->dst_rect);
SDL_RenderPresent(gfx_renderer);
} }
static void linear_blur_free(struct effect *eff) { static void linear_blur_free(struct effect *eff) {
struct linear_blur_effect *this = (struct linear_blur_effect *)eff; struct linear_blur_effect *this = (struct linear_blur_effect *)eff;
eff_finish(&this->eff, true);
for (int i = 0; i < LINEAR_BLUR_STEPS; i++) { for (int i = 0; i < LINEAR_BLUR_STEPS; i++) {
if (this->blurred_old[i]) if (this->blurred_old[i])
destroy_effect_texture(this->blurred_old[i]); destroy_effect_texture(this->blurred_old[i]);
if (this->blurred_new[i]) if (this->blurred_new[i])
destroy_effect_texture(this->blurred_new[i]); destroy_effect_texture(this->blurred_new[i]);
} }
eff_finish(&this->eff, true);
free(this); free(this);
} }
@@ -1193,7 +1188,7 @@ struct polygon_mask_effect {
SDL_Texture *tx_tmp; SDL_Texture *tx_tmp;
}; };
static void polygon_mask_step(struct effect *eff, float progress); static void polygon_mask_draw(struct effect *eff, float progress);
static void polygon_mask_free(struct effect *eff); static void polygon_mask_free(struct effect *eff);
static struct effect *polygon_mask_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *polygon_mask_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -1203,7 +1198,7 @@ static struct effect *polygon_mask_new(SDL_Rect *rect, EffectTexture *old, Effec
NOMEMERR(); NOMEMERR();
eff_init(&pmf->f, rect, old, new, type); eff_init(&pmf->f, rect, old, new, type);
pmf->tx_tmp = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); pmf->tx_tmp = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h);
pmf->f.step = polygon_mask_step; pmf->f.draw = polygon_mask_draw;
pmf->f.finish = polygon_mask_free; pmf->f.finish = polygon_mask_free;
return &pmf->f; return &pmf->f;
} }
@@ -1395,7 +1390,7 @@ static void draw_windmill_360(int w, int h, float theta) {
SDL_RenderGeometry(gfx_renderer, NULL, v, 10, indices, i); SDL_RenderGeometry(gfx_renderer, NULL, v, 10, indices, i);
} }
static void polygon_mask_step(struct effect *eff, float progress) { static void polygon_mask_draw(struct effect *eff, float progress) {
struct polygon_mask_effect *this = (struct polygon_mask_effect *)eff; struct polygon_mask_effect *this = (struct polygon_mask_effect *)eff;
int w = eff->dst_rect.w; int w = eff->dst_rect.w;
int h = eff->dst_rect.h; int h = eff->dst_rect.h;
@@ -1430,19 +1425,18 @@ static void polygon_mask_step(struct effect *eff, float progress) {
render_effect_texture(eff->tx_new, NULL, &eff->dst_rect); render_effect_texture(eff->tx_new, NULL, &eff->dst_rect);
SDL_SetTextureBlendMode(this->tx_tmp, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(this->tx_tmp, SDL_BLENDMODE_BLEND);
SDL_RenderCopy(gfx_renderer, this->tx_tmp, NULL, &eff->dst_rect); SDL_RenderCopy(gfx_renderer, this->tx_tmp, NULL, &eff->dst_rect);
SDL_RenderPresent(gfx_renderer);
} }
static void polygon_mask_free(struct effect *eff) { static void polygon_mask_free(struct effect *eff) {
struct polygon_mask_effect *this = (struct polygon_mask_effect *)eff; struct polygon_mask_effect *this = (struct polygon_mask_effect *)eff;
SDL_DestroyTexture(this->tx_tmp);
eff_finish(&this->f, true); eff_finish(&this->f, true);
SDL_DestroyTexture(this->tx_tmp);
free(this); free(this);
} }
// EFFECT_ROTATE_* // EFFECT_ROTATE_*
static void rotate_step(struct effect *eff, float progress); static void rotate_draw(struct effect *eff, float progress);
static void rotate_free(struct effect *eff); static void rotate_free(struct effect *eff);
static struct effect *rotate_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *rotate_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -1450,12 +1444,12 @@ static struct effect *rotate_new(SDL_Rect *rect, EffectTexture *old, EffectTextu
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = rotate_step; eff->draw = rotate_draw;
eff->finish = rotate_free; eff->finish = rotate_free;
return eff; return eff;
} }
static void rotate_step(struct effect *eff, float progress) { static void rotate_draw(struct effect *eff, float progress) {
EffectTexture *bg_texture, *fg_texture; EffectTexture *bg_texture, *fg_texture;
float angle = progress * 360; float angle = progress * 360;
float scale = progress; float scale = progress;
@@ -1495,7 +1489,6 @@ static void rotate_step(struct effect *eff, float progress) {
r.h *= scale; r.h *= scale;
render_effect_texture(bg_texture, NULL, &eff->dst_rect); render_effect_texture(bg_texture, NULL, &eff->dst_rect);
SDL_RenderCopyEx(gfx_renderer, fg_texture->tx, &fg_texture->rect, &r, angle, NULL, SDL_FLIP_NONE); SDL_RenderCopyEx(gfx_renderer, fg_texture->tx, &fg_texture->rect, &r, angle, NULL, SDL_FLIP_NONE);
SDL_RenderPresent(gfx_renderer);
} }
static void rotate_free(struct effect *eff) { static void rotate_free(struct effect *eff) {
@@ -1505,7 +1498,7 @@ static void rotate_free(struct effect *eff) {
// EFFECT_POLYGON_ROTATE_* // EFFECT_POLYGON_ROTATE_*
static void polygon_rotate_step(struct effect *eff, float progress); static void polygon_rotate_draw(struct effect *eff, float progress);
static void polygon_rotate_free(struct effect *eff); static void polygon_rotate_free(struct effect *eff);
static struct effect *polygon_rotate_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) { static struct effect *polygon_rotate_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new, enum effect_type type) {
@@ -1513,12 +1506,12 @@ static struct effect *polygon_rotate_new(SDL_Rect *rect, EffectTexture *old, Eff
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, old, new, type); eff_init(eff, rect, old, new, type);
eff->step = polygon_rotate_step; eff->draw = polygon_rotate_draw;
eff->finish = polygon_rotate_free; eff->finish = polygon_rotate_free;
return eff; return eff;
} }
static void polygon_rotate_step(struct effect *eff, float progress) { static void polygon_rotate_draw(struct effect *eff, float progress) {
bool vertical = eff->type == EFFECT_POLYGON_ROTATE_Y || eff->type == EFFECT_POLYGON_ROTATE_Y_CW; bool vertical = eff->type == EFFECT_POLYGON_ROTATE_Y || eff->type == EFFECT_POLYGON_ROTATE_Y_CW;
EffectTexture *texture = progress < 0.5f ? eff->tx_old : eff->tx_new; EffectTexture *texture = progress < 0.5f ? eff->tx_old : eff->tx_new;
float angle = progress < 0.5f ? progress * M_PIf : (progress - 1.f) * M_PIf; float angle = progress < 0.5f ? progress * M_PIf : (progress - 1.f) * M_PIf;
@@ -1554,8 +1547,6 @@ static void polygon_rotate_step(struct effect *eff, float progress) {
} }
render_effect_texture(texture, &sr, &dr); render_effect_texture(texture, &sr, &dr);
} }
SDL_RenderPresent(gfx_renderer);
} }
static void polygon_rotate_free(struct effect *eff) { static void polygon_rotate_free(struct effect *eff) {
@@ -1570,7 +1561,7 @@ struct zigzag_crossfade_effect {
SDL_Texture *tmp1, *tmp2; SDL_Texture *tmp1, *tmp2;
}; };
static void zigzag_crossfade_step(struct effect *eff, float progress); static void zigzag_crossfade_draw(struct effect *eff, float progress);
static void zigzag_crossfade_free(struct effect *eff); static void zigzag_crossfade_free(struct effect *eff);
static struct effect *zigzag_crossfade_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new) { static struct effect *zigzag_crossfade_new(SDL_Rect *rect, EffectTexture *old, EffectTexture *new) {
@@ -1583,7 +1574,7 @@ static struct effect *zigzag_crossfade_new(SDL_Rect *rect, EffectTexture *old, E
eff_init(&eff->eff, rect, old, new, EFFECT_ZIGZAG_CROSSFADE); eff_init(&eff->eff, rect, old, new, EFFECT_ZIGZAG_CROSSFADE);
eff->tmp1 = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); eff->tmp1 = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h);
eff->tmp2 = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); eff->tmp2 = SDL_CreateTexture(gfx_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h);
eff->eff.step = zigzag_crossfade_step; eff->eff.draw = zigzag_crossfade_draw;
eff->eff.finish = zigzag_crossfade_free; eff->eff.finish = zigzag_crossfade_free;
return &eff->eff; return &eff->eff;
} }
@@ -1614,7 +1605,7 @@ static void wave_warp_v(SDL_Texture *src, SDL_Texture *dst, int w, int h, float
SDL_SetRenderTarget(gfx_renderer, NULL); SDL_SetRenderTarget(gfx_renderer, NULL);
} }
static void zigzag_crossfade_step(struct effect *eff, float progress) { static void zigzag_crossfade_draw(struct effect *eff, float progress) {
struct zigzag_crossfade_effect *this = (struct zigzag_crossfade_effect *)eff; struct zigzag_crossfade_effect *this = (struct zigzag_crossfade_effect *)eff;
float amp = (progress < 0.5f ? progress : 1.f - progress) * 80; float amp = (progress < 0.5f ? progress : 1.f - progress) * 80;
@@ -1631,15 +1622,13 @@ static void zigzag_crossfade_step(struct effect *eff, float progress) {
SDL_SetTextureAlphaMod(this->tmp2, progress * 255); SDL_SetTextureAlphaMod(this->tmp2, progress * 255);
SDL_RenderCopy(gfx_renderer, this->tmp2, NULL, &eff->dst_rect); SDL_RenderCopy(gfx_renderer, this->tmp2, NULL, &eff->dst_rect);
SDL_SetTextureBlendMode(this->tmp2, SDL_BLENDMODE_NONE); SDL_SetTextureBlendMode(this->tmp2, SDL_BLENDMODE_NONE);
SDL_RenderPresent(gfx_renderer);
} }
static void zigzag_crossfade_free(struct effect *eff) { static void zigzag_crossfade_free(struct effect *eff) {
struct zigzag_crossfade_effect *this = (struct zigzag_crossfade_effect *)eff; struct zigzag_crossfade_effect *this = (struct zigzag_crossfade_effect *)eff;
eff_finish(&this->eff, true);
SDL_DestroyTexture(this->tmp1); SDL_DestroyTexture(this->tmp1);
SDL_DestroyTexture(this->tmp2); SDL_DestroyTexture(this->tmp2);
eff_finish(&this->eff, true);
free(this); free(this);
} }
@@ -1650,7 +1639,7 @@ struct magnify_effect {
SDL_Rect new_rect; SDL_Rect new_rect;
}; };
static void magnify_step(struct effect *eff, float progress); static void magnify_draw(struct effect *eff, float progress);
static void magnify_free(struct effect *eff); static void magnify_free(struct effect *eff);
static struct effect *magnify_new(EffectTexture *tx, SDL_Rect *old_rect, SDL_Rect *new_rect) { static struct effect *magnify_new(EffectTexture *tx, SDL_Rect *old_rect, SDL_Rect *new_rect) {
@@ -1659,12 +1648,12 @@ static struct effect *magnify_new(EffectTexture *tx, SDL_Rect *old_rect, SDL_Rec
NOMEMERR(); NOMEMERR();
eff_init(&eff->eff, old_rect, tx, NULL, EFFECT_MAGNIFY); eff_init(&eff->eff, old_rect, tx, NULL, EFFECT_MAGNIFY);
eff->new_rect = *new_rect; eff->new_rect = *new_rect;
eff->eff.step = magnify_step; eff->eff.draw = magnify_draw;
eff->eff.finish = magnify_free; eff->eff.finish = magnify_free;
return &eff->eff; return &eff->eff;
} }
static void magnify_step(struct effect *eff, float progress) { static void magnify_draw(struct effect *eff, float progress) {
struct magnify_effect *this = (struct magnify_effect *)eff; struct magnify_effect *this = (struct magnify_effect *)eff;
SDL_Rect *or = &eff->dst_rect; SDL_Rect *or = &eff->dst_rect;
SDL_Rect *nr = &this->new_rect; SDL_Rect *nr = &this->new_rect;
@@ -1675,7 +1664,6 @@ static void magnify_step(struct effect *eff, float progress) {
.h = or->h + (nr->h - or->h) * progress, .h = or->h + (nr->h - or->h) * progress,
}; };
render_effect_texture(eff->tx_old, &r, NULL); render_effect_texture(eff->tx_old, &r, NULL);
SDL_RenderPresent(gfx_renderer);
} }
static void magnify_free(struct effect *eff) { static void magnify_free(struct effect *eff) {
@@ -1685,7 +1673,7 @@ static void magnify_free(struct effect *eff) {
// EFFECT_RASTER_BLEND // EFFECT_RASTER_BLEND
static void raster_blend_step(struct effect *eff, float progress); static void raster_blend_draw(struct effect *eff, float progress);
static void raster_blend_free(struct effect *eff); static void raster_blend_free(struct effect *eff);
static struct effect *raster_blend_new(SDL_Rect *rect, int sx, int sy) { static struct effect *raster_blend_new(SDL_Rect *rect, int sx, int sy) {
@@ -1696,12 +1684,12 @@ static struct effect *raster_blend_new(SDL_Rect *rect, int sx, int sy) {
if (!eff) if (!eff)
NOMEMERR(); NOMEMERR();
eff_init(eff, rect, NULL, texture, EFFECT_RASTER_BLEND); eff_init(eff, rect, NULL, texture, EFFECT_RASTER_BLEND);
eff->step = raster_blend_step; eff->draw = raster_blend_draw;
eff->finish = raster_blend_free; eff->finish = raster_blend_free;
return eff; return eff;
} }
static void raster_blend_step(struct effect *eff, float progress) { static void raster_blend_draw(struct effect *eff, float progress) {
SDL_Rect s_rect = { 0, 0, eff->dst_rect.w, 1 }; SDL_Rect s_rect = { 0, 0, eff->dst_rect.w, 1 };
SDL_Rect d_rect = eff->dst_rect; SDL_Rect d_rect = eff->dst_rect;
d_rect.h = 1; d_rect.h = 1;
@@ -1712,7 +1700,6 @@ static void raster_blend_step(struct effect *eff, float progress) {
s_rect.y++; s_rect.y++;
d_rect.y++; d_rect.y++;
} }
SDL_RenderPresent(gfx_renderer);
} }
static void raster_blend_free(struct effect *eff) { static void raster_blend_free(struct effect *eff) {
@@ -1728,7 +1715,7 @@ struct sactamask_effect {
SDL_Surface *mask; SDL_Surface *mask;
}; };
static void sactamask_step(struct effect *eff, float progress); static void sactamask_draw(struct effect *eff, float progress);
static void sactamask_free(struct effect *eff); static void sactamask_free(struct effect *eff);
static struct effect *sactamask_new(EffectTexture *tx_old, SDL_Surface *sf_new, SDL_Surface *mask) { static struct effect *sactamask_new(EffectTexture *tx_old, SDL_Surface *sf_new, SDL_Surface *mask) {
@@ -1745,12 +1732,12 @@ static struct effect *sactamask_new(EffectTexture *tx_old, SDL_Surface *sf_new,
eff_init(&eff->eff, &rect, tx_old, tx_new, EFFECT_SACTAMASK); eff_init(&eff->eff, &rect, tx_old, tx_new, EFFECT_SACTAMASK);
eff->sf_new = sf_new; eff->sf_new = sf_new;
eff->mask = mask; eff->mask = mask;
eff->eff.step = sactamask_step; eff->eff.draw = sactamask_draw;
eff->eff.finish = sactamask_free; eff->eff.finish = sactamask_free;
return &eff->eff; return &eff->eff;
} }
static void sactamask_step(struct effect *eff, float progress) { static void sactamask_draw(struct effect *eff, float progress) {
struct sactamask_effect *this = (struct sactamask_effect *)eff; struct sactamask_effect *this = (struct sactamask_effect *)eff;
SDL_Surface *sf; SDL_Surface *sf;
@@ -1772,7 +1759,6 @@ static void sactamask_step(struct effect *eff, float progress) {
SDL_UnlockTexture(eff->tx_new->tx); SDL_UnlockTexture(eff->tx_new->tx);
render_effect_texture(eff->tx_old, NULL, &eff->dst_rect); render_effect_texture(eff->tx_old, NULL, &eff->dst_rect);
render_effect_texture(eff->tx_new, NULL, &eff->dst_rect); render_effect_texture(eff->tx_new, NULL, &eff->dst_rect);
SDL_RenderPresent(gfx_renderer);
} }
static void sactamask_free(struct effect *eff) { static void sactamask_free(struct effect *eff) {
@@ -1904,14 +1890,20 @@ struct effect *effect_sactamask_init(SDL_Surface *mask) {
return sactamask_new(tx_old, main_surface, mask); return sactamask_new(tx_old, main_surface, mask);
} }
void effect_step(struct effect *eff, float progress) { static void effect_redraw(void *arg) {
SDL_RenderClear(gfx_renderer); struct effect *eff = arg;
if (!eff->is_fullscreen) if (!eff->is_fullscreen)
SDL_RenderCopy(gfx_renderer, gfx_texture, NULL, NULL); SDL_RenderCopy(gfx_renderer, gfx_texture, NULL, NULL);
eff->step(eff, progress); eff->draw(eff, eff->progress);
}
void effect_step(struct effect *eff, float progress) {
eff->progress = progress;
if (eff->update)
eff->update(eff, progress);
gfx_requestRedraw();
} }
void effect_finish(struct effect *eff) { void effect_finish(struct effect *eff) {
eff->finish(eff); eff->finish(eff);
gfx_setEffectRunning(false);
} }
+2
View File
@@ -50,6 +50,8 @@ void gfx_updateArea(SDL_Rect *src, SDL_Point *dst);
void gfx_updateAll(SDL_Rect *view_rect); void gfx_updateAll(SDL_Rect *view_rect);
void gfx_requestRedraw(void); void gfx_requestRedraw(void);
void gfx_updateScreen(void); void gfx_updateScreen(void);
typedef void (*gfx_RedrawFunc)(void *arg);
void gfx_setRedrawHandler(gfx_RedrawFunc fn, void *arg);
/* パレット関係 */ /* パレット関係 */
void gfx_setPalette(SDL_Color *pal, int first, int count); void gfx_setPalette(SDL_Color *pal, int first, int count);
+10 -6
View File
@@ -45,7 +45,8 @@
#include "debugger.h" #include "debugger.h"
static bool gfx_dirty; static bool gfx_dirty;
static bool gfx_effect_running; static gfx_RedrawFunc redraw_handler;
static void *redraw_handler_arg;
static void gfx_pal_check(void) { static void gfx_pal_check(void) {
if (nact->ags.pal_changed) { if (nact->ags.pal_changed) {
@@ -65,19 +66,22 @@ SDL_Color gfx_getPaletteColor(uint8_t color) {
} }
void gfx_updateScreen(void) { void gfx_updateScreen(void) {
if (!gfx_dirty || gfx_effect_running) if (!gfx_dirty)
return; return;
SDL_RenderClear(gfx_renderer); SDL_RenderClear(gfx_renderer);
if (redraw_handler)
redraw_handler(redraw_handler_arg);
else
SDL_RenderCopy(gfx_renderer, gfx_texture, NULL, NULL); SDL_RenderCopy(gfx_renderer, gfx_texture, NULL, NULL);
modal_render_overlay(); modal_render_overlay();
SDL_RenderPresent(gfx_renderer); SDL_RenderPresent(gfx_renderer);
gfx_dirty = false; gfx_dirty = false;
} }
void gfx_setEffectRunning(bool running) { void gfx_setRedrawHandler(gfx_RedrawFunc fn, void *arg) {
gfx_effect_running = running; assert(!fn || !redraw_handler);
// Effects present directly. Do not replay pending redraws over their frames. redraw_handler = fn;
gfx_dirty = false; redraw_handler_arg = arg;
} }
void gfx_requestRedraw(void) { void gfx_requestRedraw(void) {
-2
View File
@@ -37,8 +37,6 @@ extern surface_t *gfx_dibinfo;
extern int view_w; extern int view_w;
extern int view_h; extern int view_h;
void gfx_setEffectRunning(bool running);
SDL_Surface *gfx_dib_to_surface_with_alpha(int x, int y, int w, int h); SDL_Surface *gfx_dib_to_surface_with_alpha(int x, int y, int w, int h);
SDL_Surface *gfx_dib_to_surface_colorkey(int x, int y, int w, int h, int col); SDL_Surface *gfx_dib_to_surface_colorkey(int x, int y, int w, int h, int col);