Mercurial > sdl-ios-xcode
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 |