Mercurial > sdl-ios-xcode
comparison src/joystick/linux/SDL_sysjoystick.c @ 1551:02e19471a694
Fixed bug #4
[Note: I'm applying this patch since it's a cleaner version of what's already implemented, and supports this controller on older kernels. I'll ask to make sure this doesn't break on the new kernels where it's no longer necessary]
Date: Mon, 21 Mar 2005 09:41:11 -0500
From: Chris Nelson
Subject: SDL Patch
Hey, Ryan.
I submitted the following patch about a year ago. It's just a simple
patch for the linux port, to make multiple joysticks each appear to SDL
as their own device, if they are on the same USB port (specifically,
these guys
<http://www.consoleplus.co.uk/product_info.php?pName=super-joybox-5-quad-joypad-converter>,
which allow 4 Playstation2 controllers to be accessed via a single USB
port). Without this patch, SDL pretty much drops the ball, and reports
that there are 4 joysticks available when less than that number are
plugged in.
My work built upon the work of another person with the same device. When
I submitted the patch to the list, he tested it, but it didn't work for
him, so the patch was never accepted. Maybe about 3 times in the past
year, I've tried to email the guy, to see if he couldn't run my new
version, complete with debug code to diagnose the problem he was having.
He never got back to me.
So, I'm attaching the patch. I wish I knew why it didn't work for him,
but I've been using it for the last year with no problems. Let me know
if you need any more information, or have any ideas as to how I could
test it. I'd like to see it in the tree, but I want to make sure it works.
-Chris
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 19 Mar 2006 06:31:34 +0000 |
parents | d910939febfa |
children | 92947e3a18db |
comparison
equal
deleted
inserted
replaced
1550:31c2b8e4885e | 1551:02e19471a694 |
---|---|
59 { "Saitek Saitek X45", 6, 1, 0 } | 59 { "Saitek Saitek X45", 6, 1, 0 } |
60 }; | 60 }; |
61 | 61 |
62 #ifndef NO_LOGICAL_JOYSTICKS | 62 #ifndef NO_LOGICAL_JOYSTICKS |
63 | 63 |
64 static struct joystick_logical_values { | 64 /* |
65 Some USB HIDs show up as a single joystick even though they actually | |
66 control 2 or more joysticks. | |
67 */ | |
68 /* | |
69 This code handles the MP-8800 (Quad) and MP-8866 (Dual), which can | |
70 be identified by their transparent blue design. It's quite trivial | |
71 to add other joysticks with similar quirky behavior. | |
72 -id | |
73 */ | |
74 | |
75 struct joystick_logical_mapping { | |
65 int njoy; | 76 int njoy; |
66 int nthing; | 77 int nthing; |
67 } joystick_logical_values[] = { | 78 }; |
68 | 79 |
69 /* +0 */ | 80 /* |
70 /* MP-8800 axes map - map to {logical joystick #, logical axis #} */ | 81 {logical joy, logical axis}, |
71 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},{1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, | 82 {logical joy, logical hat}, |
72 {3,0},{3,1},{3,2},{3,3},{0,4},{1,4},{2,4}, | 83 {logical joy, logical ball}, |
73 | 84 {logical joy, logical button} |
74 /* +19 */ | 85 */ |
75 /* MP-8800 hat map - map to {logical joystick #, logical hat #} */ | 86 |
76 {0,0},{1,0},{2,0},{3,0}, | 87 static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = { |
77 | 88 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5} |
78 /* +23 */ | 89 }; |
79 /* MP-8800 button map - map to {logical joystick #, logical button #} */ | 90 static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = { |
91 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11} | |
92 }; | |
93 | |
94 static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = { | |
95 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, | |
96 {1,2},{1,3},{0,4},{0,5},{1,4},{1,5} | |
97 }; | |
98 static struct joystick_logical_mapping mp88xx_2_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 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11} | |
101 }; | |
102 | |
103 static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = { | |
104 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, | |
105 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, | |
106 {0,4},{0,5},{1,4},{1,5},{2,4},{2,5} | |
107 }; | |
108 static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = { | |
109 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, | |
110 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, | |
111 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11} | |
112 }; | |
113 | |
114 static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = { | |
115 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, | |
116 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, | |
117 {3,0},{3,1},{3,2},{3,3},{0,4},{0,5}, | |
118 {1,4},{1,5},{2,4},{2,5},{3,4},{3,5} | |
119 }; | |
120 static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = { | |
80 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, | 121 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, |
81 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, | 122 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, |
82 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}, | 123 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}, |
83 {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11} | 124 {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11} |
84 }; | 125 }; |
85 | 126 |
86 static struct joystick_logical_layout { | 127 struct joystick_logical_layout { |
87 int naxes; | 128 int naxes; |
88 int nhats; | 129 int nhats; |
89 int nballs; | 130 int nballs; |
90 int nbuttons; | 131 int nbuttons; |
91 } joystick_logical_layout[] = { | 132 }; |
92 /* MP-8800 logical layout */ | 133 |
93 {5, 1, 0, 12}, | 134 static struct joystick_logical_layout mp88xx_1_logical_layout[] = { |
94 {5, 1, 0, 12}, | 135 {6, 0, 0, 12} |
95 {5, 1, 0, 12}, | 136 }; |
96 {4, 1, 0, 12} | 137 static struct joystick_logical_layout mp88xx_2_logical_layout[] = { |
138 {6, 0, 0, 12}, | |
139 {6, 0, 0, 12} | |
140 }; | |
141 static struct joystick_logical_layout mp88xx_3_logical_layout[] = { | |
142 {6, 0, 0, 12}, | |
143 {6, 0, 0, 12}, | |
144 {6, 0, 0, 12} | |
145 }; | |
146 static struct joystick_logical_layout mp88xx_4_logical_layout[] = { | |
147 {6, 0, 0, 12}, | |
148 {6, 0, 0, 12}, | |
149 {6, 0, 0, 12}, | |
150 {6, 0, 0, 12} | |
97 }; | 151 }; |
98 | 152 |
99 /* | 153 /* |
100 Some USB HIDs show up as a single joystick even though they actually | 154 This array sets up a means of mapping a single physical joystick to |
101 control 2 or more joysticks. This array sets up a means of mapping | 155 multiple logical joysticks. (djm) |
102 a single physical joystick to multiple logical joysticks. (djm) | |
103 | 156 |
104 njoys | 157 njoys |
105 the number of logical joysticks | 158 the number of logical joysticks |
106 | 159 |
107 layouts | 160 layouts |
108 an array of layout structures, one to describe each logical joystick | 161 an array of layout structures, one to describe each logical joystick |
109 | 162 |
110 axes, hats, balls, buttons | 163 axes, hats, balls, buttons |
111 arrays that map a physical thingy to a logical thingy | 164 arrays that map a physical thingy to a logical thingy |
112 */ | 165 */ |
113 static struct joystick_logicalmap { | 166 struct joystick_logicalmap { |
114 const char *name; | 167 const char *name; |
168 int nbuttons; | |
115 int njoys; | 169 int njoys; |
116 struct joystick_logical_layout *layouts; | 170 struct joystick_logical_layout *layout; |
117 struct joystick_logical_values *axes; | 171 struct joystick_logical_mapping *axismap; |
118 struct joystick_logical_values *hats; | 172 struct joystick_logical_mapping *hatmap; |
119 struct joystick_logical_values *balls; | 173 struct joystick_logical_mapping *ballmap; |
120 struct joystick_logical_values *buttons; | 174 struct joystick_logical_mapping *buttonmap; |
121 | 175 }; |
122 } joystick_logicalmap[] = { | 176 |
123 {"WiseGroup.,Ltd MP-8800 Quad USB Joypad", 4, joystick_logical_layout, | 177 static struct joystick_logicalmap joystick_logicalmap[] = { |
124 joystick_logical_values, joystick_logical_values+19, NULL, | 178 { |
125 joystick_logical_values+23} | 179 "WiseGroup.,Ltd MP-8866 Dual USB Joypad", |
180 12, | |
181 1, | |
182 mp88xx_1_logical_layout, | |
183 mp88xx_1_logical_axismap, | |
184 NULL, | |
185 NULL, | |
186 mp88xx_1_logical_buttonmap | |
187 }, | |
188 { | |
189 "WiseGroup.,Ltd MP-8866 Dual USB Joypad", | |
190 24, | |
191 2, | |
192 mp88xx_2_logical_layout, | |
193 mp88xx_2_logical_axismap, | |
194 NULL, | |
195 NULL, | |
196 mp88xx_2_logical_buttonmap | |
197 }, | |
198 { | |
199 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", | |
200 12, | |
201 1, | |
202 mp88xx_1_logical_layout, | |
203 mp88xx_1_logical_axismap, | |
204 NULL, | |
205 NULL, | |
206 mp88xx_1_logical_buttonmap | |
207 }, | |
208 { | |
209 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", | |
210 24, | |
211 2, | |
212 mp88xx_2_logical_layout, | |
213 mp88xx_2_logical_axismap, | |
214 NULL, | |
215 NULL, | |
216 mp88xx_2_logical_buttonmap | |
217 }, | |
218 { | |
219 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", | |
220 36, | |
221 3, | |
222 mp88xx_3_logical_layout, | |
223 mp88xx_3_logical_axismap, | |
224 NULL, | |
225 NULL, | |
226 mp88xx_3_logical_buttonmap | |
227 }, | |
228 { | |
229 "WiseGroup.,Ltd MP-8800 Quad USB Joypad", | |
230 48, | |
231 4, | |
232 mp88xx_4_logical_layout, | |
233 mp88xx_4_logical_axismap, | |
234 NULL, | |
235 NULL, | |
236 mp88xx_4_logical_buttonmap | |
237 } | |
126 }; | 238 }; |
127 | 239 |
128 /* find the head of a linked list, given a point in it | 240 /* find the head of a linked list, given a point in it |
129 */ | 241 */ |
130 #define SDL_joylist_head(i, start)\ | 242 #define SDL_joylist_head(i, start)\ |
185 | 297 |
186 static int CountLogicalJoysticks(int max) | 298 static int CountLogicalJoysticks(int max) |
187 { | 299 { |
188 register int i, j, k, ret, prev; | 300 register int i, j, k, ret, prev; |
189 const char* name; | 301 const char* name; |
302 int nbuttons, fd; | |
303 unsigned char n; | |
190 | 304 |
191 ret = 0; | 305 ret = 0; |
192 | 306 |
193 for(i = 0; i < max; i++) { | 307 for(i = 0; i < max; i++) { |
194 name = SDL_SYS_JoystickName(i); | 308 name = SDL_SYS_JoystickName(i); |
309 | |
310 fd = open(SDL_joylist[i].fname, O_RDONLY, 0); | |
311 if ( fd >= 0 ) { | |
312 if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) { | |
313 nbuttons = -1; | |
314 } else { | |
315 nbuttons = n; | |
316 } | |
317 close(fd); | |
318 } | |
319 else { | |
320 nbuttons=-1; | |
321 } | |
195 | 322 |
196 if (name) { | 323 if (name) { |
197 for(j = 0; j < SDL_arraysize(joystick_logicalmap); j++) { | 324 for(j = 0; j < SDL_arraysize(joystick_logicalmap); j++) { |
198 if (!SDL_strcmp(name, joystick_logicalmap[j].name)) { | 325 if (!SDL_strcmp(name, joystick_logicalmap[j].name) && (nbuttons==-1 || nbuttons==joystick_logicalmap[j].nbuttons)) { |
199 | |
200 prev = i; | 326 prev = i; |
201 SDL_joylist[prev].map = joystick_logicalmap+j; | 327 SDL_joylist[prev].map = &(joystick_logicalmap[j]); |
202 | 328 |
203 for(k = 1; k < joystick_logicalmap[j].njoys; k++) { | 329 for(k = 1; k < joystick_logicalmap[j].njoys; k++) { |
204 SDL_joylist[prev].next = max + ret; | 330 SDL_joylist[prev].next = max + ret; |
205 | 331 SDL_joylist[max+ret].prev = prev; |
206 if (prev != i) | 332 |
207 SDL_joylist[max+ret].prev = prev; | |
208 | |
209 prev = max + ret; | 333 prev = max + ret; |
210 SDL_joylist[prev].logicalno = k; | 334 SDL_joylist[prev].logicalno = k; |
211 SDL_joylist[prev].map = joystick_logicalmap+j; | 335 SDL_joylist[prev].map = &(joystick_logicalmap[j]); |
212 ret++; | 336 ret++; |
213 } | 337 } |
214 | 338 |
215 break; | 339 break; |
216 } | 340 } |
226 register int slen; | 350 register int slen; |
227 const static char suffixs[] = | 351 const static char suffixs[] = |
228 "01020304050607080910111213141516171819" | 352 "01020304050607080910111213141516171819" |
229 "20212223242526272829303132"; | 353 "20212223242526272829303132"; |
230 const char* suffix; | 354 const char* suffix; |
231 | |
232 slen = SDL_strlen(namebuf); | 355 slen = SDL_strlen(namebuf); |
233 | |
234 suffix = NULL; | 356 suffix = NULL; |
235 | 357 |
236 if (logicalno*2<sizeof(suffixs)) | 358 if (logicalno*2<sizeof(suffixs)) |
237 suffix = suffixs + (logicalno*2); | 359 suffix = suffixs + (logicalno*2); |
238 | 360 |
397 } else { | 519 } else { |
398 name = namebuf; | 520 name = namebuf; |
399 } | 521 } |
400 close(fd); | 522 close(fd); |
401 | 523 |
402 #ifndef NO_LOGICAL_JOYSTICKS | 524 |
403 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next) | 525 #ifndef NO_LOGICAL_JOYSTICKS |
526 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex) | |
527 { | |
404 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128); | 528 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128); |
529 } | |
405 #endif | 530 #endif |
406 } | 531 } |
407 return name; | 532 return name; |
408 } | 533 } |
409 | 534 |
633 #ifndef NO_LOGICAL_JOYSTICKS | 758 #ifndef NO_LOGICAL_JOYSTICKS |
634 static void ConfigLogicalJoystick(SDL_Joystick *joystick) | 759 static void ConfigLogicalJoystick(SDL_Joystick *joystick) |
635 { | 760 { |
636 struct joystick_logical_layout* layout; | 761 struct joystick_logical_layout* layout; |
637 | 762 |
638 layout = SDL_joylist[joystick->index].map->layouts + | 763 layout = SDL_joylist[joystick->index].map->layout + |
639 SDL_joylist[joystick->index].logicalno; | 764 SDL_joylist[joystick->index].logicalno; |
640 | 765 |
641 joystick->nbuttons = layout->nbuttons; | 766 joystick->nbuttons = layout->nbuttons; |
642 joystick->nhats = layout->nhats; | 767 joystick->nhats = layout->nhats; |
643 joystick->naxes = layout->naxes; | 768 joystick->naxes = layout->naxes; |
709 } | 834 } |
710 | 835 |
711 #ifndef NO_LOGICAL_JOYSTICKS | 836 #ifndef NO_LOGICAL_JOYSTICKS |
712 | 837 |
713 static SDL_Joystick* FindLogicalJoystick( | 838 static SDL_Joystick* FindLogicalJoystick( |
714 SDL_Joystick *joystick, struct joystick_logical_values* v) | 839 SDL_Joystick *joystick, struct joystick_logical_mapping* v) |
715 { | 840 { |
716 SDL_Joystick *logicaljoy; | 841 SDL_Joystick *logicaljoy; |
717 register int i; | 842 register int i; |
718 | 843 |
719 i = joystick->index; | 844 i = joystick->index; |
738 return logicaljoy; | 863 return logicaljoy; |
739 } | 864 } |
740 | 865 |
741 static int LogicalJoystickButton( | 866 static int LogicalJoystickButton( |
742 SDL_Joystick *joystick, Uint8 button, Uint8 state){ | 867 SDL_Joystick *joystick, Uint8 button, Uint8 state){ |
743 struct joystick_logical_values* buttons; | 868 struct joystick_logical_mapping* buttons; |
744 SDL_Joystick *logicaljoy = NULL; | 869 SDL_Joystick *logicaljoy = NULL; |
745 | 870 |
746 /* if there's no map then this is just a regular joystick | 871 /* if there's no map then this is just a regular joystick |
747 */ | 872 */ |
748 if (SDL_joylist[joystick->index].map == NULL) | 873 if (SDL_joylist[joystick->index].map == NULL) |
749 return 0; | 874 return 0; |
750 | 875 |
751 /* get the logical joystick that will receive the event | 876 /* get the logical joystick that will receive the event |
752 */ | 877 */ |
753 buttons = SDL_joylist[joystick->index].map->buttons+button; | 878 buttons = SDL_joylist[joystick->index].map->buttonmap+button; |
754 logicaljoy = FindLogicalJoystick(joystick, buttons); | 879 logicaljoy = FindLogicalJoystick(joystick, buttons); |
755 | 880 |
756 if (logicaljoy == NULL) | 881 if (logicaljoy == NULL) |
757 return 1; | 882 return 1; |
758 | 883 |
762 } | 887 } |
763 | 888 |
764 static int LogicalJoystickAxis( | 889 static int LogicalJoystickAxis( |
765 SDL_Joystick *joystick, Uint8 axis, Sint16 value) | 890 SDL_Joystick *joystick, Uint8 axis, Sint16 value) |
766 { | 891 { |
767 struct joystick_logical_values* axes; | 892 struct joystick_logical_mapping* axes; |
768 SDL_Joystick *logicaljoy = NULL; | 893 SDL_Joystick *logicaljoy = NULL; |
769 | 894 |
770 /* if there's no map then this is just a regular joystick | 895 /* if there's no map then this is just a regular joystick |
771 */ | 896 */ |
772 if (SDL_joylist[joystick->index].map == NULL) | 897 if (SDL_joylist[joystick->index].map == NULL) |
773 return 0; | 898 return 0; |
774 | 899 |
775 /* get the logical joystick that will receive the event | 900 /* get the logical joystick that will receive the event |
776 */ | 901 */ |
777 axes = SDL_joylist[joystick->index].map->axes+axis; | 902 axes = SDL_joylist[joystick->index].map->axismap+axis; |
778 logicaljoy = FindLogicalJoystick(joystick, axes); | 903 logicaljoy = FindLogicalJoystick(joystick, axes); |
779 | 904 |
780 if (logicaljoy == NULL) | 905 if (logicaljoy == NULL) |
781 return 1; | 906 return 1; |
782 | 907 |
794 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, | 919 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, |
795 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, | 920 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, |
796 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } | 921 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } |
797 }; | 922 }; |
798 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL); | 923 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL); |
799 SDL_logical_joydecl(struct joystick_logical_values* hats = NULL); | 924 SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL); |
800 | 925 |
801 the_hat = &stick->hwdata->hats[hat]; | 926 the_hat = &stick->hwdata->hats[hat]; |
802 if ( value < 0 ) { | 927 if ( value < 0 ) { |
803 value = 0; | 928 value = 0; |
804 } else | 929 } else |
816 */ | 941 */ |
817 if (SDL_joylist[stick->index].map != NULL) { | 942 if (SDL_joylist[stick->index].map != NULL) { |
818 | 943 |
819 /* get the fake joystick that will receive the event | 944 /* get the fake joystick that will receive the event |
820 */ | 945 */ |
821 hats = SDL_joylist[stick->index].map->hats+hat; | 946 hats = SDL_joylist[stick->index].map->hatmap+hat; |
822 logicaljoy = FindLogicalJoystick(stick, hats); | 947 logicaljoy = FindLogicalJoystick(stick, hats); |
823 } | 948 } |
824 | 949 |
825 if (logicaljoy) { | 950 if (logicaljoy) { |
826 stick = logicaljoy; | 951 stick = logicaljoy; |