Home | History | Annotate | Download | only in macos
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 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 (at) 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 */
    321