mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
sdl_effect: Implement EFFECT_PAN_IN_* and EFFECT_SKIP_LINE_*
This also fixes incorrect behavior of `CD 1` and `CD 2`.
This commit is contained in:
+17
-114
@@ -54,84 +54,6 @@ static void eCopyUpdateArea(int sx, int sy, int w, int h, int dx, int dy) {
|
||||
sdl_updateArea(&src, &dst);
|
||||
}
|
||||
|
||||
static int eCopyArea1(int dx, int dy, int w, int h, int opt) {
|
||||
int y, key = 0, cnt;
|
||||
int waitcnt = opt == 0 ? 20 : opt;
|
||||
|
||||
cnt = sdl_getTicks();
|
||||
for (y = 0; y < h - 24; y += 24) {
|
||||
cnt += waitcnt;
|
||||
eCopyUpdateArea(dx, dy + h - y, w, y, dx, dy);
|
||||
EC_WAIT;
|
||||
}
|
||||
|
||||
eCopyUpdateArea(dx, dy, w, h, dx, dy);
|
||||
return key;
|
||||
}
|
||||
|
||||
static int eCopyArea2(int dx, int dy, int w, int h, int opt) {
|
||||
int y, key = 0, cnt;
|
||||
int waitcnt = opt == 0 ? 20 : opt;
|
||||
|
||||
cnt = sdl_getTicks();
|
||||
for (y = 0; y < h - 24; y += 24) {
|
||||
cnt += waitcnt;
|
||||
eCopyUpdateArea(dx, dy , w, y, dx, dy + h - y);
|
||||
EC_WAIT;
|
||||
}
|
||||
|
||||
eCopyUpdateArea(dx, dy, w, h, dx, dy);
|
||||
return key;
|
||||
}
|
||||
|
||||
static int eCopyArea3(int dx, int dy, int w, int h, int opt) {
|
||||
int y1, y2, key = 0, cnt;
|
||||
int waitcnt = opt == 0 ? 3 : opt;
|
||||
|
||||
if (h % 2) {
|
||||
h--;
|
||||
eCopyUpdateArea(dx , dy + h, w, 1, dx, dy + h);
|
||||
}
|
||||
y1 = dy;
|
||||
y2 = dy + h - 1;
|
||||
cnt = sdl_getTicks();
|
||||
while (h > 0) {
|
||||
cnt += waitcnt;
|
||||
eCopyUpdateArea(dx, y1, w, 1, dx, y1);
|
||||
eCopyUpdateArea(dx, y2, w, 1, dx, y2);
|
||||
y1 += 2;
|
||||
y2 -= 2;
|
||||
h -= 2;
|
||||
EC_WAIT;
|
||||
}
|
||||
eCopyUpdateArea(dx, dy, w, h, dx, dy);
|
||||
return key;
|
||||
}
|
||||
|
||||
static int eCopyArea4(int dx, int dy, int w, int h, int opt) {
|
||||
int x1,x2, key = 0, cnt;
|
||||
int waitcnt = opt == 0 ? 3 : opt;
|
||||
|
||||
if (w % 2) {
|
||||
w--;
|
||||
eCopyUpdateArea(dx + w , dy, 1, h, dx + w, dy);
|
||||
}
|
||||
x1 = dx;
|
||||
x2 = dx + w - 1;
|
||||
cnt = sdl_getTicks();
|
||||
while (w > 0) {
|
||||
cnt += waitcnt;
|
||||
eCopyUpdateArea(x1, dy, 1, h, x1, dy);
|
||||
eCopyUpdateArea(x2, dy, 1, h, x2, dy);
|
||||
x1 += 2;
|
||||
x2 -= 2;
|
||||
w -= 2;
|
||||
EC_WAIT;
|
||||
}
|
||||
eCopyUpdateArea(dx, dy, w, h, dx, dy);
|
||||
return key;
|
||||
}
|
||||
|
||||
static int eCopyArea5(int sx, int sy, int w, int h, int dx, int dy, int opt) {
|
||||
int i, x, y, key = 0, cnt;
|
||||
int waitcnt = opt == 0 ? 20 : opt;
|
||||
@@ -299,6 +221,13 @@ static int eCopyArea2001(int sx, int sy, int w, int h, int dx, int dy, int opt)
|
||||
|
||||
static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) {
|
||||
switch (effect) {
|
||||
case NACT_EFFECT_PAN_IN_DOWN:
|
||||
case NACT_EFFECT_PAN_IN_UP:
|
||||
return (opt ? opt : 20) * (rect->h / 24);
|
||||
case NACT_EFFECT_SKIP_LINE_UP_DOWN:
|
||||
return (opt ? opt : 3) * (rect->h / 2);
|
||||
case NACT_EFFECT_SKIP_LINE_LR_RL:
|
||||
return (opt ? opt : 3) * (rect->w / 2);
|
||||
case NACT_EFFECT_ZOOM_IN:
|
||||
return opt ? opt * 64 : 500;
|
||||
case NACT_EFFECT_BLIND_DOWN:
|
||||
@@ -423,10 +352,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt
|
||||
ecp_cancel = cancel;
|
||||
|
||||
switch(sw) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 6:
|
||||
case 16:
|
||||
case 17:
|
||||
@@ -441,18 +366,6 @@ void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt
|
||||
}
|
||||
|
||||
switch(sw) {
|
||||
case 1:
|
||||
ret = eCopyArea1(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 2:
|
||||
ret = eCopyArea2(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 3:
|
||||
ret = eCopyArea3(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 4:
|
||||
ret = eCopyArea4(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 5:
|
||||
ret = eCopyArea5(sx, sy, w, h, dx, dy, opt);
|
||||
break;
|
||||
@@ -505,6 +418,16 @@ void ags_eSpriteCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, i
|
||||
|
||||
nact->waitcancel_key = 0;
|
||||
|
||||
if (1 <= sw && sw <= 4) {
|
||||
SDL_Rect rect = { dx - nact->ags.view_area.x, dy - nact->ags.view_area.y, w, h };
|
||||
struct sdl_effect *eff = sdl_sprite_effect_init(&rect, dx, dy, sx, sy, spCol, from_nact_effect(sw));
|
||||
ags_runEffect(duration(sw, opt, &rect), cancel, (ags_EffectStepFunc)sdl_effect_step, eff);
|
||||
sdl_effect_finish(eff);
|
||||
// Actual copy.
|
||||
ags_copyAreaSP(sx, sy, w, h, dx, dy, spCol);
|
||||
ags_updateArea(dx, dy, w, h);
|
||||
return;
|
||||
}
|
||||
if (sw == 5) {
|
||||
SDL_Rect rect = { dx - nact->ags.view_area.x, dy - nact->ags.view_area.y, w, h };
|
||||
struct sdl_effect *eff = sdl_effect_raster_blend_init(&rect, sx, sy);
|
||||
@@ -518,28 +441,8 @@ void ags_eSpriteCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, i
|
||||
|
||||
ecp_cancel = cancel;
|
||||
|
||||
if (1 <= sw && sw <= 4) {
|
||||
ags_copyAreaSP(sx, sy, w, h, dx, dy, spCol);
|
||||
MyRectangle r = {dx, dy, w, h}, update;
|
||||
SDL_IntersectRect(&nact->ags.view_area, &r, &update);
|
||||
w = update.w;
|
||||
h = update.h;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
switch(sw) {
|
||||
case 1:
|
||||
ret = eCopyArea1(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 2:
|
||||
ret = eCopyArea2(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 3:
|
||||
ret = eCopyArea3(dx, dy, w, h, opt);
|
||||
break;
|
||||
case 4:
|
||||
ret = eCopyArea4(dx, dy, w, h, opt);
|
||||
break;
|
||||
case NACT_EFFECT_PALETTE_SHIFT:
|
||||
if (nact->ags.world_depth != 8) return;
|
||||
ags_copyPaletteShift(sx, sy, w, h, dx, dy, spCol);
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
|
||||
// Effect types of the CE/CD command.
|
||||
enum nact_effect {
|
||||
NACT_EFFECT_PAN_IN_DOWN = 1,
|
||||
NACT_EFFECT_PAN_IN_UP = 2,
|
||||
NACT_EFFECT_SKIP_LINE_UP_DOWN = 3,
|
||||
NACT_EFFECT_SKIP_LINE_LR_RL = 4,
|
||||
NACT_EFFECT_WIPE_IN = 7,
|
||||
NACT_EFFECT_WIPE_OUT = 8,
|
||||
NACT_EFFECT_ZOOM_IN = 10,
|
||||
@@ -124,6 +128,10 @@ enum sdl_effect_type {
|
||||
EFFECT_DITHERING_FADEIN,
|
||||
EFFECT_DITHERING_WHITEOUT,
|
||||
EFFECT_DITHERING_WHITEIN,
|
||||
EFFECT_PAN_IN_DOWN,
|
||||
EFFECT_PAN_IN_UP,
|
||||
EFFECT_SKIP_LINE_UP_DOWN,
|
||||
EFFECT_SKIP_LINE_LR_RL,
|
||||
EFFECT_WIPE_IN,
|
||||
EFFECT_WIPE_OUT,
|
||||
EFFECT_WIPE_LR,
|
||||
|
||||
@@ -87,6 +87,7 @@ extern SDL_Surface *com2surface(agsurface_t *s);
|
||||
/* Effects */
|
||||
struct sdl_effect;
|
||||
struct sdl_effect *sdl_effect_init(SDL_Rect *rect, agsurface_t *old, int ox, int oy, agsurface_t *new, int nx, int ny, enum sdl_effect_type effect);
|
||||
struct sdl_effect *sdl_sprite_effect_init(SDL_Rect *rect, int dx, int dy, int sx, int sy, int col, enum sdl_effect_type type);
|
||||
struct sdl_effect *sdl_effect_magnify_init(agsurface_t *surface, SDL_Rect *view_rect, SDL_Rect *target_rect);
|
||||
struct sdl_effect *sdl_effect_raster_blend_init(SDL_Rect *rect, int sx, int sy);
|
||||
void sdl_effect_step(struct sdl_effect *eff, float progress);
|
||||
|
||||
+16
-5
@@ -202,10 +202,7 @@ void sdl_copyArea(int sx, int sy, int w, int h, int dx, int dy) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dib に指定のパレット sp を抜いてコピー
|
||||
*/
|
||||
void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, uint8_t sp) {
|
||||
static void sdl_dib_sprite_copy(SDL_Surface *dst, int sx, int sy, int w, int h, int dx, int dy, uint8_t sp) {
|
||||
sdl_pal_check();
|
||||
|
||||
Uint32 col = palette_color(sp);
|
||||
@@ -214,10 +211,24 @@ void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, uint8_t sp) {
|
||||
SDL_Rect r_src = {sx, sy, w, h};
|
||||
SDL_Rect r_dst = {dx, dy, w, h};
|
||||
|
||||
SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst);
|
||||
SDL_BlitSurface(sdl_dib, &r_src, dst, &r_dst);
|
||||
SDL_SetColorKey(sdl_dib, SDL_FALSE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* dib に指定のパレット sp を抜いてコピー
|
||||
*/
|
||||
void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, uint8_t sp) {
|
||||
sdl_dib_sprite_copy(sdl_dib, sx, sy, w, h, dx, dy, sp);
|
||||
}
|
||||
|
||||
SDL_Surface *sdl_dib_to_surface_colorkey(int x, int y, int w, int h, int sp) {
|
||||
SDL_Surface *s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
SDL_FillRect(s, NULL, 0);
|
||||
sdl_dib_sprite_copy(s, x, y, w, h, 0, 0, sp);
|
||||
return s;
|
||||
}
|
||||
|
||||
void sdl_drawImage8_fromData(cgdata *cg, int dx, int dy, int sprite_color) {
|
||||
int w = cg->width;
|
||||
int h = cg->height;
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
|
||||
enum sdl_effect_type from_nact_effect(enum nact_effect effect) {
|
||||
switch (effect) {
|
||||
case NACT_EFFECT_PAN_IN_DOWN: return EFFECT_PAN_IN_DOWN;
|
||||
case NACT_EFFECT_PAN_IN_UP: return EFFECT_PAN_IN_UP;
|
||||
case NACT_EFFECT_SKIP_LINE_UP_DOWN: return EFFECT_SKIP_LINE_UP_DOWN;
|
||||
case NACT_EFFECT_SKIP_LINE_LR_RL: return EFFECT_SKIP_LINE_LR_RL;
|
||||
case NACT_EFFECT_WIPE_IN: return EFFECT_WIPE_IN;
|
||||
case NACT_EFFECT_WIPE_OUT: return EFFECT_WIPE_OUT;
|
||||
case NACT_EFFECT_ZOOM_IN: return EFFECT_ZOOM_IN;
|
||||
@@ -563,6 +567,107 @@ static void dithering_fade_free(struct sdl_effect *eff) {
|
||||
free(eff);
|
||||
}
|
||||
|
||||
// EFFECT_PAN_IN_*
|
||||
|
||||
static void pan_in_step(struct sdl_effect *eff, float progress);
|
||||
static void pan_in_free(struct sdl_effect *eff);
|
||||
|
||||
static struct sdl_effect *pan_in_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect_type type) {
|
||||
struct sdl_effect *eff = calloc(1, sizeof(struct sdl_effect));
|
||||
if (!eff)
|
||||
NOMEMERR();
|
||||
effect_init(eff, rect, old, new, type);
|
||||
eff->step = pan_in_step;
|
||||
eff->finish = pan_in_free;
|
||||
return eff;
|
||||
}
|
||||
|
||||
static void pan_in_step(struct sdl_effect *eff, float progress) {
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_old, NULL, &eff->dst_rect);
|
||||
|
||||
int h = eff->dst_rect.h * progress;
|
||||
SDL_Rect sr = { 0, 0, eff->dst_rect.w, h };
|
||||
SDL_Rect dr = eff->dst_rect;
|
||||
dr.h = h;
|
||||
if (eff->type == EFFECT_PAN_IN_DOWN) {
|
||||
sr.y = eff->dst_rect.h - h;
|
||||
} else {
|
||||
dr.y += eff->dst_rect.h - h;
|
||||
}
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
|
||||
|
||||
SDL_RenderPresent(sdl_renderer);
|
||||
}
|
||||
|
||||
static void pan_in_free(struct sdl_effect *eff) {
|
||||
effect_finish(eff, true);
|
||||
free(eff);
|
||||
}
|
||||
|
||||
// EFFECT_SKIP_LINE_*
|
||||
|
||||
static void skip_line_step(struct sdl_effect *eff, float progress);
|
||||
static void skip_line_free(struct sdl_effect *eff);
|
||||
|
||||
static struct sdl_effect *skip_line_new(SDL_Rect *rect, SDL_Surface *old, SDL_Surface *new, enum sdl_effect_type type) {
|
||||
struct sdl_effect *eff = calloc(1, sizeof(struct sdl_effect));
|
||||
if (!eff)
|
||||
NOMEMERR();
|
||||
effect_init(eff, rect, old, new, type);
|
||||
eff->step = skip_line_step;
|
||||
eff->finish = skip_line_free;
|
||||
return eff;
|
||||
}
|
||||
|
||||
static void skip_line_step(struct sdl_effect *eff, float progress) {
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_old, NULL, &eff->dst_rect);
|
||||
|
||||
if (eff->type == EFFECT_SKIP_LINE_UP_DOWN) {
|
||||
int h = eff->dst_rect.h * progress;
|
||||
SDL_Rect sr = { 0, 0, eff->dst_rect.w, 1 };
|
||||
SDL_Rect dr = eff->dst_rect;
|
||||
dr.h = 1;
|
||||
|
||||
int bottom = (eff->dst_rect.h - 1) | 1;
|
||||
for (int y = 0; y < h; y += 2) {
|
||||
sr.y = y;
|
||||
dr.y = eff->dst_rect.y + y;
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
|
||||
|
||||
if (y == 0 && eff->dst_rect.h & 1)
|
||||
continue;
|
||||
sr.y = bottom - y;
|
||||
dr.y = eff->dst_rect.y + bottom - y;
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
|
||||
}
|
||||
} else {
|
||||
int w = eff->dst_rect.w * progress;
|
||||
SDL_Rect sr = { 0, 0, 1, eff->dst_rect.h };
|
||||
SDL_Rect dr = eff->dst_rect;
|
||||
dr.w = 1;
|
||||
|
||||
int right = (eff->dst_rect.w - 1) | 1;
|
||||
for (int x = 0; x < w; x += 2) {
|
||||
sr.x = x;
|
||||
dr.x = eff->dst_rect.x + x;
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
|
||||
|
||||
if (x == 0 && eff->dst_rect.w & 1)
|
||||
continue;
|
||||
sr.x = right - x;
|
||||
dr.x = eff->dst_rect.x + right - x;
|
||||
SDL_RenderCopy(sdl_renderer, eff->tx_new, &sr, &dr);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderPresent(sdl_renderer);
|
||||
}
|
||||
|
||||
static void skip_line_free(struct sdl_effect *eff) {
|
||||
effect_finish(eff, true);
|
||||
free(eff);
|
||||
}
|
||||
|
||||
// EFFECT_WIPE_*
|
||||
|
||||
static void wipe_step(struct sdl_effect *eff, float progress);
|
||||
@@ -1607,6 +1712,12 @@ struct sdl_effect *sdl_effect_init(SDL_Rect *rect, agsurface_t *old, int ox, int
|
||||
case EFFECT_DITHERING_WHITEOUT:
|
||||
case EFFECT_DITHERING_WHITEIN:
|
||||
return dithering_fade_new(rect, sf_old, sf_new, type);
|
||||
case EFFECT_PAN_IN_DOWN:
|
||||
case EFFECT_PAN_IN_UP:
|
||||
return pan_in_new(rect, sf_old, sf_new, type);
|
||||
case EFFECT_SKIP_LINE_UP_DOWN:
|
||||
case EFFECT_SKIP_LINE_LR_RL:
|
||||
return skip_line_new(rect, sf_old, sf_new, type);
|
||||
case EFFECT_WIPE_IN:
|
||||
case EFFECT_WIPE_OUT:
|
||||
case EFFECT_WIPE_LR:
|
||||
@@ -1663,6 +1774,23 @@ struct sdl_effect *sdl_effect_init(SDL_Rect *rect, agsurface_t *old, int ox, int
|
||||
}
|
||||
}
|
||||
|
||||
struct sdl_effect *sdl_sprite_effect_init(SDL_Rect *rect, int dx, int dy, int sx, int sy, int col, enum sdl_effect_type type) {
|
||||
SDL_Surface *sf_old = create_surface(sdl_dibinfo, dx, dy, rect->w, rect->h);
|
||||
SDL_Surface *sprite = sdl_dib_to_surface_colorkey(sx, sy, rect->w, rect->h, col);
|
||||
|
||||
switch (type) {
|
||||
case EFFECT_PAN_IN_DOWN:
|
||||
case EFFECT_PAN_IN_UP:
|
||||
return pan_in_new(rect, sf_old, sprite, type);
|
||||
case EFFECT_SKIP_LINE_UP_DOWN:
|
||||
case EFFECT_SKIP_LINE_LR_RL:
|
||||
return skip_line_new(rect, sf_old, sprite, type);
|
||||
default:
|
||||
SYSERROR("Unknown sprite effect %d", type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct sdl_effect *sdl_effect_magnify_init(agsurface_t *surface, SDL_Rect *view_rect, SDL_Rect *target_rect) {
|
||||
SDL_Surface *sf = create_surface(surface, view_rect->x, view_rect->y, view_rect->w, view_rect->h);
|
||||
return magnify_new(sf, view_rect, target_rect);
|
||||
|
||||
@@ -245,6 +245,7 @@ void sdl_copyAreaSP16_alphaBlend(int sx, int sy, int w, int h, int dx, int dy, i
|
||||
SDL_SetSurfaceBlendMode(sdl_dib, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetSurfaceAlphaMod(sdl_dib, lv);
|
||||
SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst);
|
||||
SDL_SetSurfaceAlphaMod(sdl_dib, 255);
|
||||
SDL_SetSurfaceBlendMode(sdl_dib, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
@@ -255,6 +256,7 @@ void sdl_copyAreaSP16_alphaLevel(int sx, int sy, int w, int h, int dx, int dy, i
|
||||
SDL_SetSurfaceAlphaMod(sdl_dib, lv);
|
||||
SDL_FillRect(sdl_dib, &r_dst, 0);
|
||||
SDL_BlitSurface(sdl_dib, &r_src, sdl_dib, &r_dst);
|
||||
SDL_SetSurfaceAlphaMod(sdl_dib, 255);
|
||||
SDL_SetSurfaceBlendMode(sdl_dib, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ void sdl_cursor_init(void);
|
||||
int sdl_nearest_color(int r, int g, int b);
|
||||
boolean sdl_joy_open(int index);
|
||||
SDL_Surface *sdl_dib_to_surface_with_alpha(int x, int y, int w, int h);
|
||||
SDL_Surface *sdl_dib_to_surface_colorkey(int x, int y, int w, int h, int col);
|
||||
|
||||
extern struct sdl_private_data *sdl_videodev;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user