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