diff --git a/modules/Gpx/Gpx.c b/modules/Gpx/Gpx.c index 729f2e3..da7085e 100644 --- a/modules/Gpx/Gpx.c +++ b/modules/Gpx/Gpx.c @@ -69,33 +69,17 @@ static int find_null_surface() { } static void sf_free_one(int no) { - surface_t *s; - if (no == 0) return; - - s = suf[no]; - if (s == NULL) return; - - if (s->pixel) free(s->pixel); - if (s->alpha) free(s->alpha); - free(s); - + if (no == 0 || !suf[no]) return; + sf_free(suf[no]); suf[no] = NULL; pre_freesurfno = no; } static void sf_free_all() { - int i; - surface_t *s; - - for (i = 1; i < MAX_SURFACE; i++) { - if (suf[i] == NULL) continue; - s = suf[i]; - if (s->pixel) free(s->pixel); - if (s->alpha) free(s->alpha); - free(s); + for (int i = 1; i < MAX_SURFACE; i++) { + sf_free(suf[i]); suf[i] = NULL; } - pre_freesurfno = 1; } diff --git a/modules/NIGHTDLL/sactcg.c b/modules/NIGHTDLL/sactcg.c index a90e28d..495791e 100644 --- a/modules/NIGHTDLL/sactcg.c +++ b/modules/NIGHTDLL/sactcg.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "portab.h" #include "nact.h" diff --git a/modules/NIGHTDLL/sactcg_stretch.c b/modules/NIGHTDLL/sactcg_stretch.c index 9f16f10..b1eea7e 100644 --- a/modules/NIGHTDLL/sactcg_stretch.c +++ b/modules/NIGHTDLL/sactcg_stretch.c @@ -14,7 +14,10 @@ static surface_t *stretch(surface_t *src, int dw, int dh, int mirror) { dst->bytes_per_pixel = src->bytes_per_pixel; if (src->pixel) { - dst->pixel = malloc(dh * dst->bytes_per_line); + dst->sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, dw, dh, src->depth, src->sdl_surface->format->format); + dst->pixel = dst->sdl_surface->pixels; + dst->bytes_per_line = dst->sdl_surface->pitch; + dst->bytes_per_pixel = dst->sdl_surface->format->BytesPerPixel; } if (src->alpha) { dst->alpha = malloc(dw * dh); diff --git a/modules/SACT/sactcg.c b/modules/SACT/sactcg.c index 5bd3b41..a948969 100644 --- a/modules/SACT/sactcg.c +++ b/modules/SACT/sactcg.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "portab.h" #include "nact.h" diff --git a/modules/SACT/sactcg_stretch.c b/modules/SACT/sactcg_stretch.c index 310fae6..a3272c6 100644 --- a/modules/SACT/sactcg_stretch.c +++ b/modules/SACT/sactcg_stretch.c @@ -14,7 +14,10 @@ static surface_t *stretch(surface_t *src, int dw, int dh, int mirror) { dst->bytes_per_pixel = src->bytes_per_pixel; if (src->pixel) { - dst->pixel = malloc(dh * dst->bytes_per_line); + dst->sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, dw, dh, src->depth, src->sdl_surface->format->format); + dst->pixel = dst->sdl_surface->pixels; + dst->bytes_per_line = dst->sdl_surface->pitch; + dst->bytes_per_pixel = dst->sdl_surface->format->BytesPerPixel; } if (src->alpha) { dst->alpha = malloc(dw * dh); diff --git a/modules/lib/surface.c b/modules/lib/surface.c index b9a9714..16363df 100644 --- a/modules/lib/surface.c +++ b/modules/lib/surface.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "portab.h" #include "surface.h" @@ -19,26 +20,26 @@ static surface_t *create(int width, int height, int depth, bool has_pixel, bool s->depth = depth; if (has_pixel) { + uint32_t format = 0; switch (s->depth) { case 8: - s->pixel = calloc(width * (height +1), sizeof(uint8_t)); - s->bytes_per_line = width; - s->bytes_per_pixel = 1; + format = SDL_PIXELFORMAT_INDEX8; break; case 16: - s->pixel = calloc(width * (height +1) * 2, sizeof(uint8_t)); - s->bytes_per_line = width * 2; - s->bytes_per_pixel = 2; + format = SDL_PIXELFORMAT_RGB565; break; case 24: case 32: - s->pixel = calloc(width * (height +1) * 4, sizeof(uint8_t)); - s->bytes_per_line = width * 4; - s->bytes_per_pixel = 4; + format = SDL_PIXELFORMAT_RGB888; + depth = 32; break; default: - WARNING("depth %d is not supported", s->depth); + SYSERROR("depth %d is not supported", s->depth); } + s->sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format); + s->pixel = s->sdl_surface->pixels; + s->bytes_per_line = s->sdl_surface->pitch; + s->bytes_per_pixel = s->sdl_surface->format->BytesPerPixel; } if (has_alpha) { @@ -87,7 +88,7 @@ surface_t *sf_create_pixel(int width, int height, int depth) { */ void sf_free(surface_t *s) { if (s == NULL) return; - if (s->pixel) free(s->pixel); + if (s->sdl_surface) SDL_FreeSurface(s->sdl_surface); if (s->alpha) free(s->alpha); free(s); } @@ -107,9 +108,10 @@ surface_t *sf_dup(surface_t *in) { memcpy(sf, in, sizeof(surface_t)); if (in->pixel) { - len = sf->bytes_per_line * sf->height; - sf->pixel = malloc(sizeof(uint8_t) * (len + sf->bytes_per_line)); - memcpy(sf->pixel, in->pixel, len); + sf->sdl_surface = SDL_ConvertSurface(in->sdl_surface, in->sdl_surface->format, 0); + sf->pixel = sf->sdl_surface->pixels; + sf->bytes_per_line = sf->sdl_surface->pitch; + sf->bytes_per_pixel = sf->sdl_surface->format->BytesPerPixel; } if (in->alpha) { @@ -148,39 +150,3 @@ void sf_copyall(surface_t *dst, surface_t *src) { memcpy(dst->pixel, src->pixel, len); } } - -/** - * surface の複製 - * @param in: 複製もと - * @param copypixel: pixelをコピーするか - * @param copyalpha: alpha pixel をコピーするか - * @return: 複製した surface - */ -surface_t *sf_dup2(surface_t *in, bool copypixel, bool copyalpha) { - surface_t *sf; - int len; - - if (in == NULL) return NULL; - - sf = malloc(sizeof(surface_t)); - memcpy(sf, in, sizeof(surface_t)); - - if (in->pixel) { - len = sf->bytes_per_line * sf->height; - sf->pixel = malloc(sizeof(uint8_t) * (len + sf->bytes_per_line)); - if (copypixel) { - memcpy(sf->pixel, in->pixel, len); - } - } - - if (in->alpha) { - len = sf->width * sf->height; - sf->alpha = malloc(sizeof(uint8_t) * (len + sf->width)); - if (copyalpha) { - memcpy(sf->alpha, in->alpha, len); - } - } - - return sf; -} - diff --git a/modules/lib/surface.h b/modules/lib/surface.h index 241101d..440a793 100644 --- a/modules/lib/surface.h +++ b/modules/lib/surface.h @@ -11,7 +11,6 @@ extern surface_t *sf_create_alpha(int width, int height); extern surface_t *sf_create_pixel(int width, int height, int depth); extern void sf_free(surface_t *s); extern surface_t *sf_dup(surface_t *in); -extern surface_t *sf_dup2(surface_t *in, bool copypixel, bool copyalpha); extern void sf_copyall(surface_t *dst, surface_t *src); diff --git a/src/ags.h b/src/ags.h index ddb136f..4719bde 100644 --- a/src/ags.h +++ b/src/ags.h @@ -45,6 +45,8 @@ #define CURSOR_UPARROW 12 #define CURSOR_WAIT 13 +struct SDL_Surface; + /* RGB <-> alpha plane copy type */ typedef enum { FROM_16H, @@ -69,6 +71,8 @@ struct agsurface { uint8_t *pixel; /* pixel data (can be NULL) */ uint8_t *alpha; /* alpha pixel data (can be NULL) */ + + struct SDL_Surface *sdl_surface; }; typedef struct agsurface agsurface_t; diff --git a/src/sdl_core.h b/src/sdl_core.h index cf78264..8701b54 100644 --- a/src/sdl_core.h +++ b/src/sdl_core.h @@ -48,7 +48,7 @@ extern bool sdl_isFullscreen(void); extern void sdl_raiseWindow(void); extern agsurface_t *sdl_getDIB(void); extern void sdl_setIntegerScaling(bool enable); -extern SDL_Surface *sdl_createSurfaceView(agsurface_t *s, int x, int y, int w, int h); +extern SDL_Surface *sdl_createSurfaceView(SDL_Surface *sf, int x, int y, int w, int h); /* 画面更新 */ extern void sdl_updateArea(MyRectangle *src, MyPoint *dst); diff --git a/src/sdl_effect.c b/src/sdl_effect.c index 66b1547..fd629bf 100644 --- a/src/sdl_effect.c +++ b/src/sdl_effect.c @@ -137,7 +137,7 @@ static EffectTexture *create_effect_texture(agsurface_t *as, int x, int y, int w t->tx = sdl_texture; t->rect = (SDL_Rect){ x, y, w, h }; } else { - SDL_Surface *sf = sdl_createSurfaceView(as, x, y, w, h); + SDL_Surface *sf = sdl_createSurfaceView(as->sdl_surface, x, y, w, h); t->tx = SDL_CreateTextureFromSurface(sdl_renderer, sf); SDL_FreeSurface(sf); t->rect = (SDL_Rect){ 0, 0, w, h }; diff --git a/src/sdl_video.c b/src/sdl_video.c index 14ed297..8e09397 100644 --- a/src/sdl_video.c +++ b/src/sdl_video.c @@ -198,6 +198,7 @@ static void makeDIB(int width, int height, int depth) { sdl_dibinfo->width = width; sdl_dibinfo->height = height; sdl_dibinfo->alpha = NULL; + sdl_dibinfo->sdl_surface = sdl_dib; image_setdepth(sdl_dibinfo->depth); } @@ -222,19 +223,14 @@ agsurface_t *sdl_getDIB(void) { return sdl_dibinfo; } -SDL_Surface *sdl_createSurfaceView(agsurface_t *s, int x, int y, int w, int h) { - if (s == sdl_dibinfo) { - uint8_t *pixels = sdl_dib->pixels; - pixels += y * sdl_dib->pitch + x * sdl_dib->format->BytesPerPixel; - SDL_Surface *view = SDL_CreateRGBSurfaceWithFormatFrom( - pixels, w, h, sdl_dib->format->BitsPerPixel, sdl_dib->pitch, sdl_dib->format->format); - if (sdl_dib->format->palette) - SDL_SetSurfacePalette(view, sdl_dib->format->palette); - return view; - } else { - uint8_t *pixels = s->pixel + y * s->bytes_per_line + x * s->bytes_per_pixel; - return SDL_CreateRGBSurfaceFrom(pixels, w, h, s->depth, s->bytes_per_line, 0, 0, 0, 0); - } +SDL_Surface *sdl_createSurfaceView(SDL_Surface *sf, int x, int y, int w, int h) { + uint8_t *pixels = sf->pixels; + pixels += y * sf->pitch + x * sf->format->BytesPerPixel; + SDL_Surface *view = SDL_CreateRGBSurfaceWithFormatFrom( + pixels, w, h, sf->format->BitsPerPixel, sf->pitch, sf->format->format); + if (sf->format->palette) + SDL_SetSurfacePalette(view, sf->format->palette); + return view; } /* AutoRepeat の設定 */ @@ -303,7 +299,7 @@ void sdl_setIntegerScaling(bool enable) { bool EMSCRIPTEN_KEEPALIVE save_screenshot(const char* path) { SDL_Rect *r = &nact->ags.view_area; - SDL_Surface *view = sdl_createSurfaceView(sdl_dibinfo, r->x, r->y, r->w, r->h); + SDL_Surface *view = sdl_createSurfaceView(sdl_dib, r->x, r->y, r->w, r->h); bool ok = SDL_SaveBMP(view, path) == 0; SDL_FreeSurface(view); return ok;