Mercurial > sdl-ios-xcode
annotate src/video/SDL_pixels.c @ 641:df178851293b
Date: 28 Jun 2003 22:42:52 +0100
From: Alan Swanson
Subject: Re: [SDL] New XFree 4.3 Video Mode Patch
I have a wee amendment that moves the qsort in set_best_resolution
to only occur after failing to find an exact match only. This would
make absolutely sure we get a user set mode.
While I've never had any problems for my normal resolutions (1280x1024,
1024x768, 800x600 & 640,480) while closely examining the output from
qsort I've noticed it doesn't seem to sort the modes fully. These is
one definite wrong at 1152x768 and a few that just look wrong to me.
From a program (attached) I made to examine this more easily. X has
sorted its mode list using the same method as ours (plus frequency),
and our user modes get inserted without any other movement.
On the patch I've made I've also changed cmpmodes to sort on vertical
resolution and then horizontal. Ie vertical is now most significant
bit.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 28 Jun 2003 21:52:26 +0000 |
parents | e561e8752d33 |
children | c0522010bb6d |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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; | |
64 switch (bpp) { | |
65 case 1: | |
66 /* Create the 2 color black-white palette */ | |
67 format->palette = (SDL_Palette *)malloc( | |
68 sizeof(SDL_Palette)); | |
69 if ( format->palette == NULL ) { | |
70 SDL_FreeFormat(format); | |
71 SDL_OutOfMemory(); | |
72 return(NULL); | |
73 } | |
74 (format->palette)->ncolors = 2; | |
75 (format->palette)->colors = (SDL_Color *)malloc( | |
76 (format->palette)->ncolors*sizeof(SDL_Color)); | |
77 if ( (format->palette)->colors == NULL ) { | |
78 SDL_FreeFormat(format); | |
79 SDL_OutOfMemory(); | |
80 return(NULL); | |
81 } | |
82 format->palette->colors[0].r = 0xFF; | |
83 format->palette->colors[0].g = 0xFF; | |
84 format->palette->colors[0].b = 0xFF; | |
85 format->palette->colors[1].r = 0x00; | |
86 format->palette->colors[1].g = 0x00; | |
87 format->palette->colors[1].b = 0x00; | |
88 format->Rloss = 8; | |
89 format->Gloss = 8; | |
90 format->Bloss = 8; | |
91 format->Aloss = 8; | |
92 format->Rshift = 0; | |
93 format->Gshift = 0; | |
94 format->Bshift = 0; | |
95 format->Ashift = 0; | |
96 format->Rmask = 0; | |
97 format->Gmask = 0; | |
98 format->Bmask = 0; | |
99 format->Amask = 0; | |
100 break; | |
101 | |
102 case 4: | |
103 /* Create the 16 color VGA palette */ | |
104 format->palette = (SDL_Palette *)malloc( | |
105 sizeof(SDL_Palette)); | |
106 if ( format->palette == NULL ) { | |
107 SDL_FreeFormat(format); | |
108 SDL_OutOfMemory(); | |
109 return(NULL); | |
110 } | |
111 (format->palette)->ncolors = 16; | |
112 (format->palette)->colors = (SDL_Color *)malloc( | |
113 (format->palette)->ncolors*sizeof(SDL_Color)); | |
114 if ( (format->palette)->colors == NULL ) { | |
115 SDL_FreeFormat(format); | |
116 SDL_OutOfMemory(); | |
117 return(NULL); | |
118 } | |
119 /* Punt for now, will this ever be used? */ | |
120 memset((format->palette)->colors, 0, | |
121 (format->palette)->ncolors*sizeof(SDL_Color)); | |
122 | |
123 /* Palettized formats have no mask info */ | |
124 format->Rloss = 8; | |
125 format->Gloss = 8; | |
126 format->Bloss = 8; | |
127 format->Aloss = 8; | |
128 format->Rshift = 0; | |
129 format->Gshift = 0; | |
130 format->Bshift = 0; | |
131 format->Ashift = 0; | |
132 format->Rmask = 0; | |
133 format->Gmask = 0; | |
134 format->Bmask = 0; | |
135 format->Amask = 0; | |
136 break; | |
137 | |
138 case 8: | |
139 /* Create an empty 256 color palette */ | |
140 format->palette = (SDL_Palette *)malloc( | |
141 sizeof(SDL_Palette)); | |
142 if ( format->palette == NULL ) { | |
143 SDL_FreeFormat(format); | |
144 SDL_OutOfMemory(); | |
145 return(NULL); | |
146 } | |
147 (format->palette)->ncolors = 256; | |
148 (format->palette)->colors = (SDL_Color *)malloc( | |
149 (format->palette)->ncolors*sizeof(SDL_Color)); | |
150 if ( (format->palette)->colors == NULL ) { | |
151 SDL_FreeFormat(format); | |
152 SDL_OutOfMemory(); | |
153 return(NULL); | |
154 } | |
155 memset((format->palette)->colors, 0, | |
156 (format->palette)->ncolors*sizeof(SDL_Color)); | |
157 | |
158 /* Palettized formats have no mask info */ | |
159 format->Rloss = 8; | |
160 format->Gloss = 8; | |
161 format->Bloss = 8; | |
162 format->Aloss = 8; | |
163 format->Rshift = 0; | |
164 format->Gshift = 0; | |
165 format->Bshift = 0; | |
166 format->Ashift = 0; | |
167 format->Rmask = 0; | |
168 format->Gmask = 0; | |
169 format->Bmask = 0; | |
170 format->Amask = 0; | |
171 break; | |
172 | |
173 default: | |
174 /* No palette, just packed pixel info */ | |
175 format->palette = NULL; | |
176 format->Rshift = 0; | |
177 format->Rloss = 8; | |
178 if ( Rmask ) { | |
179 for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) | |
180 ++format->Rshift; | |
181 for ( ; (mask&0x01); mask >>= 1 ) | |
182 --format->Rloss; | |
183 } | |
184 format->Gshift = 0; | |
185 format->Gloss = 8; | |
186 if ( Gmask ) { | |
187 for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) | |
188 ++format->Gshift; | |
189 for ( ; (mask&0x01); mask >>= 1 ) | |
190 --format->Gloss; | |
191 } | |
192 format->Bshift = 0; | |
193 format->Bloss = 8; | |
194 if ( Bmask ) { | |
195 for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) | |
196 ++format->Bshift; | |
197 for ( ; (mask&0x01); mask >>= 1 ) | |
198 --format->Bloss; | |
199 } | |
200 format->Ashift = 0; | |
201 format->Aloss = 8; | |
202 if ( Amask ) { | |
203 for ( mask = Amask; !(mask&0x01); mask >>= 1 ) | |
204 ++format->Ashift; | |
205 for ( ; (mask&0x01); mask >>= 1 ) | |
206 --format->Aloss; | |
207 } | |
208 format->Rmask = Rmask; | |
209 format->Gmask = Gmask; | |
210 format->Bmask = Bmask; | |
211 format->Amask = Amask; | |
212 break; | |
213 } | |
214 /* Calculate some standard bitmasks, if necessary | |
215 * Note: This could conflict with an alpha mask, if given. | |
216 */ | |
217 if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) { | |
218 /* R-G-B */ | |
219 if ( bpp > 24 ) | |
220 bpp = 24; | |
221 format->Rloss = 8-(bpp/3); | |
222 format->Gloss = 8-(bpp/3)-(bpp%3); | |
223 format->Bloss = 8-(bpp/3); | |
224 format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); | |
225 format->Gshift = (bpp/3); | |
226 format->Bshift = 0; | |
227 format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift); | |
228 format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift); | |
229 format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift); | |
230 } | |
231 return(format); | |
232 } | |
233 SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, | |
234 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) | |
235 { | |
236 if ( surface->format ) { | |
237 SDL_FreeFormat(surface->format); | |
238 SDL_FormatChanged(surface); | |
239 } | |
240 surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); | |
241 return surface->format; | |
242 } | |
243 | |
244 /* | |
245 * Change any previous mappings from/to the new surface format | |
246 */ | |
247 void SDL_FormatChanged(SDL_Surface *surface) | |
248 { | |
249 surface->format_version++; | |
250 SDL_InvalidateMap(surface->map); | |
251 } | |
252 /* | |
253 * Free a previously allocated format structure | |
254 */ | |
255 void SDL_FreeFormat(SDL_PixelFormat *format) | |
256 { | |
257 if ( format ) { | |
258 if ( format->palette ) { | |
259 if ( format->palette->colors ) { | |
260 free(format->palette->colors); | |
261 } | |
262 free(format->palette); | |
263 } | |
264 free(format); | |
265 } | |
266 } | |
267 /* | |
268 * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors | |
269 */ | |
270 void SDL_DitherColors(SDL_Color *colors, int bpp) | |
271 { | |
272 int i; | |
273 if(bpp != 8) | |
274 return; /* only 8bpp supported right now */ | |
275 | |
276 for(i = 0; i < 256; i++) { | |
277 int r, g, b; | |
278 /* map each bit field to the full [0, 255] interval, | |
279 so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ | |
280 r = i & 0xe0; | |
281 r |= r >> 3 | r >> 6; | |
282 colors[i].r = r; | |
283 g = (i << 3) & 0xe0; | |
284 g |= g >> 3 | g >> 6; | |
285 colors[i].g = g; | |
286 b = i & 0x3; | |
287 b |= b << 2; | |
288 b |= b << 4; | |
289 colors[i].b = b; | |
290 } | |
291 } | |
292 /* | |
293 * Calculate the pad-aligned scanline width of a surface | |
294 */ | |
295 Uint16 SDL_CalculatePitch(SDL_Surface *surface) | |
296 { | |
297 Uint16 pitch; | |
298 | |
299 /* Surface should be 4-byte aligned for speed */ | |
300 pitch = surface->w*surface->format->BytesPerPixel; | |
301 switch (surface->format->BitsPerPixel) { | |
302 case 1: | |
303 pitch = (pitch+7)/8; | |
304 break; | |
305 case 4: | |
306 pitch = (pitch+1)/2; | |
307 break; | |
308 default: | |
309 break; | |
310 } | |
311 pitch = (pitch + 3) & ~3; /* 4-byte aligning */ | |
312 return(pitch); | |
313 } | |
314 /* | |
315 * Match an RGB value to a particular palette index | |
316 */ | |
317 Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) | |
318 { | |
319 /* Do colorspace distance matching */ | |
320 unsigned int smallest; | |
321 unsigned int distance; | |
322 int rd, gd, bd; | |
323 int i; | |
324 Uint8 pixel=0; | |
325 | |
326 smallest = ~0; | |
327 for ( i=0; i<pal->ncolors; ++i ) { | |
328 rd = pal->colors[i].r - r; | |
329 gd = pal->colors[i].g - g; | |
330 bd = pal->colors[i].b - b; | |
331 distance = (rd*rd)+(gd*gd)+(bd*bd); | |
332 if ( distance < smallest ) { | |
333 pixel = i; | |
334 if ( distance == 0 ) { /* Perfect match! */ | |
335 break; | |
336 } | |
337 smallest = distance; | |
338 } | |
339 } | |
340 return(pixel); | |
341 } | |
342 | |
343 /* Find the opaque pixel value corresponding to an RGB triple */ | |
344 Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) | |
345 { | |
346 if ( format->palette == NULL ) { | |
347 return (r >> format->Rloss) << format->Rshift | |
348 | (g >> format->Gloss) << format->Gshift | |
349 | (b >> format->Bloss) << format->Bshift | |
350 | format->Amask; | |
351 } else { | |
352 return SDL_FindColor(format->palette, r, g, b); | |
353 } | |
354 } | |
355 | |
356 /* Find the pixel value corresponding to an RGBA quadruple */ | |
357 Uint32 SDL_MapRGBA(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) | |
358 { | |
359 if ( format->palette == NULL ) { | |
360 return (r >> format->Rloss) << format->Rshift | |
361 | (g >> format->Gloss) << format->Gshift | |
362 | (b >> format->Bloss) << format->Bshift | |
363 | ((a >> format->Aloss) << format->Ashift & format->Amask); | |
364 } else { | |
365 return SDL_FindColor(format->palette, r, g, b); | |
366 } | |
367 } | |
368 | |
369 void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, | |
370 Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) | |
371 { | |
372 if ( fmt->palette == NULL ) { | |
373 /* | |
374 * This makes sure that the result is mapped to the | |
375 * interval [0..255], and the maximum value for each | |
376 * component is 255. This is important to make sure | |
377 * that white is indeed reported as (255, 255, 255), | |
378 * and that opaque alpha is 255. | |
379 * This only works for RGB bit fields at least 4 bit | |
380 * wide, which is almost always the case. | |
381 */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
382 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
383 v = (pixel & fmt->Rmask) >> fmt->Rshift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
384 *r = (v << fmt->Rloss) + (v >> (8 - fmt->Rloss)); |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
385 v = (pixel & fmt->Gmask) >> fmt->Gshift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
386 *g = (v << fmt->Gloss) + (v >> (8 - fmt->Gloss)); |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
387 v = (pixel & fmt->Bmask) >> fmt->Bshift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
388 *b = (v << fmt->Bloss) + (v >> (8 - fmt->Bloss)); |
0 | 389 if(fmt->Amask) { |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
390 v = (pixel & fmt->Amask) >> fmt->Ashift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
391 *a = (v << fmt->Aloss) + (v >> (8 - fmt->Aloss)); |
0 | 392 } else |
393 *a = SDL_ALPHA_OPAQUE; | |
394 } else { | |
395 *r = fmt->palette->colors[pixel].r; | |
396 *g = fmt->palette->colors[pixel].g; | |
397 *b = fmt->palette->colors[pixel].b; | |
398 *a = SDL_ALPHA_OPAQUE; | |
399 } | |
400 } | |
401 | |
402 void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b) | |
403 { | |
404 if ( fmt->palette == NULL ) { | |
405 /* the note for SDL_GetRGBA above applies here too */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
406 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
407 v = (pixel & fmt->Rmask) >> fmt->Rshift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
408 *r = (v << fmt->Rloss) + (v >> (8 - fmt->Rloss)); |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
409 v = (pixel & fmt->Gmask) >> fmt->Gshift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
410 *g = (v << fmt->Gloss) + (v >> (8 - fmt->Gloss)); |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
411 v = (pixel & fmt->Bmask) >> fmt->Bshift; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
412 *b = (v << fmt->Bloss) + (v >> (8 - fmt->Bloss)); |
0 | 413 } else { |
414 *r = fmt->palette->colors[pixel].r; | |
415 *g = fmt->palette->colors[pixel].g; | |
416 *b = fmt->palette->colors[pixel].b; | |
417 } | |
418 } | |
419 | |
420 /* Apply gamma to a set of colors - this is easy. :) */ | |
421 void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, | |
422 int ncolors) | |
423 { | |
424 int i; | |
425 | |
426 for ( i=0; i<ncolors; ++i ) { | |
427 output[i].r = gamma[0*256 + colors[i].r] >> 8; | |
428 output[i].g = gamma[1*256 + colors[i].g] >> 8; | |
429 output[i].b = gamma[2*256 + colors[i].b] >> 8; | |
430 } | |
431 } | |
432 | |
433 /* Map from Palette to Palette */ | |
434 static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) | |
435 { | |
436 Uint8 *map; | |
437 int i; | |
438 | |
439 if ( identical ) { | |
440 if ( src->ncolors <= dst->ncolors ) { | |
441 /* If an identical palette, no need to map */ | |
442 if ( memcmp(src->colors, dst->colors, src->ncolors* | |
443 sizeof(SDL_Color)) == 0 ) { | |
444 *identical = 1; | |
445 return(NULL); | |
446 } | |
447 } | |
448 *identical = 0; | |
449 } | |
450 map = (Uint8 *)malloc(src->ncolors); | |
451 if ( map == NULL ) { | |
452 SDL_OutOfMemory(); | |
453 return(NULL); | |
454 } | |
455 for ( i=0; i<src->ncolors; ++i ) { | |
456 map[i] = SDL_FindColor(dst, | |
457 src->colors[i].r, src->colors[i].g, src->colors[i].b); | |
458 } | |
459 return(map); | |
460 } | |
461 /* Map from Palette to BitField */ | |
462 static Uint8 *Map1toN(SDL_Palette *src, SDL_PixelFormat *dst) | |
463 { | |
464 Uint8 *map; | |
465 int i; | |
466 int bpp; | |
50 | 467 unsigned alpha; |
0 | 468 |
469 bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); | |
470 map = (Uint8 *)malloc(src->ncolors*bpp); | |
471 if ( map == NULL ) { | |
472 SDL_OutOfMemory(); | |
473 return(NULL); | |
474 } | |
475 | |
50 | 476 alpha = dst->Amask ? SDL_ALPHA_OPAQUE : 0; |
0 | 477 /* We memory copy to the pixel map so the endianness is preserved */ |
478 for ( i=0; i<src->ncolors; ++i ) { | |
479 ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, | |
480 src->colors[i].r, src->colors[i].g, | |
50 | 481 src->colors[i].b, alpha); |
0 | 482 } |
483 return(map); | |
484 } | |
485 /* Map from BitField to Dithered-Palette to Palette */ | |
486 static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_Palette *dst, int *identical) | |
487 { | |
488 /* Generate a 256 color dither palette */ | |
489 SDL_Palette dithered; | |
490 SDL_Color colors[256]; | |
491 | |
492 dithered.ncolors = 256; | |
493 SDL_DitherColors(colors, 8); | |
494 dithered.colors = colors; | |
495 return(Map1to1(&dithered, dst, identical)); | |
496 } | |
497 | |
498 SDL_BlitMap *SDL_AllocBlitMap(void) | |
499 { | |
500 SDL_BlitMap *map; | |
501 | |
502 /* Allocate the empty map */ | |
503 map = (SDL_BlitMap *)malloc(sizeof(*map)); | |
504 if ( map == NULL ) { | |
505 SDL_OutOfMemory(); | |
506 return(NULL); | |
507 } | |
508 memset(map, 0, sizeof(*map)); | |
509 | |
510 /* Allocate the software blit data */ | |
511 map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); | |
512 if ( map->sw_data == NULL ) { | |
513 SDL_FreeBlitMap(map); | |
514 SDL_OutOfMemory(); | |
515 return(NULL); | |
516 } | |
517 memset(map->sw_data, 0, sizeof(*map->sw_data)); | |
518 | |
519 /* It's ready to go */ | |
520 return(map); | |
521 } | |
522 void SDL_InvalidateMap(SDL_BlitMap *map) | |
523 { | |
524 if ( ! map ) { | |
525 return; | |
526 } | |
527 map->dst = NULL; | |
528 map->format_version = (unsigned int)-1; | |
529 if ( map->table ) { | |
530 free(map->table); | |
531 map->table = NULL; | |
532 } | |
533 } | |
534 int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) | |
535 { | |
536 SDL_PixelFormat *srcfmt; | |
537 SDL_PixelFormat *dstfmt; | |
538 SDL_BlitMap *map; | |
539 | |
540 /* Clear out any previous mapping */ | |
541 map = src->map; | |
542 if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
543 SDL_UnRLESurface(src, 1); | |
544 } | |
545 SDL_InvalidateMap(map); | |
546 | |
547 /* Figure out what kind of mapping we're doing */ | |
548 map->identity = 0; | |
549 srcfmt = src->format; | |
550 dstfmt = dst->format; | |
551 switch (srcfmt->BytesPerPixel) { | |
552 case 1: | |
553 switch (dstfmt->BytesPerPixel) { | |
554 case 1: | |
555 /* Palette --> Palette */ | |
556 /* If both SDL_HWSURFACE, assume have same palette */ | |
557 if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | |
558 ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { | |
559 map->identity = 1; | |
560 } else { | |
561 map->table = Map1to1(srcfmt->palette, | |
562 dstfmt->palette, &map->identity); | |
563 } | |
564 if ( ! map->identity ) { | |
565 if ( map->table == NULL ) { | |
566 return(-1); | |
567 } | |
568 } | |
569 if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) | |
570 map->identity = 0; | |
571 break; | |
572 | |
573 default: | |
574 /* Palette --> BitField */ | |
575 map->table = Map1toN(srcfmt->palette, dstfmt); | |
576 if ( map->table == NULL ) { | |
577 return(-1); | |
578 } | |
579 break; | |
580 } | |
581 break; | |
582 default: | |
583 switch (dstfmt->BytesPerPixel) { | |
584 case 1: | |
585 /* BitField --> Palette */ | |
586 map->table = MapNto1(srcfmt, | |
587 dstfmt->palette, &map->identity); | |
588 if ( ! map->identity ) { | |
589 if ( map->table == NULL ) { | |
590 return(-1); | |
591 } | |
592 } | |
593 map->identity = 0; /* Don't optimize to copy */ | |
594 break; | |
595 default: | |
596 /* BitField --> BitField */ | |
597 if ( FORMAT_EQUAL(srcfmt, dstfmt) ) | |
598 map->identity = 1; | |
599 break; | |
600 } | |
601 break; | |
602 } | |
603 | |
604 map->dst = dst; | |
605 map->format_version = dst->format_version; | |
606 | |
607 /* Choose your blitters wisely */ | |
608 return(SDL_CalculateBlit(src)); | |
609 } | |
610 void SDL_FreeBlitMap(SDL_BlitMap *map) | |
611 { | |
612 if ( map ) { | |
613 SDL_InvalidateMap(map); | |
614 if ( map->sw_data != NULL ) { | |
615 free(map->sw_data); | |
616 } | |
617 free(map); | |
618 } | |
619 } |