Added SDL_FlipSurface() to flip a surface vertically or horizontally
Fixes https://github.com/libsdl-org/SDL/issues/8857main
parent
2cd583ee13
commit
308906ba25
|
@ -17,6 +17,7 @@ General:
|
|||
* Added SDL_GetPrimaryDisplay() to get the instance ID of the primary display
|
||||
* Added SDL_GetWindowParent() to get the parent of popup windows
|
||||
* Added SDL_CreateSurface() and SDL_CreateSurfaceFrom() which replace SDL_CreateRGBSurface*(), and can also be used to create YUV surfaces
|
||||
* Added SDL_FlipSurface() to flip a surface vertically or horizontally
|
||||
* Added SDL_GetJoysticks(), SDL_GetJoystickInstanceName(), SDL_GetJoystickInstancePath(), SDL_GetJoystickInstancePlayerIndex(), SDL_GetJoystickInstanceGUID(), SDL_GetJoystickInstanceVendor(), SDL_GetJoystickInstanceProduct(), SDL_GetJoystickInstanceProductVersion(), and SDL_GetJoystickInstanceType() to directly query the list of available joysticks
|
||||
* Added SDL_GetGamepads(), SDL_GetGamepadInstanceName(), SDL_GetGamepadInstancePath(), SDL_GetGamepadInstancePlayerIndex(), SDL_GetGamepadInstanceGUID(), SDL_GetGamepadInstanceVendor(), SDL_GetGamepadInstanceProduct(), SDL_GetGamepadInstanceProductVersion(), and SDL_GetGamepadInstanceType() to directly query the list of available gamepads
|
||||
* Added SDL_GetSensors(), SDL_GetSensorInstanceName(), SDL_GetSensorInstanceType(), and SDL_GetSensorInstanceNonPortableType() to directly query the list of available sensors
|
||||
|
|
|
@ -1037,6 +1037,7 @@ The following functions have been removed:
|
|||
* SDL_SetTextureUserData() - use SDL_GetTextureProperties() instead
|
||||
|
||||
The following symbols have been renamed:
|
||||
* SDL_RendererFlip => SDL_FlipMode
|
||||
* SDL_ScaleModeBest => SDL_SCALEMODE_BEST
|
||||
* SDL_ScaleModeLinear => SDL_SCALEMODE_LINEAR
|
||||
* SDL_ScaleModeNearest => SDL_SCALEMODE_NEAREST
|
||||
|
|
|
@ -105,16 +105,6 @@ typedef enum
|
|||
SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */
|
||||
} SDL_TextureAccess;
|
||||
|
||||
/**
|
||||
* Flip constants for SDL_RenderTextureRotated
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_FLIP_NONE = 0x00000000, /**< Do not flip */
|
||||
SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */
|
||||
SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */
|
||||
} SDL_RendererFlip;
|
||||
|
||||
/**
|
||||
* How the logical size is mapped to the output
|
||||
*/
|
||||
|
@ -1494,7 +1484,7 @@ extern DECLSPEC int SDLCALL SDL_RenderTexture(SDL_Renderer *renderer, SDL_Textur
|
|||
* \param center A pointer to a point indicating the point around which
|
||||
* dstrect will be rotated (if NULL, rotation will be done
|
||||
* around dstrect.w/2, dstrect.h/2).
|
||||
* \param flip An SDL_RendererFlip value stating which flipping actions should
|
||||
* \param flip An SDL_FlipMode value stating which flipping actions should
|
||||
* be performed on the texture
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
@ -1504,7 +1494,7 @@ extern DECLSPEC int SDLCALL SDL_RenderTexture(SDL_Renderer *renderer, SDL_Textur
|
|||
extern DECLSPEC int SDLCALL SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_FRect *srcrect, const SDL_FRect *dstrect,
|
||||
const double angle, const SDL_FPoint *center,
|
||||
const SDL_RendererFlip flip);
|
||||
const SDL_FlipMode flip);
|
||||
|
||||
/**
|
||||
* Render a list of triangles, optionally using a texture and indices into the
|
||||
|
|
|
@ -75,6 +75,15 @@ typedef enum
|
|||
SDL_SCALEMODE_BEST /**< anisotropic filtering */
|
||||
} SDL_ScaleMode;
|
||||
|
||||
/**
|
||||
* The flip mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_FLIP_NONE, /**< Do not flip */
|
||||
SDL_FLIP_HORIZONTAL, /**< flip horizontally */
|
||||
SDL_FLIP_VERTICAL /**< flip vertically */
|
||||
} SDL_FlipMode;
|
||||
|
||||
/**
|
||||
* A collection of pixels used in software blitting.
|
||||
|
@ -602,6 +611,18 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetSurfaceClipRect(SDL_Surface *surface,
|
|||
extern DECLSPEC int SDLCALL SDL_GetSurfaceClipRect(SDL_Surface *surface,
|
||||
SDL_Rect *rect);
|
||||
|
||||
/*
|
||||
* Flip a surface vertically or horizontally.
|
||||
*
|
||||
* \param surface the surface to flip
|
||||
* \param flip the direction to flip
|
||||
* \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.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_FlipSurface(SDL_Surface *surface, SDL_FlipMode flip);
|
||||
|
||||
/*
|
||||
* Creates a new surface identical to the existing surface.
|
||||
*
|
||||
|
|
|
@ -964,6 +964,7 @@ SDL3_0.0.0 {
|
|||
SDL_GetHapticInstanceID;
|
||||
SDL_GetHapticName;
|
||||
SDL_ReadSurfacePixel;
|
||||
SDL_FlipSurface;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
|
|
@ -989,3 +989,4 @@
|
|||
#define SDL_GetHapticInstanceID SDL_GetHapticInstanceID_REAL
|
||||
#define SDL_GetHapticName SDL_GetHapticName_REAL
|
||||
#define SDL_ReadSurfacePixel SDL_ReadSurfacePixel_REAL
|
||||
#define SDL_FlipSurface SDL_FlipSurface_REAL
|
||||
|
|
|
@ -580,7 +580,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderReadPixels,(SDL_Renderer *a, const SDL_Rect *b, Ui
|
|||
SDL_DYNAPI_PROC(int,SDL_RenderRect,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderTexture,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderTextureRotated,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderTextureRotated,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_FlipMode g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_ResetAssertionReport,(void),(),)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_ResetHint,(const char *a),(a),return)
|
||||
|
@ -1014,3 +1014,4 @@ SDL_DYNAPI_PROC(SDL_Haptic*,SDL_GetHapticFromInstanceID,(SDL_HapticID a),(a),ret
|
|||
SDL_DYNAPI_PROC(SDL_HapticID,SDL_GetHapticInstanceID,(SDL_Haptic *a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetHapticName,(SDL_Haptic *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_ReadSurfacePixel,(SDL_Surface *a, int b, int c, Uint8 *d, Uint8 *e, Uint8 *f, Uint8 *g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_FlipSurface,(SDL_Surface *a, SDL_FlipMode b),(a,b),return)
|
||||
|
|
|
@ -611,7 +611,7 @@ static int QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_
|
|||
|
||||
static int QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_FRect *srcquad, const SDL_FRect *dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
|
||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y)
|
||||
{
|
||||
SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY_EX, texture);
|
||||
int retval = -1;
|
||||
|
@ -3296,7 +3296,7 @@ int SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FR
|
|||
|
||||
int SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_FRect *srcrect, const SDL_FRect *dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip)
|
||||
{
|
||||
SDL_FRect real_srcrect;
|
||||
SDL_FRect real_dstrect;
|
||||
|
|
|
@ -173,7 +173,7 @@ struct SDL_Renderer
|
|||
const SDL_FRect *srcrect, const SDL_FRect *dstrect);
|
||||
int (*QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const SDL_FRect *srcquad, const SDL_FRect *dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y);
|
||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y);
|
||||
int (*QueueGeometry)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
|
|
|
@ -842,7 +842,7 @@ static int PSP_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Tex
|
|||
|
||||
static int PSP_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const SDL_FRect *srcrect, const SDL_FRect *dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
|
||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y)
|
||||
{
|
||||
VertTV *verts = (VertTV *)SDL_AllocateRenderVertices(renderer, 4 * sizeof(VertTV), 4, &cmd->data.draw.first);
|
||||
const float centerx = center->x;
|
||||
|
|
|
@ -257,14 +257,14 @@ typedef struct CopyExData
|
|||
SDL_Rect dstrect;
|
||||
double angle;
|
||||
SDL_FPoint center;
|
||||
SDL_RendererFlip flip;
|
||||
SDL_FlipMode flip;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
} CopyExData;
|
||||
|
||||
static int SW_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const SDL_FRect *srcrect, const SDL_FRect *dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
|
||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y)
|
||||
{
|
||||
CopyExData *verts = (CopyExData *)SDL_AllocateRenderVertices(renderer, sizeof(CopyExData), 0, &cmd->data.draw.first);
|
||||
|
||||
|
@ -311,7 +311,7 @@ static int Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surf
|
|||
|
||||
static int SW_RenderCopyEx(SDL_Renderer *renderer, SDL_Surface *surface, SDL_Texture *texture,
|
||||
const SDL_Rect *srcrect, const SDL_Rect *final_rect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
|
||||
const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y)
|
||||
{
|
||||
SDL_Surface *src = (SDL_Surface *)texture->driverdata;
|
||||
SDL_Rect tmp_rect;
|
||||
|
|
|
@ -1078,11 +1078,97 @@ void SDL_UnlockSurface(SDL_Surface *surface)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int SDL_FlipSurfaceHorizontal(SDL_Surface *surface)
|
||||
{
|
||||
SDL_bool isstack;
|
||||
Uint8 *row, *a, *b, *tmp;
|
||||
int i, j, bpp;
|
||||
|
||||
if (surface->format->BitsPerPixel < 8) {
|
||||
/* We could implement this if needed, but we'd have to flip sets of bits within a byte */
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
if (surface->h <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (surface->w <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpp = surface->format->BytesPerPixel;
|
||||
row = (Uint8 *)surface->pixels;
|
||||
tmp = SDL_small_alloc(Uint8, surface->pitch, &isstack);
|
||||
for (i = surface->h; i--; ) {
|
||||
a = row;
|
||||
b = a + (surface->w - 1) * bpp;
|
||||
for (j = surface->w / 2; j--; ) {
|
||||
SDL_memcpy(tmp, a, bpp);
|
||||
SDL_memcpy(a, b, bpp);
|
||||
SDL_memcpy(b, tmp, bpp);
|
||||
a += bpp;
|
||||
b -= bpp;
|
||||
}
|
||||
row += surface->pitch;
|
||||
}
|
||||
SDL_small_free(tmp, isstack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SDL_FlipSurfaceVertical(SDL_Surface *surface)
|
||||
{
|
||||
SDL_bool isstack;
|
||||
Uint8 *a, *b, *tmp;
|
||||
int i;
|
||||
|
||||
if (surface->h <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
a = (Uint8 *)surface->pixels;
|
||||
b = a + (surface->h - 1) * surface->pitch;
|
||||
tmp = SDL_small_alloc(Uint8, surface->pitch, &isstack);
|
||||
for (i = surface->h / 2; i--; ) {
|
||||
SDL_memcpy(tmp, a, surface->pitch);
|
||||
SDL_memcpy(a, b, surface->pitch);
|
||||
SDL_memcpy(b, tmp, surface->pitch);
|
||||
a += surface->pitch;
|
||||
b -= surface->pitch;
|
||||
}
|
||||
SDL_small_free(tmp, isstack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_FlipSurface(SDL_Surface *surface, SDL_FlipMode flip)
|
||||
{
|
||||
if (!surface || !surface->format) {
|
||||
return SDL_InvalidParamError("surface");
|
||||
}
|
||||
if (!surface->pixels) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (flip) {
|
||||
case SDL_FLIP_HORIZONTAL:
|
||||
return SDL_FlipSurfaceHorizontal(surface);
|
||||
case SDL_FLIP_VERTICAL:
|
||||
return SDL_FlipSurfaceVertical(surface);
|
||||
default:
|
||||
return SDL_InvalidParamError("flip");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new surface identical to the existing surface
|
||||
*/
|
||||
SDL_Surface *SDL_DuplicateSurface(SDL_Surface *surface)
|
||||
{
|
||||
if (!surface) {
|
||||
SDL_InvalidParamError("surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SDL_ConvertSurface(surface, surface->format);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,15 @@
|
|||
#include "testautomation_suites.h"
|
||||
#include "testautomation_images.h"
|
||||
|
||||
|
||||
#define CHECK_FUNC(FUNC, PARAMS) \
|
||||
{ \
|
||||
int result = FUNC PARAMS; \
|
||||
if (result != 0) { \
|
||||
SDLTest_AssertCheck(result == 0, "Validate result from %s, expected: 0, got: %i, %s", #FUNC, result, SDL_GetError()); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* ================= Test Case Implementation ================== */
|
||||
|
||||
/* Shared test surface */
|
||||
|
@ -791,6 +800,54 @@ static int surface_testOverflow(void *arg)
|
|||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
static int surface_testFlip(void *arg)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
Uint8 *pixels;
|
||||
int offset;
|
||||
const char *expectedError;
|
||||
|
||||
surface = SDL_CreateSurface(3, 3, SDL_PIXELFORMAT_RGB24);
|
||||
SDLTest_AssertCheck(surface != NULL, "SDL_CreateSurface()");
|
||||
|
||||
SDL_ClearError();
|
||||
expectedError = "Parameter 'surface' is invalid";
|
||||
SDL_FlipSurface(NULL, SDL_FLIP_HORIZONTAL);
|
||||
SDLTest_AssertCheck(SDL_strcmp(SDL_GetError(), expectedError) == 0,
|
||||
"Expected \"%s\", got \"%s\"", expectedError, SDL_GetError());
|
||||
|
||||
SDL_ClearError();
|
||||
expectedError = "Parameter 'flip' is invalid";
|
||||
SDL_FlipSurface(surface, SDL_FLIP_NONE);
|
||||
SDLTest_AssertCheck(SDL_strcmp(SDL_GetError(), expectedError) == 0,
|
||||
"Expected \"%s\", got \"%s\"", expectedError, SDL_GetError());
|
||||
|
||||
pixels = (Uint8 *)surface->pixels;
|
||||
*pixels = 0xFF;
|
||||
offset = 0;
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_FlipSurface(surface, SDL_FLIP_VERTICAL)");
|
||||
CHECK_FUNC(SDL_FlipSurface, (surface, SDL_FLIP_VERTICAL));
|
||||
SDLTest_AssertCheck(pixels[offset] == 0x00,
|
||||
"Expected pixels[%d] == 0x00 got 0x%.2X", offset, pixels[offset]);
|
||||
offset = 2 * surface->pitch;
|
||||
SDLTest_AssertCheck(pixels[offset] == 0xFF,
|
||||
"Expected pixels[%d] == 0xFF got 0x%.2X", offset, pixels[offset]);
|
||||
|
||||
SDLTest_AssertPass("Call to SDL_FlipSurface(surface, SDL_FLIP_HORIZONTAL)");
|
||||
CHECK_FUNC(SDL_FlipSurface, (surface, SDL_FLIP_HORIZONTAL));
|
||||
SDLTest_AssertCheck(pixels[offset] == 0x00,
|
||||
"Expected pixels[%d] == 0x00 got 0x%.2X", offset, pixels[offset]);
|
||||
offset += (surface->w - 1) * surface->format->BytesPerPixel;
|
||||
SDLTest_AssertCheck(pixels[offset] == 0xFF,
|
||||
"Expected pixels[%d] == 0xFF got 0x%.2X", offset, pixels[offset]);
|
||||
|
||||
SDL_DestroySurface(surface);
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
|
||||
/* ================= Test References ================== */
|
||||
|
||||
/* Surface test cases */
|
||||
|
@ -849,11 +906,15 @@ static const SDLTest_TestCaseReference surfaceTestOverflow = {
|
|||
surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED
|
||||
};
|
||||
|
||||
static const SDLTest_TestCaseReference surfaceTestFlip = {
|
||||
surface_testFlip, "surface_testFlip", "Test surface flipping.", TEST_ENABLED
|
||||
};
|
||||
|
||||
/* Sequence of Surface test cases */
|
||||
static const SDLTest_TestCaseReference *surfaceTests[] = {
|
||||
&surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5,
|
||||
&surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10,
|
||||
&surfaceTest11, &surfaceTest12, &surfaceTestOverflow, NULL
|
||||
&surfaceTest11, &surfaceTest12, &surfaceTestOverflow, &surfaceTestFlip, NULL
|
||||
};
|
||||
|
||||
/* Surface test suite (global) */
|
||||
|
|
Loading…
Reference in New Issue