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