comparison src/video/SDL_surface.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents 84de7511f79f
children 6e7ec5cb83c3
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
32 32
33 /* Public routines */ 33 /* Public routines */
34 /* 34 /*
35 * Create an empty RGB surface of the appropriate depth 35 * Create an empty RGB surface of the appropriate depth
36 */ 36 */
37 SDL_Surface * SDL_CreateRGBSurface (Uint32 flags, 37 SDL_Surface *
38 int width, int height, int depth, 38 SDL_CreateRGBSurface (Uint32 flags,
39 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) 39 int width, int height, int depth,
40 { 40 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
41 SDL_VideoDevice *video = current_video; 41 {
42 SDL_VideoDevice *this = current_video; 42 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
43 SDL_Surface *screen; 43 SDL_Surface *screen;
44 SDL_Surface *surface; 44 SDL_Surface *surface;
45 45
46 /* Make sure the size requested doesn't overflow our datatypes */ 46 /* Make sure the size requested doesn't overflow our datatypes */
47 /* Next time I write a library like SDL, I'll use int for size. :) */ 47 /* Next time I write a library like SDL, I'll use int for size. :) */
48 if ( width >= 16384 || height >= 65536 ) { 48 if (width >= 16384 || height >= 65536) {
49 SDL_SetError("Width or height is too large"); 49 SDL_SetError ("Width or height is too large");
50 return(NULL); 50 return (NULL);
51 } 51 }
52 52
53 /* Check to see if we desire the surface in video memory */ 53 /* Check to see if we desire the surface in video memory */
54 if ( video ) { 54 if (_this) {
55 screen = SDL_PublicSurface; 55 screen = SDL_PublicSurface;
56 } else { 56 } else {
57 screen = NULL; 57 screen = NULL;
58 } 58 }
59 if ( screen && ((screen->flags&SDL_HWSURFACE) == SDL_HWSURFACE) ) { 59 if (screen && ((screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) {
60 if ( (flags&(SDL_SRCCOLORKEY|SDL_SRCALPHA)) != 0 ) { 60 if ((flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA)) != 0) {
61 flags |= SDL_HWSURFACE; 61 flags |= SDL_HWSURFACE;
62 } 62 }
63 if ( (flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 63 if ((flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
64 if ( ! current_video->info.blit_hw_CC ) { 64 if (!_this->info.blit_hw_CC) {
65 flags &= ~SDL_HWSURFACE; 65 flags &= ~SDL_HWSURFACE;
66 } 66 }
67 } 67 }
68 if ( (flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 68 if ((flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
69 if ( ! current_video->info.blit_hw_A ) { 69 if (!_this->info.blit_hw_A) {
70 flags &= ~SDL_HWSURFACE; 70 flags &= ~SDL_HWSURFACE;
71 } 71 }
72 } 72 }
73 } else { 73 } else {
74 flags &= ~SDL_HWSURFACE; 74 flags &= ~SDL_HWSURFACE;
75 } 75 }
76 76
77 /* Allocate the surface */ 77 /* Allocate the surface */
78 surface = (SDL_Surface *)SDL_malloc(sizeof(*surface)); 78 surface = (SDL_Surface *) SDL_malloc (sizeof (*surface));
79 if ( surface == NULL ) { 79 if (surface == NULL) {
80 SDL_OutOfMemory(); 80 SDL_OutOfMemory ();
81 return(NULL); 81 return (NULL);
82 } 82 }
83 surface->flags = SDL_SWSURFACE; 83 surface->flags = SDL_SWSURFACE;
84 if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { 84 if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
85 if ((Amask) && (video->displayformatalphapixel)) 85 if ((Amask) && (_this->displayformatalphapixel)) {
86 { 86 depth = _this->displayformatalphapixel->BitsPerPixel;
87 depth = video->displayformatalphapixel->BitsPerPixel; 87 Rmask = _this->displayformatalphapixel->Rmask;
88 Rmask = video->displayformatalphapixel->Rmask; 88 Gmask = _this->displayformatalphapixel->Gmask;
89 Gmask = video->displayformatalphapixel->Gmask; 89 Bmask = _this->displayformatalphapixel->Bmask;
90 Bmask = video->displayformatalphapixel->Bmask; 90 Amask = _this->displayformatalphapixel->Amask;
91 Amask = video->displayformatalphapixel->Amask; 91 } else {
92 } 92 depth = screen->format->BitsPerPixel;
93 else 93 Rmask = screen->format->Rmask;
94 { 94 Gmask = screen->format->Gmask;
95 depth = screen->format->BitsPerPixel; 95 Bmask = screen->format->Bmask;
96 Rmask = screen->format->Rmask; 96 Amask = screen->format->Amask;
97 Gmask = screen->format->Gmask; 97 }
98 Bmask = screen->format->Bmask; 98 }
99 Amask = screen->format->Amask; 99 surface->format = SDL_AllocFormat (depth, Rmask, Gmask, Bmask, Amask);
100 } 100 if (surface->format == NULL) {
101 } 101 SDL_free (surface);
102 surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask); 102 return (NULL);
103 if ( surface->format == NULL ) { 103 }
104 SDL_free(surface); 104 if (Amask) {
105 return(NULL); 105 surface->flags |= SDL_SRCALPHA;
106 } 106 }
107 if ( Amask ) { 107 surface->w = width;
108 surface->flags |= SDL_SRCALPHA; 108 surface->h = height;
109 } 109 surface->pitch = SDL_CalculatePitch (surface);
110 surface->w = width; 110 surface->pixels = NULL;
111 surface->h = height; 111 surface->offset = 0;
112 surface->pitch = SDL_CalculatePitch(surface); 112 surface->hwdata = NULL;
113 surface->pixels = NULL; 113 surface->locked = 0;
114 surface->offset = 0; 114 surface->map = NULL;
115 surface->hwdata = NULL; 115 surface->unused1 = 0;
116 surface->locked = 0; 116 SDL_SetClipRect (surface, NULL);
117 surface->map = NULL; 117 SDL_FormatChanged (surface);
118 surface->unused1 = 0; 118
119 SDL_SetClipRect(surface, NULL); 119 /* Get the pixels */
120 SDL_FormatChanged(surface); 120 if (((flags & SDL_HWSURFACE) == SDL_SWSURFACE) ||
121 121 (_this->AllocHWSurface (_this, surface) < 0)) {
122 /* Get the pixels */ 122 if (surface->w && surface->h) {
123 if ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) || 123 surface->pixels = SDL_malloc (surface->h * surface->pitch);
124 (video->AllocHWSurface(this, surface) < 0) ) { 124 if (surface->pixels == NULL) {
125 if ( surface->w && surface->h ) { 125 SDL_FreeSurface (surface);
126 surface->pixels = SDL_malloc(surface->h*surface->pitch); 126 SDL_OutOfMemory ();
127 if ( surface->pixels == NULL ) { 127 return (NULL);
128 SDL_FreeSurface(surface); 128 }
129 SDL_OutOfMemory(); 129 /* This is important for bitmaps */
130 return(NULL); 130 SDL_memset (surface->pixels, 0, surface->h * surface->pitch);
131 } 131 }
132 /* This is important for bitmaps */ 132 }
133 SDL_memset(surface->pixels, 0, surface->h*surface->pitch); 133
134 } 134 /* Allocate an empty mapping */
135 } 135 surface->map = SDL_AllocBlitMap ();
136 136 if (surface->map == NULL) {
137 /* Allocate an empty mapping */ 137 SDL_FreeSurface (surface);
138 surface->map = SDL_AllocBlitMap(); 138 return (NULL);
139 if ( surface->map == NULL ) { 139 }
140 SDL_FreeSurface(surface); 140
141 return(NULL); 141 /* The surface is ready to go */
142 } 142 surface->refcount = 1;
143
144 /* The surface is ready to go */
145 surface->refcount = 1;
146 #ifdef CHECK_LEAKS 143 #ifdef CHECK_LEAKS
147 ++surfaces_allocated; 144 ++surfaces_allocated;
148 #endif 145 #endif
149 return(surface); 146 return (surface);
150 } 147 }
148
151 /* 149 /*
152 * Create an RGB surface from an existing memory buffer 150 * Create an RGB surface from an existing memory buffer
153 */ 151 */
154 SDL_Surface * SDL_CreateRGBSurfaceFrom (void *pixels, 152 SDL_Surface *
155 int width, int height, int depth, int pitch, 153 SDL_CreateRGBSurfaceFrom (void *pixels,
156 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) 154 int width, int height, int depth, int pitch,
157 { 155 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
158 SDL_Surface *surface; 156 Uint32 Amask)
159 157 {
160 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, depth, 158 SDL_Surface *surface;
161 Rmask, Gmask, Bmask, Amask); 159
162 if ( surface != NULL ) { 160 surface = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0, depth,
163 surface->flags |= SDL_PREALLOC; 161 Rmask, Gmask, Bmask, Amask);
164 surface->pixels = pixels; 162 if (surface != NULL) {
165 surface->w = width; 163 surface->flags |= SDL_PREALLOC;
166 surface->h = height; 164 surface->pixels = pixels;
167 surface->pitch = pitch; 165 surface->w = width;
168 SDL_SetClipRect(surface, NULL); 166 surface->h = height;
169 } 167 surface->pitch = pitch;
170 return(surface); 168 SDL_SetClipRect (surface, NULL);
171 } 169 }
170 return (surface);
171 }
172
172 /* 173 /*
173 * Set the color key in a blittable surface 174 * Set the color key in a blittable surface
174 */ 175 */
175 int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key) 176 int
176 { 177 SDL_SetColorKey (SDL_Surface * surface, Uint32 flag, Uint32 key)
177 /* Sanity check the flag as it gets passed in */ 178 {
178 if ( flag & SDL_SRCCOLORKEY ) { 179 /* Sanity check the flag as it gets passed in */
179 if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { 180 if (flag & SDL_SRCCOLORKEY) {
180 flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); 181 if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) {
181 } else { 182 flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
182 flag = SDL_SRCCOLORKEY; 183 } else {
183 } 184 flag = SDL_SRCCOLORKEY;
184 } else { 185 }
185 flag = 0; 186 } else {
186 } 187 flag = 0;
187 188 }
188 /* Optimize away operations that don't change anything */ 189
189 if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) && 190 /* Optimize away operations that don't change anything */
190 (key == surface->format->colorkey) ) { 191 if ((flag == (surface->flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK))) &&
191 return(0); 192 (key == surface->format->colorkey)) {
192 } 193 return (0);
193 194 }
194 /* UnRLE surfaces before we change the colorkey */ 195
195 if ( surface->flags & SDL_RLEACCEL ) { 196 /* UnRLE surfaces before we change the colorkey */
196 SDL_UnRLESurface(surface, 1); 197 if (surface->flags & SDL_RLEACCEL) {
197 } 198 SDL_UnRLESurface (surface, 1);
198 199 }
199 if ( flag ) { 200
200 SDL_VideoDevice *video = current_video; 201 if (flag) {
201 SDL_VideoDevice *this = current_video; 202 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
202 203
203 204 surface->flags |= SDL_SRCCOLORKEY;
204 surface->flags |= SDL_SRCCOLORKEY; 205 surface->format->colorkey = key;
205 surface->format->colorkey = key; 206 if ((surface->flags & SDL_HWACCEL) == SDL_HWACCEL) {
206 if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { 207 if ((_this->SetHWColorKey == NULL) ||
207 if ( (video->SetHWColorKey == NULL) || 208 (_this->SetHWColorKey (_this, surface, key) < 0)) {
208 (video->SetHWColorKey(this, surface, key) < 0) ) { 209 surface->flags &= ~SDL_HWACCEL;
209 surface->flags &= ~SDL_HWACCEL; 210 }
210 } 211 }
211 } 212 if (flag & SDL_RLEACCELOK) {
212 if ( flag & SDL_RLEACCELOK ) { 213 surface->flags |= SDL_RLEACCELOK;
213 surface->flags |= SDL_RLEACCELOK; 214 } else {
214 } else { 215 surface->flags &= ~SDL_RLEACCELOK;
215 surface->flags &= ~SDL_RLEACCELOK; 216 }
216 } 217 } else {
217 } else { 218 surface->flags &= ~(SDL_SRCCOLORKEY | SDL_RLEACCELOK);
218 surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK); 219 surface->format->colorkey = 0;
219 surface->format->colorkey = 0; 220 }
220 } 221 SDL_InvalidateMap (surface->map);
221 SDL_InvalidateMap(surface->map); 222 return (0);
222 return(0); 223 }
223 } 224
224 /* This function sets the alpha channel of a surface */ 225 /* This function sets the alpha channel of a surface */
225 int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value) 226 int
226 { 227 SDL_SetAlpha (SDL_Surface * surface, Uint32 flag, Uint8 value)
227 Uint32 oldflags = surface->flags; 228 {
228 Uint32 oldalpha = surface->format->alpha; 229 Uint32 oldflags = surface->flags;
229 230 Uint32 oldalpha = surface->format->alpha;
230 /* Sanity check the flag as it gets passed in */ 231
231 if ( flag & SDL_SRCALPHA ) { 232 /* Sanity check the flag as it gets passed in */
232 if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { 233 if (flag & SDL_SRCALPHA) {
233 flag = (SDL_SRCALPHA | SDL_RLEACCELOK); 234 if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) {
234 } else { 235 flag = (SDL_SRCALPHA | SDL_RLEACCELOK);
235 flag = SDL_SRCALPHA; 236 } else {
236 } 237 flag = SDL_SRCALPHA;
237 } else { 238 }
238 flag = 0; 239 } else {
239 } 240 flag = 0;
240 241 }
241 /* Optimize away operations that don't change anything */ 242
242 if ( (flag == (surface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK))) && 243 /* Optimize away operations that don't change anything */
243 (!flag || value == oldalpha) ) { 244 if ((flag == (surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK))) &&
244 return(0); 245 (!flag || value == oldalpha)) {
245 } 246 return (0);
246 247 }
247 if(!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) 248
248 SDL_UnRLESurface(surface, 1); 249 if (!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL))
249 250 SDL_UnRLESurface (surface, 1);
250 if ( flag ) { 251
251 SDL_VideoDevice *video = current_video; 252 if (flag) {
252 SDL_VideoDevice *this = current_video; 253 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
253 254
254 surface->flags |= SDL_SRCALPHA; 255 surface->flags |= SDL_SRCALPHA;
255 surface->format->alpha = value; 256 surface->format->alpha = value;
256 if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { 257 if ((surface->flags & SDL_HWACCEL) == SDL_HWACCEL) {
257 if ( (video->SetHWAlpha == NULL) || 258 if ((_this->SetHWAlpha == NULL) ||
258 (video->SetHWAlpha(this, surface, value) < 0) ) { 259 (_this->SetHWAlpha (_this, surface, value) < 0)) {
259 surface->flags &= ~SDL_HWACCEL; 260 surface->flags &= ~SDL_HWACCEL;
260 } 261 }
261 } 262 }
262 if ( flag & SDL_RLEACCELOK ) { 263 if (flag & SDL_RLEACCELOK) {
263 surface->flags |= SDL_RLEACCELOK; 264 surface->flags |= SDL_RLEACCELOK;
264 } else { 265 } else {
265 surface->flags &= ~SDL_RLEACCELOK; 266 surface->flags &= ~SDL_RLEACCELOK;
266 } 267 }
267 } else { 268 } else {
268 surface->flags &= ~SDL_SRCALPHA; 269 surface->flags &= ~SDL_SRCALPHA;
269 surface->format->alpha = SDL_ALPHA_OPAQUE; 270 surface->format->alpha = SDL_ALPHA_OPAQUE;
270 } 271 }
271 /* 272 /*
272 * The representation for software surfaces is independent of 273 * The representation for software surfaces is independent of
273 * per-surface alpha, so no need to invalidate the blit mapping 274 * per-surface alpha, so no need to invalidate the blit mapping
274 * if just the alpha value was changed. (If either is 255, we still 275 * if just the alpha value was changed. (If either is 255, we still
275 * need to invalidate.) 276 * need to invalidate.)
276 */ 277 */
277 if((surface->flags & SDL_HWACCEL) == SDL_HWACCEL 278 if ((surface->flags & SDL_HWACCEL) == SDL_HWACCEL
278 || oldflags != surface->flags 279 || oldflags != surface->flags
279 || (((oldalpha + 1) ^ (value + 1)) & 0x100)) 280 || (((oldalpha + 1) ^ (value + 1)) & 0x100))
280 SDL_InvalidateMap(surface->map); 281 SDL_InvalidateMap (surface->map);
281 return(0); 282 return (0);
282 } 283 }
283 int SDL_SetAlphaChannel(SDL_Surface *surface, Uint8 value) 284
284 { 285 int
285 int row, col; 286 SDL_SetAlphaChannel (SDL_Surface * surface, Uint8 value)
286 int offset; 287 {
287 Uint8 *buf; 288 int row, col;
288 289 int offset;
289 if ( (surface->format->Amask != 0xFF000000) && 290 Uint8 *buf;
290 (surface->format->Amask != 0x000000FF) ) { 291
291 SDL_SetError("Unsupported surface alpha mask format"); 292 if ((surface->format->Amask != 0xFF000000) &&
292 return -1; 293 (surface->format->Amask != 0x000000FF)) {
293 } 294 SDL_SetError ("Unsupported surface alpha mask format");
294 295 return -1;
296 }
295 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 297 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
296 if ( surface->format->Amask == 0xFF000000 ) { 298 if (surface->format->Amask == 0xFF000000) {
297 offset = 3; 299 offset = 3;
298 } else { 300 } else {
299 offset = 0; 301 offset = 0;
300 } 302 }
301 #else 303 #else
302 if ( surface->format->Amask == 0xFF000000 ) { 304 if (surface->format->Amask == 0xFF000000) {
303 offset = 0; 305 offset = 0;
304 } else { 306 } else {
305 offset = 3; 307 offset = 3;
306 } 308 }
307 #endif /* Byte ordering */ 309 #endif /* Byte ordering */
308 310
309 /* Quickly set the alpha channel of an RGBA or ARGB surface */ 311 /* Quickly set the alpha channel of an RGBA or ARGB surface */
310 if ( SDL_MUSTLOCK(surface) ) { 312 if (SDL_MUSTLOCK (surface)) {
311 if ( SDL_LockSurface(surface) < 0 ) { 313 if (SDL_LockSurface (surface) < 0) {
312 return -1; 314 return -1;
313 } 315 }
314 } 316 }
315 row = surface->h; 317 row = surface->h;
316 while (row--) { 318 while (row--) {
317 col = surface->w; 319 col = surface->w;
318 buf = (Uint8 *)surface->pixels + row * surface->pitch + offset; 320 buf = (Uint8 *) surface->pixels + row * surface->pitch + offset;
319 while(col--) { 321 while (col--) {
320 *buf = value; 322 *buf = value;
321 buf += 4; 323 buf += 4;
322 } 324 }
323 } 325 }
324 if ( SDL_MUSTLOCK(surface) ) { 326 if (SDL_MUSTLOCK (surface)) {
325 SDL_UnlockSurface(surface); 327 SDL_UnlockSurface (surface);
326 } 328 }
327 return 0; 329 return 0;
328 } 330 }
329 331
330 /* 332 /*
331 * A function to calculate the intersection of two rectangles: 333 * A function to calculate the intersection of two rectangles:
332 * return true if the rectangles intersect, false otherwise 334 * return true if the rectangles intersect, false otherwise
333 */ 335 */
334 static __inline__ 336 static __inline__ SDL_bool
335 SDL_bool SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *intersection) 337 SDL_IntersectRect (const SDL_Rect * A, const SDL_Rect * B,
336 { 338 SDL_Rect * intersection)
337 int Amin, Amax, Bmin, Bmax; 339 {
338 340 int Amin, Amax, Bmin, Bmax;
339 /* Horizontal intersection */ 341
340 Amin = A->x; 342 /* Horizontal intersection */
341 Amax = Amin + A->w; 343 Amin = A->x;
342 Bmin = B->x; 344 Amax = Amin + A->w;
343 Bmax = Bmin + B->w; 345 Bmin = B->x;
344 if(Bmin > Amin) 346 Bmax = Bmin + B->w;
345 Amin = Bmin; 347 if (Bmin > Amin)
346 intersection->x = Amin; 348 Amin = Bmin;
347 if(Bmax < Amax) 349 intersection->x = Amin;
348 Amax = Bmax; 350 if (Bmax < Amax)
349 intersection->w = Amax - Amin > 0 ? Amax - Amin : 0; 351 Amax = Bmax;
350 352 intersection->w = Amax - Amin > 0 ? Amax - Amin : 0;
351 /* Vertical intersection */ 353
352 Amin = A->y; 354 /* Vertical intersection */
353 Amax = Amin + A->h; 355 Amin = A->y;
354 Bmin = B->y; 356 Amax = Amin + A->h;
355 Bmax = Bmin + B->h; 357 Bmin = B->y;
356 if(Bmin > Amin) 358 Bmax = Bmin + B->h;
357 Amin = Bmin; 359 if (Bmin > Amin)
358 intersection->y = Amin; 360 Amin = Bmin;
359 if(Bmax < Amax) 361 intersection->y = Amin;
360 Amax = Bmax; 362 if (Bmax < Amax)
361 intersection->h = Amax - Amin > 0 ? Amax - Amin : 0; 363 Amax = Bmax;
362 364 intersection->h = Amax - Amin > 0 ? Amax - Amin : 0;
363 return (intersection->w && intersection->h); 365
364 } 366 return (intersection->w && intersection->h);
367 }
368
365 /* 369 /*
366 * Set the clipping rectangle for a blittable surface 370 * Set the clipping rectangle for a blittable surface
367 */ 371 */
368 SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect) 372 SDL_bool
369 { 373 SDL_SetClipRect (SDL_Surface * surface, const SDL_Rect * rect)
370 SDL_Rect full_rect; 374 {
371 375 SDL_Rect full_rect;
372 /* Don't do anything if there's no surface to act on */ 376
373 if ( ! surface ) { 377 /* Don't do anything if there's no surface to act on */
374 return SDL_FALSE; 378 if (!surface) {
375 } 379 return SDL_FALSE;
376 380 }
377 /* Set up the full surface rectangle */ 381
378 full_rect.x = 0; 382 /* Set up the full surface rectangle */
379 full_rect.y = 0; 383 full_rect.x = 0;
380 full_rect.w = surface->w; 384 full_rect.y = 0;
381 full_rect.h = surface->h; 385 full_rect.w = surface->w;
382 386 full_rect.h = surface->h;
383 /* Set the clipping rectangle */ 387
384 if ( ! rect ) { 388 /* Set the clipping rectangle */
385 surface->clip_rect = full_rect; 389 if (!rect) {
386 return 1; 390 surface->clip_rect = full_rect;
387 } 391 return 1;
388 return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect); 392 }
389 } 393 return SDL_IntersectRect (rect, &full_rect, &surface->clip_rect);
390 void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect) 394 }
391 { 395
392 if ( surface && rect ) { 396 void
393 *rect = surface->clip_rect; 397 SDL_GetClipRect (SDL_Surface * surface, SDL_Rect * rect)
394 } 398 {
395 } 399 if (surface && rect) {
400 *rect = surface->clip_rect;
401 }
402 }
403
396 /* 404 /*
397 * Set up a blit between two surfaces -- split into three parts: 405 * Set up a blit between two surfaces -- split into three parts:
398 * The upper part, SDL_UpperBlit(), performs clipping and rectangle 406 * The upper part, SDL_UpperBlit(), performs clipping and rectangle
399 * verification. The lower part is a pointer to a low level 407 * verification. The lower part is a pointer to a low level
400 * accelerated blitting function. 408 * accelerated blitting function.
402 * These parts are separated out and each used internally by this 410 * These parts are separated out and each used internally by this
403 * library in the optimimum places. They are exported so that if 411 * library in the optimimum places. They are exported so that if
404 * you know exactly what you are doing, you can optimize your code 412 * you know exactly what you are doing, you can optimize your code
405 * by calling the one(s) you need. 413 * by calling the one(s) you need.
406 */ 414 */
407 int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect, 415 int
408 SDL_Surface *dst, SDL_Rect *dstrect) 416 SDL_LowerBlit (SDL_Surface * src, SDL_Rect * srcrect,
409 { 417 SDL_Surface * dst, SDL_Rect * dstrect)
410 SDL_blit do_blit; 418 {
411 SDL_Rect hw_srcrect; 419 SDL_blit do_blit;
412 SDL_Rect hw_dstrect; 420
413 421 /* Check to make sure the blit mapping is valid */
414 /* Check to make sure the blit mapping is valid */ 422 if ((src->map->dst != dst) ||
415 if ( (src->map->dst != dst) || 423 (src->map->dst->format_version != src->map->format_version)) {
416 (src->map->dst->format_version != src->map->format_version) ) { 424 if (SDL_MapSurface (src, dst) < 0) {
417 if ( SDL_MapSurface(src, dst) < 0 ) { 425 return (-1);
418 return(-1); 426 }
419 } 427 }
420 } 428
421 429 /* Figure out which blitter to use */
422 /* Figure out which blitter to use */ 430 if ((src->flags & SDL_HWACCEL) == SDL_HWACCEL) {
423 if ( (src->flags & SDL_HWACCEL) == SDL_HWACCEL ) { 431 do_blit = src->map->hw_blit;
424 if ( src == SDL_VideoSurface ) { 432 } else {
425 hw_srcrect = *srcrect; 433 do_blit = src->map->sw_blit;
426 hw_srcrect.x += current_video->offset_x; 434 }
427 hw_srcrect.y += current_video->offset_y; 435 return (do_blit (src, srcrect, dst, dstrect));
428 srcrect = &hw_srcrect; 436 }
429 } 437
430 if ( dst == SDL_VideoSurface ) { 438
431 hw_dstrect = *dstrect; 439 int
432 hw_dstrect.x += current_video->offset_x; 440 SDL_UpperBlit (SDL_Surface * src, SDL_Rect * srcrect,
433 hw_dstrect.y += current_video->offset_y; 441 SDL_Surface * dst, SDL_Rect * dstrect)
434 dstrect = &hw_dstrect; 442 {
435 } 443 SDL_Rect fulldst;
436 do_blit = src->map->hw_blit; 444 int srcx, srcy, w, h;
437 } else { 445
438 do_blit = src->map->sw_blit; 446 /* Make sure the surfaces aren't locked */
439 } 447 if (!src || !dst) {
440 return(do_blit(src, srcrect, dst, dstrect)); 448 SDL_SetError ("SDL_UpperBlit: passed a NULL surface");
441 } 449 return (-1);
442 450 }
443 451 if (src->locked || dst->locked) {
444 int SDL_UpperBlit (SDL_Surface *src, SDL_Rect *srcrect, 452 SDL_SetError ("Surfaces must not be locked during blit");
445 SDL_Surface *dst, SDL_Rect *dstrect) 453 return (-1);
446 { 454 }
447 SDL_Rect fulldst; 455
448 int srcx, srcy, w, h; 456 /* If the destination rectangle is NULL, use the entire dest surface */
449 457 if (dstrect == NULL) {
450 /* Make sure the surfaces aren't locked */ 458 fulldst.x = fulldst.y = 0;
451 if ( ! src || ! dst ) { 459 dstrect = &fulldst;
452 SDL_SetError("SDL_UpperBlit: passed a NULL surface"); 460 }
453 return(-1); 461
454 } 462 /* clip the source rectangle to the source surface */
455 if ( src->locked || dst->locked ) { 463 if (srcrect) {
456 SDL_SetError("Surfaces must not be locked during blit"); 464 int maxw, maxh;
457 return(-1); 465
458 } 466 srcx = srcrect->x;
459 467 w = srcrect->w;
460 /* If the destination rectangle is NULL, use the entire dest surface */ 468 if (srcx < 0) {
461 if ( dstrect == NULL ) { 469 w += srcx;
462 fulldst.x = fulldst.y = 0; 470 dstrect->x -= srcx;
463 dstrect = &fulldst; 471 srcx = 0;
464 } 472 }
465 473 maxw = src->w - srcx;
466 /* clip the source rectangle to the source surface */ 474 if (maxw < w)
467 if(srcrect) { 475 w = maxw;
468 int maxw, maxh; 476
469 477 srcy = srcrect->y;
470 srcx = srcrect->x; 478 h = srcrect->h;
471 w = srcrect->w; 479 if (srcy < 0) {
472 if(srcx < 0) { 480 h += srcy;
473 w += srcx; 481 dstrect->y -= srcy;
474 dstrect->x -= srcx; 482 srcy = 0;
475 srcx = 0; 483 }
476 } 484 maxh = src->h - srcy;
477 maxw = src->w - srcx; 485 if (maxh < h)
478 if(maxw < w) 486 h = maxh;
479 w = maxw; 487
480 488 } else {
481 srcy = srcrect->y; 489 srcx = srcy = 0;
482 h = srcrect->h; 490 w = src->w;
483 if(srcy < 0) { 491 h = src->h;
484 h += srcy; 492 }
485 dstrect->y -= srcy; 493
486 srcy = 0; 494 /* clip the destination rectangle against the clip rectangle */
487 } 495 {
488 maxh = src->h - srcy; 496 SDL_Rect *clip = &dst->clip_rect;
489 if(maxh < h) 497 int dx, dy;
490 h = maxh; 498
491 499 dx = clip->x - dstrect->x;
492 } else { 500 if (dx > 0) {
493 srcx = srcy = 0; 501 w -= dx;
494 w = src->w; 502 dstrect->x += dx;
495 h = src->h; 503 srcx += dx;
496 } 504 }
497 505 dx = dstrect->x + w - clip->x - clip->w;
498 /* clip the destination rectangle against the clip rectangle */ 506 if (dx > 0)
499 { 507 w -= dx;
500 SDL_Rect *clip = &dst->clip_rect; 508
501 int dx, dy; 509 dy = clip->y - dstrect->y;
502 510 if (dy > 0) {
503 dx = clip->x - dstrect->x; 511 h -= dy;
504 if(dx > 0) { 512 dstrect->y += dy;
505 w -= dx; 513 srcy += dy;
506 dstrect->x += dx; 514 }
507 srcx += dx; 515 dy = dstrect->y + h - clip->y - clip->h;
508 } 516 if (dy > 0)
509 dx = dstrect->x + w - clip->x - clip->w; 517 h -= dy;
510 if(dx > 0) 518 }
511 w -= dx; 519
512 520 if (w > 0 && h > 0) {
513 dy = clip->y - dstrect->y; 521 SDL_Rect sr;
514 if(dy > 0) { 522 sr.x = srcx;
515 h -= dy; 523 sr.y = srcy;
516 dstrect->y += dy; 524 sr.w = dstrect->w = w;
517 srcy += dy; 525 sr.h = dstrect->h = h;
518 } 526 return SDL_LowerBlit (src, &sr, dst, dstrect);
519 dy = dstrect->y + h - clip->y - clip->h; 527 }
520 if(dy > 0) 528 dstrect->w = dstrect->h = 0;
521 h -= dy; 529 return 0;
522 } 530 }
523 531
524 if(w > 0 && h > 0) { 532 static int
525 SDL_Rect sr; 533 SDL_FillRect1 (SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
526 sr.x = srcx; 534 {
527 sr.y = srcy; 535 /* FIXME: We have to worry about packing order.. *sigh* */
528 sr.w = dstrect->w = w; 536 SDL_SetError ("1-bpp rect fill not yet implemented");
529 sr.h = dstrect->h = h; 537 return -1;
530 return SDL_LowerBlit(src, &sr, dst, dstrect); 538 }
531 } 539
532 dstrect->w = dstrect->h = 0; 540 static int
533 return 0; 541 SDL_FillRect4 (SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
534 } 542 {
535 543 /* FIXME: We have to worry about packing order.. *sigh* */
536 static int SDL_FillRect1(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) 544 SDL_SetError ("4-bpp rect fill not yet implemented");
537 { 545 return -1;
538 /* FIXME: We have to worry about packing order.. *sigh* */
539 SDL_SetError("1-bpp rect fill not yet implemented");
540 return -1;
541 }
542
543 static int SDL_FillRect4(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
544 {
545 /* FIXME: We have to worry about packing order.. *sigh* */
546 SDL_SetError("4-bpp rect fill not yet implemented");
547 return -1;
548 } 546 }
549 547
550 /* 548 /*
551 * This function performs a fast fill of the given rectangle with 'color' 549 * This function performs a fast fill of the given rectangle with 'color'
552 */ 550 */
553 int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) 551 int
554 { 552 SDL_FillRect (SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
555 SDL_VideoDevice *video = current_video; 553 {
556 SDL_VideoDevice *this = current_video; 554 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
557 int x, y; 555 int x, y;
558 Uint8 *row; 556 Uint8 *row;
559 557
560 /* This function doesn't work on surfaces < 8 bpp */ 558 /* This function doesn't work on surfaces < 8 bpp */
561 if ( dst->format->BitsPerPixel < 8 ) { 559 if (dst->format->BitsPerPixel < 8) {
562 switch(dst->format->BitsPerPixel) { 560 switch (dst->format->BitsPerPixel) {
563 case 1: 561 case 1:
564 return SDL_FillRect1(dst, dstrect, color); 562 return SDL_FillRect1 (dst, dstrect, color);
565 break; 563 break;
566 case 4: 564 case 4:
567 return SDL_FillRect4(dst, dstrect, color); 565 return SDL_FillRect4 (dst, dstrect, color);
568 break; 566 break;
569 default: 567 default:
570 SDL_SetError("Fill rect on unsupported surface format"); 568 SDL_SetError ("Fill rect on unsupported surface format");
571 return(-1); 569 return (-1);
572 break; 570 break;
573 } 571 }
574 } 572 }
575 573
576 /* If 'dstrect' == NULL, then fill the whole surface */ 574 /* If 'dstrect' == NULL, then fill the whole surface */
577 if ( dstrect ) { 575 if (dstrect) {
578 /* Perform clipping */ 576 /* Perform clipping */
579 if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) { 577 if (!SDL_IntersectRect (dstrect, &dst->clip_rect, dstrect)) {
580 return(0); 578 return (0);
581 } 579 }
582 } else { 580 } else {
583 dstrect = &dst->clip_rect; 581 dstrect = &dst->clip_rect;
584 } 582 }
585 583
586 /* Check for hardware acceleration */ 584 /* Check for hardware acceleration */
587 if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && 585 if (((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
588 video->info.blit_fill ) { 586 _this->info.blit_fill) {
589 SDL_Rect hw_rect; 587 return (_this->FillHWRect (_this, dst, dstrect, color));
590 if ( dst == SDL_VideoSurface ) { 588 }
591 hw_rect = *dstrect; 589
592 hw_rect.x += current_video->offset_x; 590 /* Perform software fill */
593 hw_rect.y += current_video->offset_y; 591 if (SDL_LockSurface (dst) != 0) {
594 dstrect = &hw_rect; 592 return (-1);
595 } 593 }
596 return(video->FillHWRect(this, dst, dstrect, color)); 594 row = (Uint8 *) dst->pixels + dstrect->y * dst->pitch +
597 } 595 dstrect->x * dst->format->BytesPerPixel;
598 596 if (dst->format->palette || (color == 0)) {
599 /* Perform software fill */ 597 x = dstrect->w * dst->format->BytesPerPixel;
600 if ( SDL_LockSurface(dst) != 0 ) { 598 if (!color && !((uintptr_t) row & 3) && !(x & 3)
601 return(-1); 599 && !(dst->pitch & 3)) {
602 } 600 int n = x >> 2;
603 row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+ 601 for (y = dstrect->h; y; --y) {
604 dstrect->x*dst->format->BytesPerPixel; 602 SDL_memset4 (row, 0, n);
605 if ( dst->format->palette || (color == 0) ) { 603 row += dst->pitch;
606 x = dstrect->w*dst->format->BytesPerPixel; 604 }
607 if ( !color && !((uintptr_t)row&3) && !(x&3) && !(dst->pitch&3) ) { 605 } else {
608 int n = x >> 2;
609 for ( y=dstrect->h; y; --y ) {
610 SDL_memset4(row, 0, n);
611 row += dst->pitch;
612 }
613 } else {
614 #ifdef __powerpc__ 606 #ifdef __powerpc__
615 /* 607 /*
616 * SDL_memset() on PPC (both glibc and codewarrior) uses 608 * SDL_memset() on PPC (both glibc and codewarrior) uses
617 * the dcbz (Data Cache Block Zero) instruction, which 609 * the dcbz (Data Cache Block Zero) instruction, which
618 * causes an alignment exception if the destination is 610 * causes an alignment exception if the destination is
619 * uncachable, so only use it on software surfaces 611 * uncachable, so only use it on software surfaces
620 */ 612 */
621 if((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { 613 if ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
622 if(dstrect->w >= 8) { 614 if (dstrect->w >= 8) {
623 /* 615 /*
624 * 64-bit stores are probably most 616 * 64-bit stores are probably most
625 * efficient to uncached video memory 617 * efficient to uncached video memory
626 */ 618 */
627 double fill; 619 double fill;
628 SDL_memset(&fill, color, (sizeof fill)); 620 SDL_memset (&fill, color, (sizeof fill));
629 for(y = dstrect->h; y; y--) { 621 for (y = dstrect->h; y; y--) {
630 Uint8 *d = row; 622 Uint8 *d = row;
631 unsigned n = x; 623 unsigned n = x;
632 unsigned nn; 624 unsigned nn;
633 Uint8 c = color; 625 Uint8 c = color;
634 double f = fill; 626 double f = fill;
635 while((unsigned long)d 627 while ((unsigned long) d & (sizeof (double) - 1)) {
636 & (sizeof(double) - 1)) { 628 *d++ = c;
637 *d++ = c; 629 n--;
638 n--; 630 }
639 } 631 nn = n / (sizeof (double) * 4);
640 nn = n / (sizeof(double) * 4); 632 while (nn) {
641 while(nn) { 633 ((double *) d)[0] = f;
642 ((double *)d)[0] = f; 634 ((double *) d)[1] = f;
643 ((double *)d)[1] = f; 635 ((double *) d)[2] = f;
644 ((double *)d)[2] = f; 636 ((double *) d)[3] = f;
645 ((double *)d)[3] = f; 637 d += 4 * sizeof (double);
646 d += 4*sizeof(double); 638 nn--;
647 nn--; 639 }
648 } 640 n &= ~(sizeof (double) * 4 - 1);
649 n &= ~(sizeof(double) * 4 - 1); 641 nn = n / sizeof (double);
650 nn = n / sizeof(double); 642 while (nn) {
651 while(nn) { 643 *(double *) d = f;
652 *(double *)d = f; 644 d += sizeof (double);
653 d += sizeof(double); 645 nn--;
654 nn--; 646 }
655 } 647 n &= ~(sizeof (double) - 1);
656 n &= ~(sizeof(double) - 1); 648 while (n) {
657 while(n) { 649 *d++ = c;
658 *d++ = c; 650 n--;
659 n--; 651 }
660 } 652 row += dst->pitch;
661 row += dst->pitch; 653 }
662 } 654 } else {
663 } else { 655 /* narrow boxes */
664 /* narrow boxes */ 656 for (y = dstrect->h; y; y--) {
665 for(y = dstrect->h; y; y--) { 657 Uint8 *d = row;
666 Uint8 *d = row; 658 Uint8 c = color;
667 Uint8 c = color; 659 int n = x;
668 int n = x; 660 while (n) {
669 while(n) { 661 *d++ = c;
670 *d++ = c; 662 n--;
671 n--; 663 }
672 } 664 row += dst->pitch;
673 row += dst->pitch; 665 }
674 } 666 }
675 } 667 } else
676 } else
677 #endif /* __powerpc__ */ 668 #endif /* __powerpc__ */
678 { 669 {
679 for(y = dstrect->h; y; y--) { 670 for (y = dstrect->h; y; y--) {
680 SDL_memset(row, color, x); 671 SDL_memset (row, color, x);
681 row += dst->pitch; 672 row += dst->pitch;
682 } 673 }
683 } 674 }
684 } 675 }
685 } else { 676 } else {
686 switch (dst->format->BytesPerPixel) { 677 switch (dst->format->BytesPerPixel) {
687 case 2: 678 case 2:
688 for ( y=dstrect->h; y; --y ) { 679 for (y = dstrect->h; y; --y) {
689 Uint16 *pixels = (Uint16 *)row; 680 Uint16 *pixels = (Uint16 *) row;
690 Uint16 c = (Uint16)color; 681 Uint16 c = (Uint16) color;
691 Uint32 cc = (Uint32)c << 16 | c; 682 Uint32 cc = (Uint32) c << 16 | c;
692 int n = dstrect->w; 683 int n = dstrect->w;
693 if((uintptr_t)pixels & 3) { 684 if ((uintptr_t) pixels & 3) {
694 *pixels++ = c; 685 *pixels++ = c;
695 n--; 686 n--;
696 } 687 }
697 if(n >> 1) 688 if (n >> 1)
698 SDL_memset4(pixels, cc, n >> 1); 689 SDL_memset4 (pixels, cc, n >> 1);
699 if(n & 1) 690 if (n & 1)
700 pixels[n - 1] = c; 691 pixels[n - 1] = c;
701 row += dst->pitch; 692 row += dst->pitch;
702 } 693 }
703 break; 694 break;
704 695
705 case 3: 696 case 3:
706 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 697 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
707 color <<= 8; 698 color <<= 8;
708 #endif 699 #endif
709 for ( y=dstrect->h; y; --y ) { 700 for (y = dstrect->h; y; --y) {
710 Uint8 *pixels = row; 701 Uint8 *pixels = row;
711 for ( x=dstrect->w; x; --x ) { 702 for (x = dstrect->w; x; --x) {
712 SDL_memcpy(pixels, &color, 3); 703 SDL_memcpy (pixels, &color, 3);
713 pixels += 3; 704 pixels += 3;
714 } 705 }
715 row += dst->pitch; 706 row += dst->pitch;
716 } 707 }
717 break; 708 break;
718 709
719 case 4: 710 case 4:
720 for(y = dstrect->h; y; --y) { 711 for (y = dstrect->h; y; --y) {
721 SDL_memset4(row, color, dstrect->w); 712 SDL_memset4 (row, color, dstrect->w);
722 row += dst->pitch; 713 row += dst->pitch;
723 } 714 }
724 break; 715 break;
725 } 716 }
726 } 717 }
727 SDL_UnlockSurface(dst); 718 SDL_UnlockSurface (dst);
728 719
729 /* We're done! */ 720 /* We're done! */
730 return(0); 721 return (0);
731 } 722 }
732 723
733 /* 724 /*
734 * Lock a surface to directly access the pixels 725 * Lock a surface to directly access the pixels
735 */ 726 */
736 int SDL_LockSurface (SDL_Surface *surface) 727 int
737 { 728 SDL_LockSurface (SDL_Surface * surface)
738 if ( ! surface->locked ) { 729 {
739 /* Perform the lock */ 730 if (!surface->locked) {
740 if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { 731 /* Perform the lock */
741 SDL_VideoDevice *video = current_video; 732 if (surface->flags & SDL_HWSURFACE) {
742 SDL_VideoDevice *this = current_video; 733 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
743 if ( video->LockHWSurface(this, surface) < 0 ) { 734 if (_this->LockHWSurface (_this, surface) < 0) {
744 return(-1); 735 return (-1);
745 } 736 }
746 } 737 }
747 if ( surface->flags & SDL_RLEACCEL ) { 738 if (surface->flags & SDL_RLEACCEL) {
748 SDL_UnRLESurface(surface, 1); 739 SDL_UnRLESurface (surface, 1);
749 surface->flags |= SDL_RLEACCEL; /* save accel'd state */ 740 surface->flags |= SDL_RLEACCEL; /* save accel'd state */
750 } 741 }
751 /* This needs to be done here in case pixels changes value */ 742 /* This needs to be done here in case pixels changes value */
752 surface->pixels = (Uint8 *)surface->pixels + surface->offset; 743 surface->pixels = (Uint8 *) surface->pixels + surface->offset;
753 } 744 }
754 745
755 /* Increment the surface lock count, for recursive locks */ 746 /* Increment the surface lock count, for recursive locks */
756 ++surface->locked; 747 ++surface->locked;
757 748
758 /* Ready to go.. */ 749 /* Ready to go.. */
759 return(0); 750 return (0);
760 } 751 }
752
761 /* 753 /*
762 * Unlock a previously locked surface 754 * Unlock a previously locked surface
763 */ 755 */
764 void SDL_UnlockSurface (SDL_Surface *surface) 756 void
765 { 757 SDL_UnlockSurface (SDL_Surface * surface)
766 /* Only perform an unlock if we are locked */ 758 {
767 if ( ! surface->locked || (--surface->locked > 0) ) { 759 /* Only perform an unlock if we are locked */
768 return; 760 if (!surface->locked || (--surface->locked > 0)) {
769 } 761 return;
770 762 }
771 /* Perform the unlock */ 763
772 surface->pixels = (Uint8 *)surface->pixels - surface->offset; 764 /* Perform the unlock */
773 765 surface->pixels = (Uint8 *) surface->pixels - surface->offset;
774 /* Unlock hardware or accelerated surfaces */ 766
775 if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { 767 /* Unlock hardware or accelerated surfaces */
776 SDL_VideoDevice *video = current_video; 768 if (surface->flags & SDL_HWSURFACE) {
777 SDL_VideoDevice *this = current_video; 769 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
778 video->UnlockHWSurface(this, surface); 770 _this->UnlockHWSurface (_this, surface);
779 } else { 771 } else {
780 /* Update RLE encoded surface with new data */ 772 /* Update RLE encoded surface with new data */
781 if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { 773 if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
782 surface->flags &= ~SDL_RLEACCEL; /* stop lying */ 774 surface->flags &= ~SDL_RLEACCEL; /* stop lying */
783 SDL_RLESurface(surface); 775 SDL_RLESurface (surface);
784 } 776 }
785 } 777 }
786 } 778 }
787 779
788 /* 780 /*
789 * Convert a surface into the specified pixel format. 781 * Convert a surface into the specified pixel format.
790 */ 782 */
791 SDL_Surface * SDL_ConvertSurface (SDL_Surface *surface, 783 SDL_Surface *
792 SDL_PixelFormat *format, Uint32 flags) 784 SDL_ConvertSurface (SDL_Surface * surface,
793 { 785 SDL_PixelFormat * format, Uint32 flags)
794 SDL_Surface *convert; 786 {
795 Uint32 colorkey = 0; 787 SDL_Surface *convert;
796 Uint8 alpha = 0; 788 Uint32 colorkey = 0;
797 Uint32 surface_flags; 789 Uint8 alpha = 0;
798 SDL_Rect bounds; 790 Uint32 surface_flags;
799 791 SDL_Rect bounds;
800 /* Check for empty destination palette! (results in empty image) */ 792
801 if ( format->palette != NULL ) { 793 /* Check for empty destination palette! (results in empty image) */
802 int i; 794 if (format->palette != NULL) {
803 for ( i=0; i<format->palette->ncolors; ++i ) { 795 int i;
804 if ( (format->palette->colors[i].r != 0) || 796 for (i = 0; i < format->palette->ncolors; ++i) {
805 (format->palette->colors[i].g != 0) || 797 if ((format->palette->colors[i].r != 0) ||
806 (format->palette->colors[i].b != 0) ) 798 (format->palette->colors[i].g != 0) ||
807 break; 799 (format->palette->colors[i].b != 0))
808 } 800 break;
809 if ( i == format->palette->ncolors ) { 801 }
810 SDL_SetError("Empty destination palette"); 802 if (i == format->palette->ncolors) {
811 return(NULL); 803 SDL_SetError ("Empty destination palette");
812 } 804 return (NULL);
813 } 805 }
814 806 }
815 /* Only create hw surfaces with alpha channel if hw alpha blits 807
816 are supported */ 808 /* Only create hw surfaces with alpha channel if hw alpha blits
817 if(format->Amask != 0 && (flags & SDL_HWSURFACE)) { 809 are supported */
818 const SDL_VideoInfo *vi = SDL_GetVideoInfo(); 810 if (format->Amask != 0 && (flags & SDL_HWSURFACE)) {
819 if(!vi || !vi->blit_hw_A) 811 const SDL_VideoInfo *vi = SDL_GetVideoInfo ();
820 flags &= ~SDL_HWSURFACE; 812 if (!vi || !vi->blit_hw_A)
821 } 813 flags &= ~SDL_HWSURFACE;
822 814 }
823 /* Create a new surface with the desired format */ 815
824 convert = SDL_CreateRGBSurface(flags, 816 /* Create a new surface with the desired format */
825 surface->w, surface->h, format->BitsPerPixel, 817 convert = SDL_CreateRGBSurface (flags,
826 format->Rmask, format->Gmask, format->Bmask, format->Amask); 818 surface->w, surface->h,
827 if ( convert == NULL ) { 819 format->BitsPerPixel, format->Rmask,
828 return(NULL); 820 format->Gmask, format->Bmask,
829 } 821 format->Amask);
830 822 if (convert == NULL) {
831 /* Copy the palette if any */ 823 return (NULL);
832 if ( format->palette && convert->format->palette ) { 824 }
833 SDL_memcpy(convert->format->palette->colors, 825
834 format->palette->colors, 826 /* Copy the palette if any */
835 format->palette->ncolors*sizeof(SDL_Color)); 827 if (format->palette && convert->format->palette) {
836 convert->format->palette->ncolors = format->palette->ncolors; 828 SDL_memcpy (convert->format->palette->colors,
837 } 829 format->palette->colors,
838 830 format->palette->ncolors * sizeof (SDL_Color));
839 /* Save the original surface color key and alpha */ 831 convert->format->palette->ncolors = format->palette->ncolors;
840 surface_flags = surface->flags; 832 }
841 if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 833
842 /* Convert colourkeyed surfaces to RGBA if requested */ 834 /* Save the original surface color key and alpha */
843 if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY 835 surface_flags = surface->flags;
844 && format->Amask) { 836 if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
845 surface_flags &= ~SDL_SRCCOLORKEY; 837 /* Convert colourkeyed surfaces to RGBA if requested */
846 } else { 838 if ((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY && format->Amask) {
847 colorkey = surface->format->colorkey; 839 surface_flags &= ~SDL_SRCCOLORKEY;
848 SDL_SetColorKey(surface, 0, 0); 840 } else {
849 } 841 colorkey = surface->format->colorkey;
850 } 842 SDL_SetColorKey (surface, 0, 0);
851 if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 843 }
852 /* Copy over the alpha channel to RGBA if requested */ 844 }
853 if ( format->Amask ) { 845 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
854 surface->flags &= ~SDL_SRCALPHA; 846 /* Copy over the alpha channel to RGBA if requested */
855 } else { 847 if (format->Amask) {
856 alpha = surface->format->alpha; 848 surface->flags &= ~SDL_SRCALPHA;
857 SDL_SetAlpha(surface, 0, 0); 849 } else {
858 } 850 alpha = surface->format->alpha;
859 } 851 SDL_SetAlpha (surface, 0, 0);
860 852 }
861 /* Copy over the image data */ 853 }
862 bounds.x = 0; 854
863 bounds.y = 0; 855 /* Copy over the image data */
864 bounds.w = surface->w; 856 bounds.x = 0;
865 bounds.h = surface->h; 857 bounds.y = 0;
866 SDL_LowerBlit(surface, &bounds, convert, &bounds); 858 bounds.w = surface->w;
867 859 bounds.h = surface->h;
868 /* Clean up the original surface, and update converted surface */ 860 SDL_LowerBlit (surface, &bounds, convert, &bounds);
869 if ( convert != NULL ) { 861
870 SDL_SetClipRect(convert, &surface->clip_rect); 862 /* Clean up the original surface, and update converted surface */
871 } 863 if (convert != NULL) {
872 if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 864 SDL_SetClipRect (convert, &surface->clip_rect);
873 Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK); 865 }
874 if ( convert != NULL ) { 866 if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
875 Uint8 keyR, keyG, keyB; 867 Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
876 868 if (convert != NULL) {
877 SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB); 869 Uint8 keyR, keyG, keyB;
878 SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK), 870
879 SDL_MapRGB(convert->format, keyR, keyG, keyB)); 871 SDL_GetRGB (colorkey, surface->format, &keyR, &keyG, &keyB);
880 } 872 SDL_SetColorKey (convert, cflags | (flags & SDL_RLEACCELOK),
881 SDL_SetColorKey(surface, cflags, colorkey); 873 SDL_MapRGB (convert->format, keyR, keyG, keyB));
882 } 874 }
883 if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 875 SDL_SetColorKey (surface, cflags, colorkey);
884 Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK); 876 }
885 if ( convert != NULL ) { 877 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
886 SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK), 878 Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
887 alpha); 879 if (convert != NULL) {
888 } 880 SDL_SetAlpha (convert, aflags | (flags & SDL_RLEACCELOK), alpha);
889 if ( format->Amask ) { 881 }
890 surface->flags |= SDL_SRCALPHA; 882 if (format->Amask) {
891 } else { 883 surface->flags |= SDL_SRCALPHA;
892 SDL_SetAlpha(surface, aflags, alpha); 884 } else {
893 } 885 SDL_SetAlpha (surface, aflags, alpha);
894 } 886 }
895 887 }
896 /* We're ready to go! */ 888
897 return(convert); 889 /* We're ready to go! */
890 return (convert);
898 } 891 }
899 892
900 /* 893 /*
901 * Free a surface created by the above function. 894 * Free a surface created by the above function.
902 */ 895 */
903 void SDL_FreeSurface (SDL_Surface *surface) 896 void
904 { 897 SDL_FreeSurface (SDL_Surface * surface)
905 /* Free anything that's not NULL, and not the screen surface */ 898 {
906 if ((surface == NULL) || 899 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
907 (current_video && 900
908 ((surface == SDL_ShadowSurface)||(surface == SDL_VideoSurface)))) { 901 /* Free anything that's not NULL, and not the screen surface */
909 return; 902 if ((surface == NULL) ||
910 } 903 (_this &&
911 if ( --surface->refcount > 0 ) { 904 ((surface == SDL_ShadowSurface) || (surface == SDL_VideoSurface)))) {
912 return; 905 return;
913 } 906 }
914 while ( surface->locked > 0 ) { 907 if (--surface->refcount > 0) {
915 SDL_UnlockSurface(surface); 908 return;
916 } 909 }
917 if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { 910 while (surface->locked > 0) {
918 SDL_UnRLESurface(surface, 0); 911 SDL_UnlockSurface (surface);
919 } 912 }
920 if ( surface->format ) { 913 if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
921 SDL_FreeFormat(surface->format); 914 SDL_UnRLESurface (surface, 0);
922 surface->format = NULL; 915 }
923 } 916 if (surface->format) {
924 if ( surface->map != NULL ) { 917 SDL_FreeFormat (surface->format);
925 SDL_FreeBlitMap(surface->map); 918 surface->format = NULL;
926 surface->map = NULL; 919 }
927 } 920 if (surface->map != NULL) {
928 if ( surface->hwdata ) { 921 SDL_FreeBlitMap (surface->map);
929 SDL_VideoDevice *video = current_video; 922 surface->map = NULL;
930 SDL_VideoDevice *this = current_video; 923 }
931 video->FreeHWSurface(this, surface); 924 if (surface->hwdata) {
932 } 925 SDL_VideoDevice *_this = SDL_GetVideoDevice ();
933 if ( surface->pixels && 926 _this->FreeHWSurface (_this, surface);
934 ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) { 927 }
935 SDL_free(surface->pixels); 928 if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) {
936 } 929 SDL_free (surface->pixels);
937 SDL_free(surface); 930 }
931 SDL_free (surface);
938 #ifdef CHECK_LEAKS 932 #ifdef CHECK_LEAKS
939 --surfaces_allocated; 933 --surfaces_allocated;
940 #endif 934 #endif
941 } 935 }
936
937 /* vi: set ts=4 sw=4 expandtab: */