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