summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Lantinga <slouken@libsdl.org>2006-07-10 07:34:50 +0000
committerSam Lantinga <slouken@libsdl.org>2006-07-10 07:34:50 +0000
commit6206cb8693da9dfe0f7ee67d9c49162eb60b50c7 (patch)
treed6fe19c1f8605151b3b800a9158e26f979b96563
parent9a41213a7a298216b0c03364e0424b40acd423b0 (diff)
downloadsdl-6206cb8693da9dfe0f7ee67d9c49162eb60b50c7.tar.gz
SDL_Rect now uses int for position and size.
Added a few more rectangle functions. Added a dirty rectangle list implementation.
-rw-r--r--include/SDL_video.h51
-rw-r--r--src/SDL_compat.c2
-rw-r--r--src/video/SDL_rect.c189
-rw-r--r--src/video/SDL_rect_c.h41
-rw-r--r--src/video/SDL_renderer_sw.c35
-rw-r--r--src/video/SDL_surface.c46
-rw-r--r--src/video/SDL_video.c1
-rw-r--r--src/video/win32/SDL_win32modes.c1
8 files changed, 300 insertions, 66 deletions
diff --git a/include/SDL_video.h b/include/SDL_video.h
index 116907a13..a42187638 100644
--- a/include/SDL_video.h
+++ b/include/SDL_video.h
@@ -53,8 +53,8 @@ extern "C" {
*/
typedef struct SDL_Rect
{
- Sint16 x, y;
- Uint16 w, h;
+ int x, y;
+ int w, h;
} SDL_Rect;
/**
@@ -177,7 +177,8 @@ typedef enum
SDL_Renderer_PresentVSync = 0x00000010, /**< Present is synchronized with the refresh rate */
SDL_Renderer_RenderTarget = 0x00000020, /**< The renderer can create texture render targets */
SDL_Renderer_Accelerated = 0x00000040, /**< The renderer uses hardware acceleration */
- SDL_Renderer_Minimal = 0x00000080, /**< The renderer only supports the read/write pixel and present functions */
+ SDL_Renderer_ = 0x00000080, /**< The renderer uses hardware acceleration */
+ SDL_Renderer_Minimal = 0x00000100, /**< The renderer only supports the read/write pixel and present functions */
} SDL_RendererFlags;
/**
@@ -1525,12 +1526,50 @@ extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void);
*/
extern DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context);
-/*
- * Calculate the intersection of two rectangles
+/**
+ * \def SDL_RectEmpty()
+ *
+ * \brief Returns true if the rectangle has no area.
+ */
+#define SDL_RectEmpty(X) (((X)->w <= 0) || ((X)->h <= 0))
+
+/**
+ * \def SDL_RectEquals()
+ *
+ * \brief Returns true if the two rectangles are equal.
+ */
+#define SDL_RectEquals(A, B) (((A)->x == (B)->x) && ((A)->y == (B)->y) && \
+ ((A)->w == (B)->w) && ((A)->h == (B)->h))
+
+/**
+ * \fn SDL_bool SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B);
+ *
+ * \brief Determine whether two rectangles intersect.
+ *
+ * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A,
+ const SDL_Rect * B);
+
+/**
+ * \fn SDL_bool SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
+ *
+ * \brief Calculate the intersection of two rectangles.
+ *
+ * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A,
const SDL_Rect * B,
- SDL_Rect * intersection);
+ SDL_Rect * result);
+
+/**
+ * \fn void SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
+ *
+ * \brief Calculate the union of two rectangles
+ */
+extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A,
+ const SDL_Rect * B,
+ SDL_Rect * result);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
diff --git a/src/SDL_compat.c b/src/SDL_compat.c
index 3a88534ef..a9b7d7a66 100644
--- a/src/SDL_compat.c
+++ b/src/SDL_compat.c
@@ -307,8 +307,6 @@ GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{
- SDL_EventFilter filter;
- void *filterparam;
const SDL_DisplayMode *desktop_mode;
SDL_DisplayMode mode;
int window_x = SDL_WINDOWPOS_UNDEFINED;
diff --git a/src/video/SDL_rect.c b/src/video/SDL_rect.c
new file mode 100644
index 000000000..27c3ad86f
--- /dev/null
+++ b/src/video/SDL_rect.c
@@ -0,0 +1,189 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2006 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_video.h"
+#include "SDL_rect_c.h"
+
+SDL_bool
+SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ /* 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;
+}
+
+SDL_bool
+SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ /* Horizontal intersection */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ result->x = Amin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ result->w = Amax - Amin;
+
+ /* Vertical intersection */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if (Bmin > Amin)
+ Amin = Bmin;
+ result->y = Amin;
+ if (Bmax < Amax)
+ Amax = Bmax;
+ result->h = Amax - Amin;
+
+ return !SDL_RectEmpty(result);
+}
+
+void
+SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ /* Horizontal union */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if (Bmin < Amin)
+ Amin = Bmin;
+ result->x = Amin;
+ if (Bmax > Amax)
+ Amax = Bmax;
+ result->w = Amax - Amin;
+
+ /* Vertical intersection */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if (Bmin < Amin)
+ Amin = Bmin;
+ result->y = Amin;
+ if (Bmax > Amax)
+ Amax = Bmax;
+ result->h = Amax - Amin;
+}
+
+void
+SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect)
+{
+ SDL_DirtyRect *dirty;
+ SDL_DirtyRect *check, *prev, *next;
+
+ if (list->free) {
+ dirty = list->free;
+ list->free = dirty->next;
+ } else {
+ dirty = (SDL_DirtyRect *) SDL_malloc(sizeof(*dirty));
+ if (!dirty) {
+ return;
+ }
+ }
+ dirty->rect = *rect;
+
+ /* FIXME: At what point is this optimization too expensive? */
+ for (prev = NULL, check = list->list; check; check = next) {
+ next = check->next;
+
+ if (SDL_HasIntersection(&dirty->rect, &check->rect)) {
+ SDL_UnionRect(&dirty->rect, &check->rect, &dirty->rect);
+ if (prev) {
+ prev->next = next;
+ } else {
+ list->list = next;
+ }
+ check->next = list->free;
+ list->free = check;
+ --list->count;
+ } else {
+ prev = check;
+ }
+ }
+
+ dirty->next = list->list;
+ list->list = dirty;
+ ++list->count;
+}
+
+void
+SDL_ClearDirtyRects(SDL_DirtyRectList * list)
+{
+ while (list->list) {
+ SDL_DirtyRect *elem = list->list;
+ list->list = elem->next;
+ elem->next = list->free;
+ list->free = elem;
+ }
+ list->count = 0;
+}
+
+void
+SDL_FreeDirtyRects(SDL_DirtyRectList * list)
+{
+ while (list->list) {
+ SDL_DirtyRect *elem = list->list;
+ list->list = elem->next;
+ SDL_free(elem);
+ }
+ while (list->free) {
+ SDL_DirtyRect *elem = list->free;
+ list->free = elem->next;
+ SDL_free(elem);
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/SDL_rect_c.h b/src/video/SDL_rect_c.h
new file mode 100644
index 000000000..0f4d3bf06
--- /dev/null
+++ b/src/video/SDL_rect_c.h
@@ -0,0 +1,41 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2006 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+typedef struct SDL_DirtyRect
+{
+ SDL_Rect rect;
+ struct SDL_DirtyRect *next;
+} SDL_DirtyRect;
+
+typedef struct SDL_DirtyRectList
+{
+ int count;
+ SDL_DirtyRect *list;
+ SDL_DirtyRect *free;
+} SDL_DirtyRectList;
+
+extern void SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect);
+extern void SDL_ClearDirtyRects(SDL_DirtyRectList * list);
+extern void SDL_FreeDirtyRects(SDL_DirtyRectList * list);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/SDL_renderer_sw.c b/src/video/SDL_renderer_sw.c
index 6dbf24fc1..4cbbd4ca2 100644
--- a/src/video/SDL_renderer_sw.c
+++ b/src/video/SDL_renderer_sw.c
@@ -23,6 +23,7 @@
#include "SDL_video.h"
#include "SDL_sysvideo.h"
+#include "SDL_rect_c.h"
#include "SDL_yuv_sw_c.h"
@@ -96,8 +97,8 @@ SDL_RenderDriver SDL_SW_RenderDriver = {
SDL_PixelFormat_BGRA8888,
SDL_PixelFormat_YUY2,
SDL_PixelFormat_UYVY},
- 32768,
- 32768}
+ 0,
+ 0}
};
typedef struct
@@ -106,6 +107,7 @@ typedef struct
SDL_Surface *screens[3];
SDL_Surface *target;
SDL_Renderer *renderer;
+ SDL_DirtyRectList dirty;
} SDL_SW_RenderData;
SDL_Renderer *
@@ -125,12 +127,11 @@ SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}
- renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer));
+ renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
SDL_OutOfMemory();
return NULL;
}
- SDL_zerop(renderer);
data = (SDL_SW_RenderData *) SDL_malloc(sizeof(*data));
if (!data) {
@@ -363,6 +364,8 @@ SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
SDL_Rect real_rect = *rect;
Uint8 r, g, b, a;
+ SDL_AddDirtyRect(&data->dirty, rect);
+
a = (Uint8) ((color >> 24) & 0xFF);
r = (Uint8) ((color >> 16) & 0xFF);
g = (Uint8) ((color >> 8) & 0xFF);
@@ -381,6 +384,8 @@ SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+ SDL_AddDirtyRect(&data->dirty, dstrect);
+
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
SDL_Surface *target = data->target;
void *pixels =
@@ -445,6 +450,8 @@ SDL_SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
int row;
size_t length;
+ SDL_AddDirtyRect(&data->dirty, rect);
+
src = (Uint8 *) pixels;
dst =
(Uint8 *) surface->pixels + rect->y * surface->pitch +
@@ -463,19 +470,22 @@ SDL_SW_RenderPresent(SDL_Renderer * renderer)
{
SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
SDL_Surface *surface = data->screens[data->current_screen];
- SDL_Rect rect;
+ SDL_DirtyRect *dirty;
int new_screen;
/* Send the data to the display */
- /* FIXME: implement dirty rect updates */
- rect.x = 0;
- rect.y = 0;
- rect.w = surface->w;
- rect.h = surface->h;
- data->renderer->RenderWritePixels(data->renderer, &rect, surface->pixels,
- surface->pitch);
+ for (dirty = data->dirty.list; dirty; dirty = dirty->next) {
+ void *pixels =
+ (void *) ((Uint8 *) surface->pixels +
+ dirty->rect.y * surface->pitch +
+ dirty->rect.x * surface->format->BytesPerPixel);
+ data->renderer->RenderWritePixels(data->renderer, &dirty->rect,
+ pixels, surface->pitch);
+ }
+ SDL_ClearDirtyRects(&data->dirty);
data->renderer->RenderPresent(data->renderer);
+
/* Update the flipping chain, if any */
if (renderer->info.flags & SDL_Renderer_PresentFlip2) {
new_screen = (data->current_screen + 1) % 2;
@@ -514,6 +524,7 @@ SDL_SW_DestroyRenderer(SDL_Renderer * renderer)
SDL_FreeSurface(data->screens[i]);
}
}
+ SDL_FreeDirtyRects(&data->dirty);
SDL_free(data);
}
SDL_free(renderer);
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index e3c41eebc..87eae187a 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -41,14 +41,6 @@ SDL_CreateRGBSurface(Uint32 flags,
{
SDL_Surface *surface;
- /* FIXME!! */
- /* Make sure the size requested doesn't overflow our datatypes */
- /* Next time I write a library like SDL, I'll use int for size. :) */
- if (width >= 16384 || height >= 65536) {
- SDL_SetError("Width or height is too large");
- return NULL;
- }
-
/* Allocate the surface */
surface = (SDL_Surface *) SDL_malloc(sizeof(*surface));
if (surface == NULL) {
@@ -211,6 +203,7 @@ SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID)
surface->flags |= SDL_HWSURFACE;
surface->w = w;
surface->h = h;
+ surface->pitch = SDL_CalculatePitch(surface);
SDL_SetClipRect(surface, NULL);
}
}
@@ -415,43 +408,6 @@ SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value)
}
/*
- * A function to calculate the intersection of two rectangles:
- * return true if the rectangles intersect, false otherwise
- */
-SDL_bool
-SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B,
- SDL_Rect * intersection)
-{
- int Amin, Amax, Bmin, Bmax;
-
- /* Horizontal intersection */
- Amin = A->x;
- Amax = Amin + A->w;
- Bmin = B->x;
- Bmax = Bmin + B->w;
- if (Bmin > Amin)
- Amin = Bmin;
- intersection->x = Amin;
- if (Bmax < Amax)
- Amax = Bmax;
- intersection->w = Amax - Amin > 0 ? Amax - Amin : 0;
-
- /* Vertical intersection */
- Amin = A->y;
- Amax = Amin + A->h;
- Bmin = B->y;
- Bmax = Bmin + B->h;
- if (Bmin > Amin)
- Amin = Bmin;
- intersection->y = Amin;
- if (Bmax < Amax)
- Amax = Bmax;
- intersection->h = Amax - Amin > 0 ? Amax - Amin : 0;
-
- return (intersection->w && intersection->h);
-}
-
-/*
* Set the clipping rectangle for a blittable surface
*/
SDL_bool
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 0ea0b3b39..9b76c2069 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -1110,6 +1110,7 @@ SDL_SetWindowFullscreen(SDL_WindowID windowID, int fullscreen)
SDL_SetDisplayMode(NULL);
}
}
+ return 0;
}
void
diff --git a/src/video/win32/SDL_win32modes.c b/src/video/win32/SDL_win32modes.c
index 8a3efb682..c4a091750 100644
--- a/src/video/win32/SDL_win32modes.c
+++ b/src/video/win32/SDL_win32modes.c
@@ -135,7 +135,6 @@ WIN_InitModes(_THIS)
printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
#endif
for (j = 0;; ++j) {
- int index;
SDL_VideoDisplay display;
SDL_DisplayData *displaydata;
SDL_DisplayMode mode;