comparison 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
comparison
equal deleted inserted replaced
1734:f7c667ded87d 1735:8dd28c4ef746
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include "SDL_video.h"
25 #include "SDL_rect_c.h"
26
27 SDL_bool
28 SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
29 {
30 int Amin, Amax, Bmin, Bmax;
31
32 /* Horizontal intersection */
33 Amin = A->x;
34 Amax = Amin + A->w;
35 Bmin = B->x;
36 Bmax = Bmin + B->w;
37 if (Bmin > Amin)
38 Amin = Bmin;
39 if (Bmax < Amax)
40 Amax = Bmax;
41 if (Amax <= Amin)
42 return SDL_FALSE;
43
44 /* Vertical intersection */
45 Amin = A->y;
46 Amax = Amin + A->h;
47 Bmin = B->y;
48 Bmax = Bmin + B->h;
49 if (Bmin > Amin)
50 Amin = Bmin;
51 if (Bmax < Amax)
52 Amax = Bmax;
53 if (Amax <= Amin)
54 return SDL_FALSE;
55
56 return SDL_TRUE;
57 }
58
59 SDL_bool
60 SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
61 {
62 int Amin, Amax, Bmin, Bmax;
63
64 /* Horizontal intersection */
65 Amin = A->x;
66 Amax = Amin + A->w;
67 Bmin = B->x;
68 Bmax = Bmin + B->w;
69 if (Bmin > Amin)
70 Amin = Bmin;
71 result->x = Amin;
72 if (Bmax < Amax)
73 Amax = Bmax;
74 result->w = Amax - Amin;
75
76 /* Vertical intersection */
77 Amin = A->y;
78 Amax = Amin + A->h;
79 Bmin = B->y;
80 Bmax = Bmin + B->h;
81 if (Bmin > Amin)
82 Amin = Bmin;
83 result->y = Amin;
84 if (Bmax < Amax)
85 Amax = Bmax;
86 result->h = Amax - Amin;
87
88 return !SDL_RectEmpty(result);
89 }
90
91 void
92 SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
93 {
94 int Amin, Amax, Bmin, Bmax;
95
96 /* Horizontal union */
97 Amin = A->x;
98 Amax = Amin + A->w;
99 Bmin = B->x;
100 Bmax = Bmin + B->w;
101 if (Bmin < Amin)
102 Amin = Bmin;
103 result->x = Amin;
104 if (Bmax > Amax)
105 Amax = Bmax;
106 result->w = Amax - Amin;
107
108 /* Vertical intersection */
109 Amin = A->y;
110 Amax = Amin + A->h;
111 Bmin = B->y;
112 Bmax = Bmin + B->h;
113 if (Bmin < Amin)
114 Amin = Bmin;
115 result->y = Amin;
116 if (Bmax > Amax)
117 Amax = Bmax;
118 result->h = Amax - Amin;
119 }
120
121 void
122 SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect)
123 {
124 SDL_DirtyRect *dirty;
125 SDL_DirtyRect *check, *prev, *next;
126
127 if (list->free) {
128 dirty = list->free;
129 list->free = dirty->next;
130 } else {
131 dirty = (SDL_DirtyRect *) SDL_malloc(sizeof(*dirty));
132 if (!dirty) {
133 return;
134 }
135 }
136 dirty->rect = *rect;
137
138 /* FIXME: At what point is this optimization too expensive? */
139 for (prev = NULL, check = list->list; check; check = next) {
140 next = check->next;
141
142 if (SDL_HasIntersection(&dirty->rect, &check->rect)) {
143 SDL_UnionRect(&dirty->rect, &check->rect, &dirty->rect);
144 if (prev) {
145 prev->next = next;
146 } else {
147 list->list = next;
148 }
149 check->next = list->free;
150 list->free = check;
151 --list->count;
152 } else {
153 prev = check;
154 }
155 }
156
157 dirty->next = list->list;
158 list->list = dirty;
159 ++list->count;
160 }
161
162 void
163 SDL_ClearDirtyRects(SDL_DirtyRectList * list)
164 {
165 while (list->list) {
166 SDL_DirtyRect *elem = list->list;
167 list->list = elem->next;
168 elem->next = list->free;
169 list->free = elem;
170 }
171 list->count = 0;
172 }
173
174 void
175 SDL_FreeDirtyRects(SDL_DirtyRectList * list)
176 {
177 while (list->list) {
178 SDL_DirtyRect *elem = list->list;
179 list->list = elem->next;
180 SDL_free(elem);
181 }
182 while (list->free) {
183 SDL_DirtyRect *elem = list->free;
184 list->free = elem->next;
185 SDL_free(elem);
186 }
187 }
188
189 /* vi: set ts=4 sw=4 expandtab: */