Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_1.c @ 156:7064032cbe77
Is this right??
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 20 Aug 2001 00:10:35 +0000 |
parents | e85e03f195b4 |
children | e8157fcb3114 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga | |
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 | |
20 slouken@devolution.com | |
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 } |