usbjoy.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /* Title: USB Joystick library
  2. Version 0.2
  3. Written by Puck2099 (puck2099@gmail.com), (c) 2006.
  4. <http://www.gp32wip.com>
  5. If you use this library or a part of it, please, let it know.
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2.1 of the License, or (at your option) any later version.
  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. You should have received a copy of the GNU Lesser General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <stdlib.h>
  19. #include <stdio.h> /* For the definition of NULL */
  20. #include <sys/types.h> // For Device open
  21. #include <sys/stat.h>
  22. #include <sys/ioctl.h>
  23. #include <fcntl.h>
  24. #include <unistd.h> // For Device read
  25. #include <string.h>
  26. #include <limits.h> /* For the definition of PATH_MAX */
  27. #include <linux/joystick.h>
  28. #include "usbjoy.h"
  29. /* This is a try to support analog joys. Untested. */
  30. #define DEAD_ZONE (8*1024)
  31. /*
  32. Function: joy_open
  33. Opens a USB joystick and fills its information.
  34. Parameters:
  35. joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick).
  36. Returns:
  37. Filled usbjoy structure.
  38. */
  39. struct usbjoy *joy_open(int joynumber)
  40. {
  41. int fd;
  42. char path [128];
  43. struct usbjoy * joy = NULL;
  44. struct js_event event;
  45. #ifdef __GP2X__
  46. static char insmod_done = 0;
  47. // notaz: on my system I get unresolved input_* symbols, so have to 'insmod input' too
  48. // also we should insmod only once, not on every joy_open() call.
  49. if (!insmod_done) {
  50. system ("insmod input");
  51. system ("insmod joydev"); // Loads joydev module
  52. insmod_done = 1;
  53. }
  54. #endif
  55. if (joynumber == 0) {
  56. }
  57. else if (joynumber > 0) {
  58. sprintf (path, "/dev/input/js%d", joynumber-1);
  59. fd = open(path, O_RDONLY, 0);
  60. if (fd == -1) {
  61. sprintf (path, "/dev/js%d", joynumber-1);
  62. fd = open(path, O_RDONLY, 0);
  63. }
  64. if (fd != -1) {
  65. joy = (struct usbjoy *) malloc(sizeof(*joy));
  66. if (joy == NULL) { close(fd); return NULL; }
  67. memset(joy, 0, sizeof(*joy));
  68. // Set the joystick to non-blocking read mode
  69. fcntl(fd, F_SETFL, O_NONBLOCK);
  70. // notaz: maybe we should flush init events now.
  71. // My pad returns axis as active when I plug it in, which is kind of annoying.
  72. while (read(fd, &event, sizeof(event)) > 0);
  73. // Joystick's file descriptor
  74. joy->fd = fd;
  75. // Joystick's name
  76. ioctl(joy->fd, JSIOCGNAME(128*sizeof(char)), joy->name);
  77. // Joystick's device
  78. strcpy(joy->device, path);
  79. // Joystick's buttons
  80. ioctl(joy->fd, JSIOCGBUTTONS, &joy->numbuttons);
  81. // Joystick's axes
  82. ioctl(joy->fd, JSIOCGAXES, &joy->numaxes);
  83. // Joystick's type (derived from name)
  84. if (strncasecmp(joy->name, "logitech", strlen("logitech")) == 0)
  85. joy->type = JOY_TYPE_LOGITECH;
  86. else joy->type = JOY_TYPE_GENERIC;
  87. } else {
  88. // printf ("ERROR: No Joystick found\n");
  89. }
  90. }
  91. return joy;
  92. }
  93. /*
  94. Function: joy_name
  95. Returns Joystick's name.
  96. Parameters:
  97. joy - Selected joystick.
  98. Returns:
  99. Joystick's name or NULL if <usbjoy> struct is empty.
  100. */
  101. char * joy_name (struct usbjoy * joy) {
  102. if (joy != NULL) return joy->name;
  103. else return NULL;
  104. }
  105. /*
  106. Function: joy_device
  107. Returns Joystick's device.
  108. Parameters:
  109. joy - Selected joystick.
  110. Returns:
  111. Joystick's device or NULL if <usbjoy> struct is empty.
  112. */
  113. char * joy_device (struct usbjoy * joy) {
  114. if (joy != NULL) return joy->device;
  115. else return NULL;
  116. }
  117. /*
  118. Function: joy_buttons
  119. Returns Joystick's buttons number.
  120. Parameters:
  121. joy - Selected joystick.
  122. Returns:
  123. Joystick's buttons or 0 if <usbjoy> struct is empty.
  124. */
  125. int joy_buttons (struct usbjoy * joy) {
  126. if (joy != NULL) return joy->numbuttons;
  127. else return 0;
  128. }
  129. /*
  130. Function: joy_axes
  131. Returns Joystick's axes number.
  132. Parameters:
  133. joy - Selected joystick.
  134. Returns:
  135. Joystick's axes or 0 if <usbjoy> struct is empty.
  136. */
  137. int joy_axes (struct usbjoy * joy) {
  138. if (joy != NULL) return joy->numaxes;
  139. else return 0;
  140. }
  141. /*
  142. Function: joy_update
  143. Updates Joystick's internal information (<statebuttons> and <stateaxes> fields).
  144. Parameters:
  145. joy - Selected joystick.
  146. Returns:
  147. 0 - No events registered (no need to update).
  148. 1 - Events registered (a button or axe has been pushed).
  149. -1 - Error: <usbjoy> struct is empty.
  150. */
  151. int joy_update (struct usbjoy * joy) {
  152. struct js_event events[0xff];
  153. int i, len;
  154. int event = 0;
  155. if (joy != NULL) {
  156. if ((len=read(joy->fd, events, (sizeof events))) >0) {
  157. len /= sizeof(events[0]);
  158. for ( i=0; i<len; ++i ) {
  159. switch (events[i].type & ~JS_EVENT_INIT) {
  160. case JS_EVENT_AXIS:
  161. if (events[i].number == 0) {
  162. joy->stateaxes[JOYLEFT] = joy->stateaxes[JOYRIGHT] = 0;
  163. if (events[i].value < -DEAD_ZONE) joy->stateaxes[JOYLEFT] = 1;
  164. else if (events[i].value > DEAD_ZONE) joy->stateaxes[JOYRIGHT] = 1;
  165. joy->axevals[0] = events[i].value;
  166. }
  167. else if (events[i].number == 1) {
  168. joy->stateaxes[JOYUP] = joy->stateaxes[JOYDOWN] = 0;
  169. if (events[i].value < -DEAD_ZONE) joy->stateaxes[JOYUP] = 1;
  170. else if (events[i].value > DEAD_ZONE) joy->stateaxes[JOYDOWN] = 1;
  171. joy->axevals[1] = events[i].value;
  172. }
  173. event = 1;
  174. break;
  175. case JS_EVENT_BUTTON:
  176. joy->statebuttons[events[i].number] = events[i].value;
  177. event = 1;
  178. break;
  179. default:
  180. break;
  181. }
  182. }
  183. }
  184. }
  185. else {
  186. event = -1;
  187. }
  188. return event;
  189. }
  190. /*
  191. Function: joy_getbutton
  192. Returns Joystick's button information.
  193. Parameters:
  194. button - Button which value you want to know (from 0 to 31).
  195. joy - Selected joystick.
  196. Returns:
  197. 0 - Button NOT pushed.
  198. 1 - Button pushed.
  199. -1 - Error: <usbjoy> struct is empty.
  200. */
  201. int joy_getbutton (int button, struct usbjoy * joy) {
  202. if (joy != NULL) {
  203. if (button < joy_buttons(joy)) return joy->statebuttons[button];
  204. else return 0;
  205. }
  206. else return -1;
  207. }
  208. /*
  209. Function: joy_getaxe
  210. Returns Joystick's axes information.
  211. Parameters:
  212. axe - Axe which value you want to know (see <Axes values>).
  213. joy - Selected joystick.
  214. Returns:
  215. 0 - Direction NOT pushed.
  216. 1 - Direction pushed.
  217. -1 - Error: <usbjoy> struct is empty.
  218. */
  219. int joy_getaxe (int axe, struct usbjoy * joy) {
  220. if (joy != NULL) {
  221. if (axe < 4) return joy->stateaxes[axe];
  222. else return 0;
  223. }
  224. else return -1;
  225. }
  226. /*
  227. Function: joy_close
  228. Closes selected joystick's file descriptor and detroys it's fields.
  229. Parameters:
  230. joy - Selected joystick.
  231. Returns:
  232. 0 - Joystick successfully closed.
  233. -1 - Error: <usbjoy> struct is empty.
  234. */
  235. int joy_close (struct usbjoy * joy) {
  236. if (joy != NULL) {
  237. close (joy->fd);
  238. free (joy);
  239. return 0;
  240. }
  241. else return -1;
  242. }
  243. /*********************************************************************/
  244. #include "../common/common.h"
  245. int num_of_joys = 0;
  246. struct usbjoy *joys[4];
  247. void usbjoy_init (void)
  248. {
  249. /* Open available joysticks -GnoStiC */
  250. int i, n = 0;
  251. printf("\n");
  252. for (i = 0; i < 4; i++) {
  253. joys[n] = joy_open(i+1);
  254. if (joys[n] && joy_buttons(joys[n]) > 0) {
  255. printf ("+-Joystick %d: \"%s\", buttons = %i\n", i+1, joy_name(joys[n]), joy_buttons(joys[n]));
  256. n++;
  257. }
  258. }
  259. num_of_joys = n;
  260. printf("Found %d Joystick(s)\n",num_of_joys);
  261. }
  262. void usbjoy_update (void)
  263. {
  264. /* Update Joystick Event Cache */
  265. int q, foo;
  266. for (q=0; q < num_of_joys; q++) {
  267. foo = joy_update (joys[q]);
  268. }
  269. }
  270. int usbjoy_check (int joyno)
  271. {
  272. /* Check Joystick */
  273. int q, joyExKey = 0;
  274. struct usbjoy *joy = joys[joyno];
  275. if (joy != NULL) {
  276. if (joy_getaxe(JOYUP, joy)) { joyExKey |= PBTN_UP; }
  277. if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= PBTN_DOWN; }
  278. if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= PBTN_LEFT; }
  279. if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= PBTN_RIGHT; }
  280. /* loop through joy buttons to check if they are pushed */
  281. for (q=0; q<joy_buttons (joy); q++) {
  282. if (joy_getbutton (q, joy)) {
  283. if (joy->type == JOY_TYPE_LOGITECH) {
  284. switch (q) {
  285. case 0: joyExKey |= PBTN_WEST; break;
  286. case 1: joyExKey |= PBTN_SOUTH; break;
  287. case 2: joyExKey |= PBTN_EAST; break;
  288. case 3: joyExKey |= PBTN_NORTH; break;
  289. }
  290. } else {
  291. switch (q) {
  292. case 0: joyExKey |= PBTN_NORTH; break;
  293. case 1: joyExKey |= PBTN_EAST; break;
  294. case 2: joyExKey |= PBTN_SOUTH; break;
  295. case 3: joyExKey |= PBTN_WEST; break;
  296. }
  297. }
  298. switch (q) {
  299. case 4: joyExKey |= PBTN_L; break;
  300. case 5: joyExKey |= PBTN_R; break;
  301. case 6: joyExKey |= PBTN_L; break; /* left shoulder button 2 */
  302. case 7: joyExKey |= PBTN_R; break; /* right shoulder button 2 */
  303. /*
  304. case 8: joyExKey |= GP2X_SELECT;break;
  305. case 9: joyExKey |= GP2X_START; break;
  306. case 10: joyExKey |= GP2X_PUSH; break;
  307. case 11: joyExKey |= GP2X_PUSH; break;
  308. */
  309. }
  310. }
  311. }
  312. }
  313. return joyExKey;
  314. }
  315. int usbjoy_check2 (int joyno)
  316. {
  317. /* Check Joystick, don't map to gp2x joy */
  318. int q, to, joyExKey = 0;
  319. struct usbjoy *joy = joys[joyno];
  320. if (joy != NULL) {
  321. if (joy_getaxe(JOYUP, joy)) { joyExKey |= 1 << 0; }
  322. if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= 1 << 1; }
  323. if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= 1 << 2; }
  324. if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= 1 << 3; }
  325. /* loop through joy buttons to check if they are pushed */
  326. to = joy->numbuttons;
  327. if (to > 32-4) to = 32-4;
  328. for (q=0; q < to; q++)
  329. if (joy->statebuttons[q]) joyExKey |= 1 << (q+4);
  330. }
  331. return joyExKey;
  332. }
  333. void usbjoy_deinit (void)
  334. {
  335. int i;
  336. for (i=0; i<num_of_joys; i++) {
  337. joy_close (joys[i]);
  338. joys[i] = NULL;
  339. }
  340. num_of_joys = 0;
  341. }