1 /* Title: USB Joystick library
3 Written by Puck2099 (puck2099@gmail.com), (c) 2006.
4 <http://www.gp32wip.com>
6 If you use this library or a part of it, please, let it know.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <stdio.h> /* For the definition of NULL */
25 #include <sys/types.h> // For Device open
27 #include <sys/ioctl.h>
29 #include <unistd.h> // For Device read
32 #include <limits.h> /* For the definition of PATH_MAX */
33 #include <linux/joystick.h>
37 /* This is a try to support analog joys. Untested. */
38 #define DEAD_ZONE (8*1024)
43 Opens a USB joystick and fills its information.
47 joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick).
51 Filled usbjoy structure.
54 struct usbjoy *joy_open(int joynumber)
58 struct usbjoy * joy = NULL;
59 struct js_event event;
61 static char insmod_done = 0;
62 // notaz: on my system I get unresolved input_* symbols, so have to 'insmod input' too
63 // also we should insmod only once, not on every joy_open() call.
65 system ("insmod input");
66 system ("insmod joydev"); // Loads joydev module
73 else if (joynumber > 0) {
74 sprintf (path, "/dev/input/js%d", joynumber-1);
75 fd = open(path, O_RDONLY, 0);
77 sprintf (path, "/dev/js%d", joynumber-1);
78 fd = open(path, O_RDONLY, 0);
81 joy = (struct usbjoy *) malloc(sizeof(*joy));
82 if (joy == NULL) { close(fd); return NULL; }
83 memset(joy, 0, sizeof(*joy));
85 // Set the joystick to non-blocking read mode
86 fcntl(fd, F_SETFL, O_NONBLOCK);
88 // notaz: maybe we should flush init events now.
89 // My pad returns axis as active when I plug it in, which is kind of annoying.
90 while (read(fd, &event, sizeof(event)) > 0);
92 // Joystick's file descriptor
96 ioctl(joy->fd, JSIOCGNAME(128*sizeof(char)), joy->name);
99 strcpy(joy->device, path);
101 // Joystick's buttons
102 ioctl(joy->fd, JSIOCGBUTTONS, &joy->numbuttons);
105 ioctl(joy->fd, JSIOCGAXES, &joy->numaxes);
107 // Joystick's type (derived from name)
108 if (strncasecmp(joy->name, "logitech", strlen("logitech")) == 0)
109 joy->type = JOY_TYPE_LOGITECH;
110 else joy->type = JOY_TYPE_GENERIC;
112 // printf ("ERROR: No Joystick found\n");
121 Returns Joystick's name.
125 joy - Selected joystick.
129 Joystick's name or NULL if <usbjoy> struct is empty.
131 char * joy_name (struct usbjoy * joy) {
132 if (joy != NULL) return joy->name;
140 Returns Joystick's device.
144 joy - Selected joystick.
148 Joystick's device or NULL if <usbjoy> struct is empty.
150 char * joy_device (struct usbjoy * joy) {
151 if (joy != NULL) return joy->device;
157 Function: joy_buttons
159 Returns Joystick's buttons number.
163 joy - Selected joystick.
167 Joystick's buttons or 0 if <usbjoy> struct is empty.
169 int joy_buttons (struct usbjoy * joy) {
170 if (joy != NULL) return joy->numbuttons;
178 Returns Joystick's axes number.
182 joy - Selected joystick.
186 Joystick's axes or 0 if <usbjoy> struct is empty.
188 int joy_axes (struct usbjoy * joy) {
189 if (joy != NULL) return joy->numaxes;
197 Updates Joystick's internal information (<statebuttons> and <stateaxes> fields).
201 joy - Selected joystick.
205 0 - No events registered (no need to update).
206 1 - Events registered (a button or axe has been pushed).
207 -1 - Error: <usbjoy> struct is empty.
209 int joy_update (struct usbjoy * joy) {
210 struct js_event events[0xff];
214 if ((len=read(joy->fd, events, (sizeof events))) >0) {
215 len /= sizeof(events[0]);
216 for ( i=0; i<len; ++i ) {
217 switch (events[i].type & ~JS_EVENT_INIT) {
219 if (events[i].number == 0) {
220 joy->stateaxes[JOYLEFT] = joy->stateaxes[JOYRIGHT] = 0;
221 if (events[i].value < -DEAD_ZONE) joy->stateaxes[JOYLEFT] = 1;
222 else if (events[i].value > DEAD_ZONE) joy->stateaxes[JOYRIGHT] = 1;
223 joy->axevals[0] = events[i].value;
225 else if (events[i].number == 1) {
226 joy->stateaxes[JOYUP] = joy->stateaxes[JOYDOWN] = 0;
227 if (events[i].value < -DEAD_ZONE) joy->stateaxes[JOYUP] = 1;
228 else if (events[i].value > DEAD_ZONE) joy->stateaxes[JOYDOWN] = 1;
229 joy->axevals[1] = events[i].value;
233 case JS_EVENT_BUTTON:
234 joy->statebuttons[events[i].number] = events[i].value;
251 Function: joy_getbutton
253 Returns Joystick's button information.
257 button - Button which value you want to know (from 0 to 31).
258 joy - Selected joystick.
262 0 - Button NOT pushed.
264 -1 - Error: <usbjoy> struct is empty.
266 int joy_getbutton (int button, struct usbjoy * joy) {
268 if (button < joy_buttons(joy)) return joy->statebuttons[button];
278 Returns Joystick's axes information.
282 axe - Axe which value you want to know (see <Axes values>).
283 joy - Selected joystick.
287 0 - Direction NOT pushed.
288 1 - Direction pushed.
289 -1 - Error: <usbjoy> struct is empty.
291 int joy_getaxe (int axe, struct usbjoy * joy) {
293 if (axe < 4) return joy->stateaxes[axe];
303 Closes selected joystick's file descriptor and detroys it's fields.
307 joy - Selected joystick.
311 0 - Joystick successfully closed.
312 -1 - Error: <usbjoy> struct is empty.
314 int joy_close (struct usbjoy * joy) {
324 /*********************************************************************/
326 #include "../common/common.h"
329 struct usbjoy *joys[4];
331 void usbjoy_init (void)
333 /* Open available joysticks -GnoStiC */
337 for (i = 0; i < 4; i++) {
338 joys[n] = joy_open(i+1);
339 if (joys[n] && joy_buttons(joys[n]) > 0) {
340 printf ("+-Joystick %d: \"%s\", buttons = %i\n", i+1, joy_name(joys[n]), joy_buttons(joys[n]));
346 printf("Found %d Joystick(s)\n",num_of_joys);
349 void usbjoy_update (void)
351 /* Update Joystick Event Cache */
353 for (q=0; q < num_of_joys; q++) {
354 foo = joy_update (joys[q]);
358 int usbjoy_check (int joyno)
362 struct usbjoy *joy = joys[joyno];
365 if (joy_getaxe(JOYUP, joy)) { joyExKey |= PBTN_UP; }
366 if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= PBTN_DOWN; }
367 if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= PBTN_LEFT; }
368 if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= PBTN_RIGHT; }
370 /* loop through joy buttons to check if they are pushed */
371 for (q=0; q<joy_buttons (joy); q++) {
372 if (joy_getbutton (q, joy)) {
373 if (joy->type == JOY_TYPE_LOGITECH) {
375 case 0: joyExKey |= PBTN_WEST; break;
376 case 1: joyExKey |= PBTN_SOUTH; break;
377 case 2: joyExKey |= PBTN_EAST; break;
378 case 3: joyExKey |= PBTN_NORTH; break;
382 case 0: joyExKey |= PBTN_NORTH; break;
383 case 1: joyExKey |= PBTN_EAST; break;
384 case 2: joyExKey |= PBTN_SOUTH; break;
385 case 3: joyExKey |= PBTN_WEST; break;
390 case 4: joyExKey |= PBTN_L; break;
391 case 5: joyExKey |= PBTN_R; break;
392 case 6: joyExKey |= PBTN_L; break; /* left shoulder button 2 */
393 case 7: joyExKey |= PBTN_R; break; /* right shoulder button 2 */
395 case 8: joyExKey |= GP2X_SELECT;break;
396 case 9: joyExKey |= GP2X_START; break;
397 case 10: joyExKey |= GP2X_PUSH; break;
398 case 11: joyExKey |= GP2X_PUSH; break;
407 int usbjoy_check2 (int joyno)
409 /* Check Joystick, don't map to gp2x joy */
410 int q, to, joyExKey = 0;
411 struct usbjoy *joy = joys[joyno];
414 if (joy_getaxe(JOYUP, joy)) { joyExKey |= 1 << 0; }
415 if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= 1 << 1; }
416 if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= 1 << 2; }
417 if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= 1 << 3; }
419 /* loop through joy buttons to check if they are pushed */
420 to = joy->numbuttons;
421 if (to > 32-4) to = 32-4;
422 for (q=0; q < to; q++)
423 if (joy->statebuttons[q]) joyExKey |= 1 << (q+4);
430 void usbjoy_deinit (void)
433 for (i=0; i<num_of_joys; i++) {