mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Make agsurface_t backed by SDL_Surface
This adds `sdl_surface` field to agsurface_t. `agsurface->pixel` is now set to `agsurfae->sdl_surface->pixels`. Note that the `sdl_surface` field does not have alpha; transparent surfaces have a separate alpha plane in `agsurface->alpha`.
This commit is contained in:
+4
-20
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "nact.h"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "nact.h"
|
||||
|
||||
@@ -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);
|
||||
|
||||
+16
-50
@@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -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 };
|
||||
|
||||
+10
-14
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user