summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan C. Gordon <icculus@icculus.org>2018-10-23 01:34:03 -0400
committerRyan C. Gordon <icculus@icculus.org>2018-10-23 01:34:03 -0400
commitccdaaae3e591521e7dbedeea4165d96a5981cdfa (patch)
treeb922412642860e45c5914ab4ce66efec1a93dc92
parent5d2733a5a4688c46b244cc31c4ab52517f2ab6a0 (diff)
downloadsdl-ccdaaae3e591521e7dbedeea4165d96a5981cdfa.tar.gz
render: Add floating point versions of various draw APIs.
-rw-r--r--include/SDL_rect.h30
-rw-r--r--include/SDL_render.h142
-rw-r--r--src/dynapi/SDL_dynapi_overrides.h10
-rw-r--r--src/dynapi/SDL_dynapi_procs.h10
-rw-r--r--src/render/SDL_render.c513
-rw-r--r--src/render/SDL_sysrender.h14
6 files changed, 643 insertions, 76 deletions
diff --git a/include/SDL_rect.h b/include/SDL_rect.h
index 543bb6186..986764cd6 100644
--- a/include/SDL_rect.h
+++ b/include/SDL_rect.h
@@ -40,7 +40,7 @@ extern "C" {
#endif
/**
- * \brief The structure that defines a point
+ * \brief The structure that defines a point (integer)
*
* \sa SDL_EnclosePoints
* \sa SDL_PointInRect
@@ -52,7 +52,20 @@ typedef struct SDL_Point
} SDL_Point;
/**
- * \brief A rectangle, with the origin at the upper left.
+ * \brief The structure that defines a point (floating point)
+ *
+ * \sa SDL_EnclosePoints
+ * \sa SDL_PointInRect
+ */
+typedef struct SDL_FPoint
+{
+ float x;
+ float y;
+} SDL_FPoint;
+
+
+/**
+ * \brief A rectangle, with the origin at the upper left (integer).
*
* \sa SDL_RectEmpty
* \sa SDL_RectEquals
@@ -67,6 +80,19 @@ typedef struct SDL_Rect
int w, h;
} SDL_Rect;
+
+/**
+ * \brief A rectangle, with the origin at the upper left (floating point).
+ */
+typedef struct SDL_FRect
+{
+ float x;
+ float y;
+ float w;
+ float h;
+} SDL_FRect;
+
+
/**
* \brief Returns true if point resides inside a rectangle.
*/
diff --git a/include/SDL_render.h b/include/SDL_render.h
index 850e908ec..738b7392a 100644
--- a/include/SDL_render.h
+++ b/include/SDL_render.h
@@ -835,6 +835,148 @@ extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer,
const SDL_Point *center,
const SDL_RendererFlip flip);
+
+/**
+ * \brief Draw a point on the current rendering target.
+ *
+ * \param renderer The renderer which should draw a point.
+ * \param x The x coordinate of the point.
+ * \param y The y coordinate of the point.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderDrawPointF(SDL_Renderer * renderer,
+ float x, float y);
+
+/**
+ * \brief Draw multiple points on the current rendering target.
+ *
+ * \param renderer The renderer which should draw multiple points.
+ * \param points The points to draw
+ * \param count The number of points to draw
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderDrawPointsF(SDL_Renderer * renderer,
+ const SDL_FPoint * points,
+ int count);
+
+/**
+ * \brief Draw a line on the current rendering target.
+ *
+ * \param renderer The renderer which should draw a line.
+ * \param x1 The x coordinate of the start point.
+ * \param y1 The y coordinate of the start point.
+ * \param x2 The x coordinate of the end point.
+ * \param y2 The y coordinate of the end point.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderDrawLineF(SDL_Renderer * renderer,
+ float x1, float y1, float x2, float y2);
+
+/**
+ * \brief Draw a series of connected lines on the current rendering target.
+ *
+ * \param renderer The renderer which should draw multiple lines.
+ * \param points The points along the lines
+ * \param count The number of points, drawing count-1 lines
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderDrawLinesF(SDL_Renderer * renderer,
+ const SDL_FPoint * points,
+ int count);
+
+/**
+ * \brief Draw a rectangle on the current rendering target.
+ *
+ * \param renderer The renderer which should draw a rectangle.
+ * \param rect A pointer to the destination rectangle, or NULL to outline the entire rendering target.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderDrawRectF(SDL_Renderer * renderer,
+ const SDL_FRect * rect);
+
+/**
+ * \brief Draw some number of rectangles on the current rendering target.
+ *
+ * \param renderer The renderer which should draw multiple rectangles.
+ * \param rects A pointer to an array of destination rectangles.
+ * \param count The number of rectangles.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderDrawRectsF(SDL_Renderer * renderer,
+ const SDL_FRect * rects,
+ int count);
+
+/**
+ * \brief Fill a rectangle on the current rendering target with the drawing color.
+ *
+ * \param renderer The renderer which should fill a rectangle.
+ * \param rect A pointer to the destination rectangle, or NULL for the entire
+ * rendering target.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderFillRectF(SDL_Renderer * renderer,
+ const SDL_FRect * rect);
+
+/**
+ * \brief Fill some number of rectangles on the current rendering target with the drawing color.
+ *
+ * \param renderer The renderer which should fill multiple rectangles.
+ * \param rects A pointer to an array of destination rectangles.
+ * \param count The number of rectangles.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderFillRectsF(SDL_Renderer * renderer,
+ const SDL_FRect * rects,
+ int count);
+
+/**
+ * \brief Copy a portion of the texture to the current rendering target.
+ *
+ * \param renderer The renderer which should copy parts of a texture.
+ * \param texture The source texture.
+ * \param srcrect A pointer to the source rectangle, or NULL for the entire
+ * texture.
+ * \param dstrect A pointer to the destination rectangle, or NULL for the
+ * entire rendering target.
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderCopyF(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * srcrect,
+ const SDL_FRect * dstrect);
+
+/**
+ * \brief Copy a portion of the source texture to the current rendering target, rotating it by angle around the given center
+ *
+ * \param renderer The renderer which should copy parts of a texture.
+ * \param texture The source texture.
+ * \param srcrect A pointer to the source rectangle, or NULL for the entire
+ * texture.
+ * \param dstrect A pointer to the destination rectangle, or NULL for the
+ * entire rendering target.
+ * \param angle An angle in degrees that indicates the rotation that will be applied to dstrect, rotating it in a clockwise direction
+ * \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 be performed on the texture
+ *
+ * \return 0 on success, or -1 on error
+ */
+extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * srcrect,
+ const SDL_FRect * dstrect,
+ const double angle,
+ const SDL_FPoint *center,
+ const SDL_RendererFlip flip);
+
/**
* \brief Read pixels from the current rendering target.
*
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 000604168..0bc6f44f0 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -697,3 +697,13 @@
#define SDL_IsTablet SDL_IsTablet_REAL
#define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL
#define SDL_RenderFlush SDL_RenderFlush_REAL
+#define SDL_RenderDrawPointF SDL_RenderDrawPointF_REAL
+#define SDL_RenderDrawPointsF SDL_RenderDrawPointsF_REAL
+#define SDL_RenderDrawLineF SDL_RenderDrawLineF_REAL
+#define SDL_RenderDrawLinesF SDL_RenderDrawLinesF_REAL
+#define SDL_RenderDrawRectF SDL_RenderDrawRectF_REAL
+#define SDL_RenderDrawRectsF SDL_RenderDrawRectsF_REAL
+#define SDL_RenderFillRectF SDL_RenderFillRectF_REAL
+#define SDL_RenderFillRectsF SDL_RenderFillRectsF_REAL
+#define SDL_RenderCopyF SDL_RenderCopyF_REAL
+#define SDL_RenderCopyExF SDL_RenderCopyExF_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 4461d5519..ce88ad9c0 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -739,3 +739,13 @@ SDL_DYNAPI_PROC(void,SDL_SensorUpdate,(void),(),)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsTablet,(void),(),return)
SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(int a),(a),return)
SDL_DYNAPI_PROC(int,SDL_RenderFlush,(SDL_Renderer *a),(a),return)
+SDL_DYNAPI_PROC(int,SDL_RenderDrawPointF,(SDL_Renderer *a, float b, float c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_RenderDrawPointsF,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_RenderDrawLineF,(SDL_Renderer *a, float b, float c, float d, float e),(a,b,c,d,e),return)
+SDL_DYNAPI_PROC(int,SDL_RenderDrawLinesF,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_RenderDrawRectF,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_RenderDrawRectsF,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_RenderFillRectF,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_RenderFillRectsF,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_RenderCopyF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(int,SDL_RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index b03524b4c..8d1ca56d8 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -2157,31 +2157,37 @@ SDL_RenderClear(SDL_Renderer * renderer)
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
+
+/* !!! FIXME: delete all the duplicate code for the integer versions in 2.1,
+ !!! FIXME: making the floating point versions the only available APIs. */
+
int
SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y)
{
- SDL_Point point;
- int retval;
+ const SDL_FPoint fpoint = { (float) x, (float) y };
+ return SDL_RenderDrawPointsF(renderer, &fpoint, 1);
+}
- point.x = x;
- point.y = y;
- retval = SDL_RenderDrawPoints(renderer, &point, 1);
- return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
+int
+SDL_RenderDrawPointF(SDL_Renderer * renderer, float x, float y)
+{
+ const SDL_FPoint fpoint = { x, y };
+ return SDL_RenderDrawPointsF(renderer, &fpoint, 1);
}
static int
RenderDrawPointsWithRects(SDL_Renderer * renderer,
- const SDL_Point * points, int count)
+ const SDL_Point * points, const int count)
{
- SDL_FRect *frects;
- int i;
int retval = -1;
SDL_bool isstack;
+ SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack);
+ int i;
- frects = SDL_small_alloc(SDL_FRect, count, &isstack);
if (!frects) {
return SDL_OutOfMemory();
}
+
for (i = 0; i < count; ++i) {
frects[i].x = points[i].x * renderer->scale.x;
frects[i].y = points[i].y * renderer->scale.y;
@@ -2239,21 +2245,148 @@ SDL_RenderDrawPoints(SDL_Renderer * renderer,
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
+static int
+RenderDrawPointsWithRectsF(SDL_Renderer * renderer,
+ const SDL_FPoint * fpoints, const int count)
+{
+ int retval = -1;
+ SDL_bool isstack;
+ SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack);
+ int i;
+
+ if (!frects) {
+ return SDL_OutOfMemory();
+ }
+
+ for (i = 0; i < count; ++i) {
+ frects[i].x = fpoints[i].x * renderer->scale.x;
+ frects[i].y = fpoints[i].y * renderer->scale.y;
+ frects[i].w = renderer->scale.x;
+ frects[i].h = renderer->scale.y;
+ }
+
+ retval = QueueCmdFillRects(renderer, frects, count);
+
+ SDL_small_free(frects, isstack);
+
+ return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
+}
+
+int
+SDL_RenderDrawPointsF(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count)
+{
+ SDL_FPoint *fpoints;
+ int i;
+ int retval;
+ SDL_bool isstack;
+
+ CHECK_RENDERER_MAGIC(renderer, -1);
+
+ if (!points) {
+ return SDL_SetError("SDL_RenderDrawFPoints(): Passed NULL points");
+ }
+ if (count < 1) {
+ return 0;
+ }
+
+ /* Don't draw while we're hidden */
+ if (renderer->hidden) {
+ return 0;
+ }
+
+ if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
+ return RenderDrawPointsWithRectsF(renderer, points, count);
+ }
+
+ fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
+ if (!fpoints) {
+ return SDL_OutOfMemory();
+ }
+ for (i = 0; i < count; ++i) {
+ fpoints[i].x = points[i].x * renderer->scale.x;
+ fpoints[i].y = points[i].y * renderer->scale.y;
+ }
+
+ retval = QueueCmdDrawPoints(renderer, fpoints, count);
+
+ SDL_small_free(fpoints, isstack);
+
+ return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
+}
+
int
SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
{
- SDL_Point points[2];
+ const SDL_FPoint points[2] = { { (float) x1, (float) y1 }, { (float) x2, (float) y2 } };
+ return SDL_RenderDrawLinesF(renderer, points, 2);
+}
- points[0].x = x1;
- points[0].y = y1;
- points[1].x = x2;
- points[1].y = y2;
- return SDL_RenderDrawLines(renderer, points, 2);
+int
+SDL_RenderDrawLineF(SDL_Renderer * renderer, float x1, float y1, float x2, float y2)
+{
+ const SDL_FPoint points[2] = { { x1, y1 }, { x2, y2 } };
+ return SDL_RenderDrawLinesF(renderer, points, 2);
}
static int
RenderDrawLinesWithRects(SDL_Renderer * renderer,
- const SDL_Point * points, int count)
+ const SDL_Point * points, const int count)
+{
+ SDL_FRect *frect;
+ SDL_FRect *frects;
+ SDL_FPoint fpoints[2];
+ int i, nrects = 0;
+ int retval = 0;
+ SDL_bool isstack;
+
+ frects = SDL_small_alloc(SDL_FRect, count-1, &isstack);
+ if (!frects) {
+ return SDL_OutOfMemory();
+ }
+
+ for (i = 0; i < count-1; ++i) {
+ if (points[i].x == points[i+1].x) {
+ const int minY = SDL_min(points[i].y, points[i+1].y);
+ const int maxY = SDL_max(points[i].y, points[i+1].y);
+
+ frect = &frects[nrects++];
+ frect->x = points[i].x * renderer->scale.x;
+ frect->y = minY * renderer->scale.y;
+ frect->w = renderer->scale.x;
+ frect->h = (maxY - minY + 1) * renderer->scale.y;
+ } else if (points[i].y == points[i+1].y) {
+ const int minX = SDL_min(points[i].x, points[i+1].x);
+ const int maxX = SDL_max(points[i].x, points[i+1].x);
+
+ frect = &frects[nrects++];
+ frect->x = minX * renderer->scale.x;
+ frect->y = points[i].y * renderer->scale.y;
+ frect->w = (maxX - minX + 1) * renderer->scale.x;
+ frect->h = renderer->scale.y;
+ } else {
+ /* FIXME: We can't use a rect for this line... */
+ fpoints[0].x = points[i].x * renderer->scale.x;
+ fpoints[0].y = points[i].y * renderer->scale.y;
+ fpoints[1].x = points[i+1].x * renderer->scale.x;
+ fpoints[1].y = points[i+1].y * renderer->scale.y;
+ retval += QueueCmdDrawLines(renderer, fpoints, 2);
+ }
+ }
+
+ retval += QueueCmdFillRects(renderer, frects, nrects);
+
+ SDL_small_free(frects, isstack);
+
+ if (retval < 0) {
+ retval = -1;
+ }
+ return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
+}
+
+static int
+RenderDrawLinesWithRectsF(SDL_Renderer * renderer,
+ const SDL_FPoint * points, const int count)
{
SDL_FRect *frect;
SDL_FRect *frects;
@@ -2350,19 +2483,82 @@ SDL_RenderDrawLines(SDL_Renderer * renderer,
}
int
+SDL_RenderDrawLinesF(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count)
+{
+ SDL_FPoint *fpoints;
+ int i;
+ int retval;
+ SDL_bool isstack;
+
+ CHECK_RENDERER_MAGIC(renderer, -1);
+
+ if (!points) {
+ return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
+ }
+ if (count < 2) {
+ return 0;
+ }
+
+ /* Don't draw while we're hidden */
+ if (renderer->hidden) {
+ return 0;
+ }
+
+ if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
+ return RenderDrawLinesWithRectsF(renderer, points, count);
+ }
+
+ fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack);
+ if (!fpoints) {
+ return SDL_OutOfMemory();
+ }
+ for (i = 0; i < count; ++i) {
+ fpoints[i].x = points[i].x * renderer->scale.x;
+ fpoints[i].y = points[i].y * renderer->scale.y;
+ }
+
+ retval = QueueCmdDrawLines(renderer, fpoints, count);
+
+ SDL_small_free(fpoints, isstack);
+
+ return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
+}
+
+int
SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
- SDL_Rect full_rect;
- SDL_Point points[5];
+ SDL_FRect frect;
+ SDL_FRect *prect = NULL;
+
+ if (rect) {
+ frect.x = (float) rect->x;
+ frect.y = (float) rect->y;
+ frect.w = (float) rect->w;
+ frect.h = (float) rect->h;
+ prect = &frect;
+ }
+
+ return SDL_RenderDrawRectF(renderer, prect);
+}
+
+int
+SDL_RenderDrawRectF(SDL_Renderer * renderer, const SDL_FRect * rect)
+{
+ SDL_FRect frect;
+ SDL_FPoint points[5];
CHECK_RENDERER_MAGIC(renderer, -1);
/* If 'rect' == NULL, then outline the whole surface */
if (!rect) {
- SDL_RenderGetViewport(renderer, &full_rect);
- full_rect.x = 0;
- full_rect.y = 0;
- rect = &full_rect;
+ SDL_Rect r;
+ SDL_RenderGetViewport(renderer, &r);
+ frect.x = 0.0f;
+ frect.y = 0.0f;
+ frect.w = (float) r.w;
+ frect.h = (float) r.h;
+ rect = &frect;
}
points[0].x = rect->x;
@@ -2375,7 +2571,7 @@ SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)
points[3].y = rect->y+rect->h-1;
points[4].x = rect->x;
points[4].y = rect->y;
- return SDL_RenderDrawLines(renderer, points, 5);
+ return SDL_RenderDrawLinesF(renderer, points, 5);
}
int
@@ -2407,20 +2603,75 @@ SDL_RenderDrawRects(SDL_Renderer * renderer,
}
int
+SDL_RenderDrawRectsF(SDL_Renderer * renderer,
+ const SDL_FRect * rects, int count)
+{
+ int i;
+
+ CHECK_RENDERER_MAGIC(renderer, -1);
+
+ if (!rects) {
+ return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
+ }
+ if (count < 1) {
+ return 0;
+ }
+
+ /* Don't draw while we're hidden */
+ if (renderer->hidden) {
+ return 0;
+ }
+
+ for (i = 0; i < count; ++i) {
+ if (SDL_RenderDrawRectF(renderer, &rects[i]) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
- SDL_Rect full_rect = { 0, 0, 0, 0 };
+ SDL_FRect frect;
+
+ CHECK_RENDERER_MAGIC(renderer, -1);
+
+ /* If 'rect' == NULL, then outline the whole surface */
+ if (rect) {
+ frect.x = (float) rect->x;
+ frect.y = (float) rect->y;
+ frect.w = (float) rect->w;
+ frect.h = (float) rect->h;
+ } else {
+ SDL_Rect r;
+ SDL_RenderGetViewport(renderer, &r);
+ frect.x = 0.0f;
+ frect.y = 0.0f;
+ frect.w = (float) r.w;
+ frect.h = (float) r.h;
+ }
+ return SDL_RenderFillRectsF(renderer, &frect, 1);
+}
+
+int
+SDL_RenderFillRectF(SDL_Renderer * renderer, const SDL_FRect * rect)
+{
+ SDL_FRect frect;
CHECK_RENDERER_MAGIC(renderer, -1);
/* If 'rect' == NULL, then outline the whole surface */
if (!rect) {
- SDL_RenderGetViewport(renderer, &full_rect);
- full_rect.x = 0;
- full_rect.y = 0;
- rect = &full_rect;
+ SDL_Rect r;
+ SDL_RenderGetViewport(renderer, &r);
+ frect.x = 0.0f;
+ frect.y = 0.0f;
+ frect.w = (float) r.w;
+ frect.h = (float) r.h;
+ rect = &frect;
}
- return SDL_RenderFillRects(renderer, rect, 1);
+ return SDL_RenderFillRectsF(renderer, rect, 1);
}
int
@@ -2465,12 +2716,123 @@ SDL_RenderFillRects(SDL_Renderer * renderer,
}
int
+SDL_RenderFillRectsF(SDL_Renderer * renderer,
+ const SDL_FRect * rects, int count)
+{
+ SDL_FRect *frects;
+ int i;
+ int retval;
+ SDL_bool isstack;
+
+ CHECK_RENDERER_MAGIC(renderer, -1);
+
+ if (!rects) {
+ return SDL_SetError("SDL_RenderFillFRects(): Passed NULL rects");
+ }
+ if (count < 1) {
+ return 0;
+ }
+
+ /* Don't draw while we're hidden */
+ if (renderer->hidden) {
+ return 0;
+ }
+
+ frects = SDL_small_alloc(SDL_FRect, count, &isstack);
+ if (!frects) {
+ return SDL_OutOfMemory();
+ }
+ for (i = 0; i < count; ++i) {
+ frects[i].x = rects[i].x * renderer->scale.x;
+ frects[i].y = rects[i].y * renderer->scale.y;
+ frects[i].w = rects[i].w * renderer->scale.x;
+ frects[i].h = rects[i].h * renderer->scale.y;
+ }
+
+ retval = QueueCmdFillRects(renderer, frects, count);
+
+ SDL_small_free(frects, isstack);
+
+ return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
+}
+
+/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
+SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
+{
+ return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE;
+}
+
+/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
+static SDL_bool
+SDL_HasIntersectionF(const SDL_FRect * A, const SDL_FRect * B)
+{
+ float Amin, Amax, Bmin, Bmax;
+
+ if (!A) {
+ SDL_InvalidParamError("A");
+ return SDL_FALSE;
+ }
+
+ if (!B) {
+ SDL_InvalidParamError("B");
+ return SDL_FALSE;
+ }
+
+ /* Special cases for empty rects */
+ if (SDL_FRectEmpty(A) || SDL_FRectEmpty(B)) {
+ return SDL_FALSE;
+ }
+
+ /* Horizontal intersection */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ if (Amax <= Amin)
+ return SDL_FALSE;
+
+ /* Vertical intersection */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ if (Amax <= Amin)
+ return SDL_FALSE;
+
+ return SDL_TRUE;
+}
+
+int
SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
- SDL_Rect real_srcrect = { 0, 0, 0, 0 };
- SDL_Rect real_dstrect = { 0, 0, 0, 0 };
- SDL_FRect frect;
+ SDL_FRect dstfrect;
+ SDL_FRect *pdstfrect = NULL;
+ if (dstrect) {
+ dstfrect.x = (float) dstrect->x;
+ dstfrect.y = (float) dstrect->y;
+ dstfrect.w = (float) dstrect->w;
+ dstfrect.h = (float) dstrect->h;
+ pdstfrect = &dstfrect;
+ }
+ return SDL_RenderCopyF(renderer, texture, srcrect, pdstfrect);
+}
+
+int
+SDL_RenderCopyF(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect)
+{
+ SDL_Rect real_srcrect;
+ SDL_FRect real_dstrect;
+ SDL_Rect r;
int retval;
CHECK_RENDERER_MAGIC(renderer, -1);
@@ -2495,11 +2857,13 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
}
}
- SDL_RenderGetViewport(renderer, &real_dstrect);
- real_dstrect.x = 0;
- real_dstrect.y = 0;
+ SDL_RenderGetViewport(renderer, &r);
+ real_dstrect.x = 0.0f;
+ real_dstrect.y = 0.0f;
+ real_dstrect.w = (float) r.w;
+ real_dstrect.h = (float) r.h;
if (dstrect) {
- if (!SDL_HasIntersection(dstrect, &real_dstrect)) {
+ if (!SDL_HasIntersectionF(dstrect, &real_dstrect)) {
return 0;
}
real_dstrect = *dstrect;
@@ -2509,31 +2873,56 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
texture = texture->native;
}
- frect.x = real_dstrect.x * renderer->scale.x;
- frect.y = real_dstrect.y * renderer->scale.y;
- frect.w = real_dstrect.w * renderer->scale.x;
- frect.h = real_dstrect.h * renderer->scale.y;
+ real_dstrect.x *= renderer->scale.x;
+ real_dstrect.y *= renderer->scale.y;
+ real_dstrect.w *= renderer->scale.x;
+ real_dstrect.h *= renderer->scale.y;
texture->last_command_generation = renderer->render_command_generation;
- retval = QueueCmdCopy(renderer, texture, &real_srcrect, &frect);
+ retval = QueueCmdCopy(renderer, texture, &real_srcrect, &real_dstrect);
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
-
int
SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect,
const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
{
- SDL_Rect real_srcrect = { 0, 0, 0, 0 };
- SDL_Rect real_dstrect = { 0, 0, 0, 0 };
- SDL_Point real_center;
- SDL_FRect frect;
+ SDL_FRect dstfrect;
+ SDL_FRect *pdstfrect = NULL;
SDL_FPoint fcenter;
+ SDL_FPoint *pfcenter = NULL;
+
+ if (dstrect) {
+ dstfrect.x = (float) dstrect->x;
+ dstfrect.y = (float) dstrect->y;
+ dstfrect.w = (float) dstrect->w;
+ dstfrect.h = (float) dstrect->h;
+ pdstfrect = &dstfrect;
+ }
+
+ if (center) {
+ fcenter.x = (float) center->x;
+ fcenter.y = (float) center->y;
+ pfcenter = &fcenter;
+ }
+
+ return SDL_RenderCopyExF(renderer, texture, srcrect, pdstfrect, angle, pfcenter, flip);
+}
+
+int
+SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect,
+ const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
+{
+ SDL_Rect real_srcrect;
+ SDL_FRect real_dstrect;
+ SDL_FPoint real_center;
+ int retval;
if (flip == SDL_FLIP_NONE && (int)(angle/360) == angle/360) { /* fast path when we don't need rotation or flipping */
- return SDL_RenderCopy(renderer, texture, srcrect, dstrect);
+ return SDL_RenderCopyF(renderer, texture, srcrect, dstrect);
}
CHECK_RENDERER_MAGIC(renderer, -1);
@@ -2565,9 +2954,12 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
if (dstrect) {
real_dstrect = *dstrect;
} else {
- SDL_RenderGetViewport(renderer, &real_dstrect);
- real_dstrect.x = 0;
- real_dstrect.y = 0;
+ SDL_Rect r;
+ SDL_RenderGetViewport(renderer, &r);
+ real_dstrect.x = 0.0f;
+ real_dstrect.y = 0.0f;
+ real_dstrect.w = (float) r.w;
+ real_dstrect.h = (float) r.h;
}
if (texture->native) {
@@ -2577,21 +2969,22 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
if (center) {
real_center = *center;
} else {
- real_center.x = real_dstrect.w/2;
- real_center.y = real_dstrect.h/2;
+ real_center.x = real_dstrect.w / 2.0f;
+ real_center.y = real_dstrect.h / 2.0f;
}
- frect.x = real_dstrect.x * renderer->scale.x;
- frect.y = real_dstrect.y * renderer->scale.y;
- frect.w = real_dstrect.w * renderer->scale.x;
- frect.h = real_dstrect.h * renderer->scale.y;
+ real_dstrect.x *= renderer->scale.x;
+ real_dstrect.y *= renderer->scale.y;
+ real_dstrect.w *= renderer->scale.x;
+ real_dstrect.h *= renderer->scale.y;
- fcenter.x = real_center.x * renderer->scale.x;
- fcenter.y = real_center.y * renderer->scale.y;
+ real_center.x *= renderer->scale.x;
+ real_center.y *= renderer->scale.y;
texture->last_command_generation = renderer->render_command_generation;
- return QueueCmdCopyEx(renderer, texture, &real_srcrect, &frect, angle, &fcenter, flip);
+ retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip);
+ return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
int
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index 240ce2de1..87586f1bb 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -39,20 +39,6 @@ typedef enum
SDL_ScaleModeBest
} SDL_ScaleMode;
-typedef struct
-{
- float x;
- float y;
-} SDL_FPoint;
-
-typedef struct
-{
- float x;
- float y;
- float w;
- float h;
-} SDL_FRect;
-
/* Define the SDL texture structure */
struct SDL_Texture
{