From 4daaa5ede52c79f948fdad249659f435f896db78 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 16 Jan 2022 09:57:36 +0900 Subject: [PATCH] Use sdl_fader in Gpx.EffectCopy --- modules/Gpx/Gpx.c | 3 +- modules/Gpx/effectcopy.c | 53 ++++++++++---------------- modules/Gpx/effectcopy.h | 2 +- modules/SACT/sprite_eupdate.c | 28 +++----------- src/ecopy.c | 5 ++- src/effect.h | 3 +- src/sdl_core.h | 2 +- src/sdl_fader.c | 71 +++++++++++++++++++---------------- 8 files changed, 73 insertions(+), 94 deletions(-) diff --git a/modules/Gpx/Gpx.c b/modules/Gpx/Gpx.c index a857b27..e58e218 100644 --- a/modules/Gpx/Gpx.c +++ b/modules/Gpx/Gpx.c @@ -1150,10 +1150,9 @@ static void EffectCopy() { default: DEBUG_COMMAND_YET("Gpx.EffectCopy %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%p:\n", no, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh, time, var); } - dib = sf_get(0); dst = sf_get(ss1); src = sf_get(ss2); - gpx_effect(no, dib, dx, dy, dst, sx1, sy1, src, sx2, sy2, sw, sh, time, var); + gpx_effect(no, dx, dy, dst, sx1, sy1, src, sx2, sy2, sw, sh, time, var); } diff --git a/modules/Gpx/effectcopy.c b/modules/Gpx/effectcopy.c index de8b98d..6000a9c 100644 --- a/modules/Gpx/effectcopy.c +++ b/modules/Gpx/effectcopy.c @@ -42,7 +42,6 @@ static ecopyparam_t ecp; #define ECA7_D 16 #define ECA12_D 256 -static void ec1_cb(int step); static void ec2_cb(int step); static void ec3_cb(int step); static void ec4_cb(int step); @@ -53,26 +52,31 @@ static void ec11_prepare(void); static void ec12_cb(int step); static void ec13_cb(int step); -#if 0 -void gle_set_check_clik() { -} -void gle_set_itimer() { -} -#endif - void gpx_effect(int no, - surface_t *write, int wx, int wy, + int wx, int wy, surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int time, int *endtype) { - - ags_faderinfo_t i; - + surface_t *write = nact->ags.dib; if (!gr_clip(dst, &dx, &dy, &width, &height, write, &wx, &wy)) return; if (!gr_clip(src, &sx, &sy, &width, &height, write, &wx, &wy)) return; - + + *endtype = 0; + + enum sdl_effect sdl_effect = from_sact_effect(no); + if (sdl_effect != EFFECT_INVALID) { + SDL_Rect rect = { wx, wy, width, height }; + struct sdl_fader *fader = sdl_fader_init(&rect, dst, dx, dy, src, sx, sy, sdl_effect); + ags_fade2(time ? time : 2700, FALSE, (ags_fade2_callback)sdl_fader_step, fader); + sdl_fader_finish(fader); + + gr_copy(write, wx, wy, src, sx, sy, width, height); + ags_updateArea(wx, wy, width, height); + return; + } + ecp.write = write; ecp.wx = wx; ecp.wy = wy; @@ -85,15 +89,10 @@ void gpx_effect(int no, ecp.w = width; ecp.h = height; ecp.time = time; - + + ags_faderinfo_t i; + switch(no) { - case 1: - i.step_max = 64; - i.effect_time = time == 0 ? 2700 : time; - i.cancel = FALSE; - i.callback = ec1_cb; - ags_fader(&i); - break; case 2: i.step_max = 64; i.effect_time = time == 0 ? 2700 : time; @@ -151,9 +150,6 @@ void gpx_effect(int no, gr_copy(write, wx, wy, src, sx, sy, width, height); ags_updateArea(wx, wy, width, height); } - - *endtype = 0; - } void sf_blend_white_level(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int lv) { @@ -200,15 +196,6 @@ void sf_blend_white_level(surface_t *dst, int dx, int dy, surface_t *src, int sx } -static void ec1_cb(int step) { - if (step == 64) { - gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h); - } else { - gre_Blend(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, step * 4); - } - ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h); -} - static void ec2_cb(int step) { if (step == 0) { gr_copy_bright(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 255); diff --git a/modules/Gpx/effectcopy.h b/modules/Gpx/effectcopy.h index a8c3290..074ddb8 100644 --- a/modules/Gpx/effectcopy.h +++ b/modules/Gpx/effectcopy.h @@ -4,7 +4,7 @@ #include "surface.h" extern void gpx_effect(int no, - surface_t *write, int wx, int wy, + int wx, int wy, surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, diff --git a/modules/SACT/sprite_eupdate.c b/modules/SACT/sprite_eupdate.c index d2691ef..13c0873 100644 --- a/modules/SACT/sprite_eupdate.c +++ b/modules/SACT/sprite_eupdate.c @@ -40,7 +40,6 @@ #include "sdl_core.h" -static void ec1_cb(surface_t *, surface_t *); static void ec6_cb(surface_t *, surface_t *); static void ec7_cb(surface_t *, surface_t *); static void ec8_cb(surface_t *, surface_t *); @@ -71,7 +70,7 @@ static ecopyparam_t ecp; typedef void entrypoint (surface_t *, surface_t *); static entrypoint *cb[39] = { - ec1_cb, + sdlfader_cb, ec_dummy_cb, // 欠番 ec_dummy_cb, // 欠番 ec_dummy_cb, // 欠番 @@ -116,23 +115,6 @@ static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) { WARNING("NOT IMPLEMENTED\n"); } -// クロスフェード -static void ec1_cb(surface_t *sfsrc, surface_t *sfdst) { - int curstep; - - curstep = 255 * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime); - if (ecp.oldstep == curstep) { - usleep(0); - return; - } - gre_Blend(sf0, 0, 0, sfsrc, 0, 0, sfdst, 0, 0, sfsrc->width, sfsrc->height, curstep); - - SACT_DEBUG("step = %d\n", curstep); - ags_updateFull(); - - ecp.oldstep = curstep; -} - // すだれ落ち static void ec7_cb(surface_t *sfsrc, surface_t *sfdst) { #define EC7DELTA 16 @@ -358,10 +340,12 @@ int sp_eupdate(int type, int time, int cancel) { sfdst = sf_dup(sf0); enum sdl_effect sdl_effect = from_sact_effect(type); - if (sdl_effect != EFFECT_INVALID) - ecp.fader = sdl_fader_init(0, 0, sfsrc->width, sfsrc->height, 0, 0, sdl_effect); - else + if (sdl_effect != EFFECT_INVALID) { + SDL_Rect rect = { 0, 0, sfsrc->width, sfsrc->height }; + ecp.fader = sdl_fader_init(&rect, NULL, 0, 0, sdl_getDIB(), 0, 0, sdl_effect); + } else { sf_copyall(sf0, sfsrc); // 全部の効果タイプにこの処理は要らないんだけど + } // 5つを越えたら別の方法を考えよう if (type == 10) { diff --git a/src/ecopy.c b/src/ecopy.c index 2a8cbdc..3290c68 100644 --- a/src/ecopy.c +++ b/src/ecopy.c @@ -1430,9 +1430,12 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt case NACT_EFFECT_WINDMILL_180: case NACT_EFFECT_WINDMILL_360: { - struct sdl_fader *fader = sdl_fader_init(ecp.sx, ecp.sy, ecp.w, ecp.h, ecp.dx, ecp.dy, from_nact_effect(sw)); + SDL_Rect rect = { ecp.dx, ecp.dy, ecp.w, ecp.h }; + struct sdl_fader *fader = sdl_fader_init(&rect, sdl_getDIB(), ecp.dx, ecp.dy, sdl_getDIB(), ecp.sx, ecp.sy, from_nact_effect(sw)); ags_fade2(opt ? opt : 1000, cancel, (ags_fade2_callback)sdl_fader_step, fader); sdl_fader_finish(fader); + // Actual copy. + sdl_copyArea(ecp.sx, ecp.sy, ecp.w, ecp.h, ecp.dx, ecp.dy); } return; diff --git a/src/effect.h b/src/effect.h index 31c12b1..d20af99 100644 --- a/src/effect.h +++ b/src/effect.h @@ -32,8 +32,9 @@ enum nact_effect { NACT_EFFECT_WINDMILL_360 = 52, }; -// Effect types of SCAT.DrawEffect. +// Effect types of SCAT.DrawEffect and Gpx.EffectCopy. enum sact_effect { + SACT_EFFECT_CROSSFADE = 1, SACT_EFFECT_PENTAGRAM_IN_OUT = 14, SACT_EFFECT_PENTAGRAM_OUT_IN = 15, SACT_EFFECT_HEXAGRAM_IN_OUT = 16, diff --git a/src/sdl_core.h b/src/sdl_core.h index 5718d58..7ad2105 100644 --- a/src/sdl_core.h +++ b/src/sdl_core.h @@ -87,7 +87,7 @@ extern SDL_Surface *com2surface(agsurface_t *s); /* fader */ struct sdl_fader; -struct sdl_fader *sdl_fader_init(int sx, int sy, int w, int h, int dx, int dy, enum sdl_effect type); +struct sdl_fader *sdl_fader_init(SDL_Rect *rect, agsurface_t *old, int ox, int oy, agsurface_t *new, int nx, int ny, enum sdl_effect effect); void sdl_fader_step(struct sdl_fader *fader, double progress); void sdl_fader_finish(struct sdl_fader *fader); extern void sdl_fadeIn(int step); diff --git a/src/sdl_fader.c b/src/sdl_fader.c index 75827eb..abfad90 100644 --- a/src/sdl_fader.c +++ b/src/sdl_fader.c @@ -45,6 +45,7 @@ enum sdl_effect from_nact_effect(enum nact_effect effect) { enum sdl_effect from_sact_effect(enum sact_effect effect) { switch (effect) { + case SACT_EFFECT_CROSSFADE: return EFFECT_CROSSFADE; 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; @@ -65,27 +66,13 @@ struct sdl_fader { SDL_Texture *tx_old, *tx_new; }; -static void fader_init(struct sdl_fader *fader, int sx, int sy, int w, int h, int dx, int dy, enum sdl_effect effect) { +static void fader_init(struct sdl_fader *fader, SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect effect) { fader->effect = effect; - fader->dst_rect.x = dx; - fader->dst_rect.y = dy; - fader->dst_rect.w = w; - fader->dst_rect.h = h; - - SDL_Surface *sf_old = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGB888); - SDL_Surface *sf_new = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGB888); - - SDL_Rect src_rect = { sx, sy, w, h }; - SDL_BlitSurface(sdl_display, &fader->dst_rect, sf_old, NULL); - SDL_BlitSurface(sdl_dib, &src_rect, sf_new, NULL); - - fader->tx_old = SDL_CreateTextureFromSurface(sdl_renderer, sf_old); - fader->tx_new = SDL_CreateTextureFromSurface(sdl_renderer, sf_new); - - SDL_FreeSurface(sf_old); - SDL_FreeSurface(sf_new); - - sdl_copyArea(sx, sy, w, h, dx, dy); + fader->dst_rect = *rect; + fader->tx_old = SDL_CreateTextureFromSurface(sdl_renderer, old); + fader->tx_new = SDL_CreateTextureFromSurface(sdl_renderer, new); + SDL_FreeSurface(old); + SDL_FreeSurface(new); } static void fader_finish(struct sdl_fader *fader) { @@ -101,11 +88,11 @@ static void fader_finish(struct sdl_fader *fader) { static void crossfade_step(struct sdl_fader *fader, double progress); static void crossfade_free(struct sdl_fader *fader); -static struct sdl_fader *crossfade_new(int sx, int sy, int w, int h, int dx, int dy) { +static struct sdl_fader *crossfade_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new) { struct sdl_fader *fader = calloc(1, sizeof(struct sdl_fader)); if (!fader) NOMEMERR(); - fader_init(fader, sx, sy, w, h, dx, dy, EFFECT_CROSSFADE); + fader_init(fader, rect, old, new, EFFECT_CROSSFADE); fader->step = crossfade_step; fader->finish = crossfade_free; return fader; @@ -135,14 +122,14 @@ struct polygon_mask_fader { static void polygon_mask_step(struct sdl_fader *fader, double progress); static void polygon_mask_free(struct sdl_fader *fader); -static struct sdl_fader *polygon_mask_new(int sx, int sy, int w, int h, int dx, int dy, enum sdl_effect effect) { +static struct sdl_fader *polygon_mask_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect effect) { #if HAS_SDL_RenderGeometry if (SDL_RenderTargetSupported(sdl_renderer)) { struct polygon_mask_fader *pmf = calloc(1, sizeof(struct polygon_mask_fader)); if (!pmf) NOMEMERR(); - fader_init(&pmf->f, sx, sy, w, h, dx, dy, effect); - pmf->tx_tmp = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h); + fader_init(&pmf->f, rect, old, new, effect); + pmf->tx_tmp = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, rect->w, rect->h); pmf->f.step = polygon_mask_step; pmf->f.finish = polygon_mask_free; return &pmf->f; @@ -150,7 +137,7 @@ static struct sdl_fader *polygon_mask_new(int sx, int sy, int w, int h, int dx, #endif // HAS_SDL_RenderGeometry WARNING("Effect %d is not supported in this system. Falling back to crossfade.\n", effect); - return crossfade_new(sx, sy, w, h, dx, dy); + return crossfade_new(rect, old, new); } #if HAS_SDL_RenderGeometry @@ -391,11 +378,11 @@ static void polygon_mask_free(struct sdl_fader *fader) { static void rotate_step(struct sdl_fader *fader, double progress); static void rotate_free(struct sdl_fader *fader); -static struct sdl_fader *rotate_new(int sx, int sy, int w, int h, int dx, int dy, enum sdl_effect effect) { +static struct sdl_fader *rotate_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, sx, sy, w, h, dx, dy, effect); + fader_init(fader, rect, old, new, effect); fader->step = rotate_step; fader->finish = rotate_free; return fader; @@ -445,10 +432,28 @@ static void rotate_free(struct sdl_fader *fader) { } -struct sdl_fader *sdl_fader_init(int sx, int sy, int w, int h, int dx, int dy, enum sdl_effect effect) { +static SDL_Surface *create_surface(agsurface_t *as, int x, int y, int w, int h) { + SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGB888); + SDL_Rect rect = { x, y, w, h }; + if (!as) { + SDL_BlitSurface(sdl_display, &rect, sf, NULL); + } else if (as == sdl_dibinfo) { + SDL_BlitSurface(sdl_dib, &rect, sf, NULL); + } else { + SDL_Surface *s = com2surface(as); + SDL_BlitSurface(s, &rect, sf, NULL); + SDL_FreeSurface(s); + } + return sf; +} + +struct sdl_fader *sdl_fader_init(SDL_Rect *rect, agsurface_t *old, int ox, int oy, agsurface_t *new, int nx, int ny, enum sdl_effect effect) { + SDL_Surface *sf_old = create_surface(old, ox, oy, rect->w, rect->h); + SDL_Surface *sf_new = create_surface(new, nx, ny, rect->w, rect->h); + switch (effect) { case EFFECT_CROSSFADE: - return crossfade_new(sx, sy, w, h, dx, dy); + return crossfade_new(rect, sf_old, sf_new); case EFFECT_PENTAGRAM_IN_OUT: case EFFECT_PENTAGRAM_OUT_IN: case EFFECT_HEXAGRAM_IN_OUT: @@ -456,15 +461,15 @@ struct sdl_fader *sdl_fader_init(int sx, int sy, int w, int h, int dx, int dy, e case EFFECT_WINDMILL: case EFFECT_WINDMILL_180: case EFFECT_WINDMILL_360: - return polygon_mask_new(sx, sy, w, h, dx, dy, effect); + return polygon_mask_new(rect, sf_old, sf_new, effect); case EFFECT_ROTATE_OUT: case EFFECT_ROTATE_IN: case EFFECT_ROTATE_OUT_CW: case EFFECT_ROTATE_IN_CW: - return rotate_new(sx, sy, w, h, dx, dy, effect); + return rotate_new(rect, sf_old, sf_new, effect); default: WARNING("Unknown effect %d\n", effect); - return crossfade_new(sx, sy, w, h, dx, dy); + return crossfade_new(rect, sf_old, sf_new); } }