Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_1.c @ 934:af585d6efec8
Date: Thu, 17 Jun 2004 11:38:51 -0700 (PDT)
From: Eric Wing <ewing2121@yahoo.com>
Subject: New OS X patch (was Re: [SDL] Bug with inverted mouse coordinates in
I have a new patch for OS X I would like to submit.
First, it appears no further action has been taken on
my fix from Apple on the OpenGL windowed mode mouse
inversion problem. The fix would reunify the code, and
no longer require case checking for which version of
the OS you are running. This is probably a good fix
because the behavior with the old code could change
again with future versions of the OS, so those fixes
are included in this new patch.
But in addition, when I was at Apple, I asked them
about the ability to distinguish between the modifier
keys on the left and right sides of the keyboard (e.g.
Left Shift, Right Shift, Left/Right Alt, L/R Cmd, L/R
Ctrl). They told me that starting with Panther, the OS
began supporting this feature. This has always been a
source of annoyance for me when bringing a program
that comes from Windows or Linux to OS X when the
keybindings happened to need distinguishable left-side
and right-side keys. So the rest of the patch I am
submitting contains new code to support this feature
on Panther (and presumably later versions of the OS).
So after removing the OS version checks for the mouse
inversion problem, I reused the OS version checks to
activate the Left/Right detection of modifier keys. If
you are running Panther (or above), the new code will
attempt to distinguish between sides. For the older
OS's, the code path reverts to the original code.
I've tested with Panther on a G4 Cube, G5 dual
processor, and Powerbook Rev C. The Cube and G5
keyboards demonstrated the ability to distinguish
between sides. The Powerbook seems to only have
left-side keys, but the patch was still able to handle
it by producing the same results as before the patch.
I also wanted to test a non-Apple keyboard.
Unfortunately, I don't have any PC USB keyboards.
However, I was able to borrow a Sun Microsystems USB
keyboard, so I tried that out on the G5, and I got the
correct behavior for left and right sides. I'm
expecting that if it worked with a Sun keyboard, most
other keyboards should work with no problems.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 20 Aug 2004 22:35:23 +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 } |