sdl_effect: Implement EFFECT_CROSSFADE_{DOWN,UP,LR,RL}

This commit is contained in:
kichikuou
2022-01-17 11:23:22 +09:00
parent a224d89233
commit d945dfe77d
6 changed files with 185 additions and 392 deletions
+3 -88
View File
@@ -39,12 +39,8 @@ static ecopyparam_t ecp;
#define ECA12_D 256
static void ec11_cb(int step);
static void ec11_prepare(void);
static void ec12_cb(int step);
static void ec13_cb(int step);
void gpx_effect(int no,
int wx, int wy,
@@ -63,7 +59,9 @@ void gpx_effect(int no,
if (sdl_effect != EFFECT_INVALID) {
SDL_Rect rect = { wx, wy, width, height };
struct sdl_effect *eff = sdl_effect_init(&rect, dst, dx, dy, src, sx, sy, sdl_effect);
ags_fade2(time ? time : 2700, FALSE, (ags_fade2_callback)sdl_effect_step, eff);
if (!time)
time = (no == SACT_EFFECT_CROSSFADE_DOWN || SACT_EFFECT_CROSSFADE_UP) ? 1150 : 2700;
ags_fade2(time, FALSE, (ags_fade2_callback)sdl_effect_step, eff);
sdl_effect_finish(eff);
switch (no) {
@@ -105,20 +103,6 @@ void gpx_effect(int no,
i.callback = ec11_cb;
ags_fader(&i);
break;
case 12:
i.step_max = ECA12_D + ecp.h;
i.effect_time = time == 0 ? 1150 : time;
i.cancel = FALSE;
i.callback = ec12_cb;
ags_fader(&i);
break;
case 13:
i.step_max = ECA12_D + ecp.h;
i.effect_time = time == 0 ? 1150 : time;
i.cancel = FALSE;
i.callback = ec13_cb;
ags_fader(&i);
break;
default:
gr_copy(write, wx, wy, src, sx, sy, width, height);
ags_updateArea(wx, wy, width, height);
@@ -186,72 +170,3 @@ static void ec11_cb(int step) {
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
}
#endif
static void ec12_cb(int step) {
int j, l;
int st_i, ed_i;
static int last_i = 0;
if (step == 0) {
return;
}
if (step == ECA12_D + ecp.h) {
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
return;
}
st_i = max(0, step - ECA12_D + 1);
ed_i = min(ecp.h - 1, step);
l = ed_i - st_i + 1;
for (j = st_i; j < ed_i; j++) {
gre_Blend(ecp.write, ecp.wx, ecp.wy + j, ecp.dst, ecp.dx, ecp.dy + j, ecp.src, ecp.sx, ecp.sy + j, ecp.w, 1, step - j);
}
if ((st_i - last_i) > 1) {
gr_copy(ecp.write, ecp.wx, ecp.wy + last_i, ecp.src, ecp.sx, ecp.sy+last_i, ecp.w, st_i - last_i);
ags_updateArea(ecp.wx, ecp.wy + last_i, ecp.w, st_i - last_i);
}
ags_updateArea(ecp.wx, ecp.wy + st_i, ecp.w, l);
last_i = st_i;
}
static void ec13_cb(int step) {
int j, l;
int st_i,ed_i;
static int last_i = 0;
int syy1 = ecp.dy + ecp.h -1;
int syy2 = ecp.sy + ecp.h -1;
int dyy = ecp.wy + ecp.h -1;
if (step == 0) {
return;
}
if (step == ECA12_D + ecp.h) {
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
return;
}
st_i = max(0, step - ECA12_D + 1);
ed_i = min(ecp.h -1, step);
l = ed_i - st_i+1;
for (j = st_i; j <= ed_i; j++) {
gre_Blend(ecp.write, ecp.wx, dyy - j, ecp.dst, ecp.dx, syy1 - j, ecp.src, ecp.sx, syy2 - j, ecp.w, 1, step - j);
}
if ((st_i - last_i) > 1) {
gr_copy(ecp.write, ecp.wx, dyy - st_i + 1, ecp.src, ecp.sx, syy2 - st_i + 1, ecp.w, st_i - last_i);
ags_updateArea(ecp.wx, dyy - st_i + 1, ecp.w, st_i - last_i);
}
ags_updateArea(ecp.wx, dyy-ed_i, ecp.w, l);
last_i = st_i;
}
-62
View File
@@ -41,8 +41,6 @@
static void ec6_cb(surface_t *, surface_t *);
static void ec11_cb(surface_t *, surface_t *);
static void ec12_cb(surface_t *, surface_t *);
static void ec13_cb(surface_t *, surface_t *);
static void ec_dummy_cb(surface_t *, surface_t *);
struct ecopyparam {
@@ -67,66 +65,6 @@ static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) {
WARNING("NOT IMPLEMENTED\n");
}
// 上->下クロスフェード
static void ec12_cb(surface_t *src, surface_t *dst) {
#define EC12DELTA 256
int curstep, maxstep = src->height + EC12DELTA;
int j, st_i, ed_i, l;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
SACT_DEBUG("step = %d\n", curstep);
if (ecp.oldstep == curstep) {
usleep(0); return;
}
st_i = max(0, curstep - EC12DELTA + 1);
ed_i = min(src->height -1, curstep);
l = ed_i - st_i + 1;
for (j = st_i; j < ed_i; j++) {
gre_Blend(sf0, 0, j, src, 0, j, dst, 0, j, src->width, 1, curstep - j);
}
if ((st_i - ecp.oldstep) > 1) {
gr_copy(sf0, 0, ecp.oldstep, dst, 0, ecp.oldstep, src->width, st_i - ecp.oldstep);
ags_updateArea(0, ecp.oldstep, src->width, st_i - ecp.oldstep);
}
ags_updateArea(0, st_i, src->width, l);
ecp.oldstep = st_i;
}
// 下->上クロスフェード
static void ec13_cb(surface_t *src, surface_t *dst) {
#define EC13DELTA 256
int curstep, maxstep = src->height + EC12DELTA;
int j, st_i, ed_i, l;
int syy1 = 0 + dst->height -1;
int syy2 = 0 + src->height -1;
int dyy = 0 + sf0->height -1;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
SACT_DEBUG("step = %d\n", curstep);
if (ecp.oldstep == curstep) {
usleep(0); return;
}
st_i = max(0, curstep - EC13DELTA + 1);
ed_i = min(src->height -1, curstep);
l = ed_i - st_i + 1;
for (j = st_i; j < ed_i; j++) {
gre_Blend(sf0, 0, dyy - j, src, 0, syy1-j, dst, 0, syy2-j, src->width, 1, curstep - j);
}
if ((st_i - ecp.oldstep) > 1) {
gr_copy(sf0, 0, dyy-ecp.oldstep, dst, 0, syy2-ecp.oldstep, src->width, st_i - ecp.oldstep);
ags_updateArea(0, dyy-ecp.oldstep, src->width, st_i - ecp.oldstep);
}
ags_updateArea(0, dyy-ed_i, src->width, l);
ecp.oldstep = st_i;
}
/*
効果つき画面更新
@param type: 効果の種類
+2 -65
View File
@@ -42,8 +42,6 @@
static void ec6_cb(surface_t *, surface_t *);
static void ec11_cb(surface_t *, surface_t *);
static void ec12_cb(surface_t *, surface_t *);
static void ec13_cb(surface_t *, surface_t *);
static void sdl_effect_cb(surface_t *, surface_t *);
static void ec_dummy_cb(surface_t *, surface_t *);
@@ -78,8 +76,8 @@ static entrypoint *cb[39] = {
sdl_effect_cb,
ec10_cb,
ec11_cb,
ec12_cb,
ec13_cb,
sdl_effect_cb,
sdl_effect_cb,
sdl_effect_cb,
sdl_effect_cb,
sdl_effect_cb,
@@ -112,71 +110,10 @@ static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) {
WARNING("NOT IMPLEMENTED\n");
}
// 上->下クロスフェード
static void ec12_cb(surface_t *src, surface_t *dst) {
#define EC12DELTA 256
int curstep, maxstep = src->height + EC12DELTA;
int j, st_i, ed_i, l;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
SACT_DEBUG("step = %d\n", curstep);
if (ecp.oldstep == curstep) {
usleep(0); return;
}
st_i = max(0, curstep - EC12DELTA + 1);
ed_i = min(src->height -1, curstep);
l = ed_i - st_i + 1;
for (j = st_i; j < ed_i; j++) {
gre_Blend(sf0, 0, j, src, 0, j, dst, 0, j, src->width, 1, curstep - j);
}
if ((st_i - ecp.oldstep) > 1) {
gr_copy(sf0, 0, ecp.oldstep, dst, 0, ecp.oldstep, src->width, st_i - ecp.oldstep);
ags_updateArea(0, ecp.oldstep, src->width, st_i - ecp.oldstep);
}
ags_updateArea(0, st_i, src->width, l);
ecp.oldstep = st_i;
}
// 下->上クロスフェード
static void ec13_cb(surface_t *src, surface_t *dst) {
#define EC13DELTA 256
int curstep, maxstep = src->height + EC12DELTA;
int j, st_i, ed_i, l;
int syy1 = 0 + dst->height -1;
int syy2 = 0 + src->height -1;
int dyy = 0 + sf0->height -1;
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
SACT_DEBUG("step = %d\n", curstep);
if (ecp.oldstep == curstep) {
usleep(0); return;
}
st_i = max(0, curstep - EC13DELTA + 1);
ed_i = min(src->height -1, curstep);
l = ed_i - st_i + 1;
for (j = st_i; j < ed_i; j++) {
gre_Blend(sf0, 0, dyy - j, src, 0, syy1-j, dst, 0, syy2-j, src->width, 1, curstep - j);
}
if ((st_i - ecp.oldstep) > 1) {
gr_copy(sf0, 0, dyy-ecp.oldstep, dst, 0, syy2-ecp.oldstep, src->width, st_i - ecp.oldstep);
ags_updateArea(0, dyy-ecp.oldstep, src->width, st_i - ecp.oldstep);
}
ags_updateArea(0, dyy-ed_i, src->width, l);
ecp.oldstep = st_i;
}
static void sdl_effect_cb(surface_t *sfsrc, surface_t *sfdst) {
sdl_effect_step(ecp.eff, (double)(ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime));
}
//ブロックディゾルブ
static void ec24_cb(surface_t *sfsrc, surface_t *sfdst) {
}
+6 -177
View File
@@ -590,155 +590,6 @@ static void eCopyArea32(int step) {
ags_updateArea(ecp.dx, ecp.dy, ecp.w, ecp.h);
}
#define ECA35_D 256
static void eCopyArea35(int step) {
int j, l;
int st_i, ed_i;
static int last_i = 0;
static void *save = NULL;
if (step == 0) {
save = ags_saveRegion(ecp.dx, ecp.dy, ecp.w,ecp.h);
return;
}
if (step == ECA35_D + ecp.h) {
ags_copyArea(ecp.sx, ecp.sy, ecp.w, ecp.h, ecp.dx, ecp.dy);
ags_updateArea(ecp.dx, ecp.dy, ecp.w, ecp.h);
ags_delRegion(save);
return;
}
st_i = max(0, step - ECA35_D + 1);
ed_i = min(ecp.h - 1, step);
l = ed_i - st_i + 1;
ags_copyRegion(save, 0, st_i, ecp.w, l, ecp.dx, ecp.dy+st_i);
ags_copyArea(ecp.sx, ecp.sy + st_i, ecp.w, 1, ecp.dx, ecp.dy + st_i);
for (j = st_i; j < ed_i; j++) {
ags_copyArea_alphaBlend(ecp.sx, ecp.sy + j, ecp.w, 1, ecp.dx, ecp.dy + j, step - j);
}
if ((st_i - last_i) > 1) {
ags_copyArea(ecp.sx, ecp.sy + last_i, ecp.w, st_i - last_i, ecp.dx, ecp.dy + last_i);
ags_updateArea(ecp.dx, ecp.dy + last_i, ecp.w, st_i - last_i);
}
ags_updateArea(ecp.dx, ecp.dy+st_i, ecp.w, l);
// if (st_i > 0) last_i = st_i;
last_i = st_i;
}
static void eCopyArea36(int step) {
int j, l;
int st_i,ed_i;
static int last_i=0;
static void *save;
int syy=ecp.sy+ecp.h-1,dyy=ecp.dy+ecp.h-1;
if (step == 0) {
save = ags_saveRegion(ecp.dx, ecp.dy, ecp.w,ecp.h);
return;
}
if (step == ECA35_D + ecp.h) {
ags_copyArea(ecp.sx, ecp.sy, ecp.w, ecp.h, ecp.dx, ecp.dy);
ags_updateArea(ecp.dx, ecp.dy, ecp.w, ecp.h);
ags_delRegion(save);
return;
}
st_i = max(0, step-ECA35_D+1);
ed_i = min(ecp.h -1, step);
l = ed_i - st_i+1;
ags_copyRegion(save,0,ecp.h -1 -ed_i,ecp.w,l,ecp.dx,dyy-ed_i);
for (j = st_i; j <= ed_i; j++) {
ags_copyArea_alphaBlend(ecp.sx, syy-j, ecp.w, 1, ecp.dx, dyy-j, step-j);
}
if ((st_i - last_i) > 1) {
ags_copyArea(ecp.sx,syy-st_i+1,ecp.w,st_i-last_i,ecp.dx,dyy-st_i+1);
ags_updateArea(ecp.dx, dyy-st_i+1, ecp.w, st_i-last_i);
}
ags_updateArea(ecp.dx, dyy-ed_i, ecp.w, l);
// if (st_i > 0) last_i = st_i;
last_i = st_i;
}
static void eCopyArea37(int step) {
int j, l;
int st_i,ed_i;
static int last_i=0;
static void *save = NULL;
if (step == 0) {
save = ags_saveRegion(ecp.dx,ecp.dy,ecp.w,ecp.h);
return;
}
if (step == ECA35_D + ecp.w) {
ags_copyArea(ecp.sx, ecp.sy, ecp.w, ecp.h, ecp.dx, ecp.dy);
ags_updateArea(ecp.dx, ecp.dy, ecp.w, ecp.h);
ags_delRegion(save);
return;
}
st_i=max(0,step-ECA35_D+1);
ed_i=min(ecp.w -1,step);
l=ed_i-st_i+1;
ags_copyRegion(save,st_i,0,l,ecp.h,ecp.dx+st_i,ecp.dy);
for (j = st_i; j <= ed_i; j++) {
ags_copyArea_alphaBlend(ecp.sx+j, ecp.sy, 1, ecp.h, ecp.dx+j, ecp.dy, step-j);
}
if ((st_i - last_i) > 1) {
ags_copyArea(ecp.sx+last_i, ecp.sy, st_i-last_i, ecp.h,ecp.dx+last_i, ecp.dy);
ags_updateArea(ecp.dx+last_i, ecp.dy, st_i-last_i, ecp.h);
}
ags_updateArea(ecp.dx+st_i, ecp.dy, l, ecp.h);
//if (st_i > 0) last_i = st_i;
last_i = st_i;
}
static void eCopyArea38(int step) {
int j, l;
int st_i, ed_i;
static int last_i=0;
static void *save;
int sxx=ecp.sx+ecp.w - 1,dxx=ecp.dx+ecp.w-1;
if (step == 0) {
save = ags_saveRegion(ecp.dx, ecp.dy, ecp.w,ecp.h);
return;
}
if (step == ECA35_D + ecp.w) {
ags_copyArea(ecp.sx, ecp.sy, ecp.w, ecp.h, ecp.dx, ecp.dy);
ags_updateArea(ecp.dx, ecp.dy, ecp.w, ecp.h);
ags_delRegion(save);
return;
}
st_i=max(0,step-ECA35_D+1);
ed_i=min(ecp.w - 1,step);
l=ed_i-st_i+1;
ags_copyRegion(save,ecp.w-1-ed_i,0,l,ecp.h,dxx-ed_i,ecp.dy);
for (j = st_i; j<=ed_i; j++) {
ags_copyArea_alphaBlend(sxx-j, ecp.sy, 1, ecp.h, dxx-j, ecp.dy, step-j);
}
if ((st_i - last_i) > 1) {
ags_copyArea(sxx-st_i+1, ecp.sy,st_i-last_i, ecp.h, dxx-st_i+1, ecp.dy);
ags_updateArea(dxx-st_i+1,ecp.dy, st_i-last_i, ecp.h);
}
ags_updateArea(dxx-ed_i, ecp.dy, l, ecp.h);
// if (st_i > 0) last_i=st_i;
last_i=st_i;
}
static int eCopyArea39(int sx, int sy, int w, int h, int dx, int dy, int opt) {
int i,dy1,dy2,sy1,sy2, key = 0, cnt;
int waitcnt = opt == 0 ? 3 : opt;
@@ -1020,6 +871,12 @@ static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) {
return opt ? opt * 32 : 1700;
case NACT_EFFECT_CROSSFADE:
return opt ? opt * 256 : 2700;
case NACT_EFFECT_CROSSFADE_DOWN:
case NACT_EFFECT_CROSSFADE_UP:
return opt ? opt * (rect->h + 256) : 1150;
case NACT_EFFECT_CROSSFADE_LR:
case NACT_EFFECT_CROSSFADE_RL:
return opt ? opt * (rect->w + 256) : 1150;
case NACT_EFFECT_PENTAGRAM_IN_OUT:
case NACT_EFFECT_PENTAGRAM_OUT_IN:
case NACT_EFFECT_HEXAGRAM_IN_OUT:
@@ -1203,34 +1060,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt
i.callback = eCopyArea32;
ags_fader(&i);
return;
case 35:
i.step_max = ECA35_D + h;
i.effect_time = opt == 0 ? 1150 : opt * i.step_max;
i.cancel = cancel;
i.callback = eCopyArea35;
ags_fader(&i);
return;
case 36:
i.step_max = ECA35_D + h;
i.effect_time = opt == 0 ? 1150 : opt * i.step_max;
i.cancel = cancel;
i.callback = eCopyArea36;
ags_fader(&i);
return;
case 37:
i.step_max = ECA35_D + w;
i.effect_time = opt == 0 ? 1150 : opt * i.step_max;
i.cancel = cancel;
i.callback = eCopyArea37;
ags_fader(&i);
return;
case 38:
i.step_max = ECA35_D + w;
i.effect_time = opt == 0 ? 1150 : opt * i.step_max;
i.cancel = cancel;
i.callback = eCopyArea38;
ags_fader(&i);
return;
case 39:
ret = eCopyArea39(sx, sy, w, h, dx, dy, opt);
break;
+10
View File
@@ -30,6 +30,10 @@ enum nact_effect {
NACT_EFFECT_CROSSFADE = 31,
NACT_EFFECT_BLIND_UP = 33,
NACT_EFFECT_BLIND_UP_DOWN = 34,
NACT_EFFECT_CROSSFADE_DOWN = 35,
NACT_EFFECT_CROSSFADE_UP = 36,
NACT_EFFECT_CROSSFADE_LR = 37,
NACT_EFFECT_CROSSFADE_RL = 38,
NACT_EFFECT_PENTAGRAM_IN_OUT = 44,
NACT_EFFECT_PENTAGRAM_OUT_IN = 45,
NACT_EFFECT_HEXAGRAM_IN_OUT = 46,
@@ -51,6 +55,8 @@ enum sact_effect {
SACT_EFFECT_BLIND_DOWN = 7,
SACT_EFFECT_BLIND_LR = 8,
SACT_EFFECT_BLIND_DOWN_LR = 9,
SACT_EFFECT_CROSSFADE_DOWN = 12,
SACT_EFFECT_CROSSFADE_UP = 13,
SACT_EFFECT_PENTAGRAM_IN_OUT = 14,
SACT_EFFECT_PENTAGRAM_OUT_IN = 15,
SACT_EFFECT_HEXAGRAM_IN_OUT = 16,
@@ -77,6 +83,10 @@ enum sdl_effect_type {
EFFECT_BLIND_RL,
EFFECT_BLIND_UP_DOWN,
EFFECT_BLIND_DOWN_LR,
EFFECT_CROSSFADE_DOWN,
EFFECT_CROSSFADE_UP,
EFFECT_CROSSFADE_LR,
EFFECT_CROSSFADE_RL,
EFFECT_PENTAGRAM_IN_OUT,
EFFECT_PENTAGRAM_OUT_IN,
EFFECT_HEXAGRAM_IN_OUT,
+164
View File
@@ -39,6 +39,10 @@ enum sdl_effect_type from_nact_effect(enum nact_effect effect) {
case NACT_EFFECT_CROSSFADE: return EFFECT_CROSSFADE;
case NACT_EFFECT_BLIND_UP: return EFFECT_BLIND_UP;
case NACT_EFFECT_BLIND_UP_DOWN: return EFFECT_BLIND_UP_DOWN;
case NACT_EFFECT_CROSSFADE_DOWN: return EFFECT_CROSSFADE_DOWN;
case NACT_EFFECT_CROSSFADE_UP: return EFFECT_CROSSFADE_UP;
case NACT_EFFECT_CROSSFADE_LR: return EFFECT_CROSSFADE_LR;
case NACT_EFFECT_CROSSFADE_RL: return EFFECT_CROSSFADE_RL;
case NACT_EFFECT_PENTAGRAM_IN_OUT: return EFFECT_PENTAGRAM_IN_OUT;
case NACT_EFFECT_PENTAGRAM_OUT_IN: return EFFECT_PENTAGRAM_OUT_IN;
case NACT_EFFECT_HEXAGRAM_IN_OUT: return EFFECT_HEXAGRAM_IN_OUT;
@@ -62,6 +66,8 @@ enum sdl_effect_type from_sact_effect(enum sact_effect effect) {
case SACT_EFFECT_BLIND_DOWN: return EFFECT_BLIND_DOWN;
case SACT_EFFECT_BLIND_LR: return EFFECT_BLIND_LR;
case SACT_EFFECT_BLIND_DOWN_LR: return EFFECT_BLIND_DOWN_LR;
case SACT_EFFECT_CROSSFADE_DOWN: return EFFECT_CROSSFADE_DOWN;
case SACT_EFFECT_CROSSFADE_UP: return EFFECT_CROSSFADE_UP;
case SACT_EFFECT_PENTAGRAM_IN_OUT: return EFFECT_PENTAGRAM_IN_OUT;
case SACT_EFFECT_PENTAGRAM_OUT_IN: return EFFECT_PENTAGRAM_OUT_IN;
case SACT_EFFECT_HEXAGRAM_IN_OUT: return EFFECT_HEXAGRAM_IN_OUT;
@@ -129,6 +135,159 @@ static void crossfade_free(struct sdl_effect *eff) {
free(eff);
}
// EFFECT_CROSSFADE_{UP,DOWN}
static void crossfade_down_step(struct sdl_effect *eff, double progress);
static void crossfade_up_step(struct sdl_effect *eff, double progress);
static void crossfade_lr_step(struct sdl_effect *eff, double progress);
static void crossfade_rl_step(struct sdl_effect *eff, double progress);
static void crossfade_animation_free(struct sdl_effect *eff);
static struct sdl_effect *crossfade_animation_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect_type type) {
struct sdl_effect *eff = calloc(1, sizeof(struct sdl_effect));
if (!eff)
NOMEMERR();
effect_init(eff, rect, old, new, type);
switch (type) {
case EFFECT_CROSSFADE_DOWN: eff->step = crossfade_down_step; break;
case EFFECT_CROSSFADE_UP: eff->step = crossfade_up_step; break;
case EFFECT_CROSSFADE_LR: eff->step = crossfade_lr_step; break;
case EFFECT_CROSSFADE_RL: eff->step = crossfade_rl_step; break;
default: assert(!"Cannot happen");
}
eff->finish = crossfade_animation_free;
return eff;
}
static void crossfade_down_step(struct sdl_effect *eff, double progress) {
const int BAND_WIDTH = 254;
SDL_RenderCopy(sdl_renderer, eff->tx_old, NULL, &eff->dst_rect);
int maxstep = eff->dst_rect.h + BAND_WIDTH;
int band_top = maxstep * progress - BAND_WIDTH;
if (band_top > 0) {
SDL_Rect sr = {0, 0, eff->dst_rect.w, band_top};
SDL_Rect dr = {eff->dst_rect.x, eff->dst_rect.y, eff->dst_rect.w, band_top};
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_BLEND);
SDL_Rect sr = {0, 0, eff->dst_rect.w, 1};
SDL_Rect dr = {eff->dst_rect.x, 0, eff->dst_rect.w, 1};
for (int i = 0; i < BAND_WIDTH; i++) {
int y = band_top + i;
if (y < 0 || y >= eff->dst_rect.h)
continue;
sr.y = y;
dr.y = eff->dst_rect.y + y;
SDL_SetTextureAlphaMod(eff->tx_new, BAND_WIDTH - i);
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_NONE);
SDL_RenderPresent(sdl_renderer);
}
static void crossfade_up_step(struct sdl_effect *eff, double progress) {
const int BAND_WIDTH = 254;
SDL_RenderCopy(sdl_renderer, eff->tx_old, NULL, &eff->dst_rect);
int maxstep = eff->dst_rect.h + BAND_WIDTH;
int band_top = maxstep - maxstep * progress - BAND_WIDTH;
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_BLEND);
SDL_Rect sr = {0, 0, eff->dst_rect.w, 1};
SDL_Rect dr = {eff->dst_rect.x, 0, eff->dst_rect.w, 1};
for (int i = 0; i < BAND_WIDTH; i++) {
int y = band_top + i;
if (y < 0 || y >= eff->dst_rect.h)
continue;
sr.y = y;
dr.y = eff->dst_rect.y + y;
SDL_SetTextureAlphaMod(eff->tx_new, i + 1);
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_NONE);
int top = band_top + BAND_WIDTH;
if (top < eff->dst_rect.h) {
SDL_Rect sr = {0, top, eff->dst_rect.w, eff->dst_rect.h - top};
SDL_Rect dr = {eff->dst_rect.x, eff->dst_rect.y + top, eff->dst_rect.w, eff->dst_rect.h - top};
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_RenderPresent(sdl_renderer);
}
static void crossfade_lr_step(struct sdl_effect *eff, double progress) {
const int BAND_WIDTH = 254;
SDL_RenderCopy(sdl_renderer, eff->tx_old, NULL, &eff->dst_rect);
int maxstep = eff->dst_rect.w + BAND_WIDTH;
int band_lhs = maxstep * progress - BAND_WIDTH;
if (band_lhs > 0) {
SDL_Rect sr = {0, 0, band_lhs, eff->dst_rect.h};
SDL_Rect dr = {eff->dst_rect.x, eff->dst_rect.y, band_lhs, eff->dst_rect.h};
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_BLEND);
SDL_Rect sr = {0, 0, 1, eff->dst_rect.h};
SDL_Rect dr = {0, eff->dst_rect.y, 1, eff->dst_rect.h};
for (int i = 0; i < BAND_WIDTH; i++) {
int x = band_lhs + i;
if (x < 0 || x >= eff->dst_rect.w)
continue;
sr.x = x;
dr.x = eff->dst_rect.x + x;
SDL_SetTextureAlphaMod(eff->tx_new, BAND_WIDTH - i);
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_NONE);
SDL_RenderPresent(sdl_renderer);
}
static void crossfade_rl_step(struct sdl_effect *eff, double progress) {
const int BAND_WIDTH = 254;
SDL_RenderCopy(sdl_renderer, eff->tx_old, NULL, &eff->dst_rect);
int maxstep = eff->dst_rect.w + BAND_WIDTH;
int band_lhs = maxstep - maxstep * progress - BAND_WIDTH;
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_BLEND);
SDL_Rect sr = {0, 0, 1, eff->dst_rect.h};
SDL_Rect dr = {0, eff->dst_rect.y, 1, eff->dst_rect.h};
for (int i = 0; i < BAND_WIDTH; i++) {
int x = band_lhs + i;
if (x < 0 || x >= eff->dst_rect.w)
continue;
sr.x = x;
dr.x = eff->dst_rect.x + x;
SDL_SetTextureAlphaMod(eff->tx_new, i + 1);
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_SetTextureBlendMode(eff->tx_new, SDL_BLENDMODE_NONE);
int lhs = band_lhs + BAND_WIDTH;
if (lhs < eff->dst_rect.w) {
SDL_Rect sr = {lhs, 0, eff->dst_rect.w - lhs, eff->dst_rect.h};
SDL_Rect dr = {eff->dst_rect.x + lhs, eff->dst_rect.y, eff->dst_rect.w - lhs, eff->dst_rect.h};
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
}
SDL_RenderPresent(sdl_renderer);
}
static void crossfade_animation_free(struct sdl_effect *eff) {
effect_finish(eff, false);
free(eff);
}
// EFFECT_{FADE,WHITE}{OUT,IN}
static void brightness_step(struct sdl_effect *eff, double progress);
@@ -657,6 +816,11 @@ struct sdl_effect *sdl_effect_init(SDL_Rect *rect, agsurface_t *old, int ox, int
switch (type) {
case EFFECT_CROSSFADE:
return crossfade_new(rect, sf_old, sf_new);
case EFFECT_CROSSFADE_DOWN:
case EFFECT_CROSSFADE_UP:
case EFFECT_CROSSFADE_LR:
case EFFECT_CROSSFADE_RL:
return crossfade_animation_new(rect, sf_old, sf_new, type);
case EFFECT_FADEOUT:
case EFFECT_FADEOUT_FROM_NEW:
case EFFECT_FADEIN: