SDL_sysjoystick.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:19k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_sysjoystick.c,v 1.4 2002/04/22 21:38:02 wmay Exp $";
  21. #endif
  22. /* This is the system specific header for the SDL joystick API */
  23. #include <stdio.h> /* For the definition of NULL */
  24. #include <stdlib.h> /* For getenv() prototype */
  25. #include <string.h>
  26. #include <sys/stat.h>
  27. #include <unistd.h>
  28. #include <fcntl.h>
  29. #include <sys/ioctl.h>
  30. #include <limits.h> /* For the definition of PATH_MAX */
  31. #include <linux/joystick.h>
  32. #ifdef USE_INPUT_EVENTS
  33. #include <linux/input.h>
  34. #endif
  35. #include "SDL_error.h"
  36. #include "SDL_joystick.h"
  37. #include "SDL_sysjoystick.h"
  38. #include "SDL_joystick_c.h"
  39. /* Define this if you want to map axes to hats and trackballs */
  40. #define FANCY_HATS_AND_BALLS
  41. #ifdef FANCY_HATS_AND_BALLS
  42. /* Special joystick configurations:
  43. 'JoystickName' Naxes Nhats Nballs
  44.  */
  45. static const char *special_joysticks[] = {
  46. "'MadCatz Panther XL' 3 2 1", /* We don't handle a rudder (axis 8) */
  47. "'SideWinder Precision Pro' 4 1 0",
  48. "'SideWinder 3D Pro' 4 1 0",
  49. "'Microsoft SideWinder 3D Pro' 4 1 0",
  50. "'Microsoft SideWinder Dual Strike USB version 1.0' 2 1 0",
  51. "'WingMan Interceptor' 3 3 0",
  52. /* WingMan Extreme Analog - not recognized by default
  53. "'Analog 3-axis 4-button joystick' 2 1 0",
  54. */
  55. "'WingMan Extreme Digital 3D' 4 1 0",
  56. "'Analog 2-axis 4-button 1-hat FCS joystick' 2 1 0",
  57. NULL
  58. };
  59. #else
  60. #undef USE_INPUT_EVENTS
  61. #endif
  62. /* The maximum number of joysticks we'll detect */
  63. #define MAX_JOYSTICKS 32
  64. /* A list of available joysticks */
  65. static char *SDL_joylist[MAX_JOYSTICKS];
  66. /* The private structure used to keep track of a joystick */
  67. struct joystick_hwdata {
  68. int fd;
  69. /* The current linux joystick driver maps hats to two axes */
  70. int analog_hat; /* Well, except for analog hats */
  71. struct hwdata_hat {
  72. int axis[2];
  73. } *hats;
  74. /* The current linux joystick driver maps balls to two axes */
  75. struct hwdata_ball {
  76. int axis[2];
  77. } *balls;
  78. /* Support for the Linux 2.4 unified input interface */
  79. SDL_bool is_hid;
  80. #ifdef USE_INPUT_EVENTS
  81. Uint8 key_map[KEY_MAX-BTN_MISC];
  82. Uint8 abs_map[ABS_MAX];
  83. struct axis_correct {
  84. int used;
  85. int coef[3];
  86. } abs_correct[ABS_MAX];
  87. #endif
  88. };
  89. static char *mystrdup(const char *string)
  90. {
  91. char *newstring;
  92. newstring = (char *)malloc(strlen(string)+1);
  93. if ( newstring ) {
  94. strcpy(newstring, string);
  95. }
  96. return(newstring);
  97. }
  98. #ifdef USE_INPUT_EVENTS
  99. #define test_bit(nr, addr) 
  100. (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
  101. static int EV_IsJoystick(int fd)
  102. {
  103. unsigned long evbit[40];
  104. unsigned long keybit[40];
  105. unsigned long absbit[40];
  106. if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
  107.      (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
  108.      (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) {
  109. return(0);
  110. }
  111. if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
  112.       test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
  113.      (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0;
  114. return(1);
  115. }
  116. #endif /* USE_INPUT_EVENTS */
  117. /* Function to scan the system for joysticks */
  118. int SDL_SYS_JoystickInit(void)
  119. {
  120. /* The base path of the joystick devices */
  121. const char *joydev_pattern[] = {
  122. "/dev/js%d",
  123. #ifdef USE_INPUT_EVENTS
  124. "/dev/input/event%d",
  125. #endif
  126. "/dev/input/js%d"
  127. };
  128. int numjoysticks;
  129. int i, j, done;
  130. int fd;
  131. char path[PATH_MAX];
  132. dev_t dev_nums[MAX_JOYSTICKS];  /* major/minor device numbers */
  133. struct stat sb;
  134. int n, duplicate;
  135. numjoysticks = 0;
  136. /* First see if the user specified a joystick to use */
  137. if ( getenv("SDL_JOYSTICK_DEVICE") != NULL ) {
  138. strncpy(path, getenv("SDL_JOYSTICK_DEVICE"), sizeof(path));
  139. path[sizeof(path)-1] = '';
  140. if ( stat(path, &sb) == 0 ) {
  141. fd = open(path, O_RDONLY, 0);
  142. if ( fd >= 0 ) {
  143. /* Assume the user knows what they're doing. */
  144. SDL_joylist[numjoysticks] = mystrdup(path);
  145. if ( SDL_joylist[numjoysticks] ) {
  146. dev_nums[numjoysticks] = sb.st_rdev;
  147. ++numjoysticks;
  148. }
  149. close(fd);
  150. }
  151. }
  152. }
  153. for ( i=0; i<SDL_TABLESIZE(joydev_pattern); ++i ) {
  154. done = 0;
  155. for ( j=0; (j < MAX_JOYSTICKS) && !done; ++j ) {
  156. sprintf(path, joydev_pattern[i], j);
  157. /* rcg06302000 replaced access(F_OK) call with stat().
  158.  * stat() will fail if the file doesn't exist, so it's
  159.  * equivalent behaviour.
  160.  */
  161. if ( stat(path, &sb) == 0 ) {
  162. /* Check to make sure it's not already in list.
  163.  * This happens when we see a stick via symlink.
  164.  */
  165. duplicate = 0;
  166. for (n=0; (n<numjoysticks) && !duplicate; ++n) {
  167. if ( sb.st_rdev == dev_nums[n] ) {
  168. duplicate = 1;
  169. }
  170. }
  171. if (duplicate) {
  172. continue;
  173. }
  174. fd = open(path, O_RDONLY, 0);
  175. if ( fd < 0 ) {
  176. continue;
  177. }
  178. #ifdef USE_INPUT_EVENTS
  179. #ifdef DEBUG_INPUT_EVENTS
  180. printf("Checking %sn", path);
  181. #endif
  182. if ( (i > 0) && ! EV_IsJoystick(fd) ) {
  183. close(fd);
  184. continue;
  185. }
  186. #endif
  187. close(fd);
  188. /* We're fine, add this joystick */
  189. SDL_joylist[numjoysticks] = mystrdup(path);
  190. if ( SDL_joylist[numjoysticks] ) {
  191. dev_nums[numjoysticks] = sb.st_rdev;
  192. ++numjoysticks;
  193. }
  194. } else {
  195. done = 1;
  196. }
  197. }
  198.         /* This is a special case...
  199.            If we're looking at the /dev/input event devices, and we found
  200.            at least one, then we don't want to look at the input joystick
  201.            devices, since they're built on top of devices that we've already
  202.            seen, so we're done.
  203.          */
  204.         if ( i > 0 && j > 0 ) {
  205.             done = 1;
  206.         }
  207. }
  208. return(numjoysticks);
  209. }
  210. /* Function to get the device-dependent name of a joystick */
  211. const char *SDL_SYS_JoystickName(int index)
  212. {
  213. int fd;
  214. static char namebuf[128];
  215. char *name;
  216. name = NULL;
  217. fd = open(SDL_joylist[index], O_RDONLY, 0);
  218. if ( fd >= 0 ) {
  219. if ( 
  220. #ifdef USE_INPUT_EVENTS
  221.      (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&
  222. #endif
  223.      (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) {
  224. name = SDL_joylist[index];
  225. } else {
  226. name = namebuf;
  227. }
  228. close(fd);
  229. }
  230. return name;
  231. }
  232. #ifdef FANCY_HATS_AND_BALLS
  233. static int allocate_hatdata(SDL_Joystick *joystick)
  234. {
  235. int i;
  236. joystick->hwdata->hats = (struct hwdata_hat *)malloc(
  237. joystick->nhats * sizeof(struct hwdata_hat));
  238. if ( joystick->hwdata->hats == NULL ) {
  239. return(-1);
  240. }
  241. for ( i=0; i<joystick->nhats; ++i ) {
  242. joystick->hwdata->hats[i].axis[0] = 1;
  243. joystick->hwdata->hats[i].axis[1] = 1;
  244. }
  245. return(0);
  246. }
  247. static int allocate_balldata(SDL_Joystick *joystick)
  248. {
  249. int i;
  250. joystick->hwdata->balls = (struct hwdata_ball *)malloc(
  251. joystick->nballs * sizeof(struct hwdata_ball));
  252. if ( joystick->hwdata->balls == NULL ) {
  253. return(-1);
  254. }
  255. for ( i=0; i<joystick->nballs; ++i ) {
  256. joystick->hwdata->balls[i].axis[0] = 0;
  257. joystick->hwdata->balls[i].axis[1] = 0;
  258. }
  259. return(0);
  260. }
  261. static SDL_bool ConfigJoystick(SDL_Joystick *joystick,
  262. const char *name, const char *config)
  263. {
  264. char cfg_name[128];
  265. SDL_bool handled;
  266. if ( config == NULL ) {
  267. return(SDL_FALSE);
  268. }
  269. strcpy(cfg_name, "");
  270. if ( *config == ''' ) {
  271. sscanf(config, "'%[^']s'", cfg_name);
  272. config += strlen(cfg_name)+2;
  273. } else {
  274. sscanf(config, "%s", cfg_name);
  275. config += strlen(cfg_name);
  276. }
  277. handled = SDL_FALSE;
  278. if ( strcmp(cfg_name, name) == 0 ) {
  279. /* Get the number of axes, hats and balls for this joystick */
  280. int joystick_axes = joystick->naxes;
  281. sscanf(config, "%d %d %d", 
  282. &joystick->naxes, &joystick->nhats, &joystick->nballs);
  283. /* Allocate the extra data for mapping them */
  284. if ( joystick->nhats > 0 ) {
  285. /* HACK: Analog hats map to only one axis */
  286. if (joystick_axes == (joystick->naxes+joystick->nhats)){
  287. joystick->hwdata->analog_hat = 1;
  288. } else {
  289. if ( allocate_hatdata(joystick) < 0 ) {
  290. joystick->nhats = 0;
  291. }
  292. joystick->hwdata->analog_hat = 0;
  293. }
  294. }
  295. if ( joystick->nballs > 0 ) {
  296. if ( allocate_balldata(joystick) < 0 ) {
  297. joystick->nballs = 0;
  298. }
  299. }
  300. handled = SDL_TRUE;
  301. }
  302. return(handled);
  303. }
  304. #ifdef USE_INPUT_EVENTS
  305. static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd)
  306. {
  307. int i;
  308. unsigned long keybit[40];
  309. unsigned long absbit[40];
  310. unsigned long relbit[40];
  311. /* See if this device uses the new unified event API */
  312. if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
  313.      (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
  314.      (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) {
  315. joystick->hwdata->is_hid = SDL_TRUE;
  316. /* Get the number of buttons, axes, and other thingamajigs */
  317. for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) {
  318. if ( test_bit(i, keybit) ) {
  319. #ifdef DEBUG_INPUT_EVENTS
  320. printf("Joystick has button: 0x%xn", i);
  321. #endif
  322. joystick->hwdata->key_map[i-BTN_MISC] =
  323. joystick->nbuttons;
  324. ++joystick->nbuttons;
  325. }
  326. }
  327. for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) {
  328. if ( test_bit(i, keybit) ) {
  329. #ifdef DEBUG_INPUT_EVENTS
  330. printf("Joystick has button: 0x%xn", i);
  331. #endif
  332. joystick->hwdata->key_map[i-BTN_MISC] =
  333. joystick->nbuttons;
  334. ++joystick->nbuttons;
  335. }
  336. }
  337. for ( i=0; i<ABS_MAX; ++i ) {
  338. /* Skip hats */
  339. if ( i == ABS_HAT0X ) {
  340. i = ABS_HAT3Y;
  341. continue;
  342. }
  343. if ( test_bit(i, absbit) ) {
  344. int values[5];
  345. ioctl(fd, EVIOCGABS(i), values);
  346. #ifdef DEBUG_INPUT_EVENTS
  347. printf("Joystick has absolute axis: %xn", i);
  348. printf("Values = { %d, %d, %d, %d, %d }n",
  349. values[0], values[1],
  350. values[2], values[3], values[4]);
  351. #endif /* DEBUG_INPUT_EVENTS */
  352. joystick->hwdata->abs_map[i] = joystick->naxes;
  353. if ( values[1] == values[2] ) {
  354.     joystick->hwdata->abs_correct[i].used = 0;
  355. } else {
  356.     joystick->hwdata->abs_correct[i].used = 1;
  357.     joystick->hwdata->abs_correct[i].coef[0] =
  358. (values[2] + values[1]) / 2 - values[4];
  359.     joystick->hwdata->abs_correct[i].coef[1] =
  360. (values[2] + values[1]) / 2 + values[4];
  361.     joystick->hwdata->abs_correct[i].coef[2] =
  362. (1 << 29) / ((values[2] - values[1]) / 2 - 2 * values[4]);
  363. }
  364. ++joystick->naxes;
  365. }
  366. }
  367. for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) {
  368. if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) {
  369. #ifdef DEBUG_INPUT_EVENTS
  370. printf("Joystick has hat %dn",(i-ABS_HAT0X)/2);
  371. #endif
  372. ++joystick->nhats;
  373. }
  374. }
  375. if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) {
  376. ++joystick->nballs;
  377. }
  378. /* Allocate data to keep track of these thingamajigs */
  379. if ( joystick->nhats > 0 ) {
  380. if ( allocate_hatdata(joystick) < 0 ) {
  381. joystick->nhats = 0;
  382. }
  383. }
  384. if ( joystick->nballs > 0 ) {
  385. if ( allocate_balldata(joystick) < 0 ) {
  386. joystick->nballs = 0;
  387. }
  388. }
  389. }
  390. return(joystick->hwdata->is_hid);
  391. }
  392. #endif /* USE_INPUT_EVENTS */
  393. #endif /* FANCY_HATS_AND_BALLS */
  394. /* Function to open a joystick for use.
  395.    The joystick to open is specified by the index field of the joystick.
  396.    This should fill the nbuttons and naxes fields of the joystick structure.
  397.    It returns 0, or -1 if there is an error.
  398.  */
  399. int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
  400. {
  401. #ifdef FANCY_HATS_AND_BALLS
  402. const char *name;
  403. int i;
  404. #endif
  405. int fd;
  406. unsigned char n;
  407. /* Open the joystick and set the joystick file descriptor */
  408. fd = open(SDL_joylist[joystick->index], O_RDONLY, 0);
  409. if ( fd < 0 ) {
  410. SDL_SetError("Unable to open %sn",
  411.              SDL_joylist[joystick->index]);
  412. return(-1);
  413. }
  414. joystick->hwdata = (struct joystick_hwdata *)
  415.                    malloc(sizeof(*joystick->hwdata));
  416. if ( joystick->hwdata == NULL ) {
  417. SDL_OutOfMemory();
  418. close(fd);
  419. return(-1);
  420. }
  421. memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
  422. joystick->hwdata->fd = fd;
  423. /* Set the joystick to non-blocking read mode */
  424. fcntl(fd, F_SETFL, O_NONBLOCK);
  425. /* Get the number of buttons and axes on the joystick */
  426. #ifdef USE_INPUT_EVENTS
  427. if ( ! EV_ConfigJoystick(joystick, fd) )
  428. #endif
  429. {
  430. if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) {
  431. joystick->naxes = 2;
  432. } else {
  433. joystick->naxes = n;
  434. }
  435. if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
  436. joystick->nbuttons = 2;
  437. } else {
  438. joystick->nbuttons = n;
  439. }
  440. #ifdef FANCY_HATS_AND_BALLS
  441. /* Check for special joystick support */
  442. name = SDL_SYS_JoystickName(joystick->index);
  443. for ( i=0; special_joysticks[i]; ++i ) {
  444. if (ConfigJoystick(joystick,name,special_joysticks[i])){
  445. break;
  446. }
  447. }
  448. if ( special_joysticks[i] == NULL ) {
  449. ConfigJoystick(joystick, name,
  450. getenv("SDL_LINUX_JOYSTICK"));
  451. }
  452. #endif /* FANCY_HATS_AND_BALLS */
  453. }
  454. return(0);
  455. }
  456. static __inline__
  457. void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
  458. {
  459. struct hwdata_hat *the_hat;
  460. const Uint8 position_map[3][3] = {
  461. { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
  462. { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
  463. { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
  464. };
  465. the_hat = &stick->hwdata->hats[hat];
  466. if ( value < 0 ) {
  467. value = 0;
  468. } else
  469. if ( value == 0 ) {
  470. value = 1;
  471. } else
  472. if ( value > 0 ) {
  473. value = 2;
  474. }
  475. if ( value != the_hat->axis[axis] ) {
  476. the_hat->axis[axis] = value;
  477. SDL_PrivateJoystickHat(stick, hat,
  478. position_map[the_hat->axis[1]][the_hat->axis[0]]);
  479. }
  480. }
  481. /* This was necessary for the Wingman Extreme Analog joystick */
  482. static __inline__
  483. void HandleAnalogHat(SDL_Joystick *stick, Uint8 hat, int value)
  484. {
  485. const Uint8 position_map[] = {
  486. SDL_HAT_UP,
  487. SDL_HAT_RIGHT,
  488. SDL_HAT_DOWN,
  489. SDL_HAT_LEFT,
  490. SDL_HAT_CENTERED
  491. };
  492. SDL_PrivateJoystickHat(stick, hat, position_map[(value/16000)+2]);
  493. }
  494. static __inline__
  495. void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
  496. {
  497. stick->hwdata->balls[ball].axis[axis] += value;
  498. }
  499. /* Function to update the state of a joystick - called as a device poll.
  500.  * This function shouldn't update the joystick structure directly,
  501.  * but instead should call SDL_PrivateJoystick*() to deliver events
  502.  * and update joystick device state.
  503.  */
  504. static __inline__ void JS_HandleEvents(SDL_Joystick *joystick)
  505. {
  506. struct js_event events[32];
  507. int i, len;
  508. Uint8 other_axis;
  509. while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
  510. len /= sizeof(events[0]);
  511. for ( i=0; i<len; ++i ) {
  512. switch (events[i].type & ~JS_EVENT_INIT) {
  513.     case JS_EVENT_AXIS:
  514. if ( events[i].number < joystick->naxes ) {
  515. SDL_PrivateJoystickAxis(joystick,
  516.            events[i].number, events[i].value);
  517. break;
  518. }
  519. events[i].number -= joystick->naxes;
  520. if ( joystick->hwdata->analog_hat ) {
  521. other_axis = events[i].number;
  522. if ( other_axis < joystick->nhats ) {
  523. HandleAnalogHat(joystick, other_axis,
  524. events[i].value);
  525. break;
  526. }
  527. } else {
  528. other_axis = (events[i].number / 2);
  529. if ( other_axis < joystick->nhats ) {
  530. HandleHat(joystick, other_axis,
  531. events[i].number%2,
  532. events[i].value);
  533. break;
  534. }
  535. }
  536. events[i].number -= joystick->nhats*2;
  537. other_axis = (events[i].number / 2);
  538. if ( other_axis < joystick->nballs ) {
  539. HandleBall(joystick, other_axis,
  540. events[i].number%2,
  541. events[i].value);
  542. break;
  543. }
  544. break;
  545.     case JS_EVENT_BUTTON:
  546. SDL_PrivateJoystickButton(joystick,
  547.            events[i].number, events[i].value);
  548. break;
  549.     default:
  550. /* ?? */
  551. break;
  552. }
  553. }
  554. }
  555. }
  556. #ifdef USE_INPUT_EVENTS
  557. static __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value)
  558. {
  559. struct axis_correct *correct;
  560. correct = &joystick->hwdata->abs_correct[which];
  561. if ( correct->used ) {
  562. if ( value > correct->coef[0] ) {
  563. if ( value < correct->coef[1] ) {
  564. return 0;
  565. }
  566. value -= correct->coef[1];
  567. } else {
  568. value -= correct->coef[0];
  569. }
  570. value *= correct->coef[2];
  571. value >>= 14;
  572. }
  573. /* Clamp and return */
  574. if ( value < -32767 ) {
  575. value = -32767;
  576. } else
  577. if ( value > 32767 ) {
  578. value = 32767;
  579. }
  580. return value;
  581. }
  582. static __inline__ void EV_HandleEvents(SDL_Joystick *joystick)
  583. {
  584. struct input_event events[32];
  585. int i, len;
  586. int code;
  587. while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
  588. len /= sizeof(events[0]);
  589. for ( i=0; i<len; ++i ) {
  590. code = events[i].code;
  591. switch (events[i].type) {
  592.     case EV_KEY:
  593. if ( code >= BTN_MISC ) {
  594. code -= BTN_MISC;
  595. SDL_PrivateJoystickButton(joystick,
  596.            joystick->hwdata->key_map[code],
  597.    events[i].value);
  598. }
  599. break;
  600.     case EV_ABS:
  601. switch (code) {
  602.     case ABS_HAT0X:
  603.     case ABS_HAT0Y:
  604.     case ABS_HAT1X:
  605.     case ABS_HAT1Y:
  606.     case ABS_HAT2X:
  607.     case ABS_HAT2Y:
  608.     case ABS_HAT3X:
  609.     case ABS_HAT3Y:
  610. code -= ABS_HAT0X;
  611. HandleHat(joystick, code/2, code%2,
  612. events[i].value);
  613. break;
  614.     default:
  615. events[i].value = EV_AxisCorrect(joystick, code, events[i].value);
  616. SDL_PrivateJoystickAxis(joystick,
  617.            joystick->hwdata->abs_map[code],
  618.    events[i].value);
  619. break;
  620. }
  621. break;
  622.     case EV_REL:
  623. switch (code) {
  624.     case REL_X:
  625.     case REL_Y:
  626. code -= REL_X;
  627. HandleBall(joystick, code/2, code%2,
  628. events[i].value);
  629. break;
  630.     default:
  631. break;
  632. }
  633. break;
  634.     default:
  635. break;
  636. }
  637. }
  638. }
  639. }
  640. #endif /* USE_INPUT_EVENTS */
  641. void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
  642. {
  643. int i;
  644. #ifdef USE_INPUT_EVENTS
  645. if ( joystick->hwdata->is_hid )
  646. EV_HandleEvents(joystick);
  647. else
  648. #endif
  649. JS_HandleEvents(joystick);
  650. /* Deliver ball motion updates */
  651. for ( i=0; i<joystick->nballs; ++i ) {
  652. int xrel, yrel;
  653. xrel = joystick->hwdata->balls[i].axis[0];
  654. yrel = joystick->hwdata->balls[i].axis[1];
  655. if ( xrel || yrel ) {
  656. joystick->hwdata->balls[i].axis[0] = 0;
  657. joystick->hwdata->balls[i].axis[1] = 0;
  658. SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel);
  659. }
  660. }
  661. }
  662. /* Function to close a joystick after use */
  663. void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
  664. {
  665. if ( joystick->hwdata ) {
  666. close(joystick->hwdata->fd);
  667. if ( joystick->hwdata->hats ) {
  668. free(joystick->hwdata->hats);
  669. }
  670. if ( joystick->hwdata->balls ) {
  671. free(joystick->hwdata->balls);
  672. }
  673. free(joystick->hwdata);
  674. joystick->hwdata = NULL;
  675. }
  676. }
  677. /* Function to perform any system-specific joystick related cleanup */
  678. void SDL_SYS_JoystickQuit(void)
  679. {
  680. int i;
  681. for ( i=0; SDL_joylist[i]; ++i ) {
  682. free(SDL_joylist[i]);
  683. }
  684. SDL_joylist[0] = NULL;
  685. }