mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-03 20:27:58 +03:00
sdl_effect: Implement linear blur effects
Now Gpx and NIGHTDLL are fully migrated to sdl_effect.
This commit is contained in:
@@ -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
|
||||
|
||||
+18
-139
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+2
-1
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user