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