From 84a0d5f623b35952243aea737b2630ab5aa941e9 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 14 Dec 2023 21:26:18 +0100 Subject: [PATCH] Added SDL_SetSurfaceScaleMode() and SDL_GetSurfaceScaleMode() to control scale mode using SDL_BlitSurfaceScaled() --- WhatsNew.txt | 1 + include/SDL3/SDL_render.h | 10 ------- include/SDL3/SDL_surface.h | 45 +++++++++++++++++++++++++++++++ src/dynapi/SDL_dynapi.sym | 2 ++ src/dynapi/SDL_dynapi_overrides.h | 2 ++ src/dynapi/SDL_dynapi_procs.h | 2 ++ src/video/SDL_surface.c | 36 +++++++++++++++++++++++-- 7 files changed, 86 insertions(+), 12 deletions(-) diff --git a/WhatsNew.txt b/WhatsNew.txt index 1b84c49b9..18dfd84cb 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -30,3 +30,4 @@ General: * Added SDL_PlayAudioDevice() to start audio playback * Added SDL_ConvertAudioSamples() to convert audio samples from one format to another * Added the hint SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY to control re-creation of Android SDL activity. +* Added SDL_SetSurfaceScaleMode() and SDL_GetSurfaceScaleMode() to control scale mode using SDL_BlitSurfaceScaled() diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h index af5889ba9..15b0836b4 100644 --- a/include/SDL3/SDL_render.h +++ b/include/SDL3/SDL_render.h @@ -95,16 +95,6 @@ typedef struct SDL_Vertex SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */ } SDL_Vertex; -/** - * The scaling mode for a texture. - */ -typedef enum -{ - SDL_SCALEMODE_NEAREST, /**< nearest pixel sampling */ - SDL_SCALEMODE_LINEAR, /**< linear filtering */ - SDL_SCALEMODE_BEST /**< anisotropic filtering */ -} SDL_ScaleMode; - /** * The access pattern allowed for a texture. */ diff --git a/include/SDL3/SDL_surface.h b/include/SDL3/SDL_surface.h index aefb42338..c9e5f765a 100644 --- a/include/SDL3/SDL_surface.h +++ b/include/SDL3/SDL_surface.h @@ -64,6 +64,17 @@ extern "C" { typedef struct SDL_BlitMap SDL_BlitMap; /* this is an opaque type. */ +/** + * The scaling mode + */ +typedef enum +{ + SDL_SCALEMODE_NEAREST, /**< nearest pixel sampling */ + SDL_SCALEMODE_LINEAR, /**< linear filtering */ + SDL_SCALEMODE_BEST /**< anisotropic filtering */ +} SDL_ScaleMode; + + /** * A collection of pixels used in software blitting. * @@ -104,6 +115,8 @@ typedef struct SDL_Surface /** clipping information */ SDL_Rect clip_rect; /**< Read-only */ + SDL_ScaleMode scaleMode; /**< The scale mode */ + /** info for fast blit mapping to other surfaces */ SDL_BlitMap *map; /**< Private */ @@ -903,6 +916,7 @@ extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface *src, * \since This function is available since SDL 3.0.0. * * \sa SDL_BlitSurface + * \sa SDL_SetSurfaceScaleMode */ extern DECLSPEC int SDLCALL SDL_BlitSurfaceScaled (SDL_Surface *src, const SDL_Rect *srcrect, @@ -926,11 +940,42 @@ extern DECLSPEC int SDLCALL SDL_BlitSurfaceScaled * \since This function is available since SDL 3.0.0. * * \sa SDL_BlitSurfaceScaled + * \sa SDL_SetSurfaceScaleMode */ extern DECLSPEC int SDLCALL SDL_BlitSurfaceUncheckedScaled (SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); +/** + * Set the scale mode used for surface scale operations. + * + * \param surface the surface to update. + * \param scaleMode the SDL_ScaleMode to use for scaling. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetSurfaceScaleMode + * \sa SDL_BlitSurfaceScaled + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceScaleMode(SDL_Surface *surface, SDL_ScaleMode scaleMode); + +/** + * Get the scale mode used for surface scale operations. + * + * \param surface the surface to query. + * \param scaleMode a pointer filled in with the current scale mode. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_SetSurfaceScaleMode + * \sa SDL_BlitSurfaceScaled + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceScaleMode(SDL_Surface *surface, SDL_ScaleMode *scaleMode); + /** * Set the YUV conversion mode * diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index e4747421a..7a68abb99 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -963,6 +963,8 @@ SDL3_0.0.0 { SDL_strnstr; SDL_wcsnstr; SDL_SyncWindow; + SDL_SetSurfaceScaleMode; + SDL_GetSurfaceScaleMode; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 25d834ce6..acfbb8c7c 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -988,3 +988,5 @@ #define SDL_strnstr SDL_strnstr_REAL #define SDL_wcsnstr SDL_wcsnstr_REAL #define SDL_SyncWindow SDL_SyncWindow_REAL +#define SDL_SetSurfaceScaleMode SDL_SetSurfaceScaleMode_REAL +#define SDL_GetSurfaceScaleMode SDL_GetSurfaceScaleMode_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index e6d79cc03..faf3d553e 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1013,3 +1013,5 @@ SDL_DYNAPI_PROC(const char*,SDL_GetTouchDeviceName,(SDL_TouchID a),(a),return) SDL_DYNAPI_PROC(char*,SDL_strnstr,(const char *a, const char *b, size_t c),(a,b,c),return) SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_SyncWindow,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_SetSurfaceScaleMode,(SDL_Surface *a, SDL_ScaleMode b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GetSurfaceScaleMode,(SDL_Surface *a, SDL_ScaleMode *b),(a,b),return) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 7b26b5e2e..a86f8e068 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -776,7 +776,7 @@ int SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, int SDL_BlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) { - return SDL_PrivateBlitSurfaceScaled(src, srcrect, dst, dstrect, SDL_SCALEMODE_NEAREST); + return SDL_PrivateBlitSurfaceScaled(src, srcrect, dst, dstrect, src->scaleMode); } int SDL_PrivateBlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, @@ -944,7 +944,7 @@ int SDL_PrivateBlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, int SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect) { - return SDL_PrivateBlitSurfaceUncheckedScaled(src, srcrect, dst, dstrect, SDL_SCALEMODE_NEAREST); + return SDL_PrivateBlitSurfaceUncheckedScaled(src, srcrect, dst, dstrect, src->scaleMode); } int SDL_PrivateBlitSurfaceUncheckedScaled(SDL_Surface *src, const SDL_Rect *srcrect, @@ -1051,6 +1051,38 @@ int SDL_PrivateBlitSurfaceUncheckedScaled(SDL_Surface *src, const SDL_Rect *srcr } } +int SDL_SetSurfaceScaleMode(SDL_Surface *surface, SDL_ScaleMode scaleMode) +{ + if (!surface) { + return SDL_InvalidParamError("surface"); + } + + if (scaleMode != SDL_SCALEMODE_NEAREST && scaleMode != SDL_SCALEMODE_LINEAR && scaleMode != SDL_SCALEMODE_BEST) { + return SDL_InvalidParamError("scaleMode"); + } + + if (scaleMode == SDL_SCALEMODE_NEAREST) { + surface->scaleMode = SDL_SCALEMODE_NEAREST; + } else { + surface->scaleMode = SDL_SCALEMODE_LINEAR; + } + + return 0; +} + +int SDL_GetSurfaceScaleMode(SDL_Surface *surface, SDL_ScaleMode *scaleMode) +{ + if (!surface) { + return SDL_InvalidParamError("surface"); + } + + if (scaleMode) { + *scaleMode = surface->scaleMode; + } + + return 0; +} + /* * Lock a surface to directly access the pixels */