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