pcsxr-1.9.92
[pcsx_rearmed.git] / macosx / plugins / DFInput / SDL / src / joystick / SDL_joystick.c
CommitLineData
ef79bbde
P
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24/* This is the joystick API for Simple DirectMedia Layer */
25#include "SDL.h"
26#include "SDL_sysjoystick.h"
27#include "SDL_joystick_c.h"
28
29/* This is used for Quake III Arena */
30#define SDL_Lock_EventThread()
31#define SDL_Unlock_EventThread()
32
33Uint8 SDL_numjoysticks = 0;
34SDL_Joystick **SDL_joysticks = NULL;
35static SDL_Joystick *default_joystick = NULL;
36
37int
38SDL_JoystickInit(void)
39{
40 int arraylen;
41 int status;
42
43 SDL_numjoysticks = 0;
44 status = SDL_SYS_JoystickInit();
45 if (status >= 0) {
46 arraylen = (status + 1) * sizeof(*SDL_joysticks);
47 SDL_joysticks = (SDL_Joystick **) SDL_malloc(arraylen);
48 if (SDL_joysticks == NULL) {
49 SDL_numjoysticks = 0;
50 } else {
51 SDL_memset(SDL_joysticks, 0, arraylen);
52 SDL_numjoysticks = status;
53 }
54 status = 0;
55 }
56 default_joystick = NULL;
57 return (status);
58}
59
60/*
61 * Count the number of joysticks attached to the system
62 */
63int
64SDL_NumJoysticks(void)
65{
66 return SDL_numjoysticks;
67}
68
69/*
70 * Get the implementation dependent name of a joystick
71 */
72const char *
73SDL_JoystickName(int device_index)
74{
75 if ((device_index < 0) || (device_index >= SDL_numjoysticks)) {
76 SDL_SetError("There are %d joysticks available", SDL_numjoysticks);
77 return (NULL);
78 }
79 return (SDL_SYS_JoystickName(device_index));
80}
81
82/*
83 * Open a joystick for use - the index passed as an argument refers to
84 * the N'th joystick on the system. This index is the value which will
85 * identify this joystick in future joystick events.
86 *
87 * This function returns a joystick identifier, or NULL if an error occurred.
88 */
89SDL_Joystick *
90SDL_JoystickOpen(int device_index)
91{
92 int i;
93 SDL_Joystick *joystick;
94
95 if ((device_index < 0) || (device_index >= SDL_numjoysticks)) {
96 SDL_SetError("There are %d joysticks available", SDL_numjoysticks);
97 return (NULL);
98 }
99
100 /* If the joystick is already open, return it */
101 for (i = 0; SDL_joysticks[i]; ++i) {
102 if (device_index == SDL_joysticks[i]->index) {
103 joystick = SDL_joysticks[i];
104 ++joystick->ref_count;
105 return (joystick);
106 }
107 }
108
109 /* Create and initialize the joystick */
110 joystick = (SDL_Joystick *) SDL_malloc((sizeof *joystick));
111 if (joystick == NULL) {
112 SDL_OutOfMemory();
113 return NULL;
114 }
115
116 SDL_memset(joystick, 0, (sizeof *joystick));
117 joystick->index = device_index;
118 if (SDL_SYS_JoystickOpen(joystick) < 0) {
119 SDL_free(joystick);
120 return NULL;
121 }
122 if (joystick->naxes > 0) {
123 joystick->axes = (Sint16 *) SDL_malloc
124 (joystick->naxes * sizeof(Sint16));
125 }
126 if (joystick->nhats > 0) {
127 joystick->hats = (Uint8 *) SDL_malloc
128 (joystick->nhats * sizeof(Uint8));
129 }
130 if (joystick->nballs > 0) {
131 joystick->balls = (struct balldelta *) SDL_malloc
132 (joystick->nballs * sizeof(*joystick->balls));
133 }
134 if (joystick->nbuttons > 0) {
135 joystick->buttons = (Uint8 *) SDL_malloc
136 (joystick->nbuttons * sizeof(Uint8));
137 }
138 if (((joystick->naxes > 0) && !joystick->axes)
139 || ((joystick->nhats > 0) && !joystick->hats)
140 || ((joystick->nballs > 0) && !joystick->balls)
141 || ((joystick->nbuttons > 0) && !joystick->buttons)) {
142 SDL_OutOfMemory();
143 SDL_JoystickClose(joystick);
144 return NULL;
145 }
146 if (joystick->axes) {
147 SDL_memset(joystick->axes, 0, joystick->naxes * sizeof(Sint16));
148 }
149 if (joystick->hats) {
150 SDL_memset(joystick->hats, 0, joystick->nhats * sizeof(Uint8));
151 }
152 if (joystick->balls) {
153 SDL_memset(joystick->balls, 0,
154 joystick->nballs * sizeof(*joystick->balls));
155 }
156 if (joystick->buttons) {
157 SDL_memset(joystick->buttons, 0, joystick->nbuttons * sizeof(Uint8));
158 }
159
160 /* Add joystick to list */
161 ++joystick->ref_count;
162 SDL_Lock_EventThread();
163 for (i = 0; SDL_joysticks[i]; ++i)
164 /* Skip to next joystick */ ;
165 SDL_joysticks[i] = joystick;
166 SDL_Unlock_EventThread();
167
168 return (joystick);
169}
170
171/*
172 * Returns 1 if the joystick has been opened, or 0 if it has not.
173 */
174int
175SDL_JoystickOpened(int device_index)
176{
177 int i, opened;
178
179 opened = 0;
180 for (i = 0; SDL_joysticks[i]; ++i) {
181 if (SDL_joysticks[i]->index == (Uint8) device_index) {
182 opened = 1;
183 break;
184 }
185 }
186 return (opened);
187}
188
189
190/*
191 * Checks to make sure the joystick is valid.
192 */
193int
194SDL_PrivateJoystickValid(SDL_Joystick ** joystick)
195{
196 int valid;
197
198 if (*joystick == NULL) {
199 *joystick = default_joystick;
200 }
201 if (*joystick == NULL) {
202 SDL_SetError("Joystick hasn't been opened yet");
203 valid = 0;
204 } else {
205 valid = 1;
206 }
207 return valid;
208}
209
210/*
211 * Get the device index of an opened joystick.
212 */
213int
214SDL_JoystickIndex(SDL_Joystick * joystick)
215{
216 if (!SDL_PrivateJoystickValid(&joystick)) {
217 return (-1);
218 }
219 return (joystick->index);
220}
221
222/*
223 * Get the number of multi-dimensional axis controls on a joystick
224 */
225int
226SDL_JoystickNumAxes(SDL_Joystick * joystick)
227{
228 if (!SDL_PrivateJoystickValid(&joystick)) {
229 return (-1);
230 }
231 return (joystick->naxes);
232}
233
234/*
235 * Get the number of hats on a joystick
236 */
237int
238SDL_JoystickNumHats(SDL_Joystick * joystick)
239{
240 if (!SDL_PrivateJoystickValid(&joystick)) {
241 return (-1);
242 }
243 return (joystick->nhats);
244}
245
246/*
247 * Get the number of trackballs on a joystick
248 */
249int
250SDL_JoystickNumBalls(SDL_Joystick * joystick)
251{
252 if (!SDL_PrivateJoystickValid(&joystick)) {
253 return (-1);
254 }
255 return (joystick->nballs);
256}
257
258/*
259 * Get the number of buttons on a joystick
260 */
261int
262SDL_JoystickNumButtons(SDL_Joystick * joystick)
263{
264 if (!SDL_PrivateJoystickValid(&joystick)) {
265 return (-1);
266 }
267 return (joystick->nbuttons);
268}
269
270/*
271 * Get the current state of an axis control on a joystick
272 */
273Sint16
274SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis)
275{
276 Sint16 state;
277
278 if (!SDL_PrivateJoystickValid(&joystick)) {
279 return (0);
280 }
281 if (axis < joystick->naxes) {
282 state = joystick->axes[axis];
283 } else {
284 SDL_SetError("Joystick only has %d axes", joystick->naxes);
285 state = 0;
286 }
287 return (state);
288}
289
290/*
291 * Get the current state of a hat on a joystick
292 */
293Uint8
294SDL_JoystickGetHat(SDL_Joystick * joystick, int hat)
295{
296 Uint8 state;
297
298 if (!SDL_PrivateJoystickValid(&joystick)) {
299 return (0);
300 }
301 if (hat < joystick->nhats) {
302 state = joystick->hats[hat];
303 } else {
304 SDL_SetError("Joystick only has %d hats", joystick->nhats);
305 state = 0;
306 }
307 return (state);
308}
309
310/*
311 * Get the ball axis change since the last poll
312 */
313int
314SDL_JoystickGetBall(SDL_Joystick * joystick, int ball, int *dx, int *dy)
315{
316 int retval;
317
318 if (!SDL_PrivateJoystickValid(&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 */
342Uint8
343SDL_JoystickGetButton(SDL_Joystick * joystick, int button)
344{
345 Uint8 state;
346
347 if (!SDL_PrivateJoystickValid(&joystick)) {
348 return (0);
349 }
350 if (button < joystick->nbuttons) {
351 state = joystick->buttons[button];
352 } else {
353 SDL_SetError("Joystick only has %d buttons", joystick->nbuttons);
354 state = 0;
355 }
356 return (state);
357}
358
359/*
360 * Close a joystick previously opened with SDL_JoystickOpen()
361 */
362void
363SDL_JoystickClose(SDL_Joystick * joystick)
364{
365 int i;
366
367 if (!SDL_PrivateJoystickValid(&joystick)) {
368 return;
369 }
370
371 /* First decrement ref count */
372 if (--joystick->ref_count > 0) {
373 return;
374 }
375
376 /* Lock the event queue - prevent joystick polling */
377 SDL_Lock_EventThread();
378
379 if (joystick == default_joystick) {
380 default_joystick = NULL;
381 }
382 SDL_SYS_JoystickClose(joystick);
383
384 /* Remove joystick from list */
385 for (i = 0; SDL_joysticks[i]; ++i) {
386 if (joystick == SDL_joysticks[i]) {
387 SDL_memmove(&SDL_joysticks[i], &SDL_joysticks[i + 1],
388 (SDL_numjoysticks - i) * sizeof(joystick));
389 break;
390 }
391 }
392
393 /* Let the event thread keep running */
394 SDL_Unlock_EventThread();
395
396 /* Free the data associated with this joystick */
397 if (joystick->axes) {
398 SDL_free(joystick->axes);
399 }
400 if (joystick->hats) {
401 SDL_free(joystick->hats);
402 }
403 if (joystick->balls) {
404 SDL_free(joystick->balls);
405 }
406 if (joystick->buttons) {
407 SDL_free(joystick->buttons);
408 }
409 SDL_free(joystick);
410}
411
412void
413SDL_JoystickQuit(void)
414{
415 /* Stop the event polling */
416 SDL_Lock_EventThread();
417 SDL_numjoysticks = 0;
418 SDL_Unlock_EventThread();
419
420 /* Quit the joystick setup */
421 SDL_SYS_JoystickQuit();
422 if (SDL_joysticks) {
423 SDL_free(SDL_joysticks);
424 SDL_joysticks = NULL;
425 }
426}
427
428
429/* These are global for SDL_sysjoystick.c and SDL_events.c */
430
431int
432SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
433{
434 int posted;
435
436 /* Update internal joystick state */
437 joystick->axes[axis] = value;
438
439 /* Post the event, if desired */
440 posted = 0;
441
442 return (posted);
443}
444
445int
446SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value)
447{
448 int posted;
449
450 /* Update internal joystick state */
451 joystick->hats[hat] = value;
452
453 /* Post the event, if desired */
454 posted = 0;
455
456 return (posted);
457}
458
459int
460SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball,
461 Sint16 xrel, Sint16 yrel)
462{
463 int posted;
464
465 /* Update internal mouse state */
466 joystick->balls[ball].dx += xrel;
467 joystick->balls[ball].dy += yrel;
468
469 /* Post the event, if desired */
470 posted = 0;
471
472 return (posted);
473}
474
475int
476SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state)
477{
478 int posted;
479
480 /* Update internal joystick state */
481 joystick->buttons[button] = state;
482
483 /* Post the event, if desired */
484 posted = 0;
485
486 return (posted);
487}
488
489void
490SDL_JoystickUpdate(void)
491{
492 int i;
493
494 for (i = 0; SDL_joysticks[i]; ++i) {
495 SDL_SYS_JoystickUpdate(SDL_joysticks[i]);
496 }
497}
498
499int
500SDL_JoystickEventState(int state)
501{
502 return SDL_IGNORE;
503}