Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_1.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 | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
297
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:
91
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <stdio.h> | |
29 | |
30 #include "SDL_types.h" | |
31 #include "SDL_video.h" | |
32 #include "SDL_blit.h" | |
33 #include "SDL_sysvideo.h" | |
34 #include "SDL_endian.h" | |
35 | |
36 /* Functions to blit from 8-bit surfaces to other surfaces */ | |
37 | |
38 static void Blit1to1(SDL_BlitInfo *info) | |
39 { | |
40 #ifndef USE_DUFFS_LOOP | |
41 int c; | |
42 #endif | |
43 int width, height; | |
44 Uint8 *src, *map, *dst; | |
45 int srcskip, dstskip; | |
46 | |
47 /* Set up some basic variables */ | |
48 width = info->d_width; | |
49 height = info->d_height; | |
50 src = info->s_pixels; | |
51 srcskip = info->s_skip; | |
52 dst = info->d_pixels; | |
53 dstskip = info->d_skip; | |
54 map = info->table; | |
55 | |
56 while ( height-- ) { | |
57 #ifdef USE_DUFFS_LOOP | |
58 DUFFS_LOOP( | |
59 { | |
60 *dst = map[*src]; | |
61 } | |
62 dst++; | |
63 src++; | |
64 , width); | |
65 #else | |
66 for ( c=width; c; --c ) { | |
67 *dst = map[*src]; | |
68 dst++; | |
69 src++; | |
70 } | |
71 #endif | |
72 src += srcskip; | |
73 dst += dstskip; | |
74 } | |
75 } | |
76 /* This is now endian dependent */ | |
77 #if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) | |
78 #define HI 1 | |
79 #define LO 0 | |
80 #else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ | |
81 #define HI 0 | |
82 #define LO 1 | |
83 #endif | |
84 static void Blit1to2(SDL_BlitInfo *info) | |
85 { | |
86 #ifndef USE_DUFFS_LOOP | |
87 int c; | |
88 #endif | |
89 int width, height; | |
90 Uint8 *src, *dst; | |
91 Uint16 *map; | |
92 int srcskip, dstskip; | |
93 | |
94 /* Set up some basic variables */ | |
95 width = info->d_width; | |
96 height = info->d_height; | |
97 src = info->s_pixels; | |
98 srcskip = info->s_skip; | |
99 dst = info->d_pixels; | |
100 dstskip = info->d_skip; | |
101 map = (Uint16 *)info->table; | |
102 | |
103 #ifdef USE_DUFFS_LOOP | |
104 while ( height-- ) { | |
105 DUFFS_LOOP( | |
106 { | |
107 *(Uint16 *)dst = map[*src++]; | |
108 dst += 2; | |
109 }, | |
110 width); | |
111 src += srcskip; | |
112 dst += dstskip; | |
113 } | |
114 #else | |
115 /* Memory align at 4-byte boundary, if necessary */ | |
116 if ( (long)dst & 0x03 ) { | |
117 /* Don't do anything if width is 0 */ | |
118 if ( width == 0 ) { | |
119 return; | |
120 } | |
121 --width; | |
122 | |
123 while ( height-- ) { | |
124 /* Perform copy alignment */ | |
125 *(Uint16 *)dst = map[*src++]; | |
126 dst += 2; | |
127 | |
128 /* Copy in 4 pixel chunks */ | |
129 for ( c=width/4; c; --c ) { | |
130 *(Uint32 *)dst = | |
131 (map[src[HI]]<<16)|(map[src[LO]]); | |
132 src += 2; | |
133 dst += 4; | |
134 *(Uint32 *)dst = | |
135 (map[src[HI]]<<16)|(map[src[LO]]); | |
136 src += 2; | |
137 dst += 4; | |
138 } | |
139 /* Get any leftovers */ | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
140 switch (width & 3) { |
0 | 141 case 3: |
142 *(Uint16 *)dst = map[*src++]; | |
143 dst += 2; | |
144 case 2: | |
145 *(Uint32 *)dst = | |
146 (map[src[HI]]<<16)|(map[src[LO]]); | |
147 src += 2; | |
148 dst += 4; | |
149 break; | |
150 case 1: | |
151 *(Uint16 *)dst = map[*src++]; | |
152 dst += 2; | |
153 break; | |
154 } | |
155 src += srcskip; | |
156 dst += dstskip; | |
157 } | |
158 } else { | |
159 while ( height-- ) { | |
160 /* Copy in 4 pixel chunks */ | |
161 for ( c=width/4; c; --c ) { | |
162 *(Uint32 *)dst = | |
163 (map[src[HI]]<<16)|(map[src[LO]]); | |
164 src += 2; | |
165 dst += 4; | |
166 *(Uint32 *)dst = | |
167 (map[src[HI]]<<16)|(map[src[LO]]); | |
168 src += 2; | |
169 dst += 4; | |
170 } | |
171 /* Get any leftovers */ | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
172 switch (width & 3) { |
0 | 173 case 3: |
174 *(Uint16 *)dst = map[*src++]; | |
175 dst += 2; | |
176 case 2: | |
177 *(Uint32 *)dst = | |
178 (map[src[HI]]<<16)|(map[src[LO]]); | |
179 src += 2; | |
180 dst += 4; | |
181 break; | |
182 case 1: | |
183 *(Uint16 *)dst = map[*src++]; | |
184 dst += 2; | |
185 break; | |
186 } | |
187 src += srcskip; | |
188 dst += dstskip; | |
189 } | |
190 } | |
191 #endif /* USE_DUFFS_LOOP */ | |
192 } | |
193 static void Blit1to3(SDL_BlitInfo *info) | |
194 { | |
195 #ifndef USE_DUFFS_LOOP | |
196 int c; | |
197 #endif | |
198 int o; | |
199 int width, height; | |
200 Uint8 *src, *map, *dst; | |
201 int srcskip, dstskip; | |
202 | |
203 /* Set up some basic variables */ | |
204 width = info->d_width; | |
205 height = info->d_height; | |
206 src = info->s_pixels; | |
207 srcskip = info->s_skip; | |
208 dst = info->d_pixels; | |
209 dstskip = info->d_skip; | |
210 map = info->table; | |
211 | |
212 while ( height-- ) { | |
213 #ifdef USE_DUFFS_LOOP | |
214 DUFFS_LOOP( | |
215 { | |
216 o = *src * 4; | |
217 dst[0] = map[o++]; | |
218 dst[1] = map[o++]; | |
219 dst[2] = map[o++]; | |
220 } | |
221 src++; | |
222 dst += 3; | |
223 , width); | |
224 #else | |
225 for ( c=width; c; --c ) { | |
226 o = *src * 4; | |
227 dst[0] = map[o++]; | |
228 dst[1] = map[o++]; | |
229 dst[2] = map[o++]; | |
230 src++; | |
231 dst += 3; | |
232 } | |
233 #endif /* USE_DUFFS_LOOP */ | |
234 src += srcskip; | |
235 dst += dstskip; | |
236 } | |
237 } | |
238 static void Blit1to4(SDL_BlitInfo *info) | |
239 { | |
240 #ifndef USE_DUFFS_LOOP | |
241 int c; | |
242 #endif | |
243 int width, height; | |
244 Uint8 *src; | |
245 Uint32 *map, *dst; | |
246 int srcskip, dstskip; | |
247 | |
248 /* Set up some basic variables */ | |
249 width = info->d_width; | |
250 height = info->d_height; | |
251 src = info->s_pixels; | |
252 srcskip = info->s_skip; | |
253 dst = (Uint32 *)info->d_pixels; | |
254 dstskip = info->d_skip/4; | |
255 map = (Uint32 *)info->table; | |
256 | |
257 while ( height-- ) { | |
258 #ifdef USE_DUFFS_LOOP | |
259 DUFFS_LOOP( | |
260 *dst++ = map[*src++]; | |
261 , width); | |
262 #else | |
263 for ( c=width/4; c; --c ) { | |
264 *dst++ = map[*src++]; | |
265 *dst++ = map[*src++]; | |
266 *dst++ = map[*src++]; | |
267 *dst++ = map[*src++]; | |
268 } | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
269 switch ( width & 3 ) { |
0 | 270 case 3: |
271 *dst++ = map[*src++]; | |
272 case 2: | |
273 *dst++ = map[*src++]; | |
274 case 1: | |
275 *dst++ = map[*src++]; | |
276 } | |
277 #endif /* USE_DUFFS_LOOP */ | |
278 src += srcskip; | |
279 dst += dstskip; | |
280 } | |
281 } | |
282 | |
283 static void Blit1to1Key(SDL_BlitInfo *info) | |
284 { | |
285 int width = info->d_width; | |
286 int height = info->d_height; | |
287 Uint8 *src = info->s_pixels; | |
288 int srcskip = info->s_skip; | |
289 Uint8 *dst = info->d_pixels; | |
290 int dstskip = info->d_skip; | |
291 Uint8 *palmap = info->table; | |
292 Uint32 ckey = info->src->colorkey; | |
293 | |
294 if ( palmap ) { | |
295 while ( height-- ) { | |
296 DUFFS_LOOP( | |
297 { | |
298 if ( *src != ckey ) { | |
299 *dst = palmap[*src]; | |
300 } | |
301 dst++; | |
302 src++; | |
303 }, | |
304 width); | |
305 src += srcskip; | |
306 dst += dstskip; | |
307 } | |
308 } else { | |
309 while ( height-- ) { | |
310 DUFFS_LOOP( | |
311 { | |
312 if ( *src != ckey ) { | |
313 *dst = *src; | |
314 } | |
315 dst++; | |
316 src++; | |
317 }, | |
318 width); | |
319 src += srcskip; | |
320 dst += dstskip; | |
321 } | |
322 } | |
323 } | |
324 | |
325 static void Blit1to2Key(SDL_BlitInfo *info) | |
326 { | |
327 int width = info->d_width; | |
328 int height = info->d_height; | |
329 Uint8 *src = info->s_pixels; | |
330 int srcskip = info->s_skip; | |
331 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
332 int dstskip = info->d_skip; | |
333 Uint16 *palmap = (Uint16 *)info->table; | |
334 Uint32 ckey = info->src->colorkey; | |
335 | |
336 /* Set up some basic variables */ | |
337 dstskip /= 2; | |
338 | |
339 while ( height-- ) { | |
340 DUFFS_LOOP( | |
341 { | |
342 if ( *src != ckey ) { | |
343 *dstp=palmap[*src]; | |
344 } | |
345 src++; | |
346 dstp++; | |
347 }, | |
348 width); | |
349 src += srcskip; | |
350 dstp += dstskip; | |
351 } | |
352 } | |
353 | |
354 static void Blit1to3Key(SDL_BlitInfo *info) | |
355 { | |
356 int width = info->d_width; | |
357 int height = info->d_height; | |
358 Uint8 *src = info->s_pixels; | |
359 int srcskip = info->s_skip; | |
360 Uint8 *dst = info->d_pixels; | |
361 int dstskip = info->d_skip; | |
362 Uint8 *palmap = info->table; | |
363 Uint32 ckey = info->src->colorkey; | |
364 int o; | |
365 | |
366 while ( height-- ) { | |
367 DUFFS_LOOP( | |
368 { | |
369 if ( *src != ckey ) { | |
370 o = *src * 4; | |
371 dst[0] = palmap[o++]; | |
372 dst[1] = palmap[o++]; | |
373 dst[2] = palmap[o++]; | |
374 } | |
375 src++; | |
376 dst += 3; | |
377 }, | |
378 width); | |
379 src += srcskip; | |
380 dst += dstskip; | |
381 } | |
382 } | |
383 | |
384 static void Blit1to4Key(SDL_BlitInfo *info) | |
385 { | |
386 int width = info->d_width; | |
387 int height = info->d_height; | |
388 Uint8 *src = info->s_pixels; | |
389 int srcskip = info->s_skip; | |
390 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
391 int dstskip = info->d_skip; | |
392 Uint32 *palmap = (Uint32 *)info->table; | |
393 Uint32 ckey = info->src->colorkey; | |
394 | |
395 /* Set up some basic variables */ | |
396 dstskip /= 4; | |
397 | |
398 while ( height-- ) { | |
399 DUFFS_LOOP( | |
400 { | |
401 if ( *src != ckey ) { | |
402 *dstp = palmap[*src]; | |
403 } | |
404 src++; | |
405 dstp++; | |
406 }, | |
407 width); | |
408 src += srcskip; | |
409 dstp += dstskip; | |
410 } | |
411 } | |
412 | |
413 static void Blit1toNAlpha(SDL_BlitInfo *info) | |
414 { | |
415 int width = info->d_width; | |
416 int height = info->d_height; | |
417 Uint8 *src = info->s_pixels; | |
418 int srcskip = info->s_skip; | |
419 Uint8 *dst = info->d_pixels; | |
420 int dstskip = info->d_skip; | |
421 SDL_PixelFormat *dstfmt = info->dst; | |
422 const SDL_Color *srcpal = info->src->palette->colors; | |
423 int dstbpp; | |
424 const int A = info->src->alpha; | |
425 | |
426 /* Set up some basic variables */ | |
427 dstbpp = dstfmt->BytesPerPixel; | |
428 | |
429 while ( height-- ) { | |
430 int sR, sG, sB; | |
431 int dR, dG, dB; | |
432 DUFFS_LOOP4( | |
433 { | |
434 Uint32 pixel; | |
435 sR = srcpal[*src].r; | |
436 sG = srcpal[*src].g; | |
437 sB = srcpal[*src].b; | |
438 DISEMBLE_RGB(dst, dstbpp, dstfmt, | |
439 pixel, dR, dG, dB); | |
440 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
441 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); | |
442 src++; | |
443 dst += dstbpp; | |
444 }, | |
445 width); | |
446 src += srcskip; | |
447 dst += dstskip; | |
448 } | |
449 } | |
450 | |
451 static void Blit1toNAlphaKey(SDL_BlitInfo *info) | |
452 { | |
453 int width = info->d_width; | |
454 int height = info->d_height; | |
455 Uint8 *src = info->s_pixels; | |
456 int srcskip = info->s_skip; | |
457 Uint8 *dst = info->d_pixels; | |
458 int dstskip = info->d_skip; | |
459 SDL_PixelFormat *srcfmt = info->src; | |
460 SDL_PixelFormat *dstfmt = info->dst; | |
461 const SDL_Color *srcpal = info->src->palette->colors; | |
462 Uint32 ckey = srcfmt->colorkey; | |
463 int dstbpp; | |
464 const int A = srcfmt->alpha; | |
465 | |
466 /* Set up some basic variables */ | |
467 dstbpp = dstfmt->BytesPerPixel; | |
468 | |
469 while ( height-- ) { | |
470 int sR, sG, sB; | |
471 int dR, dG, dB; | |
472 DUFFS_LOOP( | |
473 { | |
474 if ( *src != ckey ) { | |
475 Uint32 pixel; | |
476 sR = srcpal[*src].r; | |
477 sG = srcpal[*src].g; | |
478 sB = srcpal[*src].b; | |
479 DISEMBLE_RGB(dst, dstbpp, dstfmt, | |
480 pixel, dR, dG, dB); | |
481 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
482 ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); | |
483 } | |
484 src++; | |
485 dst += dstbpp; | |
486 }, | |
487 width); | |
488 src += srcskip; | |
489 dst += dstskip; | |
490 } | |
491 } | |
492 | |
493 static SDL_loblit one_blit[] = { | |
494 NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 | |
495 }; | |
496 | |
497 static SDL_loblit one_blitkey[] = { | |
498 NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key | |
499 }; | |
500 | |
501 SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index) | |
502 { | |
503 int which; | |
504 SDL_PixelFormat *dstfmt; | |
505 | |
506 dstfmt = surface->map->dst->format; | |
507 if ( dstfmt->BitsPerPixel < 8 ) { | |
508 which = 0; | |
509 } else { | |
510 which = dstfmt->BytesPerPixel; | |
511 } | |
512 switch(blit_index) { | |
513 case 0: /* copy */ | |
514 return one_blit[which]; | |
515 | |
516 case 1: /* colorkey */ | |
517 return one_blitkey[which]; | |
518 | |
519 case 2: /* alpha */ | |
520 /* Supporting 8bpp->8bpp alpha is doable but requires lots of | |
521 tables which consume space and takes time to precompute, | |
522 so is better left to the user */ | |
523 return which >= 2 ? Blit1toNAlpha : NULL; | |
524 | |
525 case 3: /* alpha + colorkey */ | |
526 return which >= 2 ? Blit1toNAlphaKey : NULL; | |
527 | |
528 } | |
529 return NULL; | |
530 } |