|
1 /* |
|
2 SDL - Simple DirectMedia Layer |
|
3 Copyright (C) 1997-2006 Sam Lantinga |
|
4 |
|
5 This library is free software; you can redistribute it and/or |
|
6 modify it under the terms of the GNU Lesser General Public |
|
7 License as published by the Free Software Foundation; either |
|
8 version 2.1 of the License, or (at your option) any later version. |
|
9 |
|
10 This library is distributed in the hope that it will be useful, |
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 Lesser General Public License for more details. |
|
14 |
|
15 You should have received a copy of the GNU Lesser General Public |
|
16 License along with this library; if not, write to the Free Software |
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
18 |
|
19 Sam Lantinga |
|
20 slouken@libsdl.org |
|
21 */ |
|
22 #include "SDL_config.h" |
|
23 |
|
24 #ifdef SDL_JOYSTICK_MACOS |
|
25 |
|
26 /* SDL stuff -- "SDL_sysjoystick.c" |
|
27 MacOS joystick functions by Frederick Reitberger |
|
28 |
|
29 The code that follows is meant for SDL. Use at your own risk. |
|
30 */ |
|
31 |
|
32 #include <InputSprocket.h> |
|
33 |
|
34 #include "SDL_joystick.h" |
|
35 #include "../SDL_sysjoystick.h" |
|
36 #include "../SDL_joystick_c.h" |
|
37 |
|
38 |
|
39 /* The max number of joysticks we will detect */ |
|
40 #define MAX_JOYSTICKS 16 |
|
41 /* Limit ourselves to 32 elements per device */ |
|
42 #define kMaxReferences 32 |
|
43 |
|
44 #define ISpSymmetricAxisToFloat(axis) ((((float) axis) - kISpAxisMiddle) / (kISpAxisMaximum-kISpAxisMiddle)) |
|
45 #define ISpAsymmetricAxisToFloat(axis) (((float) axis) / (kISpAxisMaximum)) |
|
46 |
|
47 |
|
48 static ISpDeviceReference SYS_Joysticks[MAX_JOYSTICKS]; |
|
49 static ISpElementListReference SYS_Elements[MAX_JOYSTICKS]; |
|
50 static ISpDeviceDefinition SYS_DevDef[MAX_JOYSTICKS]; |
|
51 |
|
52 struct joystick_hwdata |
|
53 { |
|
54 char name[64]; |
|
55 /* Uint8 id;*/ |
|
56 ISpElementReference refs[kMaxReferences]; |
|
57 /* gonna need some sort of mapping info */ |
|
58 }; |
|
59 |
|
60 |
|
61 /* Function to scan the system for joysticks. |
|
62 * Joystick 0 should be the system default joystick. |
|
63 * This function should return the number of available joysticks, or -1 |
|
64 * on an unrecoverable fatal error. |
|
65 */ |
|
66 int SDL_SYS_JoystickInit(void) |
|
67 { |
|
68 static ISpDeviceClass classes[4] = { |
|
69 kISpDeviceClass_Joystick, |
|
70 #if kISpDeviceClass_Gamepad |
|
71 kISpDeviceClass_Gamepad, |
|
72 #endif |
|
73 kISpDeviceClass_Wheel, |
|
74 0 |
|
75 }; |
|
76 OSErr err; |
|
77 int i; |
|
78 UInt32 count, numJoysticks; |
|
79 |
|
80 if ( (Ptr)0 == (Ptr)ISpStartup ) { |
|
81 SDL_SetError("InputSprocket not installed"); |
|
82 return -1; // InputSprocket not installed |
|
83 } |
|
84 |
|
85 if( (Ptr)0 == (Ptr)ISpGetVersion ) { |
|
86 SDL_SetError("InputSprocket not version 1.1 or newer"); |
|
87 return -1; // old version of ISp (not at least 1.1) |
|
88 } |
|
89 |
|
90 ISpStartup(); |
|
91 |
|
92 /* Get all the joysticks */ |
|
93 numJoysticks = 0; |
|
94 for ( i=0; classes[i]; ++i ) { |
|
95 count = 0; |
|
96 err = ISpDevices_ExtractByClass( |
|
97 classes[i], |
|
98 MAX_JOYSTICKS-numJoysticks, |
|
99 &count, |
|
100 &SYS_Joysticks[numJoysticks]); |
|
101 numJoysticks += count; |
|
102 } |
|
103 |
|
104 for(i = 0; i < numJoysticks; i++) |
|
105 { |
|
106 ISpDevice_GetDefinition( |
|
107 SYS_Joysticks[i], sizeof(ISpDeviceDefinition), |
|
108 &SYS_DevDef[i]); |
|
109 |
|
110 err = ISpElementList_New( |
|
111 0, NULL, |
|
112 &SYS_Elements[i], 0); |
|
113 |
|
114 if (err) { |
|
115 SDL_OutOfMemory(); |
|
116 return -1; |
|
117 } |
|
118 |
|
119 ISpDevice_GetElementList( |
|
120 SYS_Joysticks[i], |
|
121 &SYS_Elements[i]); |
|
122 } |
|
123 |
|
124 ISpDevices_Deactivate(numJoysticks, SYS_Joysticks); |
|
125 |
|
126 return numJoysticks; |
|
127 } |
|
128 |
|
129 /* Function to get the device-dependent name of a joystick */ |
|
130 const char *SDL_SYS_JoystickName(int index) |
|
131 { |
|
132 static char name[64]; |
|
133 int len; |
|
134 |
|
135 /* convert pascal string to c-string */ |
|
136 len = SYS_DevDef[index].deviceName[0]; |
|
137 if ( len >= sizeof(name) ) { |
|
138 len = (sizeof(name) - 1); |
|
139 } |
|
140 SDL_memcpy(name, &SYS_DevDef[index].deviceName[1], len); |
|
141 name[len] = '\0'; |
|
142 |
|
143 return name; |
|
144 } |
|
145 |
|
146 /* Function to open a joystick for use. |
|
147 The joystick to open is specified by the index field of the joystick. |
|
148 This should fill the nbuttons and naxes fields of the joystick structure. |
|
149 It returns 0, or -1 if there is an error. |
|
150 */ |
|
151 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) |
|
152 { |
|
153 int index; |
|
154 UInt32 count, gotCount, count2; |
|
155 long numAxis, numButtons, numHats, numBalls; |
|
156 |
|
157 count = kMaxReferences; |
|
158 count2 = 0; |
|
159 numAxis = numButtons = numHats = numBalls = 0; |
|
160 |
|
161 index = joystick->index; |
|
162 |
|
163 /* allocate memory for system specific hardware data */ |
|
164 joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); |
|
165 if (joystick->hwdata == NULL) |
|
166 { |
|
167 SDL_OutOfMemory(); |
|
168 return(-1); |
|
169 } |
|
170 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); |
|
171 SDL_strlcpy(joystick->hwdata->name, SDL_SYS_JoystickName(index), SDL_arraysize(joystick->hwdata->name)); |
|
172 joystick->name = joystick->hwdata->name; |
|
173 |
|
174 ISpElementList_ExtractByKind( |
|
175 SYS_Elements[index], |
|
176 kISpElementKind_Axis, |
|
177 count, |
|
178 &gotCount, |
|
179 joystick->hwdata->refs); |
|
180 |
|
181 numAxis = gotCount; |
|
182 count -= gotCount; |
|
183 count2 += gotCount; |
|
184 |
|
185 ISpElementList_ExtractByKind( |
|
186 SYS_Elements[index], |
|
187 kISpElementKind_DPad, |
|
188 count, |
|
189 &gotCount, |
|
190 &(joystick->hwdata->refs[count2])); |
|
191 |
|
192 numHats = gotCount; |
|
193 count -= gotCount; |
|
194 count2 += gotCount; |
|
195 |
|
196 ISpElementList_ExtractByKind( |
|
197 SYS_Elements[index], |
|
198 kISpElementKind_Button, |
|
199 count, |
|
200 &gotCount, |
|
201 &(joystick->hwdata->refs[count2])); |
|
202 |
|
203 numButtons = gotCount; |
|
204 count -= gotCount; |
|
205 count2 += gotCount; |
|
206 |
|
207 joystick->naxes = numAxis; |
|
208 joystick->nhats = numHats; |
|
209 joystick->nballs = numBalls; |
|
210 joystick->nbuttons = numButtons; |
|
211 |
|
212 ISpDevices_Activate( |
|
213 1, |
|
214 &SYS_Joysticks[index]); |
|
215 |
|
216 return 0; |
|
217 } |
|
218 |
|
219 /* Function to update the state of a joystick - called as a device poll. |
|
220 * This function shouldn't update the joystick structure directly, |
|
221 * but instead should call SDL_PrivateJoystick*() to deliver events |
|
222 * and update joystick device state. |
|
223 */ |
|
224 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) |
|
225 { |
|
226 int i, j; |
|
227 ISpAxisData a; |
|
228 ISpDPadData b; |
|
229 //ISpDeltaData c; |
|
230 ISpButtonData d; |
|
231 |
|
232 for(i = 0, j = 0; i < joystick->naxes; i++, j++) |
|
233 { |
|
234 Sint16 value; |
|
235 |
|
236 ISpElement_GetSimpleState( |
|
237 joystick->hwdata->refs[j], |
|
238 &a); |
|
239 value = (ISpSymmetricAxisToFloat(a)* 32767.0); |
|
240 if ( value != joystick->axes[i] ) { |
|
241 SDL_PrivateJoystickAxis(joystick, i, value); |
|
242 } |
|
243 } |
|
244 |
|
245 for(i = 0; i < joystick->nhats; i++, j++) |
|
246 { |
|
247 Uint8 pos; |
|
248 |
|
249 ISpElement_GetSimpleState( |
|
250 joystick->hwdata->refs[j], |
|
251 &b); |
|
252 switch(b) { |
|
253 case kISpPadIdle: |
|
254 pos = SDL_HAT_CENTERED; |
|
255 break; |
|
256 case kISpPadLeft: |
|
257 pos = SDL_HAT_LEFT; |
|
258 break; |
|
259 case kISpPadUpLeft: |
|
260 pos = SDL_HAT_LEFTUP; |
|
261 break; |
|
262 case kISpPadUp: |
|
263 pos = SDL_HAT_UP; |
|
264 break; |
|
265 case kISpPadUpRight: |
|
266 pos = SDL_HAT_RIGHTUP; |
|
267 break; |
|
268 case kISpPadRight: |
|
269 pos = SDL_HAT_RIGHT; |
|
270 break; |
|
271 case kISpPadDownRight: |
|
272 pos = SDL_HAT_RIGHTDOWN; |
|
273 break; |
|
274 case kISpPadDown: |
|
275 pos = SDL_HAT_DOWN; |
|
276 break; |
|
277 case kISpPadDownLeft: |
|
278 pos = SDL_HAT_LEFTDOWN; |
|
279 break; |
|
280 } |
|
281 if ( pos != joystick->hats[i] ) { |
|
282 SDL_PrivateJoystickHat(joystick, i, pos); |
|
283 } |
|
284 } |
|
285 |
|
286 for(i = 0; i < joystick->nballs; i++, j++) |
|
287 { |
|
288 /* ignore balls right now */ |
|
289 } |
|
290 |
|
291 for(i = 0; i < joystick->nbuttons; i++, j++) |
|
292 { |
|
293 ISpElement_GetSimpleState( |
|
294 joystick->hwdata->refs[j], |
|
295 &d); |
|
296 if ( d != joystick->buttons[i] ) { |
|
297 SDL_PrivateJoystickButton(joystick, i, d); |
|
298 } |
|
299 } |
|
300 } |
|
301 |
|
302 /* Function to close a joystick after use */ |
|
303 void SDL_SYS_JoystickClose(SDL_Joystick *joystick) |
|
304 { |
|
305 int index; |
|
306 |
|
307 index = joystick->index; |
|
308 |
|
309 ISpDevices_Deactivate( |
|
310 1, |
|
311 &SYS_Joysticks[index]); |
|
312 } |
|
313 |
|
314 /* Function to perform any system-specific joystick related cleanup */ |
|
315 void SDL_SYS_JoystickQuit(void) |
|
316 { |
|
317 ISpShutdown(); |
|
318 } |
|
319 |
|
320 #endif /* SDL_JOYSTICK_MACOS */ |