comparison src/joystick/linux/SDL_sysjoystick.c @ 914:bbf8dcc8aed6

Date: Wed, 23 Jun 2004 17:05:33 -0400 From: Chris Nelson Subject: [SDL] [Patch] WiseGroup MP-8800 / MP-8866 (PS2 Joystick) In the current cvs version, SDL doesn't handle these Playstation2 controller => USB adapters correctly, in linux. It will always assume that the maximum number of joysticks (2 in the case of the MP-8866, 4 in the case of the 8800) are plugged in. This is bad not only because it allows SDL to exaggerate the number of logical joysticks, but primarily because the joystick axes are mapped incorrectly, all over the place, such that the devices are effectively unusable unless you have the maximum number of joysticks plugged in. My changes to src/joystick/linux/SDL_sysjoystick.c build on another's previous work (which was a special case for this very joystick, actually), and fix both of these problems, as well as making the current code a little more general, to allow for others to more easily drop in code for quirky joysticks such as these. I've tested this code under 2.6.7 as well as 2.4.24... Both work as advertised (provided you load the JOYDEV linux code as a module, otherwise they won't work at all, new code or old, but that's another issue entirely). Though this sounds horribly formal, you have my permission to distribute all of my work on this issue under the LGPL. So there.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 25 Jul 2004 18:31:50 +0000
parents b56dc586a5ef
children cb5e1d0cad31
comparison
equal deleted inserted replaced
913:a7a8c282d62e 914:bbf8dcc8aed6
67 { "Saitek Saitek X45", 6, 1, 0 } 67 { "Saitek Saitek X45", 6, 1, 0 }
68 }; 68 };
69 69
70 #ifndef NO_LOGICAL_JOYSTICKS 70 #ifndef NO_LOGICAL_JOYSTICKS
71 71
72 static struct joystick_logical_values { 72 /*
73 Some USB HIDs show up as a single joystick even though they actually
74 control 2 or more joysticks.
75 */
76 /*
77 This code handles the MP-8800 (Quad) and MP-8866 (Dual), which can
78 be identified by their transparent blue design. It's quite trivial
79 to add other joysticks with similar quirky behavior.
80 -id
81 */
82
83 struct joystick_logical_mapping {
73 int njoy; 84 int njoy;
74 int nthing; 85 int nthing;
75 } joystick_logical_values[] = { 86 };
76 87
77 /* +0 */ 88 /*
78 /* MP-8800 axes map - map to {logical joystick #, logical axis #} */ 89 {logical joy, 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}, 90 {logical joy, logical hat},
80 {3,0},{3,1},{3,2},{3,3},{0,4},{1,4},{2,4}, 91 {logical joy, logical ball},
81 92 {logical joy, logical button}
82 /* +19 */ 93 */
83 /* MP-8800 hat map - map to {logical joystick #, logical hat #} */ 94
84 {0,0},{1,0},{2,0},{3,0}, 95 static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = {
85 96 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5}
86 /* +23 */ 97 };
87 /* MP-8800 button map - map to {logical joystick #, logical button #} */ 98 static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = {
99 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}
100 };
101
102 static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = {
103 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
104 {1,2},{1,3},{0,4},{0,5},{1,4},{1,5}
105 };
106 static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = {
107 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
108 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}
109 };
110
111 static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = {
112 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
113 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
114 {0,4},{0,5},{1,4},{1,5},{2,4},{2,5}
115 };
116 static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = {
117 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
118 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11},
119 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}
120 };
121
122 static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = {
123 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
124 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
125 {3,0},{3,1},{3,2},{3,3},{0,4},{0,5},
126 {1,4},{1,5},{2,4},{2,5},{3,4},{3,5}
127 };
128 static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = {
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}, 129 {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}, 130 {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}, 131 {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} 132 {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 }; 133 };
93 134
94 static struct joystick_logical_layout { 135 struct joystick_logical_layout {
95 int naxes; 136 int naxes;
96 int nhats; 137 int nhats;
97 int nballs; 138 int nballs;
98 int nbuttons; 139 int nbuttons;
99 } joystick_logical_layout[] = { 140 };
100 /* MP-8800 logical layout */ 141
101 {5, 1, 0, 12}, 142 static struct joystick_logical_layout mp88xx_1_logical_layout[] = {
102 {5, 1, 0, 12}, 143 {6, 0, 0, 12}
103 {5, 1, 0, 12}, 144 };
104 {4, 1, 0, 12} 145 static struct joystick_logical_layout mp88xx_2_logical_layout[] = {
146 {6, 0, 0, 12},
147 {6, 0, 0, 12}
148 };
149 static struct joystick_logical_layout mp88xx_3_logical_layout[] = {
150 {6, 0, 0, 12},
151 {6, 0, 0, 12},
152 {6, 0, 0, 12}
153 };
154 static struct joystick_logical_layout mp88xx_4_logical_layout[] = {
155 {6, 0, 0, 12},
156 {6, 0, 0, 12},
157 {6, 0, 0, 12},
158 {6, 0, 0, 12}
105 }; 159 };
106 160
107 /* 161 /*
108 Some USB HIDs show up as a single joystick even though they actually 162 This array sets up a means of mapping a single physical joystick to
109 control 2 or more joysticks. This array sets up a means of mapping 163 multiple logical joysticks. (djm)
110 a single physical joystick to multiple logical joysticks. (djm)
111 164
112 njoys 165 njoys
113 the number of logical joysticks 166 the number of logical joysticks
114 167
115 layouts 168 layouts
116 an array of layout structures, one to describe each logical joystick 169 an array of layout structures, one to describe each logical joystick
117 170
118 axes, hats, balls, buttons 171 axes, hats, balls, buttons
119 arrays that map a physical thingy to a logical thingy 172 arrays that map a physical thingy to a logical thingy
120 */ 173 */
121 static struct joystick_logicalmap { 174 struct joystick_logicalmap {
122 const char *name; 175 const char *name;
176 int nbuttons;
123 int njoys; 177 int njoys;
124 struct joystick_logical_layout *layouts; 178 struct joystick_logical_layout *layout;
125 struct joystick_logical_values *axes; 179 struct joystick_logical_mapping *axismap;
126 struct joystick_logical_values *hats; 180 struct joystick_logical_mapping *hatmap;
127 struct joystick_logical_values *balls; 181 struct joystick_logical_mapping *ballmap;
128 struct joystick_logical_values *buttons; 182 struct joystick_logical_mapping *buttonmap;
129 183 };
130 } joystick_logicalmap[] = { 184
131 {"WiseGroup.,Ltd MP-8800 Quad USB Joypad", 4, joystick_logical_layout, 185 static struct joystick_logicalmap joystick_logicalmap[] = {
132 joystick_logical_values, joystick_logical_values+19, NULL, 186 {
133 joystick_logical_values+23} 187 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
188 12,
189 1,
190 mp88xx_1_logical_layout,
191 mp88xx_1_logical_axismap,
192 NULL,
193 NULL,
194 mp88xx_1_logical_buttonmap
195 },
196 {
197 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
198 24,
199 2,
200 mp88xx_2_logical_layout,
201 mp88xx_2_logical_axismap,
202 NULL,
203 NULL,
204 mp88xx_2_logical_buttonmap
205 },
206 {
207 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
208 12,
209 1,
210 mp88xx_1_logical_layout,
211 mp88xx_1_logical_axismap,
212 NULL,
213 NULL,
214 mp88xx_1_logical_buttonmap
215 },
216 {
217 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
218 24,
219 2,
220 mp88xx_2_logical_layout,
221 mp88xx_2_logical_axismap,
222 NULL,
223 NULL,
224 mp88xx_2_logical_buttonmap
225 },
226 {
227 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
228 36,
229 3,
230 mp88xx_3_logical_layout,
231 mp88xx_3_logical_axismap,
232 NULL,
233 NULL,
234 mp88xx_3_logical_buttonmap
235 },
236 {
237 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
238 48,
239 4,
240 mp88xx_4_logical_layout,
241 mp88xx_4_logical_axismap,
242 NULL,
243 NULL,
244 mp88xx_4_logical_buttonmap
245 }
134 }; 246 };
135 247
136 /* find the head of a linked list, given a point in it 248 /* find the head of a linked list, given a point in it
137 */ 249 */
138 #define SDL_joylist_head(i, start)\ 250 #define SDL_joylist_head(i, start)\
204 316
205 static int CountLogicalJoysticks(int max) 317 static int CountLogicalJoysticks(int max)
206 { 318 {
207 register int i, j, k, ret, prev; 319 register int i, j, k, ret, prev;
208 const char* name; 320 const char* name;
321 int nbuttons, fd;
322 unsigned char n;
209 323
210 ret = 0; 324 ret = 0;
211 325
212 for(i = 0; i < max; i++) { 326 for(i = 0; i < max; i++) {
213 name = SDL_SYS_JoystickName(i); 327 name = SDL_SYS_JoystickName(i);
328
329 fd = open(SDL_joylist[i].fname, O_RDONLY, 0);
330 if ( fd >= 0 ) {
331 if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
332 nbuttons = -1;
333 } else {
334 nbuttons = n;
335 }
336 close(fd);
337 }
338 else {
339 nbuttons=-1;
340 }
214 341
215 if (name) { 342 if (name) {
216 for(j = 0; j < SDL_TABLESIZE(joystick_logicalmap); j++) { 343 for(j = 0; j < SDL_TABLESIZE(joystick_logicalmap); j++) {
217 if (!strcmp(name, joystick_logicalmap[j].name)) { 344 if (!strcmp(name, joystick_logicalmap[j].name) && (nbuttons==-1 || nbuttons==joystick_logicalmap[j].nbuttons)) {
218
219 prev = i; 345 prev = i;
220 SDL_joylist[prev].map = joystick_logicalmap+j; 346 SDL_joylist[prev].map = &(joystick_logicalmap[j]);
221 347
222 for(k = 1; k < joystick_logicalmap[j].njoys; k++) { 348 for(k = 1; k < joystick_logicalmap[j].njoys; k++) {
223 SDL_joylist[prev].next = max + ret; 349 SDL_joylist[prev].next = max + ret;
224 350 SDL_joylist[max+ret].prev = prev;
225 if (prev != i) 351
226 SDL_joylist[max+ret].prev = prev;
227
228 prev = max + ret; 352 prev = max + ret;
229 SDL_joylist[prev].logicalno = k; 353 SDL_joylist[prev].logicalno = k;
230 SDL_joylist[prev].map = joystick_logicalmap+j; 354 SDL_joylist[prev].map = &(joystick_logicalmap[j]);
231 ret++; 355 ret++;
232 } 356 }
233 357
234 break; 358 break;
235 } 359 }
245 register int slen; 369 register int slen;
246 const static char suffixs[] = 370 const static char suffixs[] =
247 "01020304050607080910111213141516171819" 371 "01020304050607080910111213141516171819"
248 "20212223242526272829303132"; 372 "20212223242526272829303132";
249 const char* suffix; 373 const char* suffix;
250
251 slen = strlen(namebuf); 374 slen = strlen(namebuf);
252
253 suffix = NULL; 375 suffix = NULL;
254 376
255 if (logicalno*2<sizeof(suffixs)) 377 if (logicalno*2<sizeof(suffixs))
256 suffix = suffixs + (logicalno*2); 378 suffix = suffixs + (logicalno*2);
257 379
417 } else { 539 } else {
418 name = namebuf; 540 name = namebuf;
419 } 541 }
420 close(fd); 542 close(fd);
421 543
422 #ifndef NO_LOGICAL_JOYSTICKS 544
423 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next) 545 #ifndef NO_LOGICAL_JOYSTICKS
546 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex)
547 {
424 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128); 548 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128);
549 }
425 #endif 550 #endif
426 } 551 }
427 return name; 552 return name;
428 } 553 }
429 554
653 #ifndef NO_LOGICAL_JOYSTICKS 778 #ifndef NO_LOGICAL_JOYSTICKS
654 static void ConfigLogicalJoystick(SDL_Joystick *joystick) 779 static void ConfigLogicalJoystick(SDL_Joystick *joystick)
655 { 780 {
656 struct joystick_logical_layout* layout; 781 struct joystick_logical_layout* layout;
657 782
658 layout = SDL_joylist[joystick->index].map->layouts + 783 layout = SDL_joylist[joystick->index].map->layout +
659 SDL_joylist[joystick->index].logicalno; 784 SDL_joylist[joystick->index].logicalno;
660 785
661 joystick->nbuttons = layout->nbuttons; 786 joystick->nbuttons = layout->nbuttons;
662 joystick->nhats = layout->nhats; 787 joystick->nhats = layout->nhats;
663 joystick->naxes = layout->naxes; 788 joystick->naxes = layout->naxes;
729 } 854 }
730 855
731 #ifndef NO_LOGICAL_JOYSTICKS 856 #ifndef NO_LOGICAL_JOYSTICKS
732 857
733 static SDL_Joystick* FindLogicalJoystick( 858 static SDL_Joystick* FindLogicalJoystick(
734 SDL_Joystick *joystick, struct joystick_logical_values* v) 859 SDL_Joystick *joystick, struct joystick_logical_mapping* v)
735 { 860 {
736 SDL_Joystick *logicaljoy; 861 SDL_Joystick *logicaljoy;
737 register int i; 862 register int i;
738 863
739 i = joystick->index; 864 i = joystick->index;
758 return logicaljoy; 883 return logicaljoy;
759 } 884 }
760 885
761 static int LogicalJoystickButton( 886 static int LogicalJoystickButton(
762 SDL_Joystick *joystick, Uint8 button, Uint8 state){ 887 SDL_Joystick *joystick, Uint8 button, Uint8 state){
763 struct joystick_logical_values* buttons; 888 struct joystick_logical_mapping* buttons;
764 SDL_Joystick *logicaljoy = NULL; 889 SDL_Joystick *logicaljoy = NULL;
765 890
766 /* if there's no map then this is just a regular joystick 891 /* if there's no map then this is just a regular joystick
767 */ 892 */
768 if (SDL_joylist[joystick->index].map == NULL) 893 if (SDL_joylist[joystick->index].map == NULL)
769 return 0; 894 return 0;
770 895
771 /* get the logical joystick that will receive the event 896 /* get the logical joystick that will receive the event
772 */ 897 */
773 buttons = SDL_joylist[joystick->index].map->buttons+button; 898 buttons = SDL_joylist[joystick->index].map->buttonmap+button;
774 logicaljoy = FindLogicalJoystick(joystick, buttons); 899 logicaljoy = FindLogicalJoystick(joystick, buttons);
775 900
776 if (logicaljoy == NULL) 901 if (logicaljoy == NULL)
777 return 1; 902 return 1;
778 903
782 } 907 }
783 908
784 static int LogicalJoystickAxis( 909 static int LogicalJoystickAxis(
785 SDL_Joystick *joystick, Uint8 axis, Sint16 value) 910 SDL_Joystick *joystick, Uint8 axis, Sint16 value)
786 { 911 {
787 struct joystick_logical_values* axes; 912 struct joystick_logical_mapping* axes;
788 SDL_Joystick *logicaljoy = NULL; 913 SDL_Joystick *logicaljoy = NULL;
789 914
790 /* if there's no map then this is just a regular joystick 915 /* if there's no map then this is just a regular joystick
791 */ 916 */
792 if (SDL_joylist[joystick->index].map == NULL) 917 if (SDL_joylist[joystick->index].map == NULL)
793 return 0; 918 return 0;
794 919
795 /* get the logical joystick that will receive the event 920 /* get the logical joystick that will receive the event
796 */ 921 */
797 axes = SDL_joylist[joystick->index].map->axes+axis; 922 axes = SDL_joylist[joystick->index].map->axismap+axis;
798 logicaljoy = FindLogicalJoystick(joystick, axes); 923 logicaljoy = FindLogicalJoystick(joystick, axes);
799 924
800 if (logicaljoy == NULL) 925 if (logicaljoy == NULL)
801 return 1; 926 return 1;
802 927
814 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, 939 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
815 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, 940 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
816 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } 941 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
817 }; 942 };
818 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL); 943 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL);
819 SDL_logical_joydecl(struct joystick_logical_values* hats = NULL); 944 SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL);
820 945
821 the_hat = &stick->hwdata->hats[hat]; 946 the_hat = &stick->hwdata->hats[hat];
822 if ( value < 0 ) { 947 if ( value < 0 ) {
823 value = 0; 948 value = 0;
824 } else 949 } else
836 */ 961 */
837 if (SDL_joylist[stick->index].map != NULL) { 962 if (SDL_joylist[stick->index].map != NULL) {
838 963
839 /* get the fake joystick that will receive the event 964 /* get the fake joystick that will receive the event
840 */ 965 */
841 hats = SDL_joylist[stick->index].map->hats+hat; 966 hats = SDL_joylist[stick->index].map->hatmap+hat;
842 logicaljoy = FindLogicalJoystick(stick, hats); 967 logicaljoy = FindLogicalJoystick(stick, hats);
843 } 968 }
844 969
845 if (logicaljoy) { 970 if (logicaljoy) {
846 stick = logicaljoy; 971 stick = logicaljoy;