From bc97e4c826ff662274dfd1cd0c1e0acd607764e4 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 16 Jan 2022 17:33:09 +0900 Subject: [PATCH] sdl_fader: Implement blind effects --- modules/Gpx/effectcopy.c | 28 ------- modules/NIGHTDLL/sprite_eupdate.c | 102 ----------------------- modules/SACT/sprite_eupdate.c | 102 +---------------------- src/ecopy.c | 130 +++-------------------------- src/effect.h | 14 ++++ src/sdl_fader.c | 134 ++++++++++++++++++++++++++++++ 6 files changed, 161 insertions(+), 349 deletions(-) diff --git a/modules/Gpx/effectcopy.c b/modules/Gpx/effectcopy.c index 2f34508..60ddd58 100644 --- a/modules/Gpx/effectcopy.c +++ b/modules/Gpx/effectcopy.c @@ -39,10 +39,8 @@ static ecopyparam_t ecp; -#define ECA7_D 16 #define ECA12_D 256 -static void ec7_cb(); static void ec11_cb(int step); static void ec11_prepare(void); static void ec12_cb(int step); @@ -99,9 +97,6 @@ void gpx_effect(int no, ags_faderinfo_t i; switch(no) { - case 7: - ec7_cb(); - break; case 11: ec11_prepare(); i.step_max = 6; @@ -131,29 +126,6 @@ void gpx_effect(int no, } -#define EC_WAIT \ - if ((key |= sys_getInputInfo()) && ecp.cancel) break; \ - key = sys_keywait(cnt - sdl_getTicks(), ecp.cancel); - -static void ec7_cb() { - int i, j, y, key = 0, cnt; - int waitcnt = ecp.time == 0 ? 40 : (ecp.time/60); - - cnt = sdl_getTicks(); - for (i = 0; i < ECA7_D + ecp.h / ECA7_D -1; i++) { - cnt += waitcnt; - for (j = 0; j < min(i + 1, ECA7_D); j++) { - y = j + ECA7_D * (i-j); - if (y < 0 || y >= ecp.h) continue; - gr_copy(ecp.write, ecp.wx, ecp.wy + y, ecp.src, ecp.sx, ecp.sy + y, ecp.w, 1); - } - ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h); - EC_WAIT; - } - - ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h); -} - static void ec11_prepare() { int i; diff --git a/modules/NIGHTDLL/sprite_eupdate.c b/modules/NIGHTDLL/sprite_eupdate.c index 137404f..d19de3c 100644 --- a/modules/NIGHTDLL/sprite_eupdate.c +++ b/modules/NIGHTDLL/sprite_eupdate.c @@ -40,9 +40,6 @@ static void ec6_cb(surface_t *, surface_t *); -static void ec7_cb(surface_t *, surface_t *); -static void ec8_cb(surface_t *, surface_t *); -static void ec9_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 *); @@ -70,99 +67,6 @@ static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) { WARNING("NOT IMPLEMENTED\n"); } -// すだれ落ち -static void ec7_cb(surface_t *sfsrc, surface_t *sfdst) { -#define EC7DELTA 16 - int curstep, maxstep = sfsrc->height / EC7DELTA + EC7DELTA; - int i, t, y; - - curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime); - //SACT_DEBUG("step = %d\n", curstep); - - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - t = ecp.oldstep; - while(t < curstep) { - for (i = 0; i < min(t + 1, EC7DELTA); i++) { - y = i + EC7DELTA * (t - i); - if (y < 0 || y >= sfsrc->height) continue; - gr_copy(sf0, 0, y, - sfdst, 0, y, sfsrc->width, 1); - } - t++; - } - - ecp.oldstep = curstep; - ags_updateFull(); -} - -// すだれ左->右 -static void ec8_cb(surface_t *sfsrc, surface_t *sfdst) { -#define EC8DELTA 16 - int curstep, maxstep = sfsrc->width / EC8DELTA + EC8DELTA; - int i, t, x; - - curstep = maxstep * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime); - //SACT_DEBUG("step = %d\n", curstep); - - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - t = ecp.oldstep; - while(t < curstep) { - for (i = 0; i < min(t + 1, EC8DELTA); i++) { - x = i + EC8DELTA * (t - i); - if (x < 0 || x >= sfsrc->width) continue; - gr_copy(sf0, x, 0, - sfdst, x, 0, 1, sfsrc->height); - } - t++; - } - - ecp.oldstep = curstep; - ags_updateFull(); -} - -// すだれ落ち&左->右 -static void ec9_cb(surface_t *sfsrc, surface_t *sfdst) { -#define EC9DELTA 16 - int curstep, maxstep; - int i, t, x, y; - - maxstep = max(sfsrc->height / EC9DELTA + EC9DELTA, - sfsrc->width / EC9DELTA + EC9DELTA); - - curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime); - //SACT_DEBUG("step = %d\n", curstep); - - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - t = ecp.oldstep; - while(t < curstep) { - for (i = 0; i < min(t + 1, EC9DELTA); i++) { - y = i + EC9DELTA * (t - i); - if (y < 0 || y >= sfsrc->height) continue; - gr_copy(sf0, 0, y, - sfdst, 0, y, sfsrc->width, 1); - } - for (i = 0; i < min(t + 1, EC9DELTA); i++) { - x = i + EC9DELTA * (t - i); - if (x < 0 || x >= sfsrc->width) continue; - gr_copy(sf0, x, 0, - sfdst, x, 0, 1, sfsrc->height); - } - t++; - } - - ecp.oldstep = curstep; - ags_updateFull(); -} - // 上->下クロスフェード static void ec12_cb(surface_t *src, surface_t *dst) { #define EC12DELTA 256 @@ -258,12 +162,6 @@ int nt_sp_eupdate(int type, int time, int cancel) { case 10: cb = ec_dummy_cb; break; - case 107: // 簾落ち - cb = ec7_cb; - break; - case 108: // 左->右すだれ - cb = ec8_cb; - break; case 111: // 線形ぼかし ec11_prepare(sfsrc, sfdst); cb = ec11_cb; diff --git a/modules/SACT/sprite_eupdate.c b/modules/SACT/sprite_eupdate.c index 65bbbb3..ff8e621 100644 --- a/modules/SACT/sprite_eupdate.c +++ b/modules/SACT/sprite_eupdate.c @@ -41,9 +41,6 @@ static void ec6_cb(surface_t *, surface_t *); -static void ec7_cb(surface_t *, surface_t *); -static void ec8_cb(surface_t *, surface_t *); -static void ec9_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 *); @@ -76,9 +73,9 @@ static entrypoint *cb[39] = { sdlfader_cb, sdlfader_cb, ec6_cb, - ec7_cb, - ec8_cb, - ec9_cb, + sdlfader_cb, + sdlfader_cb, + sdlfader_cb, ec10_cb, ec11_cb, ec12_cb, @@ -115,99 +112,6 @@ static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) { WARNING("NOT IMPLEMENTED\n"); } -// すだれ落ち -static void ec7_cb(surface_t *sfsrc, surface_t *sfdst) { -#define EC7DELTA 16 - int curstep, maxstep = sfsrc->height / EC7DELTA + EC7DELTA; - int i, t, y; - - curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime); - SACT_DEBUG("step = %d\n", curstep); - - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - t = ecp.oldstep; - while(t < curstep) { - for (i = 0; i < min(t + 1, EC7DELTA); i++) { - y = i + EC7DELTA * (t - i); - if (y < 0 || y >= sfsrc->height) continue; - gr_copy(sf0, 0, y, - sfdst, 0, y, sfsrc->width, 1); - } - t++; - } - - ecp.oldstep = curstep; - ags_updateFull(); -} - -// すだれ左->右 -static void ec8_cb(surface_t *sfsrc, surface_t *sfdst) { -#define EC8DELTA 16 - int curstep, maxstep = sfsrc->width / EC8DELTA + EC8DELTA; - int i, t, x; - - curstep = maxstep * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime); - SACT_DEBUG("step = %d\n", curstep); - - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - t = ecp.oldstep; - while(t < curstep) { - for (i = 0; i < min(t + 1, EC8DELTA); i++) { - x = i + EC8DELTA * (t - i); - if (x < 0 || x >= sfsrc->width) continue; - gr_copy(sf0, x, 0, - sfdst, x, 0, 1, sfsrc->height); - } - t++; - } - - ecp.oldstep = curstep; - ags_updateFull(); -} - -// すだれ落ち&左->右 -static void ec9_cb(surface_t *sfsrc, surface_t *sfdst) { -#define EC9DELTA 16 - int curstep, maxstep; - int i, t, x, y; - - maxstep = max(sfsrc->height / EC9DELTA + EC9DELTA, - sfsrc->width / EC9DELTA + EC9DELTA); - - curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime); - SACT_DEBUG("step = %d\n", curstep); - - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - t = ecp.oldstep; - while(t < curstep) { - for (i = 0; i < min(t + 1, EC9DELTA); i++) { - y = i + EC9DELTA * (t - i); - if (y < 0 || y >= sfsrc->height) continue; - gr_copy(sf0, 0, y, - sfdst, 0, y, sfsrc->width, 1); - } - for (i = 0; i < min(t + 1, EC9DELTA); i++) { - x = i + EC9DELTA * (t - i); - if (x < 0 || x >= sfsrc->width) continue; - gr_copy(sf0, x, 0, - sfdst, x, 0, 1, sfsrc->height); - } - t++; - } - - ecp.oldstep = curstep; - ags_updateFull(); -} - // 上->下クロスフェード static void ec12_cb(surface_t *src, surface_t *dst) { #define EC12DELTA 256 diff --git a/src/ecopy.c b/src/ecopy.c index 65370d2..b8df0c8 100644 --- a/src/ecopy.c +++ b/src/ecopy.c @@ -262,26 +262,6 @@ static void eCopyArea10(int step) { ecp.w * step / 64, ecp.h * step / 64); } -static int eCopyArea11(int dx, int dy, int w, int h, int opt) { - int i, j, y, key = 0, cnt; - int waitcnt = opt == 0 ? 40 : opt; - -#define ECA11_SLICE 16 - cnt = sdl_getTicks(); - for (i = 0; i < ECA11_SLICE + h / ECA11_SLICE -1; i++) { - cnt += waitcnt; - for (j = 0; j < min(i+1, ECA11_SLICE); j++) { - y = j + ECA11_SLICE*(i-j); - if (y < 0 || y >= h) continue; - eCopyUpdateArea(dx, dy + y, w, 1, dx, dy + y); - } - EC_WAIT; - } - - eCopyUpdateArea(dx, dy, w, h, dx, dy); - return key; -} - static int eCopyArea12(int dx, int dy, int w, int h, int opt) { int x, key = 0, cnt; int waitcnt = opt == 0 ? 20 : opt; @@ -610,45 +590,6 @@ static void eCopyArea32(int step) { ags_updateArea(ecp.dx, ecp.dy, ecp.w, ecp.h); } -static int eCopyArea33(int dx, int dy, int w, int h, int opt) { - int i, j, y, key = 0, cnt,dyy=dy+h-1; - int waitcnt = opt == 0 ? 40 : opt; - - cnt = sdl_getTicks(); - for (i = 0; i < ECA11_SLICE + h / ECA11_SLICE -1; i++) { - cnt += waitcnt; - for (j = 0; j < min(i+1, ECA11_SLICE); j++) { - y = j + ECA11_SLICE*(i-j); - if (y < 0 || y >= h) continue; - eCopyUpdateArea(dx, dyy - y, w, 1, dx, dyy - y); - } - EC_WAIT; - } - - eCopyUpdateArea(dx, dy, w, h, dx, dy); - return key; -} - -static int eCopyArea34(int dx, int dy, int w, int h, int opt) { - int i, j, y, key = 0, cnt,dyy=dy+h-1,h2=h/2; - int waitcnt = opt == 0 ? 40 : opt; - - cnt = sdl_getTicks(); - for (i = 0; i < ECA11_SLICE + h / ECA11_SLICE/2 -1; i++) { - cnt += waitcnt; - for (j = 0; j < min(i+1, ECA11_SLICE); j++) { - y = j + ECA11_SLICE*(i-j); - if (y < 0 || y >= h2 ) continue; - eCopyUpdateArea(dx, dy + y, w, 1, dx, dy + y); - eCopyUpdateArea(dx, dyy - y, w, 1, dx, dyy - y); - } - EC_WAIT; - } - - eCopyUpdateArea(dx, dy, w, h, dx, dy); - return key; -} - #define ECA35_D 256 static void eCopyArea35(int step) { int j, l; @@ -1007,44 +948,6 @@ static void eCopyArea43(int step) { nact->sys_view_area.h - deltah); } -static int eCopyArea48(int dx, int dy, int w, int h, int opt) { - int i, j, x, key = 0, cnt; - int waitcnt = opt == 0 ? 40 : opt; - - cnt = sdl_getTicks(); - for (i = 0; i < ECA11_SLICE + w / ECA11_SLICE -1; i++) { - cnt += waitcnt; - for (j = 0; j < min(i+1, ECA11_SLICE); j++) { - x = j + ECA11_SLICE*(i-j); - if (x < 0 || x >= w) continue; - eCopyUpdateArea( dx+x, dy, 1, h, dx+x, dy); - } - EC_WAIT; - } - - eCopyUpdateArea(dx, dy, w, h, dx, dy); - return key; -} - -static int eCopyArea49(int dx, int dy, int w, int h, int opt) { - int i, j, x, key = 0, cnt, dxx = dx + w - 1; - int waitcnt = opt == 0 ? 40 : opt; - - cnt = sdl_getTicks(); - for (i = 0; i < ECA11_SLICE + w / ECA11_SLICE -1; i++) { - cnt += waitcnt; - for (j = 0; j < min(i+1, ECA11_SLICE); j++) { - x = j + ECA11_SLICE*(i-j); - if (x < 0 || x >= w) continue; - eCopyUpdateArea(dxx - x, dy, 1, h, dxx - x, dy); - } - EC_WAIT; - } - - eCopyUpdateArea(dx, dy, w, h, dx, dy); - return key; -} - static int eCopyArea1000(int sx, int sy, int w, int h, int dx, int dy, int opt, int spCol) { /* XOR */ return sys_getInputInfo(); @@ -1100,8 +1003,16 @@ static int eCopyArea5sp(int sx, int sy, int w, int h, int dx, int dy, int opt) { return key; } -static int duration(enum nact_effect effect, int opt) { +static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) { switch (effect) { + case NACT_EFFECT_BLIND_DOWN: + case NACT_EFFECT_BLIND_UP: + return (opt ? opt : 40) * (rect->h / 16 + 16); + case NACT_EFFECT_BLIND_UP_DOWN: + return (opt ? opt : 40) * (rect->h / 16 + 16) / 2; + case NACT_EFFECT_BLIND_LR: + case NACT_EFFECT_BLIND_RL: + return (opt ? opt : 40) * (rect->w / 16 + 16); case NACT_EFFECT_FADEIN: case NACT_EFFECT_WHITEIN: case NACT_EFFECT_FADEOUT: @@ -1138,7 +1049,7 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt if (sdl_effect != EFFECT_INVALID) { SDL_Rect rect = { dx, dy, w, h }; struct sdl_fader *fader = sdl_fader_init(&rect, sdl_getDIB(), dx, dy, sdl_getDIB(), sx, sy, from_nact_effect(sw)); - ags_fade2(duration(sw, opt), cancel, (ags_fade2_callback)sdl_fader_step, fader); + ags_fade2(duration(sw, opt, &rect), cancel, (ags_fade2_callback)sdl_fader_step, fader); sdl_fader_finish(fader); // Actual copy. @@ -1176,7 +1087,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt case 6: case 7: case 8: - case 11: case 12: case 13: case 14: @@ -1187,10 +1097,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt case 19: case 20: case 21: - case 33: - case 34: - case 48: - case 49: case 53: case 54: if (spCol == -1) { @@ -1245,9 +1151,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt i.callback = eCopyArea10; ags_fader(&i); return; - case 11: - ret = eCopyArea11(dx, dy, w, h, opt); - break; case 12: ret = eCopyArea12(dx, dy, w, h, opt); break; @@ -1300,12 +1203,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 33: - ret = eCopyArea33(dx, dy, w, h, opt); - break; - case 34: - ret = eCopyArea34(dx, dy, w, h, opt); - break; case 35: i.step_max = ECA35_D + h; i.effect_time = opt == 0 ? 1150 : opt * i.step_max; @@ -1362,13 +1259,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt ags_fader(&i); return; - case 48: - ret = eCopyArea48(dx, dy, w, h, opt); - break; - case 49: - ret = eCopyArea49(dx, dy, w, h, opt); - break; - case 1000: if (nact->sys_world_depth != 8) return; ret = eCopyArea1000(sx, sy, w, h, dx, dy, opt, spCol); diff --git a/src/effect.h b/src/effect.h index c40b806..e415b53 100644 --- a/src/effect.h +++ b/src/effect.h @@ -22,15 +22,20 @@ // Effect types of the CE command. enum nact_effect { + NACT_EFFECT_BLIND_DOWN = 11, NACT_EFFECT_FADEIN = 27, NACT_EFFECT_WHITEIN = 28, NACT_EFFECT_FADEOUT = 29, NACT_EFFECT_WHITEOUT = 30, NACT_EFFECT_CROSSFADE = 31, + NACT_EFFECT_BLIND_UP = 33, + NACT_EFFECT_BLIND_UP_DOWN = 34, NACT_EFFECT_PENTAGRAM_IN_OUT = 44, NACT_EFFECT_PENTAGRAM_OUT_IN = 45, NACT_EFFECT_HEXAGRAM_IN_OUT = 46, NACT_EFFECT_HEXAGRAM_OUT_IN = 47, + NACT_EFFECT_BLIND_LR = 48, + NACT_EFFECT_BLIND_RL = 49, NACT_EFFECT_WINDMILL = 50, NACT_EFFECT_WINDMILL_180 = 51, NACT_EFFECT_WINDMILL_360 = 52, @@ -43,6 +48,9 @@ enum sact_effect { SACT_EFFECT_FADEIN = 3, SACT_EFFECT_WHITEOUT = 4, SACT_EFFECT_WHITEIN = 5, + SACT_EFFECT_BLIND_DOWN = 7, + SACT_EFFECT_BLIND_LR = 8, + SACT_EFFECT_BLIND_DOWN_LR = 9, SACT_EFFECT_PENTAGRAM_IN_OUT = 14, SACT_EFFECT_PENTAGRAM_OUT_IN = 15, SACT_EFFECT_HEXAGRAM_IN_OUT = 16, @@ -63,6 +71,12 @@ enum sdl_effect { EFFECT_WHITEOUT, EFFECT_WHITEOUT_FROM_NEW, EFFECT_WHITEIN, + EFFECT_BLIND_DOWN, + EFFECT_BLIND_UP, + EFFECT_BLIND_LR, + EFFECT_BLIND_RL, + EFFECT_BLIND_UP_DOWN, + EFFECT_BLIND_DOWN_LR, EFFECT_PENTAGRAM_IN_OUT, EFFECT_PENTAGRAM_OUT_IN, EFFECT_HEXAGRAM_IN_OUT, diff --git a/src/sdl_fader.c b/src/sdl_fader.c index 0b6de50..0d945dc 100644 --- a/src/sdl_fader.c +++ b/src/sdl_fader.c @@ -31,15 +31,20 @@ enum sdl_effect from_nact_effect(enum nact_effect effect) { switch (effect) { + case NACT_EFFECT_BLIND_DOWN: return EFFECT_BLIND_DOWN; case NACT_EFFECT_FADEIN: return EFFECT_FADEIN; case NACT_EFFECT_WHITEIN: return EFFECT_WHITEIN; case NACT_EFFECT_FADEOUT: return EFFECT_FADEOUT_FROM_NEW; case NACT_EFFECT_WHITEOUT: return EFFECT_WHITEOUT_FROM_NEW; 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_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; case NACT_EFFECT_HEXAGRAM_OUT_IN: return EFFECT_HEXAGRAM_OUT_IN; + case NACT_EFFECT_BLIND_LR: return EFFECT_BLIND_LR; + case NACT_EFFECT_BLIND_RL: return EFFECT_BLIND_RL; case NACT_EFFECT_WINDMILL: return EFFECT_WINDMILL; case NACT_EFFECT_WINDMILL_180: return EFFECT_WINDMILL_180; case NACT_EFFECT_WINDMILL_360: return EFFECT_WINDMILL_360; @@ -54,6 +59,9 @@ enum sdl_effect from_sact_effect(enum sact_effect effect) { case SACT_EFFECT_FADEIN: return EFFECT_FADEIN; case SACT_EFFECT_WHITEOUT: return EFFECT_WHITEOUT; case SACT_EFFECT_WHITEIN: return EFFECT_WHITEIN; + 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_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; @@ -188,6 +196,125 @@ static void brightness_free(struct sdl_fader *fader) { free(fader); } +// EFFECT_BLIND_* + +static void blind_step(struct sdl_fader *fader, double progress); +static void blind_free(struct sdl_fader *fader); + +static struct sdl_fader *blind_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect effect) { + struct sdl_fader *fader = calloc(1, sizeof(struct sdl_fader)); + if (!fader) + NOMEMERR(); + fader_init(fader, rect, old, new, effect); + fader->step = blind_step; + fader->finish = blind_free; + return fader; +} + +static void blind_step(struct sdl_fader *fader, double progress) { + const int N = 16; + + SDL_RenderCopy(sdl_renderer, fader->tx_old, NULL, &fader->dst_rect); + + if (fader->effect == EFFECT_BLIND_DOWN || fader->effect == EFFECT_BLIND_UP_DOWN || fader->effect == EFFECT_BLIND_DOWN_LR) { + SDL_Rect rect = fader->dst_rect; + if (fader->effect == EFFECT_BLIND_UP_DOWN) + rect.h = rect.h / (N * 2) * N; + + int maxstep = rect.h / N + N; + int step = maxstep * progress; + + int top = (step - N + 1) * N; + if (top > 0) { + SDL_Rect sr = {0, 0, rect.w, top}; + SDL_Rect dr = {rect.x, rect.y, rect.w, top}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + for (int i = 1; i < N; i++) { + int y = (step - N + i) * N; + if (y < 0 || y >= rect.h) + continue; + SDL_Rect sr = {0, y, rect.w, N - i}; + SDL_Rect dr = {rect.x, rect.y + y, rect.w, N - i}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + } + + if (fader->effect == EFFECT_BLIND_UP || fader->effect == EFFECT_BLIND_UP_DOWN) { + SDL_Rect rect = fader->dst_rect; + int offset = 0; + if (fader->effect == EFFECT_BLIND_UP_DOWN) { + offset = rect.h / (N * 2) * N; + rect.y += offset; + rect.h -= offset; + } + int maxstep = rect.h / N + N; + int step = maxstep - maxstep * progress; + + for (int i = 1; i < N; i++) { + int y = (step - N + i) * N; + if (y < 0 || y >= rect.h) + continue; + SDL_Rect sr = {0, offset + y + N - i, rect.w, i}; + SDL_Rect dr = {rect.x, rect.y + y + N - i, rect.w, i}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + int top = step * N; + if (top < rect.h) { + SDL_Rect sr = {0, offset + top, rect.w, rect.h - top}; + SDL_Rect dr = {rect.x, rect.y + top, rect.w, rect.h - top}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + } + + if (fader->effect == EFFECT_BLIND_LR || fader->effect == EFFECT_BLIND_DOWN_LR) { + int maxstep = fader->dst_rect.w / N + N; + int step = maxstep * progress; + + int lhs = (step - N + 1) * N; + if (lhs > 0) { + SDL_Rect sr = {0, 0, lhs, fader->dst_rect.h}; + SDL_Rect dr = {fader->dst_rect.x, fader->dst_rect.y, lhs, fader->dst_rect.h}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + for (int i = 1; i < N; i++) { + int x = (step - N + i) * N; + if (x < 0 || x >= fader->dst_rect.w) + continue; + SDL_Rect sr = {x, 0, N - i, fader->dst_rect.h}; + SDL_Rect dr = {fader->dst_rect.x + x, fader->dst_rect.y, N - i, fader->dst_rect.h}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + } + + if (fader->effect == EFFECT_BLIND_RL) { + int maxstep = fader->dst_rect.w / N + N; + int step = maxstep - maxstep * progress; + + for (int i = 1; i < N; i++) { + int x = (step - N + i) * N; + if (x < 0 || x >= fader->dst_rect.w) + continue; + SDL_Rect sr = {x + N - i, 0, i, fader->dst_rect.h}; + SDL_Rect dr = {fader->dst_rect.x + x + N - i, fader->dst_rect.y, i, fader->dst_rect.h}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + int lhs = step * N; + if (lhs < fader->dst_rect.w) { + SDL_Rect sr = {lhs, 0, fader->dst_rect.w - lhs, fader->dst_rect.h}; + SDL_Rect dr = {fader->dst_rect.x + lhs, fader->dst_rect.y, fader->dst_rect.w - lhs, fader->dst_rect.h}; + SDL_RenderCopy(sdl_renderer, fader->tx_new, &sr, &dr); + } + } + + SDL_RenderPresent(sdl_renderer); +} + +static void blind_free(struct sdl_fader *fader) { + fader_finish(fader, false); + free(fader); +} + // EFFECT_PENTAGRAM_*, EFFECT_HEXAGRAM_*, EFFECT_WINDMILL* struct polygon_mask_fader { @@ -537,6 +664,13 @@ struct sdl_fader *sdl_fader_init(SDL_Rect *rect, agsurface_t *old, int ox, int o case EFFECT_WHITEOUT_FROM_NEW: case EFFECT_WHITEIN: return brightness_new(rect, sf_old, sf_new, effect); + case EFFECT_BLIND_DOWN: + case EFFECT_BLIND_UP: + case EFFECT_BLIND_LR: + case EFFECT_BLIND_RL: + case EFFECT_BLIND_UP_DOWN: + case EFFECT_BLIND_DOWN_LR: + return blind_new(rect, sf_old, sf_new, effect); case EFFECT_PENTAGRAM_IN_OUT: case EFFECT_PENTAGRAM_OUT_IN: case EFFECT_HEXAGRAM_IN_OUT: