Mercurial > sdl-ios-xcode
diff src/video/SDL_rect.c @ 1735:8dd28c4ef746 SDL-1.3
SDL_Rect now uses int for position and size.
Added a few more rectangle functions.
Added a dirty rectangle list implementation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 07:34:50 +0000 |
parents | |
children | 175754591a13 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/SDL_rect.c Mon Jul 10 07:34:50 2006 +0000 @@ -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: */