diff --git a/modules/Gpx/effectcopy.c b/modules/Gpx/effectcopy.c index cc71dfe..cab1061 100644 --- a/modules/Gpx/effectcopy.c +++ b/modules/Gpx/effectcopy.c @@ -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; -} diff --git a/modules/NIGHTDLL/sprite_eupdate.c b/modules/NIGHTDLL/sprite_eupdate.c index c549604..cf750ed 100644 --- a/modules/NIGHTDLL/sprite_eupdate.c +++ b/modules/NIGHTDLL/sprite_eupdate.c @@ -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: 効果の種類 diff --git a/modules/SACT/sprite_eupdate.c b/modules/SACT/sprite_eupdate.c index 12e6b73..ff61361 100644 --- a/modules/SACT/sprite_eupdate.c +++ b/modules/SACT/sprite_eupdate.c @@ -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) { } diff --git a/src/ecopy.c b/src/ecopy.c index 6c64bb3..bc2efae 100644 --- a/src/ecopy.c +++ b/src/ecopy.c @@ -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; diff --git a/src/effect.h b/src/effect.h index a4f0b8c..267bae9 100644 --- a/src/effect.h +++ b/src/effect.h @@ -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, diff --git a/src/sdl_effect.c b/src/sdl_effect.c index 44f256a..847d2c2 100644 --- a/src/sdl_effect.c +++ b/src/sdl_effect.c @@ -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: