Mercurial > sdl-ios-xcode
annotate src/video/SDL_pixels.c @ 821:30168104389f
Date: Sat, 14 Feb 2004 14:52:40 +0200
From: "Mike Gorchak"
Subject: Batch of the QNX6 fixes for the SDL
1. Updated readme.QNX
2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update).
3. Fixed double-buffered fullscreen modes, now it works as needed.
4. Fixed Photon detection algorithm.
5. Fixed HWSURFACE update function.
6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon.
7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode.
8. Added available video ram amount support.
8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it.
9. Added hardware filling support.
10. Added hardware blits support (simple and colorkeyed).
And I've added to testvidinfo test color-keyed blits benchmark (maybe need to add alpha blits benchmark too ?). Currently Photon not supporting any alpha hardware blittings (all drivers lack of alpha blitting code support, only software alpha blitting exist in photon, which is hundreds times slowest than the SDL's one). So I've not added the alpha support. I suppose new QNX 6.3 will have the hardware alpha support, so when it will be done, I'll add alpha support.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 14 Feb 2004 20:22:21 +0000 |
parents | b8d311d90021 |
children | 333db1d87876 |
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; | |
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; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
384 *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
385 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
|
386 *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
387 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
|
388 *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); |
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; |
688
c0522010bb6d
Date: Tue, 12 Aug 2003 14:26:19 +0200 (MEST)
Sam Lantinga <slouken@libsdl.org>
parents:
628
diff
changeset
|
391 *a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1))); |
695 | 392 } else { |
0 | 393 *a = SDL_ALPHA_OPAQUE; |
695 | 394 } |
0 | 395 } else { |
396 *r = fmt->palette->colors[pixel].r; | |
397 *g = fmt->palette->colors[pixel].g; | |
398 *b = fmt->palette->colors[pixel].b; | |
399 *a = SDL_ALPHA_OPAQUE; | |
400 } | |
401 } | |
402 | |
403 void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b) | |
404 { | |
405 if ( fmt->palette == NULL ) { | |
406 /* the note for SDL_GetRGBA above applies here too */ | |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
407 unsigned v; |
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
408 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
|
409 *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
410 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
|
411 *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1))); |
628
e561e8752d33
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
412 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
|
413 *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1))); |
0 | 414 } else { |
415 *r = fmt->palette->colors[pixel].r; | |
416 *g = fmt->palette->colors[pixel].g; | |
417 *b = fmt->palette->colors[pixel].b; | |
418 } | |
419 } | |
420 | |
421 /* Apply gamma to a set of colors - this is easy. :) */ | |
422 void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, | |
423 int ncolors) | |
424 { | |
425 int i; | |
426 | |
427 for ( i=0; i<ncolors; ++i ) { | |
428 output[i].r = gamma[0*256 + colors[i].r] >> 8; | |
429 output[i].g = gamma[1*256 + colors[i].g] >> 8; | |
430 output[i].b = gamma[2*256 + colors[i].b] >> 8; | |
431 } | |
432 } | |
433 | |
434 /* Map from Palette to Palette */ | |
435 static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) | |
436 { | |
437 Uint8 *map; | |
438 int i; | |
439 | |
440 if ( identical ) { | |
441 if ( src->ncolors <= dst->ncolors ) { | |
442 /* If an identical palette, no need to map */ | |
443 if ( memcmp(src->colors, dst->colors, src->ncolors* | |
444 sizeof(SDL_Color)) == 0 ) { | |
445 *identical = 1; | |
446 return(NULL); | |
447 } | |
448 } | |
449 *identical = 0; | |
450 } | |
451 map = (Uint8 *)malloc(src->ncolors); | |
452 if ( map == NULL ) { | |
453 SDL_OutOfMemory(); | |
454 return(NULL); | |
455 } | |
456 for ( i=0; i<src->ncolors; ++i ) { | |
457 map[i] = SDL_FindColor(dst, | |
458 src->colors[i].r, src->colors[i].g, src->colors[i].b); | |
459 } | |
460 return(map); | |
461 } | |
462 /* Map from Palette to BitField */ | |
463 static Uint8 *Map1toN(SDL_Palette *src, SDL_PixelFormat *dst) | |
464 { | |
465 Uint8 *map; | |
466 int i; | |
467 int bpp; | |
50 | 468 unsigned alpha; |
0 | 469 |
470 bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); | |
471 map = (Uint8 *)malloc(src->ncolors*bpp); | |
472 if ( map == NULL ) { | |
473 SDL_OutOfMemory(); | |
474 return(NULL); | |
475 } | |
476 | |
50 | 477 alpha = dst->Amask ? SDL_ALPHA_OPAQUE : 0; |
0 | 478 /* We memory copy to the pixel map so the endianness is preserved */ |
479 for ( i=0; i<src->ncolors; ++i ) { | |
480 ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, | |
481 src->colors[i].r, src->colors[i].g, | |
50 | 482 src->colors[i].b, alpha); |
0 | 483 } |
484 return(map); | |
485 } | |
486 /* Map from BitField to Dithered-Palette to Palette */ | |
487 static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_Palette *dst, int *identical) | |
488 { | |
489 /* Generate a 256 color dither palette */ | |
490 SDL_Palette dithered; | |
491 SDL_Color colors[256]; | |
492 | |
493 dithered.ncolors = 256; | |
494 SDL_DitherColors(colors, 8); | |
495 dithered.colors = colors; | |
496 return(Map1to1(&dithered, dst, identical)); | |
497 } | |
498 | |
499 SDL_BlitMap *SDL_AllocBlitMap(void) | |
500 { | |
501 SDL_BlitMap *map; | |
502 | |
503 /* Allocate the empty map */ | |
504 map = (SDL_BlitMap *)malloc(sizeof(*map)); | |
505 if ( map == NULL ) { | |
506 SDL_OutOfMemory(); | |
507 return(NULL); | |
508 } | |
509 memset(map, 0, sizeof(*map)); | |
510 | |
511 /* Allocate the software blit data */ | |
512 map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); | |
513 if ( map->sw_data == NULL ) { | |
514 SDL_FreeBlitMap(map); | |
515 SDL_OutOfMemory(); | |
516 return(NULL); | |
517 } | |
518 memset(map->sw_data, 0, sizeof(*map->sw_data)); | |
519 | |
520 /* It's ready to go */ | |
521 return(map); | |
522 } | |
523 void SDL_InvalidateMap(SDL_BlitMap *map) | |
524 { | |
525 if ( ! map ) { | |
526 return; | |
527 } | |
528 map->dst = NULL; | |
529 map->format_version = (unsigned int)-1; | |
530 if ( map->table ) { | |
531 free(map->table); | |
532 map->table = NULL; | |
533 } | |
534 } | |
535 int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) | |
536 { | |
537 SDL_PixelFormat *srcfmt; | |
538 SDL_PixelFormat *dstfmt; | |
539 SDL_BlitMap *map; | |
540 | |
541 /* Clear out any previous mapping */ | |
542 map = src->map; | |
543 if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
544 SDL_UnRLESurface(src, 1); | |
545 } | |
546 SDL_InvalidateMap(map); | |
547 | |
548 /* Figure out what kind of mapping we're doing */ | |
549 map->identity = 0; | |
550 srcfmt = src->format; | |
551 dstfmt = dst->format; | |
552 switch (srcfmt->BytesPerPixel) { | |
553 case 1: | |
554 switch (dstfmt->BytesPerPixel) { | |
555 case 1: | |
556 /* Palette --> Palette */ | |
557 /* If both SDL_HWSURFACE, assume have same palette */ | |
558 if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && | |
559 ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { | |
560 map->identity = 1; | |
561 } else { | |
562 map->table = Map1to1(srcfmt->palette, | |
563 dstfmt->palette, &map->identity); | |
564 } | |
565 if ( ! map->identity ) { | |
566 if ( map->table == NULL ) { | |
567 return(-1); | |
568 } | |
569 } | |
570 if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) | |
571 map->identity = 0; | |
572 break; | |
573 | |
574 default: | |
575 /* Palette --> BitField */ | |
576 map->table = Map1toN(srcfmt->palette, dstfmt); | |
577 if ( map->table == NULL ) { | |
578 return(-1); | |
579 } | |
580 break; | |
581 } | |
582 break; | |
583 default: | |
584 switch (dstfmt->BytesPerPixel) { | |
585 case 1: | |
586 /* BitField --> Palette */ | |
587 map->table = MapNto1(srcfmt, | |
588 dstfmt->palette, &map->identity); | |
589 if ( ! map->identity ) { | |
590 if ( map->table == NULL ) { | |
591 return(-1); | |
592 } | |
593 } | |
594 map->identity = 0; /* Don't optimize to copy */ | |
595 break; | |
596 default: | |
597 /* BitField --> BitField */ | |
598 if ( FORMAT_EQUAL(srcfmt, dstfmt) ) | |
599 map->identity = 1; | |
600 break; | |
601 } | |
602 break; | |
603 } | |
604 | |
605 map->dst = dst; | |
606 map->format_version = dst->format_version; | |
607 | |
608 /* Choose your blitters wisely */ | |
609 return(SDL_CalculateBlit(src)); | |
610 } | |
611 void SDL_FreeBlitMap(SDL_BlitMap *map) | |
612 { | |
613 if ( map ) { | |
614 SDL_InvalidateMap(map); | |
615 if ( map->sw_data != NULL ) { | |
616 free(map->sw_data); | |
617 } | |
618 free(map); | |
619 } | |
620 } |