Mercurial > sdl-ios-xcode
annotate src/joystick/SDL_joystick.c @ 855:aa4ac9e65d92
I noticed MacOSX SDL sets up working directory to parent of executable.
On BeOS is should setup it the same way, but it only does when Tracker
wasn't restarted.
I checked code and it looks like a hack to me :(
It looks for env variable and than comapres it to default when OpenTracker
was started after boot, and wasn't restarted. That's probably ok, for that
exact case. Unfortunetly that variable isn't always like that. For
example, after Tracker crashes and is restarted, env variable most
probably is different (depends on how Tracker was restarted, by what
application, etc... for example: i have launcher application from which i
can restart Tracker, and after that nev variable points to that
application's directory, not Tracker's).
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 24 Feb 2004 18:58:40 +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:
716
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:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* This is the joystick API for Simple DirectMedia Layer */ | |
29 | |
30 #include <stdio.h> | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 | |
34 #include "SDL_error.h" | |
35 #include "SDL_events.h" | |
36 #ifndef DISABLE_EVENTS | |
37 #include "SDL_events_c.h" | |
38 #endif | |
39 #include "SDL_joystick_c.h" | |
40 #include "SDL_sysjoystick.h" | |
41 | |
42 /* This is used for Quake III Arena */ | |
43 #ifdef DISABLE_EVENTS | |
44 #define SDL_Lock_EventThread() | |
45 #define SDL_Unlock_EventThread() | |
46 #endif | |
47 | |
48 Uint8 SDL_numjoysticks = 0; | |
49 SDL_Joystick **SDL_joysticks = NULL; | |
50 static SDL_Joystick *default_joystick = NULL; | |
51 | |
52 int SDL_JoystickInit(void) | |
53 { | |
54 int arraylen; | |
55 int status; | |
56 | |
57 SDL_numjoysticks = 0; | |
58 status = SDL_SYS_JoystickInit(); | |
59 if ( status >= 0 ) { | |
60 arraylen = (status+1)*sizeof(*SDL_joysticks); | |
61 SDL_joysticks = (SDL_Joystick **)malloc(arraylen); | |
62 if ( SDL_joysticks == NULL ) { | |
63 SDL_numjoysticks = 0; | |
64 } else { | |
65 memset(SDL_joysticks, 0, arraylen); | |
716
f25e3334d583
SDL_JoystickInit: If malloc() fails, pretend no joysticks were detected.
Ryan C. Gordon <icculus@icculus.org>
parents:
297
diff
changeset
|
66 SDL_numjoysticks = status; |
0 | 67 } |
68 status = 0; | |
69 } | |
70 default_joystick = NULL; | |
71 return(status); | |
72 } | |
73 | |
74 /* | |
75 * Count the number of joysticks attached to the system | |
76 */ | |
77 int SDL_NumJoysticks(void) | |
78 { | |
79 return SDL_numjoysticks; | |
80 } | |
81 | |
82 /* | |
83 * Get the implementation dependent name of a joystick | |
84 */ | |
85 const char *SDL_JoystickName(int device_index) | |
86 { | |
87 if ( (device_index < 0) || (device_index >= SDL_numjoysticks) ) { | |
88 SDL_SetError("There are %d joysticks available", | |
89 SDL_numjoysticks); | |
90 return(NULL); | |
91 } | |
92 return(SDL_SYS_JoystickName(device_index)); | |
93 } | |
94 | |
95 /* | |
96 * Open a joystick for use - the index passed as an argument refers to | |
97 * the N'th joystick on the system. This index is the value which will | |
98 * identify this joystick in future joystick events. | |
99 * | |
100 * This function returns a joystick identifier, or NULL if an error occurred. | |
101 */ | |
102 SDL_Joystick *SDL_JoystickOpen(int device_index) | |
103 { | |
104 int i; | |
105 SDL_Joystick *joystick; | |
106 | |
107 if ( (device_index < 0) || (device_index >= SDL_numjoysticks) ) { | |
108 SDL_SetError("There are %d joysticks available", | |
109 SDL_numjoysticks); | |
110 return(NULL); | |
111 } | |
112 | |
113 /* If the joystick is already open, return it */ | |
114 for ( i=0; SDL_joysticks[i]; ++i ) { | |
115 if ( device_index == SDL_joysticks[i]->index ) { | |
116 joystick = SDL_joysticks[i]; | |
117 ++joystick->ref_count; | |
118 return(joystick); | |
119 } | |
120 } | |
121 | |
122 /* Create and initialize the joystick */ | |
123 joystick = (SDL_Joystick *)malloc((sizeof *joystick)); | |
124 if ( joystick != NULL ) { | |
125 memset(joystick, 0, (sizeof *joystick)); | |
126 joystick->index = device_index; | |
127 if ( SDL_SYS_JoystickOpen(joystick) < 0 ) { | |
128 free(joystick); | |
129 joystick = NULL; | |
130 } else { | |
131 if ( joystick->naxes > 0 ) { | |
132 joystick->axes = (Sint16 *)malloc | |
133 (joystick->naxes*sizeof(Sint16)); | |
134 } | |
135 if ( joystick->nhats > 0 ) { | |
136 joystick->hats = (Uint8 *)malloc | |
137 (joystick->nhats*sizeof(Uint8)); | |
138 } | |
139 if ( joystick->nballs > 0 ) { | |
140 joystick->balls = (struct balldelta *)malloc | |
141 (joystick->nballs*sizeof(*joystick->balls)); | |
142 } | |
143 if ( joystick->nbuttons > 0 ) { | |
144 joystick->buttons = (Uint8 *)malloc | |
145 (joystick->nbuttons*sizeof(Uint8)); | |
146 } | |
147 if ( ((joystick->naxes > 0) && !joystick->axes) | |
148 || ((joystick->nhats > 0) && !joystick->hats) | |
149 || ((joystick->nballs > 0) && !joystick->balls) | |
150 || ((joystick->nbuttons > 0) && !joystick->buttons)) { | |
151 SDL_OutOfMemory(); | |
152 SDL_JoystickClose(joystick); | |
153 joystick = NULL; | |
154 } | |
155 if ( joystick->axes ) { | |
156 memset(joystick->axes, 0, | |
157 joystick->naxes*sizeof(Sint16)); | |
158 } | |
159 if ( joystick->hats ) { | |
160 memset(joystick->hats, 0, | |
161 joystick->nhats*sizeof(Uint8)); | |
162 } | |
163 if ( joystick->balls ) { | |
164 memset(joystick->balls, 0, | |
165 joystick->nballs*sizeof(*joystick->balls)); | |
166 } | |
167 if ( joystick->buttons ) { | |
168 memset(joystick->buttons, 0, | |
169 joystick->nbuttons*sizeof(Uint8)); | |
170 } | |
171 } | |
172 } | |
173 if ( joystick ) { | |
174 /* Add joystick to list */ | |
175 ++joystick->ref_count; | |
176 SDL_Lock_EventThread(); | |
177 for ( i=0; SDL_joysticks[i]; ++i ) | |
178 /* Skip to next joystick */; | |
179 SDL_joysticks[i] = joystick; | |
180 SDL_Unlock_EventThread(); | |
181 } | |
182 return(joystick); | |
183 } | |
184 | |
185 /* | |
186 * Returns 1 if the joystick has been opened, or 0 if it has not. | |
187 */ | |
188 int SDL_JoystickOpened(int device_index) | |
189 { | |
190 int i, opened; | |
191 | |
192 opened = 0; | |
193 for ( i=0; SDL_joysticks[i]; ++i ) { | |
194 if ( SDL_joysticks[i]->index == (Uint8)device_index ) { | |
195 opened = 1; | |
196 break; | |
197 } | |
198 } | |
199 return(opened); | |
200 } | |
201 | |
202 static int ValidJoystick(SDL_Joystick **joystick) | |
203 { | |
204 int valid; | |
205 | |
206 if ( *joystick == NULL ) { | |
207 *joystick = default_joystick; | |
208 } | |
209 if ( *joystick == NULL ) { | |
210 SDL_SetError("Joystick hasn't been opened yet"); | |
211 valid = 0; | |
212 } else { | |
213 valid = 1; | |
214 } | |
215 return valid; | |
216 } | |
217 | |
218 /* | |
219 * Get the device index of an opened joystick. | |
220 */ | |
221 int SDL_JoystickIndex(SDL_Joystick *joystick) | |
222 { | |
223 if ( ! ValidJoystick(&joystick) ) { | |
224 return(-1); | |
225 } | |
226 return(joystick->index); | |
227 } | |
228 | |
229 /* | |
230 * Get the number of multi-dimensional axis controls on a joystick | |
231 */ | |
232 int SDL_JoystickNumAxes(SDL_Joystick *joystick) | |
233 { | |
234 if ( ! ValidJoystick(&joystick) ) { | |
235 return(-1); | |
236 } | |
237 return(joystick->naxes); | |
238 } | |
239 | |
240 /* | |
241 * Get the number of hats on a joystick | |
242 */ | |
243 int SDL_JoystickNumHats(SDL_Joystick *joystick) | |
244 { | |
245 if ( ! ValidJoystick(&joystick) ) { | |
246 return(-1); | |
247 } | |
248 return(joystick->nhats); | |
249 } | |
250 | |
251 /* | |
252 * Get the number of trackballs on a joystick | |
253 */ | |
254 int SDL_JoystickNumBalls(SDL_Joystick *joystick) | |
255 { | |
256 if ( ! ValidJoystick(&joystick) ) { | |
257 return(-1); | |
258 } | |
259 return(joystick->nballs); | |
260 } | |
261 | |
262 /* | |
263 * Get the number of buttons on a joystick | |
264 */ | |
265 int SDL_JoystickNumButtons(SDL_Joystick *joystick) | |
266 { | |
267 if ( ! ValidJoystick(&joystick) ) { | |
268 return(-1); | |
269 } | |
270 return(joystick->nbuttons); | |
271 } | |
272 | |
273 /* | |
274 * Get the current state of an axis control on a joystick | |
275 */ | |
276 Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis) | |
277 { | |
278 Sint16 state; | |
279 | |
280 if ( ! ValidJoystick(&joystick) ) { | |
281 return(0); | |
282 } | |
283 if ( axis < joystick->naxes ) { | |
284 state = joystick->axes[axis]; | |
285 } else { | |
286 SDL_SetError("Joystick only has %d axes", joystick->naxes); | |
287 state = 0; | |
288 } | |
289 return(state); | |
290 } | |
291 | |
292 /* | |
293 * Get the current state of a hat on a joystick | |
294 */ | |
295 Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat) | |
296 { | |
297 Uint8 state; | |
298 | |
299 if ( ! ValidJoystick(&joystick) ) { | |
300 return(0); | |
301 } | |
302 if ( hat < joystick->nhats ) { | |
303 state = joystick->hats[hat]; | |
304 } else { | |
305 SDL_SetError("Joystick only has %d hats", joystick->nhats); | |
306 state = 0; | |
307 } | |
308 return(state); | |
309 } | |
310 | |
311 /* | |
312 * Get the ball axis change since the last poll | |
313 */ | |
314 int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy) | |
315 { | |
316 int retval; | |
317 | |
318 if ( ! ValidJoystick(&joystick) ) { | |
319 return(-1); | |
320 } | |
321 | |
322 retval = 0; | |
323 if ( ball < joystick->nballs ) { | |
324 if ( dx ) { | |
325 *dx = joystick->balls[ball].dx; | |
326 } | |
327 if ( dy ) { | |
328 *dy = joystick->balls[ball].dy; | |
329 } | |
330 joystick->balls[ball].dx = 0; | |
331 joystick->balls[ball].dy = 0; | |
332 } else { | |
333 SDL_SetError("Joystick only has %d balls", joystick->nballs); | |
334 retval = -1; | |
335 } | |
336 return(retval); | |
337 } | |
338 | |
339 /* | |
340 * Get the current state of a button on a joystick | |
341 */ | |
342 Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button) | |
343 { | |
344 Uint8 state; | |
345 | |
346 if ( ! ValidJoystick(&joystick) ) { | |
347 return(0); | |
348 } | |
349 if ( button < joystick->nbuttons ) { | |
350 state = joystick->buttons[button]; | |
351 } else { | |
352 SDL_SetError("Joystick only has %d buttons",joystick->nbuttons); | |
353 state = 0; | |
354 } | |
355 return(state); | |
356 } | |
357 | |
358 /* | |
359 * Close a joystick previously opened with SDL_JoystickOpen() | |
360 */ | |
361 void SDL_JoystickClose(SDL_Joystick *joystick) | |
362 { | |
363 int i; | |
364 | |
365 if ( ! ValidJoystick(&joystick) ) { | |
366 return; | |
367 } | |
368 | |
369 /* First decrement ref count */ | |
370 if ( --joystick->ref_count > 0 ) { | |
371 return; | |
372 } | |
373 | |
374 /* Lock the event queue - prevent joystick polling */ | |
375 SDL_Lock_EventThread(); | |
376 | |
377 if ( joystick == default_joystick ) { | |
378 default_joystick = NULL; | |
379 } | |
380 SDL_SYS_JoystickClose(joystick); | |
381 | |
382 /* Remove joystick from list */ | |
383 for ( i=0; SDL_joysticks[i]; ++i ) { | |
384 if ( joystick == SDL_joysticks[i] ) { | |
385 memcpy(&SDL_joysticks[i], &SDL_joysticks[i+1], | |
386 (SDL_numjoysticks-i)*sizeof(joystick)); | |
387 break; | |
388 } | |
389 } | |
390 | |
391 /* Let the event thread keep running */ | |
392 SDL_Unlock_EventThread(); | |
393 | |
394 /* Free the data associated with this joystick */ | |
395 if ( joystick->axes ) { | |
396 free(joystick->axes); | |
397 } | |
398 if ( joystick->hats ) { | |
399 free(joystick->hats); | |
400 } | |
401 if ( joystick->balls ) { | |
402 free(joystick->balls); | |
403 } | |
404 if ( joystick->buttons ) { | |
405 free(joystick->buttons); | |
406 } | |
407 free(joystick); | |
408 } | |
409 | |
410 void SDL_JoystickQuit(void) | |
411 { | |
412 /* Stop the event polling */ | |
413 SDL_Lock_EventThread(); | |
414 SDL_numjoysticks = 0; | |
415 SDL_Unlock_EventThread(); | |
416 | |
417 /* Quit the joystick setup */ | |
418 SDL_SYS_JoystickQuit(); | |
419 if ( SDL_joysticks ) { | |
420 free(SDL_joysticks); | |
421 SDL_joysticks = NULL; | |
422 } | |
423 } | |
424 | |
425 | |
426 /* These are global for SDL_sysjoystick.c and SDL_events.c */ | |
427 | |
428 int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value) | |
429 { | |
430 int posted; | |
431 | |
432 /* Update internal joystick state */ | |
433 joystick->axes[axis] = value; | |
434 | |
435 /* Post the event, if desired */ | |
436 posted = 0; | |
437 #ifndef DISABLE_EVENTS | |
438 if ( SDL_ProcessEvents[SDL_JOYAXISMOTION] == SDL_ENABLE ) { | |
439 SDL_Event event; | |
440 event.type = SDL_JOYAXISMOTION; | |
441 event.jaxis.which = joystick->index; | |
442 event.jaxis.axis = axis; | |
443 event.jaxis.value = value; | |
444 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { | |
445 posted = 1; | |
446 SDL_PushEvent(&event); | |
447 } | |
448 } | |
449 #endif /* !DISABLE_EVENTS */ | |
450 return(posted); | |
451 } | |
452 | |
453 int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value) | |
454 { | |
455 int posted; | |
456 | |
457 /* Update internal joystick state */ | |
458 joystick->hats[hat] = value; | |
459 | |
460 /* Post the event, if desired */ | |
461 posted = 0; | |
462 #ifndef DISABLE_EVENTS | |
463 if ( SDL_ProcessEvents[SDL_JOYHATMOTION] == SDL_ENABLE ) { | |
464 SDL_Event event; | |
465 event.jhat.type = SDL_JOYHATMOTION; | |
466 event.jhat.which = joystick->index; | |
467 event.jhat.hat = hat; | |
468 event.jhat.value = value; | |
469 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { | |
470 posted = 1; | |
471 SDL_PushEvent(&event); | |
472 } | |
473 } | |
474 #endif /* !DISABLE_EVENTS */ | |
475 return(posted); | |
476 } | |
477 | |
478 int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, | |
479 Sint16 xrel, Sint16 yrel) | |
480 { | |
481 int posted; | |
482 | |
483 /* Update internal mouse state */ | |
484 joystick->balls[ball].dx += xrel; | |
485 joystick->balls[ball].dy += yrel; | |
486 | |
487 /* Post the event, if desired */ | |
488 posted = 0; | |
489 #ifndef DISABLE_EVENTS | |
490 if ( SDL_ProcessEvents[SDL_JOYBALLMOTION] == SDL_ENABLE ) { | |
491 SDL_Event event; | |
492 event.jball.type = SDL_JOYBALLMOTION; | |
493 event.jball.which = joystick->index; | |
494 event.jball.ball = ball; | |
495 event.jball.xrel = xrel; | |
496 event.jball.yrel = yrel; | |
497 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { | |
498 posted = 1; | |
499 SDL_PushEvent(&event); | |
500 } | |
501 } | |
502 #endif /* !DISABLE_EVENTS */ | |
503 return(posted); | |
504 } | |
505 | |
506 int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state) | |
507 { | |
508 int posted; | |
509 #ifndef DISABLE_EVENTS | |
510 SDL_Event event; | |
511 | |
512 switch ( state ) { | |
513 case SDL_PRESSED: | |
514 event.type = SDL_JOYBUTTONDOWN; | |
515 break; | |
516 case SDL_RELEASED: | |
517 event.type = SDL_JOYBUTTONUP; | |
518 break; | |
519 default: | |
520 /* Invalid state -- bail */ | |
521 return(0); | |
522 } | |
523 #endif /* !DISABLE_EVENTS */ | |
524 | |
525 /* Update internal joystick state */ | |
526 joystick->buttons[button] = state; | |
527 | |
528 /* Post the event, if desired */ | |
529 posted = 0; | |
530 #ifndef DISABLE_EVENTS | |
531 if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) { | |
532 event.jbutton.which = joystick->index; | |
533 event.jbutton.button = button; | |
534 event.jbutton.state = state; | |
535 if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { | |
536 posted = 1; | |
537 SDL_PushEvent(&event); | |
538 } | |
539 } | |
540 #endif /* !DISABLE_EVENTS */ | |
541 return(posted); | |
542 } | |
543 | |
544 void SDL_JoystickUpdate(void) | |
545 { | |
546 int i; | |
547 | |
548 for ( i=0; SDL_joysticks[i]; ++i ) { | |
549 SDL_SYS_JoystickUpdate(SDL_joysticks[i]); | |
550 } | |
551 } | |
552 | |
553 int SDL_JoystickEventState(int state) | |
554 { | |
555 #ifdef DISABLE_EVENTS | |
556 return SDL_IGNORE; | |
557 #else | |
558 const Uint8 event_list[] = { | |
559 SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION, | |
560 SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, | |
561 }; | |
562 int i; | |
563 | |
564 switch (state) { | |
565 case SDL_QUERY: | |
566 state = SDL_IGNORE; | |
567 for ( i=0; i<SDL_TABLESIZE(event_list); ++i ) { | |
568 state = SDL_EventState(event_list[i],SDL_QUERY); | |
569 if ( state == SDL_ENABLE ) { | |
570 break; | |
571 } | |
572 } | |
573 break; | |
574 default: | |
575 for ( i=0; i<SDL_TABLESIZE(event_list); ++i ) { | |
576 SDL_EventState(event_list[i], state); | |
577 } | |
578 break; | |
579 } | |
580 return(state); | |
581 #endif /* DISABLE_EVENTS */ | |
582 } |