Mercurial > sdl-ios-xcode
annotate src/video/SDL_pixels.c @ 1050:8e1815fd9777
Holding down shift while moving the mouse's scrollwheel on MacOS X makes the
OS report these are "horizontal scrollwheel" events, which confuses gaming
apps in several legitimate conditions. Now all scrollwheel events are made
to look vertical when passed to the app.
Patch by John Knottenbelt.
http://www.libsdl.org/pipermail/sdl/2005-March/067978.html
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sun, 17 Apr 2005 10:32:41 +0000 |
parents | c69697a85412 |
children | e9d23bb80140 |
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:
695
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:
50
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* General (mostly internal) pixel/color manipulation routines for SDL */ | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 | |
34 #include "SDL_error.h" | |
35 #include "SDL_endian.h" | |
36 #include "SDL_video.h" | |
37 #include "SDL_sysvideo.h" | |
38 #include "SDL_blit.h" | |
39 #include "SDL_pixels_c.h" | |
40 #include "SDL_RLEaccel_c.h" | |
41 | |
42 /* Helper functions */ | |
43 /* | |
44 * Allocate a pixel format structure and fill it according to the given info. | |
45 */ | |
46 SDL_PixelFormat *SDL_AllocFormat(int bpp, | |
47 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | |
48 { | |
49 SDL_PixelFormat *format; | |
50 Uint32 mask; | |
51 | |
52 /* Allocate an empty pixel format structure */ | |
53 format = malloc(sizeof(*format)); | |
54 if ( format == NULL ) { | |
55 SDL_OutOfMemory(); | |
56 return(NULL); | |
57 } | |
58 memset(format, 0, sizeof(*format)); | |
59 format->alpha = SDL_ALPHA_OPAQUE; | |
60 | |
61 /* Set up the format */ | |
62 format->BitsPerPixel = bpp; | |
63 format->BytesPerPixel = (bpp+7)/8; | |
1027
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
64 if ( Rmask || Bmask || Gmask ) { /* Packed pixels with custom mask */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
65 format->palette = NULL; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
66 format->Rshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
67 format->Rloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
68 if ( Rmask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
69 for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
70 ++format->Rshift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
71 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
72 --format->Rloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
73 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
74 format->Gshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
75 format->Gloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
76 if ( Gmask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
77 for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
78 ++format->Gshift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
79 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
80 --format->Gloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
81 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
82 format->Bshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
83 format->Bloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
84 if ( Bmask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
85 for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
86 ++format->Bshift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
87 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
88 --format->Bloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
89 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
90 format->Ashift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
91 format->Aloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
92 if ( Amask ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
93 for ( mask = Amask; !(mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
94 ++format->Ashift; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
95 for ( ; (mask&0x01); mask >>= 1 ) |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
96 --format->Aloss; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
97 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
98 format->Rmask = Rmask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
99 format->Gmask = Gmask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
100 format->Bmask = Bmask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
101 format->Amask = Amask; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
102 } else if ( bpp > 8 ) { /* Packed pixels with standard mask */ |
0 | 103 /* R-G-B */ |
104 if ( bpp > 24 ) | |
105 bpp = 24; | |
106 format->Rloss = 8-(bpp/3); | |
107 format->Gloss = 8-(bpp/3)-(bpp%3); | |
108 format->Bloss = 8-(bpp/3); | |
109 format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); | |
110 format->Gshift = (bpp/3); | |
111 format->Bshift = 0; | |
112 format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift); | |
113 format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift); | |
114 format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift); | |
1027
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
115 } else { /* Palettized mode */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
116 int i, ncolors = 1; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
117 for ( i = 0; i < bpp; ++i ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
118 ncolors *= 2; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
119 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
120 format->palette = (SDL_Palette *)malloc(sizeof(SDL_Palette)); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
121 if ( format->palette == NULL ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
122 SDL_FreeFormat(format); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
123 SDL_OutOfMemory(); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
124 return(NULL); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
125 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
126 (format->palette)->ncolors = ncolors; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
127 (format->palette)->colors = (SDL_Color *)malloc( |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
128 (format->palette)->ncolors*sizeof(SDL_Color)); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
129 if ( (format->palette)->colors == NULL ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
130 SDL_FreeFormat(format); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
131 SDL_OutOfMemory(); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
132 return(NULL); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
133 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
134 if ( ncolors == 2 ) { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
135 /* Create a black and white bitmap palette */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
136 format->palette->colors[0].r = 0xFF; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
137 format->palette->colors[0].g = 0xFF; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
138 format->palette->colors[0].b = 0xFF; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
139 format->palette->colors[1].r = 0x00; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
140 format->palette->colors[1].g = 0x00; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
141 format->palette->colors[1].b = 0x00; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
142 } else { |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
143 /* Create an empty palette */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
144 memset((format->palette)->colors, 0, |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
145 (format->palette)->ncolors*sizeof(SDL_Color)); |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
146 } |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
147 |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
148 /* Palettized formats have no mask info */ |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
149 format->Rloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
150 format->Gloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
151 format->Bloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
152 format->Aloss = 8; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
153 format->Rshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
154 format->Gshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
155 format->Bshift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
156 format->Ashift = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
157 format->Rmask = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
158 format->Gmask = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
159 format->Bmask = 0; |
c69697a85412
Clarified the code in the pixel format allocation
Sam Lantinga <slouken@libsdl.org>
parents:
997
diff
changeset
|
160 format->Amask = 0; |
0 | 161 } |
162 return(format); | |
163 } | |
164 SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, | |
165 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | |
166 { | |
167 if ( surface->format ) { | |
168 SDL_FreeFormat(surface->format); | |
169 SDL_FormatChanged(surface); | |
170 } | |
171 surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
172 return surface->format; | |
173 } | |
174 | |
175 /* | |
176 * Change any previous mappings from/to the new surface format | |
177 */ | |
178 void SDL_FormatChanged(SDL_Surface *surface) | |
179 { | |
845
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
180 static int format_version = 0; |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
181 ++format_version; |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
182 if ( format_version < 0 ) { /* It wrapped... */ |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
183 format_version = 1; |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
184 } |
333db1d87876
Fixed a bug in detecting surface mapping changes
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
185 surface->format_version = format_version; |
0 | 186 SDL_InvalidateMap(surface->map); |
187 } | |
188 /* | |
189 * Free a previously allocated format structure | |
190 */ | |
191 void SDL_FreeFormat(SDL_PixelFormat *format) | |
192 { | |
193 if ( format ) { | |
194 if ( format->palette ) { | |
195 if ( format->palette->colors ) { | |
196 free(format->palette->colors); | |
197 } | |
198 free(format->palette); | |
199 } | |
200 free(format); | |
201 } | |
202 } | |
203 /* | |
204 * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors | |
205 */ | |
206 void SDL_DitherColors(SDL_Color *colors, int bpp) | |
207 { | |
208 int i; | |
209 if(bpp != 8) | |
210 return; /* only 8bpp supported right now */ | |
211 | |
212 for(i = 0; i < 256; i++) { | |
213 int r, g, b; | |
214 /* map each bit field to the full [0, 255] interval, | |
215 so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ | |
216 r = i & 0xe0; | |
217 r |= r >> 3 | r >> 6; | |
218 colors[i].r = r; | |
219 g = (i << 3) & 0xe0; | |
220 g |= g >> 3 | g >> 6; | |
221 colors[i].g = g; | |
222 b = i & 0x3; | |
223 b |= b << 2; | |
224 b |= b << 4; | |
225 colors[i].b = b; | |
226 } | |
227 } | |
228 /* | |
229 * Calculate the pad-aligned scanline width of a surface | |
230 */ | |
231 Uint16 SDL_CalculatePitch(SDL_Surface *surface) | |
232 { | |
233 Uint16 pitch; | |
234 | |
235 /* Surface should be 4-byte aligned for speed */ | |
236 pitch = surface->w*surface->format->BytesPerPixel; | |
237 switch (surface->format->BitsPerPixel) { | |
238 case 1: | |
239 pitch = (pitch+7)/8; | |
240 break; | |
241 case 4: | |
242 pitch = (pitch+1)/2; | |
243 break; | |
244 default: | |
245 break; | |
246 } | |
247 pitch = (pitch + 3) & ~3; /* 4-byte aligning */ | |
248 return(pitch); | |
249 } | |
250 /* | |
251 * Match an RGB value to a particular palette index | |
252 */ | |
253 Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) | |
254 { | |
255 /* Do colorspace distance matching */ | |
256 unsigned int smallest; | |
257 unsigned int distance; | |
258 int rd, gd, bd; | |
259 int i; | |
260 Uint8 pixel=0; | |
261 | |
262 smallest = ~0; | |
263 for ( i=0; i<pal->ncolors; ++i ) { | |
264 rd = pal->colors[i].r - r; | |
265 gd = pal->colors[i].g - g; | |
266 bd = pal->colors[i].b - b; | |
267 distance = (rd*rd)+(gd*gd)+(bd*bd); | |
268 if ( distance < smallest ) { | |
269 pixel = i; | |
270 if ( distance == 0 ) { /* Perfect match! */ | |
271 break; | |
272 } | |
273 smallest = distance; | |
274 } | |
275 } | |
276 return(pixel); | |
277 } | |
278 | |
279 /* Find the opaque pixel value corresponding to an RGB triple */ | |
280 Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) | |
281 { | |
282 if ( format->palette == NULL ) { | |
283 return (r >> format->Rloss) << format->Rshift | |
284 | (g >> format->Gloss) << format->Gshift | |
285 | (b >> format->Bloss) << format->Bshift | |
286 | format->Amask; | |
287 } else { | |
288 return SDL_FindColor(format->palette, r, g, b); | |
289 } | |
290 } | |
291 | |
292 /* Find the pixel value corresponding to an RGBA quadruple */ | |
293 Uint32 SDL_MapRGBA(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) | |
294 { | |
295 if ( format->palette == NULL ) { | |
296 return (r >> format->Rloss) << format->Rshift | |
297 | (g >> format->Gloss) << format->Gshift | |
298 | (b >> format->Bloss) << format->Bshift | |
299 | ((a >> format->Aloss) << format->Ashift & format->Amask); | |
300 } else { | |
301 return SDL_FindColor(format->palette, r, g, b); | |
302 } | |
303 } | |
304 | |
305 void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, | |
306 Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) | |
307 { | |
308 if ( fmt->palette == NULL ) { | |
309 /* | |
310 * This makes sure that the result is mapped to the | |
311 * interval [0..255], and the maximum value for each | |
312 * component is 255. This is important to make sure | |
313 * that white is indeed reported as (255, 255, 255), | |
314 * and that opaque alpha is 255. | |
315 * This only works for RGB bit fields at least 4 bit | |
316 * wide, which is almost always the case. | |
317 */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
318 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
319 v = (pixel & fmt->Rmask) >> fmt->Rshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
320 *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
321 v = (pixel & fmt->Gmask) >> fmt->Gshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
322 *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
323 v = (pixel & fmt->Bmask) >> fmt->Bshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
324 *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); |
0 | 325 if(fmt->Amask) { |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
326 v = (pixel & fmt->Amask) >> fmt->Ashift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
327 *a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1))); |
695 | 328 } else { |
0 | 329 *a = SDL_ALPHA_OPAQUE; |
695 | 330 } |
0 | 331 } else { |
332 *r = fmt->palette->colors[pixel].r; | |
333 *g = fmt->palette->colors[pixel].g; | |
334 *b = fmt->palette->colors[pixel].b; | |
335 *a = SDL_ALPHA_OPAQUE; | |
336 } | |
337 } | |
338 | |
339 void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b) | |
340 { | |
341 if ( fmt->palette == NULL ) { | |
342 /* the note for SDL_GetRGBA above applies here too */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
343 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
344 v = (pixel & fmt->Rmask) >> fmt->Rshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
345 *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
346 v = (pixel & fmt->Gmask) >> fmt->Gshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
347 *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
348 v = (pixel & fmt->Bmask) >> fmt->Bshift; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
349 *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); |
0 | 350 } else { |
351 *r = fmt->palette->colors[pixel].r; | |
352 *g = fmt->palette->colors[pixel].g; | |
353 *b = fmt->palette->colors[pixel].b; | |
354 } | |
355 } | |
356 | |
357 /* Apply gamma to a set of colors - this is easy. :) */ | |
358 void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, | |
359 int ncolors) | |
360 { | |
361 int i; | |
362 | |
363 for ( i=0; i<ncolors; ++i ) { | |
364 output[i].r = gamma[0*256 + colors[i].r] >> 8; | |
365 output[i].g = gamma[1*256 + colors[i].g] >> 8; | |
366 output[i].b = gamma[2*256 + colors[i].b] >> 8; | |
367 } | |
368 } | |
369 | |
370 /* Map from Palette to Palette */ | |
371 static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) | |
372 { | |
373 Uint8 *map; | |
374 int i; | |
375 | |
376 if ( identical ) { | |
377 if ( src->ncolors <= dst->ncolors ) { | |
378 /* If an identical palette, no need to map */ | |
379 if ( memcmp(src->colors, dst->colors, src->ncolors* | |
380 sizeof(SDL_Color)) == 0 ) { | |
381 *identical = 1; | |
382 return(NULL); | |
383 } | |
384 } | |
385 *identical = 0; | |
386 } | |
387 map = (Uint8 *)malloc(src->ncolors); | |
388 if ( map == NULL ) { | |
389 SDL_OutOfMemory(); | |
390 return(NULL); | |
391 } | |
392 for ( i=0; i<src->ncolors; ++i ) { | |
393 map[i] = SDL_FindColor(dst, | |
394 src->colors[i].r, src->colors[i].g, src->colors[i].b); | |
395 } | |
396 return(map); | |
397 } | |
398 /* Map from Palette to BitField */ | |
399 static Uint8 *Map1toN(SDL_Palette *src, SDL_PixelFormat *dst) | |
400 { | |
401 Uint8 *map; | |
402 int i; | |
403 int bpp; | |
50 | 404 unsigned alpha; |
0 | 405 |
406 bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); | |
407 map = (Uint8 *)malloc(src->ncolors*bpp); | |
408 if ( map == NULL ) { | |
409 SDL_OutOfMemory(); | |
410 return(NULL); | |
411 } | |
412 | |
50 | 413 alpha = dst->Amask ? SDL_ALPHA_OPAQUE : 0; |
0 | 414 /* We memory copy to the pixel map so the endianness is preserved */ |
415 for ( i=0; i<src->ncolors; ++i ) { | |
416 ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, | |
417 src->colors[i].r, src->colors[i].g, | |
50 | 418 src->colors[i].b, alpha); |
0 | 419 } |
420 return(map); | |
421 } | |
422 /* Map from BitField to Dithered-Palette to Palette */ | |
423 static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_Palette *dst, int *identical) | |
424 { | |
425 /* Generate a 256 color dither palette */ | |
426 SDL_Palette dithered; | |
427 SDL_Color colors[256]; | |
997
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
428 |
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
429 /* SDL_DitherColors does not initialize the 'unused' component of colors, |
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
430 but Map1to1 compares it against dst, so we should initialize it. */ |
3bf4103b2b89
Date: Sat, 27 Nov 2004 13:35:43 +0100
Sam Lantinga <slouken@libsdl.org>
parents:
845
diff
changeset
|
431 memset(colors, 0, sizeof(colors)); |
0 | 432 |
433 dithered.ncolors = 256; | |
434 SDL_DitherColors(colors, 8); | |
435 dithered.colors = colors; | |
436 return(Map1to1(&dithered, dst, identical)); | |
437 } | |
438 | |
439 SDL_BlitMap *SDL_AllocBlitMap(void) | |
440 { | |
441 SDL_BlitMap *map; | |
442 | |
443 /* Allocate the empty map */ | |
444 map = (SDL_BlitMap *)malloc(sizeof(*map)); | |
445 if ( map == NULL ) { | |
446 SDL_OutOfMemory(); | |
447 return(NULL); | |
448 } | |
449 memset(map, 0, sizeof(*map)); | |
450 | |
451 /* Allocate the software blit data */ | |
452 map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); | |
453 if ( map->sw_data == NULL ) { | |
454 SDL_FreeBlitMap(map); | |
455 SDL_OutOfMemory(); | |
456 return(NULL); | |
457 } | |
458 memset(map->sw_data, 0, sizeof(*map->sw_data)); | |
459 | |
460 /* It's ready to go */ | |
461 return(map); | |
462 } | |
463 void SDL_InvalidateMap(SDL_BlitMap *map) | |
464 { | |
465 if ( ! map ) { | |
466 return; | |
467 } | |
468 map->dst = NULL; | |
469 map->format_version = (unsigned int)-1; | |
470 if ( map->table ) { | |
471 free(map->table); | |
472 map->table = NULL; | |
473 } | |
474 } | |
475 int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) | |
476 { | |
477 SDL_PixelFormat *srcfmt; | |
478 SDL_PixelFormat *dstfmt; | |
479 SDL_BlitMap *map; | |
480 | |
481 /* Clear out any previous mapping */ | |
482 map = src->map; | |
483 if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
484 SDL_UnRLESurface(src, 1); | |
485 } | |
486 SDL_InvalidateMap(map); | |
487 | |
488 /* Figure out what kind of mapping we're doing */ | |
489 map->identity = 0; | |
490 srcfmt = src->format; | |
491 dstfmt = dst->format; | |
492 switch (srcfmt->BytesPerPixel) { | |
493 case 1: | |
494 switch (dstfmt->BytesPerPixel) { | |
495 case 1: | |
496 /* Palette --> Palette */ | |
497 /* If both SDL_HWSURFACE, assume have same palette */ | |
498 if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | |
499 ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { | |
500 map->identity = 1; | |
501 } else { | |
502 map->table = Map1to1(srcfmt->palette, | |
503 dstfmt->palette, &map->identity); | |
504 } | |
505 if ( ! map->identity ) { | |
506 if ( map->table == NULL ) { | |
507 return(-1); | |
508 } | |
509 } | |
510 if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) | |
511 map->identity = 0; | |
512 break; | |
513 | |
514 default: | |
515 /* Palette --> BitField */ | |
516 map->table = Map1toN(srcfmt->palette, dstfmt); | |
517 if ( map->table == NULL ) { | |
518 return(-1); | |
519 } | |
520 break; | |
521 } | |
522 break; | |
523 default: | |
524 switch (dstfmt->BytesPerPixel) { | |
525 case 1: | |
526 /* BitField --> Palette */ | |
527 map->table = MapNto1(srcfmt, | |
528 dstfmt->palette, &map->identity); | |
529 if ( ! map->identity ) { | |
530 if ( map->table == NULL ) { | |
531 return(-1); | |
532 } | |
533 } | |
534 map->identity = 0; /* Don't optimize to copy */ | |
535 break; | |
536 default: | |
537 /* BitField --> BitField */ | |
538 if ( FORMAT_EQUAL(srcfmt, dstfmt) ) | |
539 map->identity = 1; | |
540 break; | |
541 } | |
542 break; | |
543 } | |
544 | |
545 map->dst = dst; | |
546 map->format_version = dst->format_version; | |
547 | |
548 /* Choose your blitters wisely */ | |
549 return(SDL_CalculateBlit(src)); | |
550 } | |
551 void SDL_FreeBlitMap(SDL_BlitMap *map) | |
552 { | |
553 if ( map ) { | |
554 SDL_InvalidateMap(map); | |
555 if ( map->sw_data != NULL ) { | |
556 free(map->sw_data); | |
557 } | |
558 free(map); | |
559 } | |
560 } |