• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
SDL_SYS_JoystickInit(void)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 */
SDL_SYS_JoystickName(int index)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  */
SDL_SYS_JoystickOpen(SDL_Joystick * joystick)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  */
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)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 */
SDL_SYS_JoystickClose(SDL_Joystick * joystick)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 */
SDL_SYS_JoystickQuit(void)315 void SDL_SYS_JoystickQuit(void)
316 {
317     ISpShutdown();
318 }
319 
320 #endif /* SDL_JOYSTICK_MACOS */
321