SDL-1.2.14
[sdl_omap.git] / src / joystick / macos / SDL_sysjoystick.c
CommitLineData
e14743d1 1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 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
48static ISpDeviceReference SYS_Joysticks[MAX_JOYSTICKS];
49static ISpElementListReference SYS_Elements[MAX_JOYSTICKS];
50static ISpDeviceDefinition SYS_DevDef[MAX_JOYSTICKS];
51
52struct 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 */
66int 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 */
130const 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 */
151int 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 */
224void 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 */
303void 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 */
315void SDL_SYS_JoystickQuit(void)
316{
317 ISpShutdown();
318}
319
320#endif /* SDL_JOYSTICK_MACOS */