mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-13 01:28:14 +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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user