src/joystick/beos/SDL_bejoystick.cc
author Sam Lantinga <slouken@libsdl.org>
Thu, 29 Aug 2013 08:29:21 -0700
changeset 7719 31b5f9ff36ca
parent 7191 75360622e65f
permissions -rw-r--r--
Christoph Mallon: Remove pointless if (x) before SDL_free(x)
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 #ifdef SDL_JOYSTICK_BEOS
    24 
    25 /* This is the system specific header for the SDL joystick API */
    26 
    27 #include <be/support/String.h>
    28 #include <be/device/Joystick.h>
    29 
    30 extern "C"
    31 {
    32 
    33 #include "SDL_joystick.h"
    34 #include "../SDL_sysjoystick.h"
    35 #include "../SDL_joystick_c.h"
    36 
    37 
    38 /* The maximum number of joysticks we'll detect */
    39 #define MAX_JOYSTICKS	16
    40 
    41 /* A list of available joysticks */
    42     static char *SDL_joyport[MAX_JOYSTICKS];
    43     static char *SDL_joyname[MAX_JOYSTICKS];
    44 
    45 /* The private structure used to keep track of a joystick */
    46     struct joystick_hwdata
    47     {
    48         BJoystick *stick;
    49         uint8 *new_hats;
    50         int16 *new_axes;
    51     };
    52 
    53     static int SDL_SYS_numjoysticks = 0;
    54 
    55 /* Function to scan the system for joysticks.
    56  * This function should set SDL_numjoysticks to the number of available
    57  * joysticks.  Joystick 0 should be the system default joystick.
    58  * It should return 0, or -1 on an unrecoverable fatal error.
    59  */
    60     int SDL_SYS_JoystickInit(void)
    61     {
    62         BJoystick joystick;
    63         int i;
    64         int32 nports;
    65         char name[B_OS_NAME_LENGTH];
    66 
    67         /* Search for attached joysticks */
    68           nports = joystick.CountDevices();
    69           SDL_SYS_numjoysticks = 0;
    70           SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
    71           SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
    72         for (i = 0; (SDL_SYS_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i)
    73         {
    74             if (joystick.GetDeviceName(i, name) == B_OK) {
    75                 if (joystick.Open(name) != B_ERROR) {
    76                     BString stick_name;
    77                       joystick.GetControllerName(&stick_name);
    78                       SDL_joyport[SDL_SYS_numjoysticks] = strdup(name);
    79                       SDL_joyname[SDL_SYS_numjoysticks] = strdup(stick_name.String());
    80                       SDL_SYS_numjoysticks++;
    81                       joystick.Close();
    82                 }
    83             }
    84         }
    85         return (SDL_SYS_numjoysticks);
    86     }
    87 
    88     int SDL_SYS_NumJoysticks()
    89     {
    90         return SDL_SYS_numjoysticks;
    91     }
    92 
    93     void SDL_SYS_JoystickDetect()
    94     {
    95     }
    96 
    97     SDL_bool SDL_SYS_JoystickNeedsPolling()
    98     {
    99         return SDL_FALSE;
   100     }
   101 
   102 /* Function to get the device-dependent name of a joystick */
   103     const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   104     {
   105         return SDL_joyname[device_index];
   106     }
   107 
   108 /* Function to perform the mapping from device index to the instance id for this index */
   109     SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   110     {
   111         return device_index;
   112     }
   113 
   114 /* Function to open a joystick for use.
   115    The joystick to open is specified by the index field of the joystick.
   116    This should fill the nbuttons and naxes fields of the joystick structure.
   117    It returns 0, or -1 if there is an error.
   118  */
   119     int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   120     {
   121         BJoystick *stick;
   122 
   123         /* Create the joystick data structure */
   124         joystick->instance_id = device_index;
   125         joystick->hwdata = (struct joystick_hwdata *)
   126             SDL_malloc(sizeof(*joystick->hwdata));
   127         if (joystick->hwdata == NULL) {
   128             return SDL_OutOfMemory();
   129         }
   130         SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
   131         stick = new BJoystick;
   132         joystick->hwdata->stick = stick;
   133 
   134         /* Open the requested joystick for use */
   135         if (stick->Open(SDL_joyport[device_index]) == B_ERROR) {
   136             SDL_SYS_JoystickClose(joystick);
   137             return SDL_SetError("Unable to open joystick");
   138         }
   139 
   140         /* Set the joystick to calibrated mode */
   141         stick->EnableCalibration();
   142 
   143         /* Get the number of buttons, hats, and axes on the joystick */
   144         joystick->nbuttons = stick->CountButtons();
   145         joystick->naxes = stick->CountAxes();
   146         joystick->nhats = stick->CountHats();
   147 
   148         joystick->hwdata->new_axes = (int16 *)
   149             SDL_malloc(joystick->naxes * sizeof(int16));
   150         joystick->hwdata->new_hats = (uint8 *)
   151             SDL_malloc(joystick->nhats * sizeof(uint8));
   152         if (!joystick->hwdata->new_hats || !joystick->hwdata->new_axes) {
   153             SDL_SYS_JoystickClose(joystick);
   154             return SDL_OutOfMemory();
   155         }
   156 
   157         /* We're done! */
   158         return (0);
   159     }
   160 
   161 /* Function to determine is this joystick is attached to the system right now */
   162     SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
   163     {
   164         return SDL_TRUE;
   165     }
   166 
   167 /* Function to update the state of a joystick - called as a device poll.
   168  * This function shouldn't update the joystick structure directly,
   169  * but instead should call SDL_PrivateJoystick*() to deliver events
   170  * and update joystick device state.
   171  */
   172     void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   173     {
   174         static const Uint8 hat_map[9] = {
   175             SDL_HAT_CENTERED,
   176             SDL_HAT_UP,
   177             SDL_HAT_RIGHTUP,
   178             SDL_HAT_RIGHT,
   179             SDL_HAT_RIGHTDOWN,
   180             SDL_HAT_DOWN,
   181             SDL_HAT_LEFTDOWN,
   182             SDL_HAT_LEFT,
   183             SDL_HAT_LEFTUP
   184         };
   185         const int JITTER = (32768 / 10);        /* 10% jitter threshold (ok?) */
   186 
   187         BJoystick *stick;
   188         int i, change;
   189         int16 *axes;
   190         uint8 *hats;
   191         uint32 buttons;
   192 
   193         /* Set up data pointers */
   194         stick = joystick->hwdata->stick;
   195         axes = joystick->hwdata->new_axes;
   196         hats = joystick->hwdata->new_hats;
   197 
   198         /* Get the new joystick state */
   199         stick->Update();
   200         stick->GetAxisValues(axes);
   201         stick->GetHatValues(hats);
   202         buttons = stick->ButtonValues();
   203 
   204         /* Generate axis motion events */
   205         for (i = 0; i < joystick->naxes; ++i) {
   206             change = ((int32) axes[i] - joystick->axes[i]);
   207             if ((change > JITTER) || (change < -JITTER)) {
   208                 SDL_PrivateJoystickAxis(joystick, i, axes[i]);
   209             }
   210         }
   211 
   212         /* Generate hat change events */
   213         for (i = 0; i < joystick->nhats; ++i) {
   214             if (hats[i] != joystick->hats[i]) {
   215                 SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]);
   216             }
   217         }
   218 
   219         /* Generate button events */
   220         for (i = 0; i < joystick->nbuttons; ++i) {
   221             if ((buttons & 0x01) != joystick->buttons[i]) {
   222                 SDL_PrivateJoystickButton(joystick, i, (buttons & 0x01));
   223             }
   224             buttons >>= 1;
   225         }
   226     }
   227 
   228 /* Function to close a joystick after use */
   229     void SDL_SYS_JoystickClose(SDL_Joystick * joystick)
   230     {
   231         if (joystick->hwdata) {
   232             joystick->hwdata->stick->Close();
   233             delete joystick->hwdata->stick;
   234             SDL_free(joystick->hwdata->new_hats);
   235             SDL_free(joystick->hwdata->new_axes);
   236             SDL_free(joystick->hwdata);
   237             joystick->hwdata = NULL;
   238         }
   239     }
   240 
   241 /* Function to perform any system-specific joystick related cleanup */
   242     void SDL_SYS_JoystickQuit(void)
   243     {
   244         int i;
   245 
   246         for (i = 0; SDL_joyport[i]; ++i) {
   247             SDL_free(SDL_joyport[i]);
   248         }
   249         SDL_joyport[0] = NULL;
   250 
   251         for (i = 0; SDL_joyname[i]; ++i) {
   252             SDL_free(SDL_joyname[i]);
   253         }
   254         SDL_joyname[0] = NULL;
   255     }
   256 
   257     SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   258     {
   259         SDL_JoystickGUID guid;
   260         /* the GUID is just the first 16 chars of the name for now */
   261         const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
   262         SDL_zero( guid );
   263         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   264         return guid;
   265     }
   266 
   267     SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   268     {
   269         SDL_JoystickGUID guid;
   270         /* the GUID is just the first 16 chars of the name for now */
   271         const char *name = joystick->name;
   272         SDL_zero( guid );
   273         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   274         return guid;
   275     }
   276 
   277 };                              // extern "C"
   278 
   279 #endif /* SDL_JOYSTICK_BEOS */
   280 /* vi: set ts=4 sw=4 expandtab: */