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