comparison src/joystick/linux/SDL_sysjoystick.c @ 892:dc29e5907694

Date: Sun, 18 Apr 2004 16:09:53 -0400 (EDT) From: David MacCormack Subject: [SDL] Linux joystick patch I recently got myself a PS2 -> USB converter (a super joybox 5). It accepts 4 PSX/PS2 controllers. It's implemented as a HID, which is nice because it doesn't require its own driver, but the problem is that it's implemented as a *single* HID -- that is, it shows up as a single joystick with 19 axes, 4 hats, and 48 buttons. This poses a problem for a number of apps which use SDL (stella, fce ultra, zsnes, to name a few) and see only a single (physical) joystick even though there are really 4 (logical) joysticks. There are a number of these types of devices on the market, and I've seen others post messages (in the zsnes forum, for example) with the same problem, so I came up with what I think is a pretty generic solution. I patched src/joystick/linux/SDL_sysjoystic.c to include support for logical joysticks; basically, it's a static array and supporting functions that map a single physical joystick to multiple logical joysticks. The attached patch has the new code. It's wrapped inside #ifndef statements so that you can get the old behavior if you want.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 16 May 2004 18:46:24 +0000
parents e7be95d758e8
children b56dc586a5ef
comparison
equal deleted inserted replaced
891:ab40b9b2d0d5 892:dc29e5907694
65 { "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0 }, 65 { "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0 },
66 { "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0 }, 66 { "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0 },
67 { "Saitek Saitek X45", 6, 1, 0 } 67 { "Saitek Saitek X45", 6, 1, 0 }
68 }; 68 };
69 69
70 #ifndef NO_LOGICAL_JOYSTICKS
71
72 static struct joystick_logical_values {
73 int njoy;
74 int nthing;
75 } joystick_logical_values[] = {
76
77 /* +0 */
78 /* MP-8800 axes map - map to {logical joystick #, logical axis #} */
79 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},{1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
80 {3,0},{3,1},{3,2},{3,3},{0,4},{1,4},{2,4},
81
82 /* +19 */
83 /* MP-8800 hat map - map to {logical joystick #, logical hat #} */
84 {0,0},{1,0},{2,0},{3,0},
85
86 /* +23 */
87 /* MP-8800 button map - map to {logical joystick #, logical button #} */
88 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
89 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11},
90 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11},
91 {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11}
92 };
93
94 static struct joystick_logical_layout {
95 int naxes;
96 int nhats;
97 int nballs;
98 int nbuttons;
99 } joystick_logical_layout[] = {
100 /* MP-8800 logical layout */
101 {5, 1, 0, 12},
102 {5, 1, 0, 12},
103 {5, 1, 0, 12},
104 {4, 1, 0, 12}
105 };
106
107 /*
108 Some USB HIDs show up as a single joystick even though they actually
109 control 2 or more joysticks. This array sets up a means of mapping
110 a single physical joystick to multiple logical joysticks. (djm)
111
112 njoys
113 the number of logical joysticks
114
115 layouts
116 an array of layout structures, one to describe each logical joystick
117
118 axes, hats, balls, buttons
119 arrays that map a physical thingy to a logical thingy
120 */
121 static struct joystick_logicalmap {
122 const char *name;
123 int njoys;
124 struct joystick_logical_layout *layouts;
125 struct joystick_logical_values *axes;
126 struct joystick_logical_values *hats;
127 struct joystick_logical_values *balls;
128 struct joystick_logical_values *buttons;
129
130 } joystick_logicalmap[] = {
131 {"WiseGroup.,Ltd MP-8800 Quad USB Joypad", 4, joystick_logical_layout,
132 joystick_logical_values, joystick_logical_values+19, NULL,
133 joystick_logical_values+23}
134 };
135
136 /* find the head of a linked list, given a point in it
137 */
138 #define SDL_joylist_head(i, start)\
139 for(i = start; SDL_joylist[i].fname == NULL;) i = SDL_joylist[i].prev;
140
141 #define SDL_logical_joydecl(d) d
142
143
144 #else
145
146 #define SDL_logical_joydecl(d)
147
148 #endif /* USE_LOGICAL_JOYSTICKS */
149
70 /* The maximum number of joysticks we'll detect */ 150 /* The maximum number of joysticks we'll detect */
71 #define MAX_JOYSTICKS 32 151 #define MAX_JOYSTICKS 32
72 152
73 /* A list of available joysticks */ 153 /* A list of available joysticks */
74 static char *SDL_joylist[MAX_JOYSTICKS]; 154 static struct
155 {
156 char* fname;
157 #ifndef NO_LOGICAL_JOYSTICKS
158 SDL_Joystick* joy;
159 struct joystick_logicalmap* map;
160 int prev;
161 int next;
162 int logicalno;
163 #endif /* USE_LOGICAL_JOYSTICKS */
164 } SDL_joylist[MAX_JOYSTICKS];
165
75 166
76 /* The private structure used to keep track of a joystick */ 167 /* The private structure used to keep track of a joystick */
77 struct joystick_hwdata { 168 struct joystick_hwdata {
78 int fd; 169 int fd;
79 /* The current linux joystick driver maps hats to two axes */ 170 /* The current linux joystick driver maps hats to two axes */
106 strcpy(newstring, string); 197 strcpy(newstring, string);
107 } 198 }
108 return(newstring); 199 return(newstring);
109 } 200 }
110 201
202
203 #ifndef NO_LOGICAL_JOYSTICKS
204
205 static int CountLogicalJoysticks(int max)
206 {
207 register int i, j, k, ret, prev;
208 const char* name;
209
210 ret = 0;
211
212 for(i = 0; i < max; i++) {
213 name = SDL_SYS_JoystickName(i);
214
215 if (name) {
216 for(j = 0; j < SDL_TABLESIZE(joystick_logicalmap); j++) {
217 if (!strcmp(name, joystick_logicalmap[j].name)) {
218
219 prev = i;
220 SDL_joylist[prev].map = joystick_logicalmap+j;
221
222 for(k = 1; k < joystick_logicalmap[j].njoys; k++) {
223 SDL_joylist[prev].next = max + ret;
224
225 if (prev != i)
226 SDL_joylist[max+ret].prev = prev;
227
228 prev = max + ret;
229 SDL_joylist[prev].logicalno = k;
230 SDL_joylist[prev].map = joystick_logicalmap+j;
231 ret++;
232 }
233
234 break;
235 }
236 }
237 }
238 }
239
240 return ret;
241 }
242
243 static void LogicalSuffix(int logicalno, char* namebuf, int len)
244 {
245 register int slen;
246 const static char suffixs[] =
247 "01020304050607080910111213141516171819"
248 "20212223242526272829303132";
249 const char* suffix;
250
251 slen = strlen(namebuf);
252
253 suffix = NULL;
254
255 if (logicalno*2<sizeof(suffixs))
256 suffix = suffixs + (logicalno*2);
257
258 if (slen + 4 < len && suffix) {
259 namebuf[slen++] = ' ';
260 namebuf[slen++] = '#';
261 namebuf[slen++] = suffix[0];
262 namebuf[slen++] = suffix[1];
263 namebuf[slen++] = 0;
264 }
265 }
266
267 #endif /* USE_LOGICAL_JOYSTICKS */
268
111 #ifdef USE_INPUT_EVENTS 269 #ifdef USE_INPUT_EVENTS
112 #define test_bit(nr, addr) \ 270 #define test_bit(nr, addr) \
113 (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0) 271 (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
114 272
115 static int EV_IsJoystick(int fd) 273 static int EV_IsJoystick(int fd)
158 path[sizeof(path)-1] = '\0'; 316 path[sizeof(path)-1] = '\0';
159 if ( stat(path, &sb) == 0 ) { 317 if ( stat(path, &sb) == 0 ) {
160 fd = open(path, O_RDONLY, 0); 318 fd = open(path, O_RDONLY, 0);
161 if ( fd >= 0 ) { 319 if ( fd >= 0 ) {
162 /* Assume the user knows what they're doing. */ 320 /* Assume the user knows what they're doing. */
163 SDL_joylist[numjoysticks] = mystrdup(path); 321 SDL_joylist[numjoysticks].fname =mystrdup(path);
164 if ( SDL_joylist[numjoysticks] ) { 322 if ( SDL_joylist[numjoysticks].fname ) {
165 dev_nums[numjoysticks] = sb.st_rdev; 323 dev_nums[numjoysticks] = sb.st_rdev;
166 ++numjoysticks; 324 ++numjoysticks;
167 } 325 }
168 close(fd); 326 close(fd);
169 } 327 }
206 } 364 }
207 #endif 365 #endif
208 close(fd); 366 close(fd);
209 367
210 /* We're fine, add this joystick */ 368 /* We're fine, add this joystick */
211 SDL_joylist[numjoysticks] = mystrdup(path); 369 SDL_joylist[numjoysticks].fname =mystrdup(path);
212 if ( SDL_joylist[numjoysticks] ) { 370 if ( SDL_joylist[numjoysticks].fname ) {
213 dev_nums[numjoysticks] = sb.st_rdev; 371 dev_nums[numjoysticks] = sb.st_rdev;
214 ++numjoysticks; 372 ++numjoysticks;
215 } 373 }
216 } else 374 } else
217 break; 375 break;
227 */ 385 */
228 if ( (i == 0) && (numjoysticks > 0) ) 386 if ( (i == 0) && (numjoysticks > 0) )
229 break; 387 break;
230 #endif 388 #endif
231 } 389 }
390 #ifndef NO_LOGICAL_JOYSTICKS
391 numjoysticks += CountLogicalJoysticks(numjoysticks);
392 #endif
232 393
233 return(numjoysticks); 394 return(numjoysticks);
234 } 395 }
235 396
236 /* Function to get the device-dependent name of a joystick */ 397 /* Function to get the device-dependent name of a joystick */
237 const char *SDL_SYS_JoystickName(int index) 398 const char *SDL_SYS_JoystickName(int index)
238 { 399 {
239 int fd; 400 int fd;
240 static char namebuf[128]; 401 static char namebuf[128];
241 char *name; 402 char *name;
242 403 SDL_logical_joydecl(int oindex = index);
404
405 #ifndef NO_LOGICAL_JOYSTICKS
406 SDL_joylist_head(index, index);
407 #endif
243 name = NULL; 408 name = NULL;
244 fd = open(SDL_joylist[index], O_RDONLY, 0); 409 fd = open(SDL_joylist[index].fname, O_RDONLY, 0);
245 if ( fd >= 0 ) { 410 if ( fd >= 0 ) {
246 if ( 411 if (
247 #ifdef USE_INPUT_EVENTS 412 #ifdef USE_INPUT_EVENTS
248 (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) && 413 (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&
249 #endif 414 #endif
250 (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) { 415 (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) {
251 name = SDL_joylist[index]; 416 name = SDL_joylist[index].fname;
252 } else { 417 } else {
253 name = namebuf; 418 name = namebuf;
254 } 419 }
255 close(fd); 420 close(fd);
421
422 #ifndef NO_LOGICAL_JOYSTICKS
423 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next)
424 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128);
425 #endif
256 } 426 }
257 return name; 427 return name;
258 } 428 }
259 429
260 static int allocate_hatdata(SDL_Joystick *joystick) 430 static int allocate_hatdata(SDL_Joystick *joystick)
477 return(joystick->hwdata->is_hid); 647 return(joystick->hwdata->is_hid);
478 } 648 }
479 649
480 #endif /* USE_INPUT_EVENTS */ 650 #endif /* USE_INPUT_EVENTS */
481 651
652 #ifndef NO_LOGICAL_JOYSTICKS
653 static void ConfigLogicalJoystick(SDL_Joystick *joystick)
654 {
655 struct joystick_logical_layout* layout;
656
657 layout = SDL_joylist[joystick->index].map->layouts +
658 SDL_joylist[joystick->index].logicalno;
659
660 joystick->nbuttons = layout->nbuttons;
661 joystick->nhats = layout->nhats;
662 joystick->naxes = layout->naxes;
663 joystick->nballs = layout->nballs;
664 }
665 #endif
666
667
482 /* Function to open a joystick for use. 668 /* Function to open a joystick for use.
483 The joystick to open is specified by the index field of the joystick. 669 The joystick to open is specified by the index field of the joystick.
484 This should fill the nbuttons and naxes fields of the joystick structure. 670 This should fill the nbuttons and naxes fields of the joystick structure.
485 It returns 0, or -1 if there is an error. 671 It returns 0, or -1 if there is an error.
486 */ 672 */
487 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) 673 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
488 { 674 {
489 int fd; 675 int fd;
676 SDL_logical_joydecl(int realindex);
677 SDL_logical_joydecl(SDL_Joystick *realjoy = NULL);
490 678
491 /* Open the joystick and set the joystick file descriptor */ 679 /* Open the joystick and set the joystick file descriptor */
492 fd = open(SDL_joylist[joystick->index], O_RDONLY, 0); 680 #ifndef NO_LOGICAL_JOYSTICKS
681 if (SDL_joylist[joystick->index].fname == NULL) {
682 SDL_joylist_head(realindex, joystick->index);
683 realjoy = SDL_JoystickOpen(realindex);
684
685 if (realjoy == NULL)
686 return(-1);
687
688 fd = realjoy->hwdata->fd;
689
690 } else {
691 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
692 }
693 SDL_joylist[joystick->index].joy = joystick;
694 #else
695 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
696 #endif
697
493 if ( fd < 0 ) { 698 if ( fd < 0 ) {
494 SDL_SetError("Unable to open %s\n", 699 SDL_SetError("Unable to open %s\n",
495 SDL_joylist[joystick->index]); 700 SDL_joylist[joystick->index]);
496 return(-1); 701 return(-1);
497 } 702 }
507 712
508 /* Set the joystick to non-blocking read mode */ 713 /* Set the joystick to non-blocking read mode */
509 fcntl(fd, F_SETFL, O_NONBLOCK); 714 fcntl(fd, F_SETFL, O_NONBLOCK);
510 715
511 /* Get the number of buttons and axes on the joystick */ 716 /* Get the number of buttons and axes on the joystick */
717 #ifndef NO_LOGICAL_JOYSTICKS
718 if (realjoy)
719 ConfigLogicalJoystick(joystick);
720 else
721 #endif
512 #ifdef USE_INPUT_EVENTS 722 #ifdef USE_INPUT_EVENTS
513 if ( ! EV_ConfigJoystick(joystick, fd) ) 723 if ( ! EV_ConfigJoystick(joystick, fd) )
514 #endif 724 #endif
515 JS_ConfigJoystick(joystick, fd); 725 JS_ConfigJoystick(joystick, fd);
516 726
517 return(0); 727 return(0);
518 } 728 }
729
730 #ifndef NO_LOGICAL_JOYSTICKS
731
732 static SDL_Joystick* FindLogicalJoystick(
733 SDL_Joystick *joystick, struct joystick_logical_values* v)
734 {
735 SDL_Joystick *logicaljoy;
736 register int i;
737
738 i = joystick->index;
739 logicaljoy = NULL;
740
741 /* get the fake joystick that will receive the event
742 */
743 for(;;) {
744
745 if (SDL_joylist[i].logicalno == v->njoy) {
746 logicaljoy = SDL_joylist[i].joy;
747 break;
748 }
749
750 if (SDL_joylist[i].next == 0)
751 break;
752
753 i = SDL_joylist[i].next;
754
755 }
756
757 return logicaljoy;
758 }
759
760 static int LogicalJoystickButton(
761 SDL_Joystick *joystick, Uint8 button, Uint8 state){
762 struct joystick_logical_values* buttons;
763 SDL_Joystick *logicaljoy = NULL;
764
765 /* if there's no map then this is just a regular joystick
766 */
767 if (SDL_joylist[joystick->index].map == NULL)
768 return 0;
769
770 /* get the logical joystick that will receive the event
771 */
772 buttons = SDL_joylist[joystick->index].map->buttons+button;
773 logicaljoy = FindLogicalJoystick(joystick, buttons);
774
775 if (logicaljoy == NULL)
776 return 1;
777
778 SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state);
779
780 return 1;
781 }
782
783 static int LogicalJoystickAxis(
784 SDL_Joystick *joystick, Uint8 axis, Sint16 value)
785 {
786 struct joystick_logical_values* axes;
787 SDL_Joystick *logicaljoy = NULL;
788
789 /* if there's no map then this is just a regular joystick
790 */
791 if (SDL_joylist[joystick->index].map == NULL)
792 return 0;
793
794 /* get the logical joystick that will receive the event
795 */
796 axes = SDL_joylist[joystick->index].map->axes+axis;
797 logicaljoy = FindLogicalJoystick(joystick, axes);
798
799 if (logicaljoy == NULL)
800 return 1;
801
802 SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value);
803
804 return 1;
805 }
806 #endif /* USE_LOGICAL_JOYSTICKS */
519 807
520 static __inline__ 808 static __inline__
521 void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value) 809 void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
522 { 810 {
523 struct hwdata_hat *the_hat; 811 struct hwdata_hat *the_hat;
524 const Uint8 position_map[3][3] = { 812 const Uint8 position_map[3][3] = {
525 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, 813 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
526 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, 814 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
527 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } 815 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
528 }; 816 };
817 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL);
818 SDL_logical_joydecl(struct joystick_logical_values* hats = NULL);
529 819
530 the_hat = &stick->hwdata->hats[hat]; 820 the_hat = &stick->hwdata->hats[hat];
531 if ( value < 0 ) { 821 if ( value < 0 ) {
532 value = 0; 822 value = 0;
533 } else 823 } else
537 if ( value > 0 ) { 827 if ( value > 0 ) {
538 value = 2; 828 value = 2;
539 } 829 }
540 if ( value != the_hat->axis[axis] ) { 830 if ( value != the_hat->axis[axis] ) {
541 the_hat->axis[axis] = value; 831 the_hat->axis[axis] = value;
832
833 #ifndef NO_LOGICAL_JOYSTICKS
834 /* if there's no map then this is just a regular joystick
835 */
836 if (SDL_joylist[stick->index].map != NULL) {
837
838 /* get the fake joystick that will receive the event
839 */
840 hats = SDL_joylist[stick->index].map->hats+hat;
841 logicaljoy = FindLogicalJoystick(stick, hats);
842 }
843
844 if (logicaljoy) {
845 stick = logicaljoy;
846 hat = hats->nthing;
847 }
848 #endif /* USE_LOGICAL_JOYSTICKS */
849
542 SDL_PrivateJoystickHat(stick, hat, 850 SDL_PrivateJoystickHat(stick, hat,
543 position_map[the_hat->axis[1]][the_hat->axis[0]]); 851 position_map[the_hat->axis[1]][the_hat->axis[0]]);
544 } 852 }
545 } 853 }
546 854
559 { 867 {
560 struct js_event events[32]; 868 struct js_event events[32];
561 int i, len; 869 int i, len;
562 Uint8 other_axis; 870 Uint8 other_axis;
563 871
872 #ifndef NO_LOGICAL_JOYSTICKS
873 if (SDL_joylist[joystick->index].fname == NULL) {
874 SDL_joylist_head(i, joystick->index);
875 return JS_HandleEvents(SDL_joylist[i].joy);
876 }
877 #endif
878
564 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { 879 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
565 len /= sizeof(events[0]); 880 len /= sizeof(events[0]);
566 for ( i=0; i<len; ++i ) { 881 for ( i=0; i<len; ++i ) {
567 switch (events[i].type & ~JS_EVENT_INIT) { 882 switch (events[i].type & ~JS_EVENT_INIT) {
568 case JS_EVENT_AXIS: 883 case JS_EVENT_AXIS:
569 if ( events[i].number < joystick->naxes ) { 884 if ( events[i].number < joystick->naxes ) {
885 #ifndef NO_LOGICAL_JOYSTICKS
886 if (!LogicalJoystickAxis(joystick,
887 events[i].number, events[i].value))
888 #endif
570 SDL_PrivateJoystickAxis(joystick, 889 SDL_PrivateJoystickAxis(joystick,
571 events[i].number, events[i].value); 890 events[i].number, events[i].value);
572 break; 891 break;
573 } 892 }
574 events[i].number -= joystick->naxes; 893 events[i].number -= joystick->naxes;
587 events[i].value); 906 events[i].value);
588 break; 907 break;
589 } 908 }
590 break; 909 break;
591 case JS_EVENT_BUTTON: 910 case JS_EVENT_BUTTON:
911 #ifndef NO_LOGICAL_JOYSTICKS
912 if (!LogicalJoystickButton(joystick,
913 events[i].number, events[i].value))
914 #endif
592 SDL_PrivateJoystickButton(joystick, 915 SDL_PrivateJoystickButton(joystick,
593 events[i].number, events[i].value); 916 events[i].number, events[i].value);
594 break; 917 break;
595 default: 918 default:
596 /* ?? */ 919 /* ?? */
628 static __inline__ void EV_HandleEvents(SDL_Joystick *joystick) 951 static __inline__ void EV_HandleEvents(SDL_Joystick *joystick)
629 { 952 {
630 struct input_event events[32]; 953 struct input_event events[32];
631 int i, len; 954 int i, len;
632 int code; 955 int code;
956
957 #ifndef NO_LOGICAL_JOYSTICKS
958 if (SDL_joylist[joystick->index].fname == NULL) {
959 SDL_joylist_head(i, joystick->index);
960 return EV_HandleEvents(SDL_joylist[i].joy);
961 }
962 #endif
633 963
634 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { 964 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
635 len /= sizeof(events[0]); 965 len /= sizeof(events[0]);
636 for ( i=0; i<len; ++i ) { 966 for ( i=0; i<len; ++i ) {
637 code = events[i].code; 967 code = events[i].code;
638 switch (events[i].type) { 968 switch (events[i].type) {
639 case EV_KEY: 969 case EV_KEY:
640 if ( code >= BTN_MISC ) { 970 if ( code >= BTN_MISC ) {
641 code -= BTN_MISC; 971 code -= BTN_MISC;
972 #ifndef NO_LOGICAL_JOYSTICKS
973 if (!LogicalJoystickButton(joystick,
974 joystick->hwdata->key_map[code],
975 events[i].value))
976 #endif
642 SDL_PrivateJoystickButton(joystick, 977 SDL_PrivateJoystickButton(joystick,
643 joystick->hwdata->key_map[code], 978 joystick->hwdata->key_map[code],
644 events[i].value); 979 events[i].value);
645 } 980 }
646 break; 981 break;
658 HandleHat(joystick, code/2, code%2, 993 HandleHat(joystick, code/2, code%2,
659 events[i].value); 994 events[i].value);
660 break; 995 break;
661 default: 996 default:
662 events[i].value = EV_AxisCorrect(joystick, code, events[i].value); 997 events[i].value = EV_AxisCorrect(joystick, code, events[i].value);
998 #ifndef NO_LOGICAL_JOYSTICKS
999 if (!LogicalJoystickAxis(joystick,
1000 joystick->hwdata->abs_map[code],
1001 events[i].value))
1002 #endif
663 SDL_PrivateJoystickAxis(joystick, 1003 SDL_PrivateJoystickAxis(joystick,
664 joystick->hwdata->abs_map[code], 1004 joystick->hwdata->abs_map[code],
665 events[i].value); 1005 events[i].value);
666 break; 1006 break;
667 } 1007 }
712 } 1052 }
713 1053
714 /* Function to close a joystick after use */ 1054 /* Function to close a joystick after use */
715 void SDL_SYS_JoystickClose(SDL_Joystick *joystick) 1055 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
716 { 1056 {
1057 #ifndef NO_LOGICAL_JOYSTICKS
1058 register int i;
1059 if (SDL_joylist[joystick->index].fname == NULL) {
1060 SDL_joylist_head(i, joystick->index);
1061 SDL_JoystickClose(SDL_joylist[i].joy);
1062 }
1063 #endif
1064
717 if ( joystick->hwdata ) { 1065 if ( joystick->hwdata ) {
1066 #ifndef NO_LOGICAL_JOYSTICKS
1067 if (SDL_joylist[joystick->index].fname != NULL)
1068 #endif
718 close(joystick->hwdata->fd); 1069 close(joystick->hwdata->fd);
719 if ( joystick->hwdata->hats ) { 1070 if ( joystick->hwdata->hats ) {
720 free(joystick->hwdata->hats); 1071 free(joystick->hwdata->hats);
721 } 1072 }
722 if ( joystick->hwdata->balls ) { 1073 if ( joystick->hwdata->balls ) {
730 /* Function to perform any system-specific joystick related cleanup */ 1081 /* Function to perform any system-specific joystick related cleanup */
731 void SDL_SYS_JoystickQuit(void) 1082 void SDL_SYS_JoystickQuit(void)
732 { 1083 {
733 int i; 1084 int i;
734 1085
735 for ( i=0; SDL_joylist[i]; ++i ) { 1086 for ( i=0; SDL_joylist[i].fname; ++i ) {
736 free(SDL_joylist[i]); 1087 free(SDL_joylist[i].fname);
737 } 1088 }
738 SDL_joylist[0] = NULL; 1089 SDL_joylist[0].fname = NULL;
739 } 1090 }
740 1091