Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_1.c @ 563:04dcaf3da918
Massive Quartz input enhancements from Darrell Walisser. His email:
Enclosed is a patch that addresses the following:
--Various minor cleanups.
Removed dead/obsolete code, made some style cleanups
--Mouse Events
Now keep track of what button(s) were pressed so we know when to send
the mouse up event. This fixes the case where the mouse is dragged
outside of the game window and released (in which case we want to send
the mouse up event even though the mouse is outside the game window).
--Input Grabbing
Here is my take on the grabbing situation, which is the basis for the
new implementation.
There are 3 grab states, ungrabbed (UG), visible (VG), and invisible
(IG). Both VG and IG keep the mouse constrained to the window and
produce relative motion events. In VG the cursor is visible (duh), in
IG it is not. In VG, absolute motion events also work.
There are 6 actions that can affect grabbing:
1. Set Fullscreen/Window (F/W). In fullscreen, a visible grab should do
nothing. However, a fullscreen visible grab can be treated just like a
windowed visible grab, which is what I have done to help simplify
things.
2. Cursor hide/show (H/S). If the cursor is hidden when grabbing, the
grab is an invisible grab. If the cursor is visible, the grab should
just constrain the mouse to the window.
3. Input grab/ungrab(G/U). If grabbed, the cursor should be confined to
the window as should the keyboard input. On Mac OS X, the keyboard
input is implicitly grabbed by confining the cursor, except for
command-tab which can switch away from the application. Should the
window come to the foreground if the application is deactivated and
grab input is called? This isn't necessary in this implementation
because the grab state will be asserted upon activation.
Using my notation, these are all the cases that need to be handled
(state + action = new state).
UG+U = UG
UG+G = VG or IG, if cursor is visible or not
UG+H = UG
UG+S = UG
VG+U = UG
VG+G = VG
VG+H = IG
VG+S = VG
IG+U = UG
IG+G = IG
IG+H = IG
IG+S = VG
The cases that result in the same state can be ignored in the code,
which cuts it down to just 5 cases.
Another issue is what happens when the app loses/gains input focus from
deactivate/activate or iconify/deiconify. I think that if input focus
is ever lost (outside of SDL's control), the grab state should be
suspended and the cursor should become visible and active again. When
regained, the cursor should reappear in its original location and/or
grab state. This way, when reactivating the cursor is still in the same
position as before so apps shouldn't get confused when the next motion
event comes in. This is what I've done in this patch.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 27 Dec 2002 20:52:41 +0000 |
parents | f6ffac90895c |
children | b8d311d90021 |
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:
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 } |