From 6c54b494f40435cbb804ebec12515f5055db26e4 Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Tue, 5 Nov 2024 23:30:36 +0100 Subject: [PATCH 1/4] Porting surface.c to SDL3 - first step. --- src_c/_pygame.h | 18 +++++++++ src_c/surface.c | 105 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 95 insertions(+), 28 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 07f236149a..3be2a9e028 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -78,6 +78,14 @@ #define PG_ConvertSurfaceFormat SDL_ConvertSurface #define PG_PixelFormatEnum SDL_PixelFormat +#define PG_PixelFormat SDL_PixelFormatDetails +#define PG_SurfaceFormatEnum(surf) (surf)->format +#define PG_GetSurfaceFormat(surf) \ + SDL_GetPixelFormatDetails(PG_SurfaceFormatEnum(surf)) +#define PG_GetSurfacePalette SDL_GetSurfacePalette +#define PG_SurfaceMapRGBA(surf, r, g, b, a) \ + SDL_MapSurfaceRGBA(surface, r, g, b, a) +#define PG_GetSurfaceClipRect(surf, rect) SDL_GetSurfaceClipRect(surf, &rect) #define PG_SurfaceHasRLE SDL_SurfaceHasRLE @@ -149,6 +157,16 @@ PG_UnlockMutex(SDL_mutex *mutex) SDL_ConvertSurfaceFormat(src, pixel_format, 0) #define PG_PixelFormatEnum SDL_PixelFormatEnum +#define PG_PixelFormat SDL_PixelFormat +#define PG_SurfaceFormatEnum(surf) (surf)->format->format +#define PG_GetSurfaceFormat(surf) (surf)->format +#define PG_GetSurfacePalette(surf) (surf)->format->palette +#define PG_SurfaceMapRGBA(surf, r, g, b, a) \ + SDL_MapRGBA(PG_GetSurfaceFormat(surface), r, g, b, a) +#define PG_GetSurfaceClipRect(surf, rect) \ + { \ + rect = surf->clip_rect; \ + } #define PG_SoftStretchNearest(src, srcrect, dst, dstrect) \ SDL_SoftStretch(src, srcrect, dst, dstrect) diff --git a/src_c/surface.c b/src_c/surface.c index d4a8eae2e9..a7600fa85f 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -481,7 +481,7 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) int bpp; Uint32 Rmask, Gmask, Bmask, Amask; SDL_Surface *surface; - SDL_PixelFormat default_format; + PG_PixelFormat default_format; char *kwids[] = {"size", "flags", "depth", "masks", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iOO", kwids, &size, &flags, @@ -507,8 +507,6 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) return -1; } - default_format.palette = NULL; - surface_cleanup(self); if (depth && masks) { /* all info supplied, most errorchecking @@ -602,18 +600,20 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) } } else { /* no depth or surface */ - SDL_PixelFormat *pix; - if (depth && pgSurface_Check(depth)) - pix = ((pgSurfaceObject *)depth)->surf->format; + PG_PixelFormat *pix; + if (depth && pgSurface_Check(depth)) { + /* For SDL3 PG_GetSurfaceFormat returns (const PG_PixelFormat *) + * and not (PG_PixelFormat *), but it's not an issue here, as in + * this case pix is not mutated. */ + pix = (PG_PixelFormat *)PG_GetSurfaceFormat( + ((pgSurfaceObject *)depth)->surf); + } else if (pg_GetDefaultWindowSurface()) - pix = pgSurface_AsSurface(pg_GetDefaultWindowSurface())->format; + pix = (PG_PixelFormat *)PG_GetSurfaceFormat( + pgSurface_AsSurface(pg_GetDefaultWindowSurface())); else { pix = &default_format; -#if SDL_VERSION_ATLEAST(3, 0, 0) - pix->bits_per_pixel = 32; -#else - pix->BitsPerPixel = 32; -#endif + PG_FORMAT_BitsPerPixel(pix) = 32; pix->Amask = 0; pix->Rmask = 0xFF0000; pix->Gmask = 0xFF00; @@ -682,14 +682,14 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) */ if (Amask != 0) { SDL_FillRect(surface, NULL, - SDL_MapRGBA(surface->format, 0, 0, 0, 255)); + PG_SurfaceMapRGBA(surface, 0, 0, 0, 255)); } } - if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { + if (SDL_ISPIXELFORMAT_INDEXED(PG_SurfaceFormatEnum(surface))) { /* Give the surface something other than an all white palette. * */ - if (SDL_SetPaletteColors(surface->format->palette, + if (SDL_SetPaletteColors(PG_GetSurfacePalette(surface), default_palette_colors, 0, default_palette_size - 1) != 0) { PyErr_SetString(pgExc_SDLError, SDL_GetError()); @@ -712,7 +712,11 @@ static PyObject * surf_get_at(PyObject *self, PyObject *position) { SDL_Surface *surf = pgSurface_AsSurface(self); - SDL_PixelFormat *format = NULL; +#if SDL_VERSION_ATLEAST(3, 0, 0) + const PG_PixelFormat *format = NULL; +#else + PG_PixelFormat *format = NULL; +#endif Uint8 *pixels = NULL; int x, y; Uint32 color; @@ -729,7 +733,7 @@ surf_get_at(PyObject *self, PyObject *position) if (x < 0 || x >= surf->w || y < 0 || y >= surf->h) return RAISE(PyExc_IndexError, "pixel index out of range"); - format = surf->format; + format = PG_GetSurfaceFormat(surf); if (PG_FORMAT_BytesPerPixel(format) < 1 || PG_FORMAT_BytesPerPixel(format) > 4) @@ -743,11 +747,21 @@ surf_get_at(PyObject *self, PyObject *position) switch (PG_FORMAT_BytesPerPixel(format)) { case 1: color = (Uint32) * ((Uint8 *)pixels + y * surf->pitch + x); +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetRGB(color, format, PG_GetSurfacePalette(surf), rgba, + rgba + 1, rgba + 2); +#else SDL_GetRGB(color, format, rgba, rgba + 1, rgba + 2); +#endif break; case 2: color = (Uint32) * ((Uint16 *)(pixels + y * surf->pitch) + x); +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetRGBA(color, format, PG_GetSurfacePalette(surf), rgba, + rgba + 1, rgba + 2, rgba + 3); +#else SDL_GetRGBA(color, format, rgba, rgba + 1, rgba + 2, rgba + 3); +#endif break; case 3: pix = ((Uint8 *)(pixels + y * surf->pitch) + x * 3); @@ -756,12 +770,22 @@ surf_get_at(PyObject *self, PyObject *position) #else color = (pix[2]) + (pix[1] << 8) + (pix[0] << 16); #endif +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetRGB(color, format, PG_GetSurfacePalette(surf), rgba, + rgba + 1, rgba + 2); +#else SDL_GetRGB(color, format, rgba, rgba + 1, rgba + 2); +#endif break; default: /* case 4: */ assert(PG_FORMAT_BytesPerPixel(format) == 4); color = *((Uint32 *)(pixels + y * surf->pitch) + x); +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetRGBA(color, format, PG_GetSurfacePalette(surf), rgba, + rgba + 1, rgba + 2, rgba + 3); +#else SDL_GetRGBA(color, format, rgba, rgba + 1, rgba + 2, rgba + 3); +#endif break; } if (!pgSurface_Unlock((pgSurfaceObject *)self)) @@ -775,12 +799,17 @@ surf_set_at(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { SDL_Surface *surf = pgSurface_AsSurface(self); SURF_INIT_CHECK(surf) - SDL_PixelFormat *format = NULL; +#if SDL_VERSION_ATLEAST(3, 0, 0) + const PG_PixelFormat *format = NULL; +#else + PG_PixelFormat *format = NULL; +#endif Uint8 *pixels; int x, y; Uint32 color; PyObject *rgba_obj; Uint8 *byte_buf; + SDL_Rect clip_rect; if (nargs != 2) { return PyErr_Format(PyExc_TypeError, @@ -795,13 +824,15 @@ surf_set_at(PyObject *self, PyObject *const *args, Py_ssize_t nargs) rgba_obj = args[1]; - format = surf->format; + format = PG_GetSurfaceFormat(surf); if (PG_FORMAT_BytesPerPixel(format) < 1 || PG_FORMAT_BytesPerPixel(format) > 4) return RAISE(PyExc_RuntimeError, "invalid color depth for surface"); - if (x < surf->clip_rect.x || x >= surf->clip_rect.x + surf->clip_rect.w || - y < surf->clip_rect.y || y >= surf->clip_rect.y + surf->clip_rect.h) { + PG_GetSurfaceClipRect(surf, clip_rect); + + if (x < clip_rect.x || x >= clip_rect.x + clip_rect.w || y < clip_rect.y || + y >= clip_rect.y + clip_rect.h) { /* out of clip area */ Py_RETURN_NONE; } @@ -854,7 +885,11 @@ static PyObject * surf_get_at_mapped(PyObject *self, PyObject *position) { SDL_Surface *surf = pgSurface_AsSurface(self); - SDL_PixelFormat *format = NULL; +#if SDL_VERSION_ATLEAST(3, 0, 0) + const PG_PixelFormat *format = NULL; +#else + PG_PixelFormat *format = NULL; +#endif Uint8 *pixels = NULL; int x, y; Sint32 color; @@ -870,7 +905,7 @@ surf_get_at_mapped(PyObject *self, PyObject *position) if (x < 0 || x >= surf->w || y < 0 || y >= surf->h) return RAISE(PyExc_IndexError, "pixel index out of range"); - format = surf->format; + format = PG_GetSurfaceFormat(surf); if (PG_FORMAT_BytesPerPixel(format) < 1 || PG_FORMAT_BytesPerPixel(format) > 4) @@ -918,7 +953,11 @@ surf_map_rgb(PyObject *self, PyObject *args) SURF_INIT_CHECK(surf) +#if SDL_VERSION_ATLEAST(3, 0, 0) + color = SDL_MapSurfaceRGBA(surf, rgba[0], rgba[1], rgba[2], rgba[3]); +#else color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); +#endif return PyLong_FromLong(color); } @@ -936,10 +975,20 @@ surf_unmap_rgb(PyObject *self, PyObject *arg) } SURF_INIT_CHECK(surf) - if (SDL_ISPIXELFORMAT_ALPHA(surf->format->format)) + if (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(surf))) +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetRGBA(col, PG_GetSurfaceFormat(surf), PG_GetSurfacePalette(surf), + rgba, rgba + 1, rgba + 2, rgba + 3); +#else SDL_GetRGBA(col, surf->format, rgba, rgba + 1, rgba + 2, rgba + 3); +#endif else { +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_GetRGB(col, PG_GetSurfaceFormat(surf), PG_GetSurfacePalette(surf), + rgba, rgba + 1, rgba + 2); +#else SDL_GetRGB(col, surf->format, rgba, rgba + 1, rgba + 2); +#endif rgba[3] = 255; } @@ -1029,7 +1078,7 @@ surf_get_palette(PyObject *self, PyObject *_null) SURF_INIT_CHECK(surf) - pal = surf->format->palette; + pal = PG_GetSurfacePalette(surf); if (!pal) return RAISE(pgExc_SDLError, "Surface has no palette to get\n"); @@ -1068,7 +1117,7 @@ surf_get_palette_at(PyObject *self, PyObject *args) return NULL; SURF_INIT_CHECK(surf) - pal = surf->format->palette; + pal = PG_GetSurfacePalette(surf); if (!pal) return RAISE(pgExc_SDLError, "Surface has no palette to set\n"); @@ -1107,9 +1156,9 @@ surf_set_palette(PyObject *self, PyObject *seq) if (!PySequence_Check(seq)) return RAISE(PyExc_ValueError, "Argument must be a sequence type"); - pal = surf->format->palette; + pal = PG_GetSurfacePalette(surf); - if (!SDL_ISPIXELFORMAT_INDEXED(surf->format->format)) + if (!SDL_ISPIXELFORMAT_INDEXED(PG_SurfaceFormatEnum(surf))) return RAISE(pgExc_SDLError, "Surface colors are not indexed\n"); if (!pal) From 5d79eddfbc8ba107ce1a30d3f9fcd57d3339136f Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:33:31 +0100 Subject: [PATCH 2/4] Porting surface.c SDL3 - second step --- src_c/_pygame.h | 21 +++++- src_c/surface.c | 188 ++++++++++++++++++++++-------------------------- src_c/surface.h | 15 ++++ 3 files changed, 120 insertions(+), 104 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index 3be2a9e028..a9c8a73b46 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -78,14 +78,15 @@ #define PG_ConvertSurfaceFormat SDL_ConvertSurface #define PG_PixelFormatEnum SDL_PixelFormat -#define PG_PixelFormat SDL_PixelFormatDetails +#define PG_PixelFormat const SDL_PixelFormatDetails +#define PG_PixelFormatMut SDL_PixelFormatDetails #define PG_SurfaceFormatEnum(surf) (surf)->format #define PG_GetSurfaceFormat(surf) \ SDL_GetPixelFormatDetails(PG_SurfaceFormatEnum(surf)) #define PG_GetSurfacePalette SDL_GetSurfacePalette #define PG_SurfaceMapRGBA(surf, r, g, b, a) \ SDL_MapSurfaceRGBA(surface, r, g, b, a) -#define PG_GetSurfaceClipRect(surf, rect) SDL_GetSurfaceClipRect(surf, &rect) +#define PG_GetSurfaceClipRect(surf, rect) SDL_GetSurfaceClipRect(surf, rect) #define PG_SurfaceHasRLE SDL_SurfaceHasRLE @@ -108,6 +109,13 @@ PG_UnlockMutex(SDL_mutex *mutex) return 0; } +/* Emulating SDL2 SDL_FillRect API. In SDL3, it returns -1 on failure. */ +static inline int +PG_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color) +{ + return SDL_FillSurfaceRect(dst, rect, color) ? 0 : -1; +} + #define PG_SURF_BitsPerPixel(surf) SDL_BITSPERPIXEL(surf->format) #define PG_SURF_BytesPerPixel(surf) SDL_BYTESPERPIXEL(surf->format) #define PG_FORMAT_BitsPerPixel(format) format->bits_per_pixel @@ -158,6 +166,7 @@ PG_UnlockMutex(SDL_mutex *mutex) #define PG_PixelFormatEnum SDL_PixelFormatEnum #define PG_PixelFormat SDL_PixelFormat +#define PG_PixelFormatMut SDL_PixelFormat #define PG_SurfaceFormatEnum(surf) (surf)->format->format #define PG_GetSurfaceFormat(surf) (surf)->format #define PG_GetSurfacePalette(surf) (surf)->format->palette @@ -165,7 +174,7 @@ PG_UnlockMutex(SDL_mutex *mutex) SDL_MapRGBA(PG_GetSurfaceFormat(surface), r, g, b, a) #define PG_GetSurfaceClipRect(surf, rect) \ { \ - rect = surf->clip_rect; \ + rect = &surf->clip_rect; \ } #define PG_SoftStretchNearest(src, srcrect, dst, dstrect) \ @@ -183,6 +192,12 @@ PG_UnlockMutex(SDL_mutex *mutex) return SDL_UnlockMutex(mutex); } +static inline int +PG_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color) +{ + return SDL_FillRect(dst, rect, color); +} + #define PG_SURF_BitsPerPixel(surf) surf->format->BitsPerPixel #define PG_SURF_BytesPerPixel(surf) surf->format->BytesPerPixel #define PG_FORMAT_BitsPerPixel(format) format->BitsPerPixel diff --git a/src_c/surface.c b/src_c/surface.c index a7600fa85f..de24501bbd 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -481,7 +481,7 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) int bpp; Uint32 Rmask, Gmask, Bmask, Amask; SDL_Surface *surface; - PG_PixelFormat default_format; + PG_PixelFormatMut default_format; char *kwids[] = {"size", "flags", "depth", "masks", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iOO", kwids, &size, &flags, @@ -507,6 +507,8 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) return -1; } + default_format.palette = NULL; + surface_cleanup(self); if (depth && masks) { /* all info supplied, most errorchecking @@ -600,16 +602,16 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) } } else { /* no depth or surface */ - PG_PixelFormat *pix; + PG_PixelFormatMut *pix; if (depth && pgSurface_Check(depth)) { /* For SDL3 PG_GetSurfaceFormat returns (const PG_PixelFormat *) * and not (PG_PixelFormat *), but it's not an issue here, as in * this case pix is not mutated. */ - pix = (PG_PixelFormat *)PG_GetSurfaceFormat( + pix = (PG_PixelFormatMut *)PG_GetSurfaceFormat( ((pgSurfaceObject *)depth)->surf); } else if (pg_GetDefaultWindowSurface()) - pix = (PG_PixelFormat *)PG_GetSurfaceFormat( + pix = (PG_PixelFormatMut *)PG_GetSurfaceFormat( pgSurface_AsSurface(pg_GetDefaultWindowSurface())); else { pix = &default_format; @@ -712,11 +714,7 @@ static PyObject * surf_get_at(PyObject *self, PyObject *position) { SDL_Surface *surf = pgSurface_AsSurface(self); -#if SDL_VERSION_ATLEAST(3, 0, 0) - const PG_PixelFormat *format = NULL; -#else PG_PixelFormat *format = NULL; -#endif Uint8 *pixels = NULL; int x, y; Uint32 color; @@ -747,21 +745,11 @@ surf_get_at(PyObject *self, PyObject *position) switch (PG_FORMAT_BytesPerPixel(format)) { case 1: color = (Uint32) * ((Uint8 *)pixels + y * surf->pitch + x); -#if SDL_VERSION_ATLEAST(3, 0, 0) - SDL_GetRGB(color, format, PG_GetSurfacePalette(surf), rgba, - rgba + 1, rgba + 2); -#else - SDL_GetRGB(color, format, rgba, rgba + 1, rgba + 2); -#endif + PG_SurfaceGetRGB(color, surf, rgba, rgba + 1, rgba + 2); break; case 2: color = (Uint32) * ((Uint16 *)(pixels + y * surf->pitch) + x); -#if SDL_VERSION_ATLEAST(3, 0, 0) - SDL_GetRGBA(color, format, PG_GetSurfacePalette(surf), rgba, - rgba + 1, rgba + 2, rgba + 3); -#else - SDL_GetRGBA(color, format, rgba, rgba + 1, rgba + 2, rgba + 3); -#endif + PG_SurfaceGetRGBA(color, surf, rgba, rgba + 1, rgba + 2, rgba + 3); break; case 3: pix = ((Uint8 *)(pixels + y * surf->pitch) + x * 3); @@ -770,22 +758,12 @@ surf_get_at(PyObject *self, PyObject *position) #else color = (pix[2]) + (pix[1] << 8) + (pix[0] << 16); #endif -#if SDL_VERSION_ATLEAST(3, 0, 0) - SDL_GetRGB(color, format, PG_GetSurfacePalette(surf), rgba, - rgba + 1, rgba + 2); -#else - SDL_GetRGB(color, format, rgba, rgba + 1, rgba + 2); -#endif + PG_SurfaceGetRGB(color, surf, rgba, rgba + 1, rgba + 2); break; default: /* case 4: */ assert(PG_FORMAT_BytesPerPixel(format) == 4); color = *((Uint32 *)(pixels + y * surf->pitch) + x); -#if SDL_VERSION_ATLEAST(3, 0, 0) - SDL_GetRGBA(color, format, PG_GetSurfacePalette(surf), rgba, - rgba + 1, rgba + 2, rgba + 3); -#else - SDL_GetRGBA(color, format, rgba, rgba + 1, rgba + 2, rgba + 3); -#endif + PG_SurfaceGetRGBA(color, surf, rgba, rgba + 1, rgba + 2, rgba + 3); break; } if (!pgSurface_Unlock((pgSurfaceObject *)self)) @@ -799,17 +777,13 @@ surf_set_at(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { SDL_Surface *surf = pgSurface_AsSurface(self); SURF_INIT_CHECK(surf) -#if SDL_VERSION_ATLEAST(3, 0, 0) - const PG_PixelFormat *format = NULL; -#else PG_PixelFormat *format = NULL; -#endif Uint8 *pixels; int x, y; Uint32 color; PyObject *rgba_obj; Uint8 *byte_buf; - SDL_Rect clip_rect; + SDL_Rect *clip_rect; if (nargs != 2) { return PyErr_Format(PyExc_TypeError, @@ -831,8 +805,8 @@ surf_set_at(PyObject *self, PyObject *const *args, Py_ssize_t nargs) PG_GetSurfaceClipRect(surf, clip_rect); - if (x < clip_rect.x || x >= clip_rect.x + clip_rect.w || y < clip_rect.y || - y >= clip_rect.y + clip_rect.h) { + if (x < clip_rect->x || x >= clip_rect->x + clip_rect->w || + y < clip_rect->y || y >= clip_rect->y + clip_rect->h) { /* out of clip area */ Py_RETURN_NONE; } @@ -885,11 +859,7 @@ static PyObject * surf_get_at_mapped(PyObject *self, PyObject *position) { SDL_Surface *surf = pgSurface_AsSurface(self); -#if SDL_VERSION_ATLEAST(3, 0, 0) - const PG_PixelFormat *format = NULL; -#else PG_PixelFormat *format = NULL; -#endif Uint8 *pixels = NULL; int x, y; Sint32 color; @@ -976,19 +946,9 @@ surf_unmap_rgb(PyObject *self, PyObject *arg) SURF_INIT_CHECK(surf) if (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(surf))) -#if SDL_VERSION_ATLEAST(3, 0, 0) - SDL_GetRGBA(col, PG_GetSurfaceFormat(surf), PG_GetSurfacePalette(surf), - rgba, rgba + 1, rgba + 2, rgba + 3); -#else - SDL_GetRGBA(col, surf->format, rgba, rgba + 1, rgba + 2, rgba + 3); -#endif + PG_SurfaceGetRGBA(col, surf, rgba, rgba + 1, rgba + 2, rgba + 3); else { -#if SDL_VERSION_ATLEAST(3, 0, 0) - SDL_GetRGB(col, PG_GetSurfaceFormat(surf), PG_GetSurfacePalette(surf), - rgba, rgba + 1, rgba + 2); -#else - SDL_GetRGB(col, surf->format, rgba, rgba + 1, rgba + 2); -#endif + PG_SurfaceGetRGB(col, surf, rgba, rgba + 1, rgba + 2); rgba[3] = 255; } @@ -1213,10 +1173,10 @@ surf_set_palette_at(PyObject *self, PyObject *args) return NULL; } - if (!SDL_ISPIXELFORMAT_INDEXED(surf->format->format)) + if (!SDL_ISPIXELFORMAT_INDEXED(PG_SurfaceFormatEnum(surf))) return RAISE(pgExc_SDLError, "Surface colors are not indexed\n"); - pal = surf->format->palette; + pal = PG_GetSurfacePalette(surf); if (!pal) { return RAISE(pgExc_SDLError, "Surface is not palettized\n"); @@ -1297,10 +1257,10 @@ surf_get_colorkey(pgSurfaceObject *self, PyObject *_null) SDL_GetColorKey(surf, &mapped_color); - if (SDL_ISPIXELFORMAT_ALPHA(surf->format->format)) - SDL_GetRGBA(mapped_color, surf->format, &r, &g, &b, &a); + if (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(surf))) + PG_SurfaceGetRGBA(mapped_color, surf, &r, &g, &b, &a); else - SDL_GetRGB(mapped_color, surf->format, &r, &g, &b); + PG_SurfaceGetRGB(mapped_color, surf, &r, &g, &b); return Py_BuildValue("(bbbb)", r, g, b, a); } @@ -1363,7 +1323,7 @@ surf_set_alpha(pgSurfaceObject *self, PyObject *args) sdlrect.h = 0; sdlrect.w = 0; - surface = PG_CreateSurface(1, 1, surf->format->format); + surface = PG_CreateSurface(1, 1, PG_SurfaceFormatEnum(surf)); SDL_LowerBlit(surf, &sdlrect, surface, &sdlrect); SDL_FreeSurface(surface); @@ -1460,11 +1420,10 @@ surf_convert(pgSurfaceObject *self, PyObject *args) if ((has_colorkey = SDL_HasColorKey(surf))) { SDL_GetColorKey(surf, &colorkey); - if (SDL_ISPIXELFORMAT_ALPHA(surf->format->format)) - SDL_GetRGBA(colorkey, surf->format, &key_r, &key_g, &key_b, - &key_a); + if (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(surf))) + PG_SurfaceGetRGBA(colorkey, surf, &key_r, &key_g, &key_b, &key_a); else - SDL_GetRGB(colorkey, surf->format, &key_r, &key_g, &key_b); + PG_SurfaceGetRGB(colorkey, surf, &key_r, &key_g, &key_b); } if (argobject) { @@ -1477,9 +1436,9 @@ surf_convert(pgSurfaceObject *self, PyObject *args) */ int bpp = 0; SDL_Palette *palette = SDL_AllocPalette(default_palette_size); - SDL_PixelFormat format; + PG_PixelFormatMut format; - memcpy(&format, surf->format, sizeof(format)); + memcpy(&format, PG_GetSurfaceFormat(surf), sizeof(format)); if (pg_IntFromObj(argobject, &bpp)) { Uint32 Rmask, Gmask, Bmask, Amask; @@ -1758,9 +1717,11 @@ static PyObject * surf_get_clip(PyObject *self, PyObject *_null) { SDL_Surface *surf = pgSurface_AsSurface(self); + SDL_Rect *clip_rect; SURF_INIT_CHECK(surf) - return pgRect_New(&surf->clip_rect); + PG_GetSurfaceClipRect(surf, clip_rect); + return pgRect_New(clip_rect); } static PyObject * @@ -2529,7 +2490,7 @@ surf_scroll(PyObject *self, PyObject *args, PyObject *keywds) } } - clip_rect = &surf->clip_rect; + PG_GetSurfaceClipRect(surf, clip_rect); SDL_Rect surf_rect = {0, 0, surf->w, surf->h}; // In SDL3, SDL_IntersectRect is renamed to SDL_GetRectIntersection @@ -2547,7 +2508,7 @@ surf_scroll(PyObject *self, PyObject *args, PyObject *keywds) if (!repeat) { if (dx >= w || dx <= -w || dy >= h || dy <= -h) { if (erase) { - if (SDL_FillRect(surf, NULL, 0) == -1) { + if (PG_FillRect(surf, NULL, 0) == -1) { PyErr_SetString(pgExc_SDLError, SDL_GetError()); return NULL; } @@ -2742,10 +2703,12 @@ static PyObject * surf_get_masks(PyObject *self, PyObject *_null) { SDL_Surface *surf = pgSurface_AsSurface(self); + PG_PixelFormat *format; SURF_INIT_CHECK(surf) - return Py_BuildValue("(IIII)", surf->format->Rmask, surf->format->Gmask, - surf->format->Bmask, surf->format->Amask); + format = PG_GetSurfaceFormat(surf); + return Py_BuildValue("(IIII)", format->Rmask, format->Gmask, format->Bmask, + format->Amask); } static PyObject * @@ -2758,10 +2721,12 @@ static PyObject * surf_get_shifts(PyObject *self, PyObject *_null) { SDL_Surface *surf = pgSurface_AsSurface(self); + PG_PixelFormat *format; SURF_INIT_CHECK(surf) - return Py_BuildValue("(iiii)", surf->format->Rshift, surf->format->Gshift, - surf->format->Bshift, surf->format->Ashift); + format = PG_GetSurfaceFormat(surf); + return Py_BuildValue("(iiii)", format->Rshift, format->Gshift, + format->Bshift, format->Ashift); } static PyObject * @@ -2770,21 +2735,29 @@ surf_set_shifts(PyObject *self, PyObject *args) return RAISE(PyExc_TypeError, "The surface shifts are read-only in SDL2"); } +// TODO: deprecation and implementation of surf_get_bits. static PyObject * surf_get_losses(PyObject *self, PyObject *_null) { SDL_Surface *surf = pgSurface_AsSurface(self); + PG_PixelFormat *format; SURF_INIT_CHECK(surf) - return Py_BuildValue("(iiii)", surf->format->Rloss, surf->format->Gloss, - surf->format->Bloss, surf->format->Aloss); + format = PG_GetSurfaceFormat(surf); +#if SDL_VERSION_ATLEAST(3, 0, 0) + return Py_BuildValue("(iiii)", 8 - format->Rbits, 8 - format->Gbits, + 8 - format->Bbits, 8 - format->Abits); +#else + return Py_BuildValue("(iiii)", format->Rloss, format->Gloss, format->Bloss, + format->Aloss); +#endif } static PyObject * surf_subsurface(PyObject *self, PyObject *args) { SDL_Surface *surf = pgSurface_AsSurface(self); - SDL_PixelFormat *format; + PG_PixelFormat *format; SDL_Rect *rect, temp; SDL_Surface *sub; PyObject *subobj; @@ -2794,7 +2767,7 @@ surf_subsurface(PyObject *self, PyObject *args) SURF_INIT_CHECK(surf) - format = surf->format; + format = PG_GetSurfaceFormat(surf); if (!(rect = pgRect_FromObject(args, &temp))) return RAISE(PyExc_ValueError, "invalid rectstyle argument"); if (rect->x < 0 || rect->y < 0 || rect->x + rect->w > surf->w || @@ -2980,7 +2953,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) #endif PyObject *rect; SDL_Surface *surf = pgSurface_AsSurface(self); - SDL_PixelFormat *format = NULL; + PG_PixelFormat *format = NULL; Uint8 *pixels = NULL; Uint8 *pixel; int x, y; @@ -3004,11 +2977,11 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) if (!pgSurface_Lock((pgSurfaceObject *)self)) return RAISE(pgExc_SDLError, "could not lock surface"); - format = surf->format; + format = PG_GetSurfaceFormat(surf); if ((has_colorkey = SDL_HasColorKey(surf))) { SDL_GetColorKey(surf, &colorkey); - SDL_GetRGBA(colorkey, surf->format, &keyr, &keyg, &keyb, &a); + PG_SurfaceGetRGBA(colorkey, surf, &keyr, &keyg, &keyb, &a); } pixels = (Uint8 *)surf->pixels; @@ -3038,7 +3011,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - SDL_GetRGBA(value, surf->format, &r, &g, &b, &a); + PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3071,7 +3044,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - SDL_GetRGBA(value, surf->format, &r, &g, &b, &a); + PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3105,7 +3078,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - SDL_GetRGBA(value, surf->format, &r, &g, &b, &a); + PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3138,7 +3111,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - SDL_GetRGBA(value, surf->format, &r, &g, &b, &a); + PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3212,7 +3185,7 @@ static PyObject * surf_get_view(PyObject *self, PyObject *args) { SDL_Surface *surface = pgSurface_AsSurface(self); - SDL_PixelFormat *format; + PG_PixelFormat *format; Uint32 mask = 0; SurfViewKind view_kind = VIEWKIND_2D; getbufferproc get_buffer = 0; @@ -3223,7 +3196,7 @@ surf_get_view(PyObject *self, PyObject *args) SURF_INIT_CHECK(surface) - format = surface->format; + format = PG_GetSurfaceFormat(surface); switch (view_kind) { /* This switch statement is exhaustive over the SurfViewKind enum */ @@ -3566,6 +3539,7 @@ static int _get_buffer_3D(PyObject *obj, Py_buffer *view_p, int flags) { SDL_Surface *surface = pgSurface_AsSurface(obj); + PG_PixelFormat *format = PG_GetSurfaceFormat(surface); int pixelsize = PG_SURF_BytesPerPixel(surface); char *startpixel = (char *)surface->pixels; @@ -3597,7 +3571,7 @@ _get_buffer_3D(PyObject *obj, Py_buffer *view_p, int flags) view_p->shape[2] = 3; view_p->strides[0] = pixelsize; view_p->strides[1] = surface->pitch; - switch (surface->format->Rmask) { + switch (format->Rmask) { #if SDL_BYTEORDER == SDL_LIL_ENDIAN case 0xffU: view_p->strides[2] = 1; @@ -3643,29 +3617,33 @@ _get_buffer_3D(PyObject *obj, Py_buffer *view_p, int flags) static int _get_buffer_red(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane(obj, view_p, flags, "red", - pgSurface_AsSurface(obj)->format->Rmask); + return _get_buffer_colorplane( + obj, view_p, flags, "red", + PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Rmask); } static int _get_buffer_green(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane(obj, view_p, flags, "green", - pgSurface_AsSurface(obj)->format->Gmask); + return _get_buffer_colorplane( + obj, view_p, flags, "green", + PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Gmask); } static int _get_buffer_blue(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane(obj, view_p, flags, "blue", - pgSurface_AsSurface(obj)->format->Bmask); + return _get_buffer_colorplane( + obj, view_p, flags, "blue", + PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Bmask); } static int _get_buffer_alpha(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane(obj, view_p, flags, "alpha", - pgSurface_AsSurface(obj)->format->Amask); + return _get_buffer_colorplane( + obj, view_p, flags, "alpha", + PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Amask); } static int @@ -3927,7 +3905,8 @@ surface_do_overlap(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, int x, y; int w = srcrect->w, h = srcrect->h; int maxw, maxh; - SDL_Rect *clip = &dst->clip_rect; + SDL_Rect *clip; + PG_GetSurfaceClipRect(dst, clip); int span; int dstoffset; @@ -4060,15 +4039,15 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, } /* can't blit alpha to 8bit, crashes SDL */ else if (PG_SURF_BytesPerPixel(dst) == 1 && - (SDL_ISPIXELFORMAT_ALPHA(src->format->format) || + (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(src)) || ((SDL_GetSurfaceAlphaMod(src, &alpha) == 0 && alpha != 255)))) { /* Py_BEGIN_ALLOW_THREADS */ if (PG_SURF_BytesPerPixel(src) == 1) { result = pygame_Blit(src, srcrect, dst, dstrect, 0); } else { - SDL_PixelFormat *fmt = src->format; - SDL_PixelFormat newfmt; + PG_PixelFormat *fmt = PG_GetSurfaceFormat(src); + PG_PixelFormatMut newfmt; newfmt.palette = 0; /* Set NULL (or SDL gets confused) */ #if SDL_VERSION_ATLEAST(3, 0, 0) @@ -4086,10 +4065,17 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, newfmt.Rshift = fmt->Rshift; newfmt.Gshift = fmt->Gshift; newfmt.Bshift = fmt->Bshift; +#if SDL_VERSION_ATLEAST(3, 0, 0) + newfmt.Abits = 0; + newfmt.Rbits = fmt->Rbits; + newfmt.Gbits = fmt->Gbits; + newfmt.Bbits = fmt->Bbits; +#else newfmt.Aloss = 0; newfmt.Rloss = fmt->Rloss; newfmt.Gloss = fmt->Gloss; newfmt.Bloss = fmt->Bloss; +#endif src = PG_ConvertSurface(src, &newfmt); if (src) { result = SDL_BlitSurface(src, srcrect, dst, dstrect); @@ -4106,7 +4092,7 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, (PG_SURF_BytesPerPixel(dst) == 4 || PG_SURF_BytesPerPixel(dst) == 2) && _PgSurface_SrcAlpha(src) && - (SDL_ISPIXELFORMAT_ALPHA(src->format->format)) && + (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(src))) && !PG_SurfaceHasRLE(src) && !PG_SurfaceHasRLE(dst) && !(src->flags & SDL_RLEACCEL) && !(dst->flags & SDL_RLEACCEL)) { /* If we have a 32bit source surface with per pixel alpha diff --git a/src_c/surface.h b/src_c/surface.h index 4009579d1d..fde2c39a26 100644 --- a/src_c/surface.h +++ b/src_c/surface.h @@ -342,6 +342,21 @@ } while (0) #endif +#if SDL_VERSION_ATLEAST(3, 0, 0) + +#define PG_SurfaceGetRGBA(colorkey, surf, r, g, b, a) \ + SDL_GetRGBA(colorkey, PG_GetSurfaceFormat(surf), \ + PG_GetSurfacePalette(surf), r, g, b, a) +#define PG_SurfaceGetRGB(colorkey, surf, r, g, b) \ + SDL_GetRGB(colorkey, PG_GetSurfaceFormat(surf), \ + PG_GetSurfacePalette(surf), r, g, b) +#else +#define PG_SurfaceGetRGBA(colorkey, surf, r, g, b, a) \ + SDL_GetRGBA(colorkey, PG_GetSurfaceFormat(surf), r, g, b, a) +#define PG_SurfaceGetRGB(colorkey, surf, r, g, b) \ + SDL_GetRGB(colorkey, PG_GetSurfaceFormat(surf), r, g, b) +#endif + int surface_fill_blend(SDL_Surface *surface, SDL_Rect *rect, Uint32 color, int blendargs); From 23ff10a551073ca4133fd015d20dd88498df6a70 Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:06:13 +0100 Subject: [PATCH 3/4] No errors in surface.c --- src_c/_pygame.h | 4 +-- src_c/surface.c | 89 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index a9c8a73b46..a04f96903e 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -85,7 +85,7 @@ SDL_GetPixelFormatDetails(PG_SurfaceFormatEnum(surf)) #define PG_GetSurfacePalette SDL_GetSurfacePalette #define PG_SurfaceMapRGBA(surf, r, g, b, a) \ - SDL_MapSurfaceRGBA(surface, r, g, b, a) + SDL_MapSurfaceRGBA(surf, r, g, b, a) #define PG_GetSurfaceClipRect(surf, rect) SDL_GetSurfaceClipRect(surf, rect) #define PG_SurfaceHasRLE SDL_SurfaceHasRLE @@ -171,7 +171,7 @@ PG_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color) #define PG_GetSurfaceFormat(surf) (surf)->format #define PG_GetSurfacePalette(surf) (surf)->format->palette #define PG_SurfaceMapRGBA(surf, r, g, b, a) \ - SDL_MapRGBA(PG_GetSurfaceFormat(surface), r, g, b, a) + SDL_MapRGBA(PG_GetSurfaceFormat(surf), r, g, b, a) #define PG_GetSurfaceClipRect(surf, rect) \ { \ rect = &surf->clip_rect; \ diff --git a/src_c/surface.c b/src_c/surface.c index de24501bbd..17a35ab96d 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -507,8 +507,6 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) return -1; } - default_format.palette = NULL; - surface_cleanup(self); if (depth && masks) { /* all info supplied, most errorchecking @@ -923,11 +921,7 @@ surf_map_rgb(PyObject *self, PyObject *args) SURF_INIT_CHECK(surf) -#if SDL_VERSION_ATLEAST(3, 0, 0) - color = SDL_MapSurfaceRGBA(surf, rgba[0], rgba[1], rgba[2], rgba[3]); -#else - color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); -#endif + color = PG_SurfaceMapRGBA(surf, rgba[0], rgba[1], rgba[2], rgba[3]); return PyLong_FromLong(color); } @@ -1314,6 +1308,9 @@ surf_set_alpha(pgSurfaceObject *self, PyObject *args) pgSurface_Prep(self); result = SDL_SetSurfaceRLE(surf, (flags & PGS_RLEACCEL) ? SDL_TRUE : SDL_FALSE); + +#if !SDL_VERSION_ATLEAST(3, 0, 0) + // TODO: is it fine to ignore this part for SDL3? /* HACK HACK HACK */ if ((surf->flags & SDL_RLEACCEL) && (!(flags & PGS_RLEACCEL))) { /* hack to strip SDL_RLEACCEL flag off surface immediately when @@ -1328,6 +1325,7 @@ surf_set_alpha(pgSurfaceObject *self, PyObject *args) SDL_LowerBlit(surf, &sdlrect, surface, &sdlrect); SDL_FreeSurface(surface); } +#endif /* HACK HACK HACK */ if (result == 0) result = SDL_SetSurfaceAlphaMod(surf, alpha); @@ -1533,18 +1531,30 @@ surf_convert(pgSurfaceObject *self, PyObject *args) format.BytesPerPixel = (bpp + 7) / 8; #endif if (PG_FORMAT_BitsPerPixel((&format)) > 8) - /* Allow a 8 bit source surface with an empty palette to be - * converted to a format without a palette (pygame-ce issue - * #146). If the target format has a non-NULL palette pointer - * then SDL_ConvertSurface checks that the palette is not - * empty-- that at least one entry is not black. - */ + /* Allow an 8 bit source surface with an empty palette to be + * converted to a format without a palette (pygame-ce issue + * #146). If the target format has a non-NULL palette pointer + * then SDL_ConvertSurface checks that the palette is not + * empty-- that at least one entry is not black. + */ +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_FreePalette(palette); + palette = NULL; +#else format.palette = NULL; +#endif if (SDL_ISPIXELFORMAT_INDEXED(SDL_MasksToPixelFormatEnum( PG_FORMAT_BitsPerPixel((&format)), format.Rmask, format.Gmask, format.Bmask, format.Amask))) { - if (SDL_ISPIXELFORMAT_INDEXED(surf->format->format)) { - SDL_SetPixelFormatPalette(&format, surf->format->palette); + if (SDL_ISPIXELFORMAT_INDEXED(PG_SurfaceFormatEnum(surf))) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (palette) + SDL_FreePalette(palette); + palette = PG_GetSurfacePalette(surf); +#else + SDL_SetPixelFormatPalette(&format, + PG_GetSurfacePalette(surf)); +#endif } else { /* Give the surface something other than an all white @@ -1552,10 +1562,21 @@ surf_convert(pgSurfaceObject *self, PyObject *args) */ SDL_SetPaletteColors(palette, default_palette_colors, 0, default_palette_size); +#if !SDL_VERSION_ATLEAST(3, 0, 0) SDL_SetPixelFormatPalette(&format, palette); +#endif } } +#if SDL_VERSION_ATLEAST(3, 0, 0) + PG_PixelFormatEnum format_enum = SDL_GetPixelFormatForMasks( + format.bits_per_pixel, format.Rmask, format.Gmask, + format.Bmask, format.Amask); + newsurf = SDL_ConvertSurfaceAndColorspace( + surf, format_enum, palette, SDL_GetSurfaceColorspace(surf), + SDL_GetSurfaceProperties(surf)); +#else newsurf = PG_ConvertSurface(surf, &format); +#endif SDL_SetSurfaceBlendMode(newsurf, SDL_BLENDMODE_NONE); SDL_FreePalette(palette); } @@ -1571,7 +1592,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args) } if (has_colorkey) { - colorkey = SDL_MapRGBA(newsurf->format, key_r, key_g, key_b, key_a); + colorkey = PG_SurfaceMapRGBA(newsurf, key_r, key_g, key_b, key_a); if (SDL_SetColorKey(newsurf, SDL_TRUE, colorkey) != 0) { PyErr_SetString(pgExc_SDLError, SDL_GetError()); SDL_FreeSurface(newsurf); @@ -2540,7 +2561,12 @@ static int _PgSurface_SrcAlpha(SDL_Surface *surf) { SDL_BlendMode mode; - if (SDL_GetSurfaceBlendMode(surf, &mode) < 0) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + if (!SDL_GetSurfaceBlendMode(surf, &mode)) +#else + if (SDL_GetSurfaceBlendMode(surf, &mode) < 0) +#endif + { PyErr_SetString(pgExc_SDLError, SDL_GetError()); return -1; } @@ -2579,7 +2605,11 @@ surf_get_flags(PyObject *self, PyObject *_null) flags |= PGS_PREALLOC; if (PG_SurfaceHasRLE(surf)) flags |= PGS_RLEACCELOK; +#if SDL_VERSION_ATLEAST(3, 0, 0) // TODO: is there a better solution? + if (PG_SurfaceHasRLE(surf)) +#else if ((sdl_flags & SDL_RLEACCEL)) +#endif flags |= PGS_RLEACCEL; if (is_window_surf) { if (window_flags & PG_WINDOW_FULLSCREEN_INCLUSIVE) @@ -2790,10 +2820,11 @@ surf_subsurface(PyObject *self, PyObject *args) return RAISE(pgExc_SDLError, SDL_GetError()); /* copy the colormap if we need it */ - if (SDL_ISPIXELFORMAT_INDEXED(surf->format->format) && - surf->format->palette) { - SDL_Color *colors = surf->format->palette->colors; - int ncolors = surf->format->palette->ncolors; + if (SDL_ISPIXELFORMAT_INDEXED(PG_SurfaceFormatEnum(surf)) && + PG_GetSurfacePalette(surf)) { + SDL_Palette *surf_pallete = PG_GetSurfacePalette(surf); + SDL_Color *colors = surf_pallete->colors; + int ncolors = surf_pallete->ncolors; SDL_Palette *pal = SDL_AllocPalette(ncolors); if (!pal) { @@ -4049,11 +4080,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, PG_PixelFormat *fmt = PG_GetSurfaceFormat(src); PG_PixelFormatMut newfmt; - newfmt.palette = 0; /* Set NULL (or SDL gets confused) */ #if SDL_VERSION_ATLEAST(3, 0, 0) newfmt.bits_per_pixel = fmt->bits_per_pixel; newfmt.bytes_per_pixel = fmt->bytes_per_pixel; #else + newfmt.palette = 0; /* Set NULL (or SDL gets confused) */ newfmt.BitsPerPixel = fmt->BitsPerPixel; newfmt.BytesPerPixel = fmt->BytesPerPixel; #endif @@ -4076,7 +4107,14 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, newfmt.Gloss = fmt->Gloss; newfmt.Bloss = fmt->Bloss; #endif +#if SDL_VERSION_ATLEAST(3, 0, 0) + PG_PixelFormatEnum format_enum = SDL_GetPixelFormatForMasks( + newfmt.bits_per_pixel, newfmt.Rmask, newfmt.Gmask, + newfmt.Bmask, newfmt.Amask); + src = SDL_ConvertSurface(src, format_enum); +#else src = PG_ConvertSurface(src, &newfmt); +#endif if (src) { result = SDL_BlitSurface(src, srcrect, dst, dstrect); SDL_FreeSurface(src); @@ -4093,8 +4131,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, PG_SURF_BytesPerPixel(dst) == 2) && _PgSurface_SrcAlpha(src) && (SDL_ISPIXELFORMAT_ALPHA(PG_SurfaceFormatEnum(src))) && - !PG_SurfaceHasRLE(src) && !PG_SurfaceHasRLE(dst) && - !(src->flags & SDL_RLEACCEL) && !(dst->flags & SDL_RLEACCEL)) { + !PG_SurfaceHasRLE(src) && !PG_SurfaceHasRLE(dst) +#if !SDL_VERSION_ATLEAST(3, 0, 0) + && !(src->flags & SDL_RLEACCEL) && !(dst->flags & SDL_RLEACCEL) +#endif + ) { /* If we have a 32bit source surface with per pixel alpha and no RLE we'll use pygame_Blit so we can mimic how SDL1 behaved */ From 427b15cc889fa5d565a70195619c802ee988653b Mon Sep 17 00:00:00 2001 From: polastyn <78505251+gresm@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:25:10 +0100 Subject: [PATCH 4/4] Feedback applied. --- src_c/_pygame.h | 15 ++-- src_c/surface.c | 214 ++++++++++++++++++++++++++++++++++-------------- src_c/surface.h | 12 ++- 3 files changed, 168 insertions(+), 73 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index a04f96903e..70fae7450a 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -26,6 +26,8 @@ #ifndef _PYGAME_INTERNAL_H #define _PYGAME_INTERNAL_H +#include + #include "pgplatform.h" /* If PY_SSIZE_T_CLEAN is defined before including Python.h, length is a @@ -86,7 +88,7 @@ #define PG_GetSurfacePalette SDL_GetSurfacePalette #define PG_SurfaceMapRGBA(surf, r, g, b, a) \ SDL_MapSurfaceRGBA(surf, r, g, b, a) -#define PG_GetSurfaceClipRect(surf, rect) SDL_GetSurfaceClipRect(surf, rect) +#define PG_GetSurfaceClipRect SDL_GetSurfaceClipRect #define PG_SurfaceHasRLE SDL_SurfaceHasRLE @@ -109,12 +111,7 @@ PG_UnlockMutex(SDL_mutex *mutex) return 0; } -/* Emulating SDL2 SDL_FillRect API. In SDL3, it returns -1 on failure. */ -static inline int -PG_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color) -{ - return SDL_FillSurfaceRect(dst, rect, color) ? 0 : -1; -} +#define PG_FillRect SDL_FillSurfaceRect #define PG_SURF_BitsPerPixel(surf) SDL_BITSPERPIXEL(surf->format) #define PG_SURF_BytesPerPixel(surf) SDL_BYTESPERPIXEL(surf->format) @@ -192,10 +189,10 @@ PG_UnlockMutex(SDL_mutex *mutex) return SDL_UnlockMutex(mutex); } -static inline int +static inline bool PG_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color) { - return SDL_FillRect(dst, rect, color); + return SDL_FillRect(dst, rect, color) != -1; } #define PG_SURF_BitsPerPixel(surf) surf->format->BitsPerPixel diff --git a/src_c/surface.c b/src_c/surface.c index 17a35ab96d..e1cf2fff90 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -619,6 +619,11 @@ surface_init(pgSurfaceObject *self, PyObject *args, PyObject *kwds) pix->Gmask = 0xFF00; pix->Bmask = 0xFF; } + + if (pix == NULL) { + RAISERETURN(pgExc_SDLError, SDL_GetError(), -1); + } + bpp = PG_FORMAT_BitsPerPixel(pix); if (flags & PGS_SRCALPHA) { @@ -731,6 +736,9 @@ surf_get_at(PyObject *self, PyObject *position) format = PG_GetSurfaceFormat(surf); + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + if (PG_FORMAT_BytesPerPixel(format) < 1 || PG_FORMAT_BytesPerPixel(format) > 4) return RAISE(PyExc_RuntimeError, "invalid color depth for surface"); @@ -797,12 +805,19 @@ surf_set_at(PyObject *self, PyObject *const *args, Py_ssize_t nargs) rgba_obj = args[1]; format = PG_GetSurfaceFormat(surf); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + if (PG_FORMAT_BytesPerPixel(format) < 1 || PG_FORMAT_BytesPerPixel(format) > 4) return RAISE(PyExc_RuntimeError, "invalid color depth for surface"); PG_GetSurfaceClipRect(surf, clip_rect); + if (clip_rect == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + if (x < clip_rect->x || x >= clip_rect->x + clip_rect->w || y < clip_rect->y || y >= clip_rect->y + clip_rect->h) { /* out of clip area */ @@ -875,6 +890,9 @@ surf_get_at_mapped(PyObject *self, PyObject *position) format = PG_GetSurfaceFormat(surf); + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + if (PG_FORMAT_BytesPerPixel(format) < 1 || PG_FORMAT_BytesPerPixel(format) > 4) return RAISE(PyExc_RuntimeError, "invalid color depth for surface"); @@ -1435,8 +1453,12 @@ surf_convert(pgSurfaceObject *self, PyObject *args) int bpp = 0; SDL_Palette *palette = SDL_AllocPalette(default_palette_size); PG_PixelFormatMut format; + PG_PixelFormat *surf_format = PG_GetSurfaceFormat(surf); + + if (surf_format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); - memcpy(&format, PG_GetSurfaceFormat(surf), sizeof(format)); + memcpy(&format, surf_format, sizeof(format)); if (pg_IntFromObj(argobject, &bpp)) { Uint32 Rmask, Gmask, Bmask, Amask; @@ -1530,19 +1552,21 @@ surf_convert(pgSurfaceObject *self, PyObject *args) format.BitsPerPixel = (Uint8)bpp; format.BytesPerPixel = (bpp + 7) / 8; #endif - if (PG_FORMAT_BitsPerPixel((&format)) > 8) - /* Allow an 8 bit source surface with an empty palette to be - * converted to a format without a palette (pygame-ce issue - * #146). If the target format has a non-NULL palette pointer - * then SDL_ConvertSurface checks that the palette is not - * empty-- that at least one entry is not black. - */ + if (PG_FORMAT_BitsPerPixel((&format)) > 8) { + /* Allow an 8 bit source surface with an empty palette to be + * converted to a format without a palette (pygame-ce issue + * #146). If the target format has a non-NULL palette pointer + * then SDL_ConvertSurface checks that the palette is not + * empty-- that at least one entry is not black. + */ #if SDL_VERSION_ATLEAST(3, 0, 0) SDL_FreePalette(palette); - palette = NULL; + palette = NULL; #else format.palette = NULL; #endif + } + if (SDL_ISPIXELFORMAT_INDEXED(SDL_MasksToPixelFormatEnum( PG_FORMAT_BitsPerPixel((&format)), format.Rmask, format.Gmask, format.Bmask, format.Amask))) { @@ -1578,7 +1602,8 @@ surf_convert(pgSurfaceObject *self, PyObject *args) newsurf = PG_ConvertSurface(surf, &format); #endif SDL_SetSurfaceBlendMode(newsurf, SDL_BLENDMODE_NONE); - SDL_FreePalette(palette); + if (palette) + SDL_FreePalette(palette); } } else { @@ -1742,6 +1767,10 @@ surf_get_clip(PyObject *self, PyObject *_null) SURF_INIT_CHECK(surf) PG_GetSurfaceClipRect(surf, clip_rect); + + if (clip_rect == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + return pgRect_New(clip_rect); } @@ -2512,6 +2541,10 @@ surf_scroll(PyObject *self, PyObject *args, PyObject *keywds) } PG_GetSurfaceClipRect(surf, clip_rect); + + if (clip_rect == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + SDL_Rect surf_rect = {0, 0, surf->w, surf->h}; // In SDL3, SDL_IntersectRect is renamed to SDL_GetRectIntersection @@ -2529,9 +2562,8 @@ surf_scroll(PyObject *self, PyObject *args, PyObject *keywds) if (!repeat) { if (dx >= w || dx <= -w || dy >= h || dy <= -h) { if (erase) { - if (PG_FillRect(surf, NULL, 0) == -1) { - PyErr_SetString(pgExc_SDLError, SDL_GetError()); - return NULL; + if (!PG_FillRect(surf, NULL, 0)) { + return RAISE(pgExc_SDLError, SDL_GetError()); } } Py_RETURN_NONE; @@ -2737,6 +2769,10 @@ surf_get_masks(PyObject *self, PyObject *_null) SURF_INIT_CHECK(surf) format = PG_GetSurfaceFormat(surf); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + return Py_BuildValue("(IIII)", format->Rmask, format->Gmask, format->Bmask, format->Amask); } @@ -2755,6 +2791,10 @@ surf_get_shifts(PyObject *self, PyObject *_null) SURF_INIT_CHECK(surf) format = PG_GetSurfaceFormat(surf); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + return Py_BuildValue("(iiii)", format->Rshift, format->Gshift, format->Bshift, format->Ashift); } @@ -2774,6 +2814,10 @@ surf_get_losses(PyObject *self, PyObject *_null) SURF_INIT_CHECK(surf) format = PG_GetSurfaceFormat(surf); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + #if SDL_VERSION_ATLEAST(3, 0, 0) return Py_BuildValue("(iiii)", 8 - format->Rbits, 8 - format->Gbits, 8 - format->Bbits, 8 - format->Abits); @@ -2798,6 +2842,10 @@ surf_subsurface(PyObject *self, PyObject *args) SURF_INIT_CHECK(surf) format = PG_GetSurfaceFormat(surf); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + if (!(rect = pgRect_FromObject(args, &temp))) return RAISE(PyExc_ValueError, "invalid rectstyle argument"); if (rect->x < 0 || rect->y < 0 || rect->x + rect->w > surf->w || @@ -2985,6 +3033,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *rect; SDL_Surface *surf = pgSurface_AsSurface(self); PG_PixelFormat *format = NULL; + SDL_Palette *palette; Uint8 *pixels = NULL; Uint8 *pixel; int x, y; @@ -3009,10 +3058,14 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) return RAISE(pgExc_SDLError, "could not lock surface"); format = PG_GetSurfaceFormat(surf); + palette = PG_GetSurfacePalette(surf); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); if ((has_colorkey = SDL_HasColorKey(surf))) { SDL_GetColorKey(surf, &colorkey); - PG_SurfaceGetRGBA(colorkey, surf, &keyr, &keyg, &keyb, &a); + PG_GetRGBA(colorkey, format, palette, &keyr, &keyg, &keyb, &a); } pixels = (Uint8 *)surf->pixels; @@ -3042,7 +3095,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); + PG_GetRGBA(value, format, palette, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3075,7 +3128,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); + PG_GetRGBA(value, format, palette, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3109,7 +3162,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); + PG_GetRGBA(value, format, palette, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3142,7 +3195,7 @@ surf_get_bounding_rect(PyObject *self, PyObject *args, PyObject *kwargs) assert(PG_FORMAT_BytesPerPixel(format) == 4); value = *(Uint32 *)pixel; } - PG_SurfaceGetRGBA(value, surf, &r, &g, &b, &a); + PG_GetRGBA(value, format, palette, &r, &g, &b, &a); if ((a >= min_alpha && has_colorkey == 0) || (has_colorkey != 0 && (r != keyr || g != keyg || b != keyb))) { found_alpha = 1; @@ -3228,6 +3281,10 @@ surf_get_view(PyObject *self, PyObject *args) SURF_INIT_CHECK(surface) format = PG_GetSurfaceFormat(surface); + + if (format == NULL) + return RAISE(pgExc_SDLError, SDL_GetError()); + switch (view_kind) { /* This switch statement is exhaustive over the SurfViewKind enum */ @@ -3571,6 +3628,11 @@ _get_buffer_3D(PyObject *obj, Py_buffer *view_p, int flags) { SDL_Surface *surface = pgSurface_AsSurface(obj); PG_PixelFormat *format = PG_GetSurfaceFormat(surface); + + if (format == NULL) { + RAISERETURN(pgExc_SDLError, SDL_GetError(), -1); + } + int pixelsize = PG_SURF_BytesPerPixel(surface); char *startpixel = (char *)surface->pixels; @@ -3648,33 +3710,49 @@ _get_buffer_3D(PyObject *obj, Py_buffer *view_p, int flags) static int _get_buffer_red(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane( - obj, view_p, flags, "red", - PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Rmask); + PG_PixelFormat *format = PG_GetSurfaceFormat(pgSurface_AsSurface(obj)); + + if (format == NULL) { + RAISERETURN(pgExc_SDLError, SDL_GetError(), -1); + } + + return _get_buffer_colorplane(obj, view_p, flags, "red", format->Rmask); } static int _get_buffer_green(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane( - obj, view_p, flags, "green", - PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Gmask); + PG_PixelFormat *format = PG_GetSurfaceFormat(pgSurface_AsSurface(obj)); + + if (format == NULL) { + RAISERETURN(pgExc_SDLError, SDL_GetError(), -1); + } + + return _get_buffer_colorplane(obj, view_p, flags, "green", format->Gmask); } static int _get_buffer_blue(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane( - obj, view_p, flags, "blue", - PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Bmask); + PG_PixelFormat *format = PG_GetSurfaceFormat(pgSurface_AsSurface(obj)); + + if (format == NULL) { + RAISERETURN(pgExc_SDLError, SDL_GetError(), -1); + } + + return _get_buffer_colorplane(obj, view_p, flags, "blue", format->Bmask); } static int _get_buffer_alpha(PyObject *obj, Py_buffer *view_p, int flags) { - return _get_buffer_colorplane( - obj, view_p, flags, "alpha", - PG_GetSurfaceFormat(pgSurface_AsSurface(obj))->Amask); + PG_PixelFormat *format = PG_GetSurfaceFormat(pgSurface_AsSurface(obj)); + + if (format == NULL) { + RAISERETURN(pgExc_SDLError, SDL_GetError(), -1); + } + + return _get_buffer_colorplane(obj, view_p, flags, "alpha", format->Amask); } static int @@ -3938,6 +4016,10 @@ surface_do_overlap(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, int maxw, maxh; SDL_Rect *clip; PG_GetSurfaceClipRect(dst, clip); + + if (clip == NULL) + return -1; + int span; int dstoffset; @@ -4063,7 +4145,8 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, owner is locked. */ dst->pixels == src->pixels && srcrect != NULL && - surface_do_overlap(src, srcrect, dst, dstrect))) { + (result = surface_do_overlap(src, srcrect, dst, dstrect)) && + result != -1)) { /* Py_BEGIN_ALLOW_THREADS */ result = pygame_Blit(src, srcrect, dst, dstrect, blend_flags); /* Py_END_ALLOW_THREADS */ @@ -4080,47 +4163,52 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj, PG_PixelFormat *fmt = PG_GetSurfaceFormat(src); PG_PixelFormatMut newfmt; + if (fmt == NULL) { + result = -1; + } + else { #if SDL_VERSION_ATLEAST(3, 0, 0) - newfmt.bits_per_pixel = fmt->bits_per_pixel; - newfmt.bytes_per_pixel = fmt->bytes_per_pixel; + newfmt.bits_per_pixel = fmt->bits_per_pixel; + newfmt.bytes_per_pixel = fmt->bytes_per_pixel; #else - newfmt.palette = 0; /* Set NULL (or SDL gets confused) */ - newfmt.BitsPerPixel = fmt->BitsPerPixel; - newfmt.BytesPerPixel = fmt->BytesPerPixel; + newfmt.palette = 0; /* Set NULL (or SDL gets confused) */ + newfmt.BitsPerPixel = fmt->BitsPerPixel; + newfmt.BytesPerPixel = fmt->BytesPerPixel; #endif - newfmt.Amask = 0; - newfmt.Rmask = fmt->Rmask; - newfmt.Gmask = fmt->Gmask; - newfmt.Bmask = fmt->Bmask; - newfmt.Ashift = 0; - newfmt.Rshift = fmt->Rshift; - newfmt.Gshift = fmt->Gshift; - newfmt.Bshift = fmt->Bshift; + newfmt.Amask = 0; + newfmt.Rmask = fmt->Rmask; + newfmt.Gmask = fmt->Gmask; + newfmt.Bmask = fmt->Bmask; + newfmt.Ashift = 0; + newfmt.Rshift = fmt->Rshift; + newfmt.Gshift = fmt->Gshift; + newfmt.Bshift = fmt->Bshift; #if SDL_VERSION_ATLEAST(3, 0, 0) - newfmt.Abits = 0; - newfmt.Rbits = fmt->Rbits; - newfmt.Gbits = fmt->Gbits; - newfmt.Bbits = fmt->Bbits; + newfmt.Abits = 0; + newfmt.Rbits = fmt->Rbits; + newfmt.Gbits = fmt->Gbits; + newfmt.Bbits = fmt->Bbits; #else - newfmt.Aloss = 0; - newfmt.Rloss = fmt->Rloss; - newfmt.Gloss = fmt->Gloss; - newfmt.Bloss = fmt->Bloss; + newfmt.Aloss = 0; + newfmt.Rloss = fmt->Rloss; + newfmt.Gloss = fmt->Gloss; + newfmt.Bloss = fmt->Bloss; #endif #if SDL_VERSION_ATLEAST(3, 0, 0) - PG_PixelFormatEnum format_enum = SDL_GetPixelFormatForMasks( - newfmt.bits_per_pixel, newfmt.Rmask, newfmt.Gmask, - newfmt.Bmask, newfmt.Amask); - src = SDL_ConvertSurface(src, format_enum); + PG_PixelFormatEnum format_enum = SDL_GetPixelFormatForMasks( + newfmt.bits_per_pixel, newfmt.Rmask, newfmt.Gmask, + newfmt.Bmask, newfmt.Amask); + src = SDL_ConvertSurface(src, format_enum); #else - src = PG_ConvertSurface(src, &newfmt); + src = PG_ConvertSurface(src, &newfmt); #endif - if (src) { - result = SDL_BlitSurface(src, srcrect, dst, dstrect); - SDL_FreeSurface(src); - } - else { - result = -1; + if (src) { + result = SDL_BlitSurface(src, srcrect, dst, dstrect); + SDL_FreeSurface(src); + } + else { + result = -1; + } } } /* Py_END_ALLOW_THREADS */ diff --git a/src_c/surface.h b/src_c/surface.h index fde2c39a26..8a43dacb8a 100644 --- a/src_c/surface.h +++ b/src_c/surface.h @@ -350,11 +350,21 @@ #define PG_SurfaceGetRGB(colorkey, surf, r, g, b) \ SDL_GetRGB(colorkey, PG_GetSurfaceFormat(surf), \ PG_GetSurfacePalette(surf), r, g, b) -#else + +#define PG_GetRGBA SDL_GetRGBA + +#else /* ~SDL_VERSION_ATLEAST(3, 0, 0) */ #define PG_SurfaceGetRGBA(colorkey, surf, r, g, b, a) \ SDL_GetRGBA(colorkey, PG_GetSurfaceFormat(surf), r, g, b, a) #define PG_SurfaceGetRGB(colorkey, surf, r, g, b) \ SDL_GetRGB(colorkey, PG_GetSurfaceFormat(surf), r, g, b) + +static inline void +PG_GetRGBA(Uint32 pixel, const SDL_PixelFormat *format, SDL_Palette *palette, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) +{ + SDL_GetRGBA(pixel, format, r, g, b, a); +} #endif int