diff --git a/src/ags.c b/src/ags.c index 5cb6839..405a73d 100644 --- a/src/ags.c +++ b/src/ags.c @@ -370,15 +370,6 @@ void ags_putRegion(void *region, int x, int y) { sdl_putRegion(region, x, y); } -void ags_copyRegion(void *region, int sx, int sy , int w, int h, int dx, int dy) { - if (region == NULL) return; - - if (!ags_check_param_xy(&dx, &dy)) return; - if (!ags_check_param(&dx, &dy, &w, &h)) return; - - sdl_CopyRegion(region, sx, sy, w, h, dx, dy); -} - void ags_delRegion(void *region) { if (region == NULL) return; diff --git a/src/ags.h b/src/ags.h index 676a5fb..758e8e5 100644 --- a/src/ags.h +++ b/src/ags.h @@ -167,7 +167,6 @@ extern void ags_changeColorArea(int x, int y, int w, int h, int dst, int src, in extern void* ags_saveRegion(int x, int y, int w, int h); extern void ags_restoreRegion(void *region, int x, int y); extern void ags_putRegion(void *region, int x, int y); -extern void ags_copyRegion(void *region, int sx, int sy, int w,int h,int dx,int dy); extern void ags_delRegion(void *region); extern MyRectangle ags_drawString(int x, int y, const char *src, int col); diff --git a/src/ecopy.c b/src/ecopy.c index c96b231..3ceac89 100644 --- a/src/ecopy.c +++ b/src/ecopy.c @@ -297,38 +297,6 @@ static int eCopyArea2001(int sx, int sy, int w, int h, int dx, int dy, int opt) return sys_getInputInfo(); } -static int eCopyArea5sp(int sx, int sy, int w, int h, int dx, int dy, int opt) { - int i, j, k, key = 0, cnt; - int st_i, ed_i; - int waitcnt = opt == 0 ? 50 : opt * 10; - int step[200]; - void *save = ags_saveRegion(dx - 50, dy, w + 100, h); - - for (i = 0; i < 200; i++) { - step[i] = 50 * sin((2 * M_PI * i) / 50); - } - - cnt = sdl_getTicks(); - - for (i = 150; i < h + 200; i++) { - cnt += waitcnt; - st_i = max(0, i - 200); - ed_i = h; - ags_copyRegion(save, 0, st_i, w + 100, ed_i - st_i, dx - 50, dy + st_i); - for (j = st_i, k = 0; j < ed_i; j++, k++) { - ags_copyArea_shadow(sx , sy + j, w, 1, - dx + step[(k + max(0, 200 - i)) % 200], - dy + j); - } - ags_updateArea(dx - 50, dy + st_i, w + 100, ed_i - st_i); - EC_WAIT; - } - - ags_delRegion(save); - - return key; -} - static int duration(enum nact_effect effect, int opt, SDL_Rect *rect) { switch (effect) { case NACT_EFFECT_ZOOM_IN: @@ -537,6 +505,17 @@ void ags_eSpriteCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, i nact->waitcancel_key = 0; + 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); + ags_runEffect((opt ? opt : 25) * h, cancel, (ags_EffectStepFunc)sdl_effect_step, eff); + sdl_effect_finish(eff); + // Actual copy. + ags_copyArea_shadow(sx, sy, w, h, dx, dy); + ags_updateArea(dx, dy, w, h); + return; + } + ecp_cancel = cancel; if (1 <= sw && sw <= 4) { @@ -561,9 +540,6 @@ void ags_eSpriteCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, i case 4: ret = eCopyArea4(dx, dy, w, h, opt); break; - case 5: - ret = eCopyArea5sp(sx, sy, w, h, dx, dy, opt); - break; case NACT_EFFECT_PALETTE_SHIFT: if (nact->ags.world_depth != 8) return; ags_copyPaletteShift(sx, sy, w, h, dx, dy, spCol); diff --git a/src/effect.h b/src/effect.h index 7a21566..7d9af48 100644 --- a/src/effect.h +++ b/src/effect.h @@ -173,6 +173,7 @@ enum sdl_effect_type { EFFECT_POLYGON_ROTATE_X_CW, EFFECT_ZIGZAG_CROSSFADE, EFFECT_MAGNIFY, + EFFECT_RASTER_BLEND, }; enum sdl_effect_type from_nact_effect(enum nact_effect effect); diff --git a/src/sdl_core.h b/src/sdl_core.h index d8585c0..5fa3762 100644 --- a/src/sdl_core.h +++ b/src/sdl_core.h @@ -79,7 +79,6 @@ extern void sdl_copy_from_alpha(int sx, int sy, int w, int h, int dx, int dy, AL extern void sdl_copy_to_alpha(int sx, int sy, int w, int h, int dx, int dy, ALPHA_DIB_COPY_TYPE flag); extern void sdl_getPixel(int x, int y, Palette *cell); extern void sdl_putRegion(void *src, int x, int y); -extern void sdl_CopyRegion(void *src, int sx, int sy, int w, int h, int dx, int dy); extern void sdl_restoreRegion(void *src, int x, int y); extern void* sdl_saveRegion(int x, int y, int w, int h); extern void sdl_delRegion(void *src); @@ -89,6 +88,7 @@ extern SDL_Surface *com2surface(agsurface_t *s); 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_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, double progress); void sdl_effect_finish(struct sdl_effect *eff); diff --git a/src/sdl_effect.c b/src/sdl_effect.c index 80d1e8b..aac8915 100644 --- a/src/sdl_effect.c +++ b/src/sdl_effect.c @@ -1525,6 +1525,41 @@ static void magnify_free(struct sdl_effect *eff) { free(eff); } +// EFFECT_RASTER_BLEND + +static void raster_blend_step(struct sdl_effect *eff, double progress); +static void raster_blend_free(struct sdl_effect *eff); + +static struct sdl_effect *raster_blend_new(SDL_Rect *rect, int sx, int sy) { + SDL_Surface *sprite = sdl_dib_to_surface_with_alpha(sx, sy, rect->w, rect->h); + struct sdl_effect *eff = calloc(1, sizeof(struct sdl_effect)); + if (!eff) + NOMEMERR(); + effect_init(eff, rect, NULL, sprite, EFFECT_RASTER_BLEND); + eff->step = raster_blend_step; + eff->finish = raster_blend_free; + return eff; +} + +static void raster_blend_step(struct sdl_effect *eff, double progress) { + SDL_Rect s_rect = { 0, 0, eff->dst_rect.w, 1 }; + SDL_Rect d_rect = eff->dst_rect; + d_rect.h = 1; + for (int y = 0; y < eff->dst_rect.h; y++) { + float t = 1.f - 4.f * progress + 3.f * y / eff->dst_rect.h; + d_rect.x = eff->dst_rect.x + (t < 0 ? 0 : sinf(2 * M_PI * t) * 50); + SDL_RenderCopy(sdl_renderer, eff->tx_new, &s_rect, &d_rect); + s_rect.y++; + d_rect.y++; + } + SDL_RenderPresent(sdl_renderer); +} + +static void raster_blend_free(struct sdl_effect *eff) { + effect_finish(eff, false); + free(eff); +} + // ----------------- static SDL_Surface *create_surface(agsurface_t *as, int x, int y, int w, int h) { @@ -1632,6 +1667,10 @@ struct sdl_effect *sdl_effect_magnify_init(agsurface_t *surface, SDL_Rect *view_ return magnify_new(sf, view_rect, target_rect); } +struct sdl_effect *sdl_effect_raster_blend_init(SDL_Rect *rect, int sx, int sy) { + return raster_blend_new(rect, sx, sy); +} + void sdl_effect_step(struct sdl_effect *eff, double progress) { SDL_RenderClear(sdl_renderer); if (!eff->is_fullscreen) diff --git a/src/sdl_image.c b/src/sdl_image.c index a21b299..8ef37da 100644 --- a/src/sdl_image.c +++ b/src/sdl_image.c @@ -204,19 +204,18 @@ void sdl_drawImage24_fromData(cgdata *cg, int x, int y, int brightness) { SDL_FreeSurface(s); } -void sdl_copyAreaSP16_shadow(int sx, int sy, int w, int h, int dx, int dy, int lv) { +SDL_Surface *sdl_dib_to_surface_with_alpha(int x, int y, int w, int h) { SDL_Surface *s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888); - SDL_Rect r_src = {sx, sy, w, h}; - SDL_Rect r_tmp = { 0, 0, w, h}; - SDL_BlitSurface(sdl_dib, &r_src, s, &r_tmp); + SDL_Rect r_src = {x, y, w, h}; + SDL_BlitSurface(sdl_dib, &r_src, s, NULL); #if SDL_BYTEORDER == SDL_LIL_ENDIAN uint8_t *p_ds = s->pixels + 3; #else uint8_t *p_ds = s->pixels; #endif - uint8_t *adata = GETOFFSET_ALPHA(sdl_dibinfo, sx, sy); + uint8_t *adata = GETOFFSET_ALPHA(sdl_dibinfo, x, y); for (int y = 0; y < h; y++) { uint8_t *p_src = adata; uint8_t *p_dst = p_ds; @@ -227,11 +226,16 @@ void sdl_copyAreaSP16_shadow(int sx, int sy, int w, int h, int dx, int dy, int l adata += sdl_dibinfo->width; p_ds += s->pitch; } + return s; +} + +void sdl_copyAreaSP16_shadow(int sx, int sy, int w, int h, int dx, int dy, int lv) { + SDL_Surface *s = sdl_dib_to_surface_with_alpha(sx, sy, w, h); if (lv < 255) SDL_SetSurfaceAlphaMod(s, lv); SDL_Rect r_dst = {dx, dy, w, h}; - SDL_BlitSurface(s, &r_tmp, sdl_dib, &r_dst); + SDL_BlitSurface(s, NULL, sdl_dib, &r_dst); SDL_FreeSurface(s); } @@ -330,18 +334,6 @@ void sdl_putRegion(void *psrc, int x, int y) { SDL_BlitSurface(src, &r_src, sdl_dib, &r_dst); } -/* - * dib にセーブした領域からコピー - */ -void sdl_CopyRegion(void *psrc, int sx, int sy, int w,int h, int dx, int dy) { - SDL_Surface *src = (SDL_Surface *)psrc; - - SDL_Rect r_src = {sx, sy, w, h}; - SDL_Rect r_dst = {dx, dy, w, h}; - - SDL_BlitSurface(src, &r_src, sdl_dib, &r_dst); -} - /* * dib に dstを描画後、後始末 */ diff --git a/src/sdl_private.h b/src/sdl_private.h index 1db8e14..5827622 100644 --- a/src/sdl_private.h +++ b/src/sdl_private.h @@ -56,6 +56,7 @@ void sdl_event_init(void); 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); extern struct sdl_private_data *sdl_videodev;