X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fgp2x%2Fusbjoy.c;fp=drivers%2Fgp2x%2Fusbjoy.c;h=de1178a44898f293f5be1673ae21305162171780;hb=b2b95d2e0d1fd5e52d03c2152605b09b024c1d0e;hp=0000000000000000000000000000000000000000;hpb=e1591a12a775a600572ffccb2d6f8f4d6343b7dd;p=fceu.git diff --git a/drivers/gp2x/usbjoy.c b/drivers/gp2x/usbjoy.c new file mode 100644 index 0000000..de1178a --- /dev/null +++ b/drivers/gp2x/usbjoy.c @@ -0,0 +1,424 @@ +/* Title: USB Joystick library + Version 0.2 + Written by Puck2099 (puck2099@gmail.com), (c) 2006. + + + If you use this library or a part of it, please, let it know. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include /* For the definition of NULL */ +#include // For Device open +#include +#include +#include +#include // For Device read + +#include +#include /* For the definition of PATH_MAX */ +#include + +#include "usbjoy.h" + + +/* + Function: joy_open + + Opens a USB joystick and fills its information. + + Parameters: + + joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick). + + Returns: + + Filled usbjoy structure. + +*/ +struct usbjoy *joy_open(int joynumber) +{ + int fd; + char path [128]; + struct usbjoy * joy = NULL; + struct js_event event; + static char insmod_done = 0; + + // notaz: on my system I get unresolved input_* symbols, so have to 'insmod input' too + // also we should insmod only once, not on every joy_open() call. + if (!insmod_done) { + system ("insmod input"); + system ("insmod joydev"); // Loads joydev module + insmod_done = 1; + } + + if (joynumber == 0) { + } + else if (joynumber > 0) { + sprintf (path, "/dev/input/js%d", joynumber-1); + fd = open(path, O_RDONLY, 0); + if (fd > 0) { + joy = (struct usbjoy *) malloc(sizeof(*joy)); + if (joy == NULL) { close(fd); return NULL; } + memset(joy, 0, sizeof(*joy)); + + // Set the joystick to non-blocking read mode + fcntl(fd, F_SETFL, O_NONBLOCK); + + // notaz: maybe we should flush init events now. + // My pad returns axis as active when I plug it in, which is kind of annoying. + while (read(fd, &event, sizeof(event)) > 0); + + // Joystick's file descriptor + joy->fd = fd; + + // Joystick's name + ioctl(joy->fd, JSIOCGNAME(128*sizeof(char)), joy->name); + + // Joystick's device + strcpy(joy->device, path); + + // Joystick's buttons + ioctl(joy->fd, JSIOCGBUTTONS, &joy->numbuttons); + + // Joystick's axes + ioctl(joy->fd, JSIOCGAXES, &joy->numaxes); + + // Joystick's type (derived from name) + if (strncasecmp(joy->name, "logitech", strlen("logitech")) == 0) + joy->type = JOY_TYPE_LOGITECH; + else joy->type = JOY_TYPE_GENERIC; + } else { + // printf ("ERROR: No Joystick found\n"); + } + } + return joy; +} + +/* + Function: joy_name + + Returns Joystick's name. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's name or NULL if struct is empty. +*/ +char * joy_name (struct usbjoy * joy) { + if (joy != NULL) return joy->name; + else return NULL; +} + + +/* + Function: joy_device + + Returns Joystick's device. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's device or NULL if struct is empty. +*/ +char * joy_device (struct usbjoy * joy) { + if (joy != NULL) return joy->device; + else return NULL; +} + + +/* + Function: joy_buttons + + Returns Joystick's buttons number. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's buttons or 0 if struct is empty. +*/ +int joy_buttons (struct usbjoy * joy) { + if (joy != NULL) return joy->numbuttons; + else return 0; +} + + +/* + Function: joy_axes + + Returns Joystick's axes number. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's axes or 0 if struct is empty. +*/ +int joy_axes (struct usbjoy * joy) { + if (joy != NULL) return joy->numaxes; + else return 0; +} + + +/* + Function: joy_update + + Updates Joystick's internal information ( and fields). + + Parameters: + + joy - Selected joystick. + + Returns: + + 0 - No events registered (no need to update). + 1 - Events registered (a button or axe has been pushed). + -1 - Error: struct is empty. +*/ +int joy_update (struct usbjoy * joy) { + struct js_event events[0xff]; + int i, len; + int event = 0; + if (joy != NULL) { + if ((len=read(joy->fd, events, (sizeof events))) >0) { + len /= sizeof(events[0]); + for ( i=0; istateaxes[JOYLEFT] = joy->stateaxes[JOYRIGHT] = 0; + else if (events[i].value < 0) joy->stateaxes[JOYLEFT] = 1; + else joy->stateaxes[JOYRIGHT] = 1; + } + else if (events[i].number == 1) { + if (events[i].value == 0) joy->stateaxes[JOYUP] = joy->stateaxes[JOYDOWN] = 0; + else if (events[i].value < 0) joy->stateaxes[JOYUP] = 1; + else joy->stateaxes[JOYDOWN] = 1; + } + event = 1; + break; + case JS_EVENT_BUTTON: + joy->statebuttons[events[i].number] = events[i].value; + event = 1; + break; + default: + break; + } + } + } + } + else { + event = -1; + } + return event; +} + + +/* + Function: joy_getbutton + + Returns Joystick's button information. + + Parameters: + + button - Button which value you want to know (from 0 to 31). + joy - Selected joystick. + + Returns: + + 0 - Button NOT pushed. + 1 - Button pushed. + -1 - Error: struct is empty. +*/ +int joy_getbutton (int button, struct usbjoy * joy) { + if (joy != NULL) { + if (button < joy_buttons(joy)) return joy->statebuttons[button]; + else return 0; + } + else return -1; +} + + +/* + Function: joy_getaxe + + Returns Joystick's axes information. + + Parameters: + + axe - Axe which value you want to know (see ). + joy - Selected joystick. + + Returns: + + 0 - Direction NOT pushed. + 1 - Direction pushed. + -1 - Error: struct is empty. +*/ +int joy_getaxe (int axe, struct usbjoy * joy) { + if (joy != NULL) { + if (axe < 4) return joy->stateaxes[axe]; + else return 0; + } + else return -1; +} + + +/* + Function: joy_close + + Closes selected joystick's file descriptor and detroys it's fields. + + Parameters: + + joy - Selected joystick. + + Returns: + + 0 - Joystick successfully closed. + -1 - Error: struct is empty. +*/ +int joy_close (struct usbjoy * joy) { + if (joy != NULL) { + close (joy->fd); + free (joy); + return 0; + } + else return -1; +} + + +/*********************************************************************/ +/* GP2X USB Joystick Handling -GnoStiC */ +/*********************************************************************/ + +#include "minimal.h" + +int num_of_joys = 0; +struct usbjoy *joys[4]; + +void gp2x_usbjoy_init (void) { + /* Open available joysticks -GnoStiC */ + int i, n = 0; + + printf("\n"); + for (i = 0; i < 4; i++) { + joys[n] = joy_open(i+1); + if (joys[n] && joy_buttons(joys[n]) > 0) { + printf ("+-Joystick %d: \"%s\", buttons = %i\n", i+1, joy_name(joys[n]), joy_buttons(joys[n])); + n++; + } + } + num_of_joys = n; + + printf("Found %d Joystick(s)\n",num_of_joys); +} + +void gp2x_usbjoy_update (void) { + /* Update Joystick Event Cache */ + int q, foo; + for (q=0; q < num_of_joys; q++) { + foo = joy_update (joys[q]); + } +} + +int gp2x_usbjoy_check (int joyno) { + /* Check Joystick */ + int q, joyExKey = 0; + struct usbjoy *joy = joys[joyno]; + + if (joy != NULL) { + if (joy_getaxe(JOYUP, joy)) { joyExKey |= GP2X_UP; } + if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= GP2X_DOWN; } + if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= GP2X_LEFT; } + if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= GP2X_RIGHT; } + + /* loop through joy buttons to check if they are pushed */ + for (q=0; qtype == JOY_TYPE_LOGITECH) { + switch (q) { + case 0: joyExKey |= GP2X_A; break; + case 1: joyExKey |= GP2X_X; break; + case 2: joyExKey |= GP2X_B; break; + case 3: joyExKey |= GP2X_Y; break; + } + } else { + switch (q) { + case 0: joyExKey |= GP2X_Y; break; + case 1: joyExKey |= GP2X_B; break; + case 2: joyExKey |= GP2X_X; break; + case 3: joyExKey |= GP2X_A; break; + } + } + + switch (q) { + case 4: joyExKey |= GP2X_L; break; + case 5: joyExKey |= GP2X_R; break; + case 6: joyExKey |= GP2X_L; break; /* left shoulder button 2 */ + case 7: joyExKey |= GP2X_R; break; /* right shoulder button 2 */ + case 8: joyExKey |= GP2X_SELECT;break; + case 9: joyExKey |= GP2X_START; break; + case 10: joyExKey |= GP2X_PUSH; break; + case 11: joyExKey |= GP2X_PUSH; break; + } + } + } + } + return joyExKey; +} + +int gp2x_usbjoy_check2 (int joyno) { + /* Check Joystick, don't map to gp2x joy */ + int q, to, joyExKey = 0; + struct usbjoy *joy = joys[joyno]; + + if (joy != NULL) { + if (joy_getaxe(JOYUP, joy)) { joyExKey |= 1 << 0; } + if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= 1 << 1; } + if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= 1 << 2; } + if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= 1 << 3; } + + /* loop through joy buttons to check if they are pushed */ + to = joy->numbuttons; + if (to > 32-4) to = 32-4; + for (q=0; q < to; q++) + if (joy->statebuttons[q]) joyExKey |= 1 << (q+4); + } + return joyExKey; +} + + + +void gp2x_usbjoy_deinit (void) { + int i; + for (i=0; i