diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 721edce..f249492 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -79,7 +79,6 @@ add_library(modules STATIC lib/graph_draw_amap.c lib/graph_stretch.c lib/graph_cg.c - lib/graph_buller.c lib/gre_blend_useamap.c lib/gre_blend.c lib/gre_blend_screen.c diff --git a/modules/Gpx/effectcopy.c b/modules/Gpx/effectcopy.c index cab1061..200c376 100644 --- a/modules/Gpx/effectcopy.c +++ b/modules/Gpx/effectcopy.c @@ -5,43 +5,12 @@ #include "portab.h" #include "system.h" #include "surface.h" -// #include "gleffectcopy.h" #include "sdl_core.h" #include "ags.h" #include "input.h" #include "graph.h" #include "ngraph.h" -/* saved parameter */ -struct ecopyparam { - surface_t *src; - int sx; - int sy; - surface_t *dst; - int dx; - int dy; - int w; - int h; - surface_t *write; - int wx; - int wy; - int time; - boolean cancel; - int spCol; - int extp[10]; - - // for ec11 - surface_t *ss[8]; - surface_t *sd[8]; -}; -typedef struct ecopyparam ecopyparam_t; -static ecopyparam_t ecp; - - - -static void ec11_cb(int step); -static void ec11_prepare(void); - void gpx_effect(int no, int wx, int wy, surface_t *dst, int dx, int dy, @@ -55,118 +24,28 @@ void gpx_effect(int no, *endtype = 0; - enum sdl_effect_type sdl_effect = from_sact_effect(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); - 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) { - case SACT_EFFECT_FADEOUT: - gr_fill(write, wx, wy, width, height, 0, 0, 0); - break; - case SACT_EFFECT_WHITEOUT: - gr_fill(write, wx, wy, width, height, 255, 255, 255); - break; - default: - gr_copy(write, wx, wy, src, sx, sy, width, height); - break; - } - ags_updateArea(wx, wy, width, height); - return; + enum sdl_effect_type type = from_sact_effect(no); + if (type == EFFECT_INVALID) { + WARNING("Unimplemented effect %d\n", no); + type = EFFECT_CROSSFADE; } + SDL_Rect rect = { wx, wy, width, height }; + struct sdl_effect *eff = sdl_effect_init(&rect, dst, dx, dy, src, sx, sy, type); + 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); - ecp.write = write; - ecp.wx = wx; - ecp.wy = wy; - ecp.dst = dst; - ecp.dx = dx; - ecp.dy = dy; - ecp.src = src; - ecp.sx = sx; - ecp.sy = sy; - ecp.w = width; - ecp.h = height; - ecp.time = time; - - ags_faderinfo_t i; - - switch(no) { - case 11: - ec11_prepare(); - i.step_max = 6; - i.effect_time = time == 0 ? 2700 : time; - i.cancel = FALSE; - i.callback = ec11_cb; - ags_fader(&i); + switch (no) { + case SACT_EFFECT_FADEOUT: + gr_fill(write, wx, wy, width, height, 0, 0, 0); + break; + case SACT_EFFECT_WHITEOUT: + gr_fill(write, wx, wy, width, height, 255, 255, 255); break; default: gr_copy(write, wx, wy, src, sx, sy, width, height); - ags_updateArea(wx, wy, width, height); + break; } + ags_updateArea(wx, wy, width, height); } - - -static void ec11_prepare() { - int i; - - ecp.ss[0] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth); - ecp.sd[0] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth); - gr_buller(ecp.ss[0], 0, 0, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 1 << 2); - gr_buller(ecp.sd[0], 0, 0, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 1 << 2); - - for (i = 1; i < 6; i++) { - ecp.ss[i] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth); - ecp.sd[i] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth); - gr_buller(ecp.ss[i], 0, 0, ecp.ss[i-1], 0, 0, ecp.w, ecp.h, 1 << (i+2)); - gr_buller(ecp.sd[i], 0, 0, ecp.sd[i-1], 0, 0, ecp.w, ecp.h, 1 << (i+2)); - } -} - -static void ec11_cb(int step) { - int i; - - if (step == 6) { - for (i = 0; i < 6; i++) { - sf_free(ecp.ss[i]); - sf_free(ecp.sd[i]); - } - 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; - } - - gre_Blend(ecp.write, ecp.wx, ecp.wy, ecp.sd[step], 0, 0, ecp.ss[5-step], 0, 0, ecp.w, ecp.h, ((step+1)*256)/7); - - ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h); -} - -#if 0 -static void ec11_cb(int step) { - static surface_t *ss; - static surface_t *sd; - - if (step == 0) { - ss = sf_create_surface(ecp.w, ecp.h, ecp.write->depth); - sd = sf_create_surface(ecp.w, ecp.h, ecp.write->depth); - gr_copy(ss, 0, 0, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h); - gr_copy(sd, 0, 0, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h); - return; - } - if (step == 6) { - sf_free(ss); - sf_free(sd); - 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; - } - - gr_buller(ss, 0, 0, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 1 << (7-step)); - gr_buller(sd, 0, 0, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 1 << (step+1)); - gre_Blend(ecp.write, ecp.wx, ecp.wy, sd, 0, 0, ss, 0, 0, ecp.w, ecp.h, (step*256)/6); - ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h); -} -#endif diff --git a/modules/NIGHTDLL/sprite_eupdate.c b/modules/NIGHTDLL/sprite_eupdate.c index cf750ed..1d64234 100644 --- a/modules/NIGHTDLL/sprite_eupdate.c +++ b/modules/NIGHTDLL/sprite_eupdate.c @@ -38,106 +38,40 @@ #include "sactcg.h" #include "sdl_core.h" - -static void ec6_cb(surface_t *, surface_t *); -static void ec11_cb(surface_t *, surface_t *); -static void ec_dummy_cb(surface_t *, surface_t *); - -struct ecopyparam { - int sttime; - int curtime; - int edtime; - int curstep; - int oldstep; -}; -typedef struct ecopyparam ecopyparam_t; -static ecopyparam_t ecp; - -// #include "sprite_eupdate_perspect.c" -// #include "sprite_eupdate_mosaic.c" -// #include "sprite_eupdate_uneune.c" -#include "sprite_eupdate_buller.c" -// #include "sprite_eupdate_zmbbul.c" - -typedef void entrypoint (surface_t *, surface_t *); - -static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) { - WARNING("NOT IMPLEMENTED\n"); -} - /* 効果つき画面更新 - @param type: 効果の種類 + @param no: 効果の種類 @param time: 実行時間(msec) @param cancel: キー抜け(0:なし, 1:あり) */ -int nt_sp_eupdate(int type, int time, int cancel) { - surface_t *sfsrc, *sfdst; - int key; - entrypoint *cb; +int nt_sp_eupdate(int no, int time, int cancel) { + if (no == 1013) { + nt_sp_update_all(TRUE); + return OK; + } - // 現在の sf0 をセーブ - sfsrc = sf_dup(sf0); - nt_sp_update_all(FALSE); - sfdst = sf_dup(sf0); - - enum sdl_effect_type sdl_effect = from_sact_effect(type - 100); - struct sdl_effect *eff = NULL; - if (sdl_effect != EFFECT_INVALID) { - SDL_Rect rect = { 0, 0, sfsrc->width, sfsrc->height }; - eff = sdl_effect_init(&rect, NULL, 0, 0, sdl_getDIB(), 0, 0, sdl_effect); - } else { - sf_copyall(sf0, sfsrc); // 全部の効果タイプにこの処理は要らないんだけど + enum sdl_effect_type type = from_sact_effect(no - 100); + if (type == EFFECT_INVALID) { + WARNING("Unimplemented effect %d\n", no); + type = EFFECT_CROSSFADE; } + SDL_Rect rect = { 0, 0, sf0->width, sf0->height }; + struct sdl_effect *eff = sdl_effect_init(&rect, NULL, 0, 0, sdl_getDIB(), 0, 0, type); - ecp.sttime = ecp.curtime = sdl_getTicks(); - ecp.edtime = ecp.curtime + time; - ecp.oldstep = 0; - - switch(type) { - case 10: - cb = ec_dummy_cb; - break; - case 111: // 線形ぼかし - ec11_prepare(sfsrc, sfdst); - cb = ec11_cb; - break; - case 1011: - cb = ec_dummy_cb; - break; - case 1013: - nt_sp_update_all(TRUE); return OK; - // cb = ec_dummy_cb; - break; - default: - cb = ec_dummy_cb; - break; + int sttime, curtime; + sttime = curtime = sdl_getTicks(); + int edtime = curtime + time; + + while ((curtime = sdl_getTicks()) < edtime) { + sdl_effect_step(eff, (double)(curtime - sttime) / (edtime - sttime)); + int rest = 16 - (sdl_getTicks() - curtime); + int key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE); + if (cancel && key) + break; } - - while ((ecp.curtime = sdl_getTicks()) < ecp.edtime) { - if (eff) { - sdl_effect_step(eff, (double)(ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime)); - } else { - cb(sfsrc, sfdst); - } - int rest = 15 - (sdl_getTicks() - ecp.curtime); - key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE); - - if (cancel && key) break; - } - - sf_copyall(sf0, sfdst); + sdl_effect_finish(eff); ags_updateFull(); - sf_free(sfsrc); - sf_free(sfdst); - - if (type == 111) { - ec11_drain(sfsrc, sfdst); - } - if (eff) - sdl_effect_finish(eff); - return OK; } diff --git a/modules/NIGHTDLL/sprite_eupdate_buller.c b/modules/NIGHTDLL/sprite_eupdate_buller.c deleted file mode 100644 index 12bb7ed..0000000 --- a/modules/NIGHTDLL/sprite_eupdate_buller.c +++ /dev/null @@ -1,66 +0,0 @@ -// 11 と 19 で共有 -static surface_t *ec11_ss[6]; -static surface_t *ec11_sd[6]; - -// 線形ブラー -static void ec11_cb(surface_t *sfsrc, surface_t *sfdst) { - int curstep, maxstep = 6; - curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime); - if (curstep < 6) { - gre_Blend(sf0, 0, 0, ec11_ss[curstep], 0, 0, ec11_sd[5-curstep], 0, 0, sfsrc->width, sfsrc->height, (curstep+1)*256/7); - ags_updateFull(); - } -} - -static void ec11_prepare(surface_t *src, surface_t *dst) { - int i; - - ec11_ss[0] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[0] = sf_create_surface(src->width, src->height, src->depth); - gr_buller(ec11_ss[0], 0, 0, src, 0, 0, src->width, src->height, 1 << 2); - gr_buller(ec11_sd[0], 0, 0, dst, 0, 0, dst->width, dst->height, 1 << 2); - for (i = 1; i < 6; i++) { - ec11_ss[i] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[i] = sf_create_surface(dst->width, dst->height, dst->depth); - gr_buller(ec11_ss[i], 0, 0, ec11_ss[i-1], 0, 0, src->width, src->height, 1 << (i+2)); - gr_buller(ec11_sd[i], 0, 0, ec11_sd[i-1], 0, 0, dst->width, dst->height, 1 << (i+2)); - } -} - -static void ec11_drain(surface_t *src, surface_t *dst) { - int i; - - for (i = 0; i < 6; i++) { - sf_free(ec11_ss[i]); - sf_free(ec11_sd[i]); - } -} - -// 縦線形ブラー -static void ec19_cb(surface_t *sfsrc, surface_t *sfdst) { - ec11_cb(sfsrc, sfdst); -} - -static void ec19_prepare(surface_t *src, surface_t *dst) { - int i; - - ec11_ss[0] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[0] = sf_create_surface(src->width, src->height, src->depth); - gr_buller_v(ec11_ss[0], 0, 0, src, 0, 0, src->width, src->height, 1 << 2); - gr_buller_v(ec11_sd[0], 0, 0, dst, 0, 0, dst->width, dst->height, 1 << 2); - for (i = 1; i < 6; i++) { - ec11_ss[i] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[i] = sf_create_surface(dst->width, dst->height, dst->depth); - gr_buller_v(ec11_ss[i], 0, 0, ec11_ss[i-1], 0, 0, src->width, src->height, 1 << (i+2)); - gr_buller_v(ec11_sd[i], 0, 0, ec11_sd[i-1], 0, 0, dst->width, dst->height, 1 << (i+2)); - } -} - -static void ec19_drain(surface_t *src, surface_t *dst) { - int i; - - for (i = 0; i < 6; i++) { - sf_free(ec11_ss[i]); - sf_free(ec11_sd[i]); - } -} diff --git a/modules/SACT/sprite_eupdate.c b/modules/SACT/sprite_eupdate.c index ff61361..15f06b9 100644 --- a/modules/SACT/sprite_eupdate.c +++ b/modules/SACT/sprite_eupdate.c @@ -41,7 +41,6 @@ static void ec6_cb(surface_t *, surface_t *); -static void ec11_cb(surface_t *, surface_t *); static void sdl_effect_cb(surface_t *, surface_t *); static void ec_dummy_cb(surface_t *, surface_t *); @@ -59,7 +58,6 @@ static ecopyparam_t ecp; #include "sprite_eupdate_perspect.c" #include "sprite_eupdate_mosaic.c" #include "sprite_eupdate_uneune.c" -#include "sprite_eupdate_buller.c" #include "sprite_eupdate_zmbbul.c" typedef void entrypoint (surface_t *, surface_t *); @@ -75,7 +73,7 @@ static entrypoint *cb[39] = { sdl_effect_cb, sdl_effect_cb, ec10_cb, - ec11_cb, + sdl_effect_cb, sdl_effect_cb, sdl_effect_cb, sdl_effect_cb, @@ -83,7 +81,7 @@ static entrypoint *cb[39] = { sdl_effect_cb, sdl_effect_cb, ec_dummy_cb, // 欠番 - ec19_cb, + sdl_effect_cb, sdl_effect_cb, sdl_effect_cb, sdl_effect_cb, @@ -192,12 +190,6 @@ int sp_eupdate(int type, int time, int cancel) { if (type == 10) { ec10_prepare(sfsrc, sfdst); } - if (type == 11) { - ec11_prepare(sfsrc, sfdst); - } - if (type == 19) { - ec19_prepare(sfsrc, sfdst); - } ecp.sttime = ecp.curtime = sdl_getTicks(); ecp.edtime = ecp.curtime + time*10; @@ -221,12 +213,6 @@ int sp_eupdate(int type, int time, int cancel) { if (type == 10) { ec10_drain(sfsrc, sfdst); } - if (type == 11) { - ec11_drain(sfsrc, sfdst); - } - if (type == 19) { - ec19_drain(sfsrc, sfdst); - } if (ecp.eff) { sdl_effect_finish(ecp.eff); ecp.eff = NULL; diff --git a/modules/SACT/sprite_eupdate_buller.c b/modules/SACT/sprite_eupdate_buller.c deleted file mode 100644 index 12bb7ed..0000000 --- a/modules/SACT/sprite_eupdate_buller.c +++ /dev/null @@ -1,66 +0,0 @@ -// 11 と 19 で共有 -static surface_t *ec11_ss[6]; -static surface_t *ec11_sd[6]; - -// 線形ブラー -static void ec11_cb(surface_t *sfsrc, surface_t *sfdst) { - int curstep, maxstep = 6; - curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime); - if (curstep < 6) { - gre_Blend(sf0, 0, 0, ec11_ss[curstep], 0, 0, ec11_sd[5-curstep], 0, 0, sfsrc->width, sfsrc->height, (curstep+1)*256/7); - ags_updateFull(); - } -} - -static void ec11_prepare(surface_t *src, surface_t *dst) { - int i; - - ec11_ss[0] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[0] = sf_create_surface(src->width, src->height, src->depth); - gr_buller(ec11_ss[0], 0, 0, src, 0, 0, src->width, src->height, 1 << 2); - gr_buller(ec11_sd[0], 0, 0, dst, 0, 0, dst->width, dst->height, 1 << 2); - for (i = 1; i < 6; i++) { - ec11_ss[i] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[i] = sf_create_surface(dst->width, dst->height, dst->depth); - gr_buller(ec11_ss[i], 0, 0, ec11_ss[i-1], 0, 0, src->width, src->height, 1 << (i+2)); - gr_buller(ec11_sd[i], 0, 0, ec11_sd[i-1], 0, 0, dst->width, dst->height, 1 << (i+2)); - } -} - -static void ec11_drain(surface_t *src, surface_t *dst) { - int i; - - for (i = 0; i < 6; i++) { - sf_free(ec11_ss[i]); - sf_free(ec11_sd[i]); - } -} - -// 縦線形ブラー -static void ec19_cb(surface_t *sfsrc, surface_t *sfdst) { - ec11_cb(sfsrc, sfdst); -} - -static void ec19_prepare(surface_t *src, surface_t *dst) { - int i; - - ec11_ss[0] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[0] = sf_create_surface(src->width, src->height, src->depth); - gr_buller_v(ec11_ss[0], 0, 0, src, 0, 0, src->width, src->height, 1 << 2); - gr_buller_v(ec11_sd[0], 0, 0, dst, 0, 0, dst->width, dst->height, 1 << 2); - for (i = 1; i < 6; i++) { - ec11_ss[i] = sf_create_surface(src->width, src->height, src->depth); - ec11_sd[i] = sf_create_surface(dst->width, dst->height, dst->depth); - gr_buller_v(ec11_ss[i], 0, 0, ec11_ss[i-1], 0, 0, src->width, src->height, 1 << (i+2)); - gr_buller_v(ec11_sd[i], 0, 0, ec11_sd[i-1], 0, 0, dst->width, dst->height, 1 << (i+2)); - } -} - -static void ec19_drain(surface_t *src, surface_t *dst) { - int i; - - for (i = 0; i < 6; i++) { - sf_free(ec11_ss[i]); - sf_free(ec11_sd[i]); - } -} diff --git a/modules/lib/graph_buller.c b/modules/lib/graph_buller.c deleted file mode 100644 index 0d65223..0000000 --- a/modules/lib/graph_buller.c +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include - -#include "portab.h" -#include "surface.h" -#include "ngraph.h" -#include "ags.h" - -int gr_buller(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int step) { - BYTE *dp, *sp; - int x, y; - int r1, g1, b1; - int r2, g2, b2; - int r3, g3, b3; - - if (src == NULL || dst == NULL) return NG; - if (!gr_clip(src, &sx, &sy, &width, &height, dst, &dx, &dy)) return NG; - - sp = GETOFFSET_PIXEL(src, sx, sy); - dp = GETOFFSET_PIXEL(dst, dx, dy); - switch(dst->depth) { - case 16: - { - WORD *yld, *yls; - - for (y = 0; y < height; y++) { - yls = (WORD *)(sp + y * src->bytes_per_line); - yld = (WORD *)(dp + y * dst->bytes_per_line); - for (x = 0; x < step; x++) { - *yld = *(yls+step); - yls++; yld++; - } - - for (; x < (width - step*2); x++) { - r1 = PIXR16((*(yls+step))); - g1 = PIXG16((*(yls+step))); - b1 = PIXB16((*(yls+step))); - r2 = PIXR16((*(yls-step))); - g2 = PIXG16((*(yls-step))); - b2 = PIXB16((*(yls-step))); - r3 = min(255, (r1+r2) >> 1); - g3 = min(255, (g1+g2) >> 1); - b3 = min(255, (b1+b2) >> 1); - - *yld = PIX16(r3, g3, b3); - yld++; yls++; - } - for (; x < width; x++) { - *yld = *(yls-step); - yls++; yld++; - } - } - break; - } - case 24: - case 32: - { - DWORD *yld, *yls; - - for (y = 0; y < height; y++) { - yls = (DWORD *)(sp + y * src->bytes_per_line); - yld = (DWORD *)(dp + y * dst->bytes_per_line); - for (x = 0; x < step; x++) { - *yld = *(yls+step); - yls++; yld++; - } - - for (; x < (width - step*2); x++) { - r1 = PIXR24((*(yls+step))); - g1 = PIXG24((*(yls+step))); - b1 = PIXB24((*(yls+step))); - r2 = PIXR24((*(yls-step))); - g2 = PIXG24((*(yls-step))); - b2 = PIXB24((*(yls-step))); - r3 = min(255, (r1+r2) >> 1); - g3 = min(255, (g1+g2) >> 1); - b3 = min(255, (b1+b2) >> 1); - - *yld = PIX24(r3, g3, b3); - yld++; yls++; - } - for (; x < width; x++) { - *yld = *(yls-step); - yls++; yld++; - } - } - break; - }} - - return OK; -} - -// 縦方向ブラー -int gr_buller_v(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int step) { - BYTE *dp, *sp; - int x, y; - int r1, g1, b1; - int r2, g2, b2; - int r3, g3, b3; - - if (src == NULL || dst == NULL) return NG; - if (!gr_clip(src, &sx, &sy, &width, &height, dst, &dx, &dy)) return NG; - - sp = GETOFFSET_PIXEL(src, sx, sy); - dp = GETOFFSET_PIXEL(dst, dx, dy); - switch(dst->depth) { - case 16: - { - WORD *yld, *yls; - - for (x = 0; x < width; x++) { - yls = (WORD *)(sp + x * src->bytes_per_pixel); - yld = (WORD *)(dp + x * dst->bytes_per_pixel); - for (y = 0; y < step; y++) { - *(yld+y*dst->width) = *(yls+(y+step)*src->width); - } - - for (; y < (height - step*2); y++) { - r1 = PIXR16((*(yls+(y+step)*src->width))); - g1 = PIXG16((*(yls+(y+step)*src->width))); - b1 = PIXB16((*(yls+(y+step)*src->width))); - r2 = PIXR16((*(yls+(y-step)*src->width))); - g2 = PIXG16((*(yls+(y-step)*src->width))); - b2 = PIXB16((*(yls+(y-step)*src->width))); - r3 = min(255, (r1+r2) >> 1); - g3 = min(255, (g1+g2) >> 1); - b3 = min(255, (b1+b2) >> 1); - - *(yld+y*dst->width) = PIX16(r3, g3, b3); - } - for (; y < height; y++) { - *(yld+y*dst->width) = *(yls+(y-step)*src->width); - } - } - break; - } - case 24: - case 32: - { - DWORD *yld, *yls; - - for (x = 0; x < width; x++) { - yls = (DWORD *)(sp + x * src->bytes_per_pixel); - yld = (DWORD *)(dp + x * dst->bytes_per_pixel); - for (y = 0; y < step; y++) { - *(yld+y*dst->width) = *(yls+(y+step)*src->width); - } - - for (; y < (height - step*2); y++) { - r1 = PIXR24((*(yls+(y+step)*src->width))); - g1 = PIXG24((*(yls+(y+step)*src->width))); - b1 = PIXB24((*(yls+(y+step)*src->width))); - r2 = PIXR24((*(yls+(y-step)*src->width))); - g2 = PIXG24((*(yls+(y-step)*src->width))); - b2 = PIXB24((*(yls+(y-step)*src->width))); - r3 = min(255, (r1+r2) >> 1); - g3 = min(255, (g1+g2) >> 1); - b3 = min(255, (b1+b2) >> 1); - - *(yld+y*dst->width) = PIX24(r3, g3, b3); - } - for (; y < height; y++) { - *(yld+y*dst->width) = *(yls+(y-step)*src->width); - } - } - break; - }} - - return OK; -} - diff --git a/modules/lib/ngraph.h b/modules/lib/ngraph.h index a96677b..cfe0ab6 100644 --- a/modules/lib/ngraph.h +++ b/modules/lib/ngraph.h @@ -64,10 +64,6 @@ extern int gre_Blend(surface_t *write, int wx, int wy, surface_t *dst, int dx, i /* in gre_blend_screen.c */ extern int gre_BlendScreen(surface_t *write, int wx, int wy, surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height); -/* in graph_buller */ -extern int gr_buller(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int step); -extern int gr_buller_v(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int step); - /* in graph_stretch.c */ extern void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh); diff --git a/src/ecopy.c b/src/ecopy.c index bc2efae..4039988 100644 --- a/src/ecopy.c +++ b/src/ecopy.c @@ -885,6 +885,8 @@ static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) { case NACT_EFFECT_WINDMILL_180: case NACT_EFFECT_WINDMILL_360: return opt ? opt : 1000; + case NACT_EFFECT_LINEAR_BLUR: + return opt ? opt : 1700; } return 1000; } @@ -954,7 +956,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 53: case 54: if (spCol == -1) { ags_copyArea(sx, sy, w, h, dx, dy); diff --git a/src/effect.h b/src/effect.h index 267bae9..88e3a76 100644 --- a/src/effect.h +++ b/src/effect.h @@ -43,6 +43,7 @@ enum nact_effect { NACT_EFFECT_WINDMILL = 50, NACT_EFFECT_WINDMILL_180 = 51, NACT_EFFECT_WINDMILL_360 = 52, + NACT_EFFECT_LINEAR_BLUR = 53, }; // Effect types of SCAT.DrawEffect and Gpx.EffectCopy. @@ -55,12 +56,14 @@ enum sact_effect { SACT_EFFECT_BLIND_DOWN = 7, SACT_EFFECT_BLIND_LR = 8, SACT_EFFECT_BLIND_DOWN_LR = 9, + SACT_EFFECT_LINEAR_BLUR = 11, 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, SACT_EFFECT_HEXAGRAM_OUT_IN = 17, + SACT_EFFECT_LINEAR_BLUR_VERT = 19, SACT_EFFECT_ROTATE_OUT = 20, SACT_EFFECT_ROTATE_IN = 21, SACT_EFFECT_ROTATE_OUT_CW = 22, @@ -87,6 +90,8 @@ enum sdl_effect_type { EFFECT_CROSSFADE_UP, EFFECT_CROSSFADE_LR, EFFECT_CROSSFADE_RL, + EFFECT_LINEAR_BLUR, + EFFECT_LINEAR_BLUR_VERT, 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 847d2c2..15c681e 100644 --- a/src/sdl_effect.c +++ b/src/sdl_effect.c @@ -52,6 +52,7 @@ enum sdl_effect_type from_nact_effect(enum nact_effect effect) { 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; + case NACT_EFFECT_LINEAR_BLUR: return EFFECT_LINEAR_BLUR; default: return EFFECT_INVALID; } } @@ -66,12 +67,14 @@ 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_LINEAR_BLUR: return EFFECT_LINEAR_BLUR; 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; case SACT_EFFECT_HEXAGRAM_OUT_IN: return EFFECT_HEXAGRAM_OUT_IN; + case SACT_EFFECT_LINEAR_BLUR_VERT: return EFFECT_LINEAR_BLUR_VERT; case SACT_EFFECT_ROTATE_OUT: return EFFECT_ROTATE_OUT; case SACT_EFFECT_ROTATE_IN: return EFFECT_ROTATE_IN; case SACT_EFFECT_ROTATE_OUT_CW: return EFFECT_ROTATE_OUT_CW; @@ -474,6 +477,114 @@ static void blind_free(struct sdl_effect *eff) { free(eff); } +// EFFECT_LINEAR_BLUR, EFFECT_LINEAR_BLUR_VERT + +#define LINEAR_BLUR_STEPS 10 + +struct linear_blur_effect { + struct sdl_effect eff; + SDL_Texture *blurred_old[LINEAR_BLUR_STEPS]; + SDL_Texture *blurred_new[LINEAR_BLUR_STEPS]; +}; + +static void linear_blur_step(struct sdl_effect *eff, double progress); +static void linear_blur_free(struct sdl_effect *eff); + +static struct sdl_effect *linear_blur_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect_type type) { + if (!SDL_RenderTargetSupported(sdl_renderer)) { + WARNING("Effect %d is not supported in this system. Falling back to crossfade.\n", type); + return crossfade_new(rect, old, new); + } + + struct linear_blur_effect *lbe = calloc(1, sizeof(struct linear_blur_effect)); + if (!lbe) + NOMEMERR(); + effect_init(&lbe->eff, rect, old, new, type); + lbe->eff.step = linear_blur_step; + lbe->eff.finish = linear_blur_free; + return &lbe->eff; +} + +static SDL_Texture *blur(struct linear_blur_effect *this, SDL_Texture *src, int stride) { + bool vertical = this->eff.type == EFFECT_LINEAR_BLUR_VERT; + int w = this->eff.dst_rect.w; + int h = this->eff.dst_rect.h; + SDL_Texture *dst = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, w, h); + + SDL_SetRenderTarget(sdl_renderer, dst); + SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, 255); + SDL_RenderClear(sdl_renderer); + SDL_SetTextureBlendMode(src, SDL_BLENDMODE_ADD); + SDL_SetTextureAlphaMod(src, 127); + + SDL_Rect dr = {0, 0, w, h}; + *(vertical ? &dr. y : &dr.x) = -stride / 2; + SDL_RenderCopy(sdl_renderer, src, NULL, &dr); + *(vertical ? &dr. y : &dr.x) = max(1, stride / 2); + SDL_RenderCopy(sdl_renderer, src, NULL, &dr); + + // Copy the edge pixels to emulate texture clamping. + SDL_Rect sr = {0, 0, vertical ? w : 1, vertical ? 1 : h}; + *(vertical ? &dr.h : &dr.w) = max(1, stride / 2); + *(vertical ? &dr.y : &dr.x) = 0; + SDL_RenderCopy(sdl_renderer, src, &sr, &dr); + if (stride > 1) { + if (vertical) { + sr.y = h - 1; + dr.y = h - stride / 2; + } else { + sr.x = w - 1; + dr.x = w - stride / 2; + } + SDL_RenderCopy(sdl_renderer, src, &sr, &dr); + } + + SDL_SetTextureAlphaMod(src, 255); + SDL_SetTextureBlendMode(src, SDL_BLENDMODE_NONE); + SDL_SetRenderTarget(sdl_renderer, NULL); + + return dst; +} + +static void linear_blur_step(struct sdl_effect *eff, double progress) { + struct linear_blur_effect *this = (struct linear_blur_effect *)eff; + + int step = progress * LINEAR_BLUR_STEPS * 2; + if (step == LINEAR_BLUR_STEPS * 2) { + SDL_RenderCopy(sdl_renderer, eff->tx_new, NULL, NULL); + SDL_RenderPresent(sdl_renderer); + return; + } + + for (int i = 0; i <= step && i < LINEAR_BLUR_STEPS; i++) { + if (this->blurred_old[i]) + continue; + this->blurred_old[i] = blur(this, i ? this->blurred_old[i - 1] : eff->tx_old, 1 << i); + this->blurred_new[i] = blur(this, i ? this->blurred_new[i - 1] : eff->tx_new, 1 << i); + } + + int i = step < LINEAR_BLUR_STEPS ? step : LINEAR_BLUR_STEPS * 2 - 1 - step; + SDL_Texture *old = this->blurred_old[i]; + SDL_Texture *new = this->blurred_new[i]; + SDL_RenderCopy(sdl_renderer, old, NULL, &eff->dst_rect); + SDL_SetTextureBlendMode(new, SDL_BLENDMODE_BLEND); + SDL_SetTextureAlphaMod(new, 255 * progress); + SDL_RenderCopy(sdl_renderer, new, NULL, &eff->dst_rect); + SDL_RenderPresent(sdl_renderer); +} + +static void linear_blur_free(struct sdl_effect *eff) { + struct linear_blur_effect *this = (struct linear_blur_effect *)eff; + for (int i = 0; i < LINEAR_BLUR_STEPS; i++) { + if (this->blurred_old[i]) + SDL_DestroyTexture(this->blurred_old[i]); + if (this->blurred_new[i]) + SDL_DestroyTexture(this->blurred_new[i]); + } + effect_finish(&this->eff, true); + free(this); +} + // EFFECT_PENTAGRAM_*, EFFECT_HEXAGRAM_*, EFFECT_WINDMILL* struct polygon_mask_effect { @@ -835,6 +946,9 @@ struct sdl_effect *sdl_effect_init(SDL_Rect *rect, agsurface_t *old, int ox, int case EFFECT_BLIND_UP_DOWN: case EFFECT_BLIND_DOWN_LR: return blind_new(rect, sf_old, sf_new, type); + case EFFECT_LINEAR_BLUR: + case EFFECT_LINEAR_BLUR_VERT: + return linear_blur_new(rect, sf_old, sf_new, type); case EFFECT_PENTAGRAM_IN_OUT: case EFFECT_PENTAGRAM_OUT_IN: case EFFECT_HEXAGRAM_IN_OUT: