comparison docs/html/guideinput.html @ 55:55f1f1b3e27d

Added new docs for SDL 1.2.1
author Sam Lantinga <slouken@lokigames.com>
date Sun, 10 Jun 2001 19:31:57 +0000
parents 74212992fb08
children e5bc29de3f0a
comparison
equal deleted inserted replaced
54:028447a8a758 55:55f1f1b3e27d
2 ><HEAD 2 ><HEAD
3 ><TITLE 3 ><TITLE
4 >Input handling</TITLE 4 >Input handling</TITLE
5 ><META 5 ><META
6 NAME="GENERATOR" 6 NAME="GENERATOR"
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.61 7 CONTENT="Modular DocBook HTML Stylesheet Version 1.64
8 "><LINK 8 "><LINK
9 REL="HOME" 9 REL="HOME"
10 TITLE="SDL Library Documentation" 10 TITLE="SDL Library Documentation"
11 HREF="index.html"><LINK 11 HREF="index.html"><LINK
12 REL="UP" 12 REL="UP"
13 TITLE="SDL Guide" 13 TITLE="SDL Guide"
14 HREF="guide.html"><LINK 14 HREF="guide.html"><LINK
15 REL="PREVIOUS" 15 REL="PREVIOUS"
16 TITLE="Graphics and Video" 16 TITLE="Using OpenGL With SDL"
17 HREF="guidevideo.html"><LINK 17 HREF="guidevideoopengl.html"><LINK
18 REL="NEXT" 18 REL="NEXT"
19 TITLE="Handling the Keyboard" 19 TITLE="Handling the Keyboard"
20 HREF="guideinputkeyboard.html"></HEAD 20 HREF="guideinputkeyboard.html"></HEAD
21 ><BODY 21 ><BODY
22 CLASS="CHAPTER" 22 CLASS="CHAPTER"
42 ><TD 42 ><TD
43 WIDTH="10%" 43 WIDTH="10%"
44 ALIGN="left" 44 ALIGN="left"
45 VALIGN="bottom" 45 VALIGN="bottom"
46 ><A 46 ><A
47 HREF="guidevideo.html" 47 HREF="guidevideoopengl.html"
48 >Prev</A 48 >Prev</A
49 ></TD 49 ></TD
50 ><TD 50 ><TD
51 WIDTH="80%" 51 WIDTH="80%"
52 ALIGN="center" 52 ALIGN="center"
102 ><DIV 102 ><DIV
103 CLASS="SECT2" 103 CLASS="SECT2"
104 ><H2 104 ><H2
105 CLASS="SECT2" 105 CLASS="SECT2"
106 ><A 106 ><A
107 NAME="AEN94" 107 NAME="AEN135"
108 >Initialization</A 108 >Initialization</A
109 ></H2 109 ></H2
110 ><P 110 ><P
111 >The first step in using a joystick in a SDL program is to initialize the Joystick subsystems of SDL. This done by passing the <TT 111 >The first step in using a joystick in a SDL program is to initialize the Joystick subsystems of SDL. This done by passing the <TT
112 CLASS="LITERAL" 112 CLASS="LITERAL"
115 HREF="sdlinit.html" 115 HREF="sdlinit.html"
116 ><TT 116 ><TT
117 CLASS="FUNCTION" 117 CLASS="FUNCTION"
118 >SDL_Init</TT 118 >SDL_Init</TT
119 ></A 119 ></A
120 >. The joystick flag will usually be used in conjunction with other flags (like the video flag) because the joystick is usually used to control something. 120 >. The joystick flag will usually be used in conjunction with other flags (like the video flag) because the joystick is usually used to control something.</P
121 <PRE 121 ><DIV
122 CLASS="PROGRAMLISTING" 122 CLASS="EXAMPLE"
123 > if ( ! SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) ) 123 ><A
124 NAME="AEN141"
125 ></A
126 ><P
127 ><B
128 >Example 3-1. Initializing SDL with Joystick Support</B
129 ></P
130 ><PRE
131 CLASS="PROGRAMLISTING"
132 > if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) &#60; 0)
124 { 133 {
125 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); 134 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
126 exit(1); 135 exit(1);
127 }</PRE 136 }</PRE
128 > 137 ></DIV
129 This will attempt to start SDL with both the video and the joystick subsystems activated.</P 138 ><P
139 >This will attempt to start SDL with both the video and the joystick subsystems activated.</P
130 ></DIV 140 ></DIV
131 ><DIV 141 ><DIV
132 CLASS="SECT2" 142 CLASS="SECT2"
133 ><H2 143 ><H2
134 CLASS="SECT2" 144 CLASS="SECT2"
135 ><A 145 ><A
136 NAME="AEN101" 146 NAME="AEN145"
137 >Querying</A 147 >Querying</A
138 ></H2 148 ></H2
139 ><P 149 ><P
140 >If we have reached this point then we can safely assume that the SDL library has been initialized and that the Joystick subsystem is active. We can now call some video and/or sound functions to get things going before we need the joystick. Eventually we have to make sure that there is actually a joystick to work with. It's wise to always check even if you know a joystick will be present on the system because it can also help detect when the joystick is unplugged. The function used to check for joysticks is <A 150 >If we have reached this point then we can safely assume that the SDL library has been initialized and that the Joystick subsystem is active. We can now call some video and/or sound functions to get things going before we need the joystick. Eventually we have to make sure that there is actually a joystick to work with. It's wise to always check even if you know a joystick will be present on the system because it can also help detect when the joystick is unplugged. The function used to check for joysticks is <A
141 HREF="sdlnumjoysticks.html" 151 HREF="sdlnumjoysticks.html"
152 >SDL_JoystickName</TT 162 >SDL_JoystickName</TT
153 ></A 163 ></A
154 >. The joystick is specified by an index where 0 is the first joystick and the last joystick is the number returned by <TT 164 >. The joystick is specified by an index where 0 is the first joystick and the last joystick is the number returned by <TT
155 CLASS="FUNCTION" 165 CLASS="FUNCTION"
156 >SDL_NumJoysticks</TT 166 >SDL_NumJoysticks</TT
157 > - 1. In the demonstration a list of all available joysticks is printed to stdout. 167 > - 1. In the demonstration a list of all available joysticks is printed to stdout.</P
158 <PRE 168 ><DIV
169 CLASS="EXAMPLE"
170 ><A
171 NAME="AEN154"
172 ></A
173 ><P
174 ><B
175 >Example 3-2. Querying the Number of Available Joysticks</B
176 ></P
177 ><PRE
159 CLASS="PROGRAMLISTING" 178 CLASS="PROGRAMLISTING"
160 > printf("%i joysticks were found.\n\n", SDL_NumJoysticks() ); 179 > printf("%i joysticks were found.\n\n", SDL_NumJoysticks() );
161 printf("The names of the joysticks are:\n"); 180 printf("The names of the joysticks are:\n");
162 181
163 for( i=0; i &#60; SDL_NumJoysticks(); i++ ) 182 for( i=0; i &#60; SDL_NumJoysticks(); i++ )
164 { 183 {
165 printf(" %s\n", SDL_JoystickName(i)); 184 printf(" %s\n", SDL_JoystickName(i));
166 }</PRE 185 }</PRE
167 ></P 186 ></DIV
168 ></DIV 187 ></DIV
169 ><DIV 188 ><DIV
170 CLASS="SECT2" 189 CLASS="SECT2"
171 ><H2 190 ><H2
172 CLASS="SECT2" 191 CLASS="SECT2"
173 ><A 192 ><A
174 NAME="AEN111" 193 NAME="AEN157"
175 >Opening a Joystick and Receiving Joystick Events</A 194 >Opening a Joystick and Receiving Joystick Events</A
176 ></H2 195 ></H2
177 ><P 196 ><P
178 >SDL's event driven architecture makes working with joysticks a snap. Joysticks can trigger 4 different types of events: 197 >SDL's event driven architecture makes working with joysticks a snap. Joysticks can trigger 4 different types of events:
179 <P 198 <P
248 HREF="sdljoystickopen.html" 267 HREF="sdljoystickopen.html"
249 ><TT 268 ><TT
250 CLASS="FUNCTION" 269 CLASS="FUNCTION"
251 >SDL_JoystickOpen</TT 270 >SDL_JoystickOpen</TT
252 ></A 271 ></A
253 > function. For the example we are only interested in events from the first joystick on the system, regardless of what it may be. To receive events from it we would do this: 272 > function. For the example we are only interested in events from the first joystick on the system, regardless of what it may be. To receive events from it we would do this:</P
254 <PRE 273 ><DIV
274 CLASS="EXAMPLE"
275 ><A
276 NAME="AEN183"
277 ></A
278 ><P
279 ><B
280 >Example 3-3. Opening a Joystick</B
281 ></P
282 ><PRE
255 CLASS="PROGRAMLISTING" 283 CLASS="PROGRAMLISTING"
256 > SDL_Joystick *joystick; 284 > SDL_Joystick *joystick;
257 285
258 SDL_JoystickEventState(SDL_ENABLE); 286 SDL_JoystickEventState(SDL_ENABLE);
259 joystick = SDL_JoystickOpen(0);</PRE 287 joystick = SDL_JoystickOpen(0);</PRE
260 > 288 ></DIV
261 If we wanted to receive events for other joysticks we would open them with calls to <TT 289 ><P
290 >If we wanted to receive events for other joysticks we would open them with calls to <TT
262 CLASS="FUNCTION" 291 CLASS="FUNCTION"
263 >SDL_JoystickOpen</TT 292 >SDL_JoystickOpen</TT
264 > just like we opened joystick 0, except we would store the <SPAN 293 > just like we opened joystick 0, except we would store the <SPAN
265 CLASS="STRUCTNAME" 294 CLASS="STRUCTNAME"
266 >SDL_Joystick</SPAN 295 >SDL_Joystick</SPAN
267 > structure they return in a different pointer. We only need the joystick pointer when we are querying the joysticks or when we are closing the joystick.</P 296 > structure they return in a different pointer. We only need the joystick pointer when we are querying the joysticks or when we are closing the joystick.</P
268 ><P 297 ><P
269 >Up to this point all the code we have is used just to initialize the joysticks in order to read values at run time. All we need now is an event loop, which is something that all SDL programs should have anyway to receive the systems quit events. We must now add code to check the event loop for at least some of the above mentioned events. Let's assume our event loop looks like this: 298 >Up to this point all the code we have is used just to initialize the joysticks in order to read values at run time. All we need now is an event loop, which is something that all SDL programs should have anyway to receive the systems quit events. We must now add code to check the event loop for at least some of the above mentioned events. Let's assume our event loop looks like this:
270 <PRE 299 <PRE
271 CLASS="PROGRAMLISTING" 300 CLASS="PROGRAMLISTING"
272 > SDL_Event *event; 301 > SDL_Event event;
273 /* Other initializtion code goes here */ 302 /* Other initializtion code goes here */
274 303
275 /* Start main game loop here */ 304 /* Start main game loop here */
276 305
277 while(SDL_PollEvent(&#38;event)) 306 while(SDL_PollEvent(&#38;event))
289 } 318 }
290 } 319 }
291 320
292 /* End loop here */</PRE 321 /* End loop here */</PRE
293 > 322 >
294 To handle Joystick events we merely add cases for them, first we'll add axis handling code. Axis checks can get kinda of tricky because alot of the joystick events received are junk. Joystick axis have a tendency to vary just a little between polling due to the way they are designed. To compensate for this you have to set a threshold for changes and ignore the events that have'nt exceeded the threshold. 10% is usually a good threshold value. This sounds a lot more complicated than it is. Here is the Axis event handler: 323 To handle Joystick events we merely add cases for them, first we'll add axis handling code. Axis checks can get kinda of tricky because alot of the joystick events received are junk. Joystick axis have a tendency to vary just a little between polling due to the way they are designed. To compensate for this you have to set a threshold for changes and ignore the events that have'nt exceeded the threshold. 10% is usually a good threshold value. This sounds a lot more complicated than it is. Here is the Axis event handler:</P
295 <PRE 324 ><DIV
325 CLASS="EXAMPLE"
326 ><A
327 NAME="AEN191"
328 ></A
329 ><P
330 ><B
331 >Example 3-4. Joystick Axis Events</B
332 ></P
333 ><PRE
296 CLASS="PROGRAMLISTING" 334 CLASS="PROGRAMLISTING"
297 > case SDL_JOYAXISMOTION: /* Handle Joystick Motion */ 335 > case SDL_JOYAXISMOTION: /* Handle Joystick Motion */
298 if ( ( event.jaxis.value &#60; -3200 ) || (event.jaxis.value &#62; 3200 ) ) 336 if ( ( event.jaxis.value &#60; -3200 ) || (event.jaxis.value &#62; 3200 ) )
299 { 337 {
300 /* code goes here */ 338 /* code goes here */
301 } 339 }
302 break;</PRE 340 break;</PRE
303 > 341 ></DIV
304 Another trick with axis events is that up-down and left-right movement are two different sets of axes. The most important axis is axis 0 (left-right) and axis 1 (up-down). To handle them seperatly in the code we do the following: 342 ><P
305 <PRE 343 >Another trick with axis events is that up-down and left-right movement are two different sets of axes. The most important axis is axis 0 (left-right) and axis 1 (up-down). To handle them seperatly in the code we do the following:</P
344 ><DIV
345 CLASS="EXAMPLE"
346 ><A
347 NAME="AEN195"
348 ></A
349 ><P
350 ><B
351 >Example 3-5. More Joystick Axis Events</B
352 ></P
353 ><PRE
306 CLASS="PROGRAMLISTING" 354 CLASS="PROGRAMLISTING"
307 > case SDL_JOYAXISMOTION: /* Handle Joystick Motion */ 355 > case SDL_JOYAXISMOTION: /* Handle Joystick Motion */
308 if ( ( event.jaxis.value &#60; -3200 ) || (event.jaxis.value &#62; 3200 ) ) 356 if ( ( event.jaxis.value &#60; -3200 ) || (event.jaxis.value &#62; 3200 ) )
309 { 357 {
310 if( event.jaxis.axis == 0) 358 if( event.jaxis.axis == 0)
316 { 364 {
317 /* Up-Down movement code goes here */ 365 /* Up-Down movement code goes here */
318 } 366 }
319 } 367 }
320 break;</PRE 368 break;</PRE
321 > 369 ></DIV
322 Ideally the code here should use <TT 370 ><P
371 >Ideally the code here should use <TT
323 CLASS="STRUCTFIELD" 372 CLASS="STRUCTFIELD"
324 ><I 373 ><I
325 >event.jaxis.value</I 374 >event.jaxis.value</I
326 ></TT 375 ></TT
327 > to scale something. For example lets assume you are using the joystick to control the movement of a spaceship. If the user is using an analog joystick and they push the stick a little bit they expect to move less than if they pushed it a lot. Designing your code for this situation is preferred because it makes the experience for users of analog controls better and remains the same for users of digital controls.</P 376 > to scale something. For example lets assume you are using the joystick to control the movement of a spaceship. If the user is using an analog joystick and they push the stick a little bit they expect to move less than if they pushed it a lot. Designing your code for this situation is preferred because it makes the experience for users of analog controls better and remains the same for users of digital controls.</P
331 ><I 380 ><I
332 >event.jaxis.axis</I 381 >event.jaxis.axis</I
333 ></TT 382 ></TT
334 > values.</P 383 > values.</P
335 ><P 384 ><P
336 >Button handling is simple compared to the axis checking. 385 >Button handling is simple compared to the axis checking.</P
337 <PRE 386 ><DIV
387 CLASS="EXAMPLE"
388 ><A
389 NAME="AEN203"
390 ></A
391 ><P
392 ><B
393 >Example 3-6. Joystick Button Events</B
394 ></P
395 ><PRE
338 CLASS="PROGRAMLISTING" 396 CLASS="PROGRAMLISTING"
339 > case SDL_JOYBUTTONDOWN: /* Handle Joystick Button Presses */ 397 > case SDL_JOYBUTTONDOWN: /* Handle Joystick Button Presses */
340 if ( event.jbutton.button == 0 ) 398 if ( event.jbutton.button == 0 )
341 { 399 {
342 /* code goes here */ 400 /* code goes here */
343 } 401 }
344 break;</PRE 402 break;</PRE
345 > 403 ></DIV
346 404 ><P
347 Button checks are simpler than axis checks because a button can only be pressed or not pressed. The <TT 405 >Button checks are simpler than axis checks because a button can only be pressed or not pressed. The <TT
348 CLASS="LITERAL" 406 CLASS="LITERAL"
349 >SDL_JOYBUTTONDOWN</TT 407 >SDL_JOYBUTTONDOWN</TT
350 > event is triggered when a button is pressed and the <TT 408 > event is triggered when a button is pressed and the <TT
351 CLASS="LITERAL" 409 CLASS="LITERAL"
352 >SDL_JOYBUTTONUP</TT 410 >SDL_JOYBUTTONUP</TT
372 ><DIV 430 ><DIV
373 CLASS="SECT2" 431 CLASS="SECT2"
374 ><H2 432 ><H2
375 CLASS="SECT2" 433 CLASS="SECT2"
376 ><A 434 ><A
377 NAME="AEN156" 435 NAME="AEN214"
378 >Advanced Joystick Functions</A 436 >Advanced Joystick Functions</A
379 ></H2 437 ></H2
380 ><P 438 ><P
381 >That takes care of the controls that you can count on being on every joystick under the sun, but there are a few extra things that SDL can support. Joyballs are next on our list, they are alot like axis we a few minor differences. Joyballs store relative changes unlike the the absolute postion stored in a axis event. Also one trackball event contains both the change in x and they change in y. Our case for it is as follows: 439 >That takes care of the controls that you can count on being on every joystick under the sun, but there are a few extra things that SDL can support. Joyballs are next on our list, they are alot like axis we a few minor differences. Joyballs store relative changes unlike the the absolute postion stored in a axis event. Also one trackball event contains both the change in x and they change in y. Our case for it is as follows:</P
382 <PRE 440 ><DIV
441 CLASS="EXAMPLE"
442 ><A
443 NAME="AEN217"
444 ></A
445 ><P
446 ><B
447 >Example 3-7. Joystick Ball Events</B
448 ></P
449 ><PRE
383 CLASS="PROGRAMLISTING" 450 CLASS="PROGRAMLISTING"
384 > case SDL_JOYBALLMOTION: /* Handle Joyball Motion */ 451 > case SDL_JOYBALLMOTION: /* Handle Joyball Motion */
385 if( event.jball.ball == 0 ) 452 if( event.jball.ball == 0 )
386 { 453 {
387 /* ball handling */ 454 /* ball handling */
388 } 455 }
389 break;</PRE 456 break;</PRE
390 > 457 ></DIV
391 The above checks the first joyball on the joystick. The change in position will be stored in <TT 458 ><P
459 >The above checks the first joyball on the joystick. The change in position will be stored in <TT
392 CLASS="STRUCTFIELD" 460 CLASS="STRUCTFIELD"
393 ><I 461 ><I
394 >event.jball.xrel</I 462 >event.jball.xrel</I
395 ></TT 463 ></TT
396 > and <TT 464 > and <TT
486 ></TABLE 554 ></TABLE
487 ><P 555 ><P
488 ></P 556 ></P
489 > 557 >
490 558
491 Our case for the hat may resemble the following: 559 Our case for the hat may resemble the following:</P
492 560 ><DIV
493 <PRE 561 CLASS="EXAMPLE"
562 ><A
563 NAME="AEN244"
564 ></A
565 ><P
566 ><B
567 >Example 3-8. Joystick Hat Events</B
568 ></P
569 ><PRE
494 CLASS="PROGRAMLISTING" 570 CLASS="PROGRAMLISTING"
495 > case SDL_JOYHATMOTION: /* Handle Hat Motion */ 571 > case SDL_JOYHATMOTION: /* Handle Hat Motion */
496 if ( event.jhat.hat | SDL_HAT_UP ) 572 if ( event.jhat.hat | SDL_HAT_UP )
497 { 573 {
498 /* Do up stuff here */ 574 /* Do up stuff here */
506 if ( event.jhat.hat | SDL_HAT_RIGHTDOWN ) 582 if ( event.jhat.hat | SDL_HAT_RIGHTDOWN )
507 { 583 {
508 /* Do right and down together stuff here */ 584 /* Do right and down together stuff here */
509 } 585 }
510 break;</PRE 586 break;</PRE
511 ></P 587 ></DIV
512 ><P 588 ><P
513 >In addition to the queries for number of joysticks on the system and their names there are additional functions to query the capabilities of attached joysticks: 589 >In addition to the queries for number of joysticks on the system and their names there are additional functions to query the capabilities of attached joysticks:
514 <P 590 <P
515 ></P 591 ></P
516 ><TABLE 592 ><TABLE
568 ></TABLE 644 ></TABLE
569 ><P 645 ><P
570 ></P 646 ></P
571 > 647 >
572 648
573 To use these functions we just have to pass in the joystick structure we got when we opened the joystick. For Example: 649 To use these functions we just have to pass in the joystick structure we got when we opened the joystick. For Example:</P
574 650 ><DIV
575 <PRE 651 CLASS="EXAMPLE"
652 ><A
653 NAME="AEN265"
654 ></A
655 ><P
656 ><B
657 >Example 3-9. Querying Joystick Characteristics</B
658 ></P
659 ><PRE
576 CLASS="PROGRAMLISTING" 660 CLASS="PROGRAMLISTING"
577 > int number_of_buttons; 661 > int number_of_buttons;
578 SDL_Joystick *joystick; 662 SDL_Joystick *joystick;
579 663
580 joystick = SDL_JoystickOpen(0); 664 joystick = SDL_JoystickOpen(0);
581 number_of_buttons = SDL_JoystickNumButtons(joystick);</PRE 665 number_of_buttons = SDL_JoystickNumButtons(joystick);</PRE
582 > 666 ></DIV
583 667 ><P
584 This block of code would get the number of buttons on the first joystick in the system. </P 668 >This block of code would get the number of buttons on the first joystick in the system. </P
585 ></DIV 669 ></DIV
586 ></DIV 670 ></DIV
587 ></DIV 671 ></DIV
588 ><DIV 672 ><DIV
589 CLASS="NAVFOOTER" 673 CLASS="NAVFOOTER"
598 ><TD 682 ><TD
599 WIDTH="33%" 683 WIDTH="33%"
600 ALIGN="left" 684 ALIGN="left"
601 VALIGN="top" 685 VALIGN="top"
602 ><A 686 ><A
603 HREF="guidevideo.html" 687 HREF="guidevideoopengl.html"
604 >Prev</A 688 >Prev</A
605 ></TD 689 ></TD
606 ><TD 690 ><TD
607 WIDTH="34%" 691 WIDTH="34%"
608 ALIGN="center" 692 ALIGN="center"
623 ><TR 707 ><TR
624 ><TD 708 ><TD
625 WIDTH="33%" 709 WIDTH="33%"
626 ALIGN="left" 710 ALIGN="left"
627 VALIGN="top" 711 VALIGN="top"
628 >Graphics and Video</TD 712 >Using OpenGL With SDL</TD
629 ><TD 713 ><TD
630 WIDTH="34%" 714 WIDTH="34%"
631 ALIGN="center" 715 ALIGN="center"
632 VALIGN="top" 716 VALIGN="top"
633 ><A 717 ><A