src/joystick/haiku/SDL_haikujoystick.cc
author Ryan C. Gordon <icculus@icculus.org>
Tue, 24 Mar 2015 13:52:01 -0400
changeset 9433 bd062398b648
parent 9380 07b7c1005a23
child 9561 d8ad01792399
permissions -rw-r--r--
Cleanups in the joystick code.

Removed some redundant state and other confusions.

Fixes Bugzilla #2738.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 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_internal.h"
    22 
    23 #ifdef SDL_JOYSTICK_HAIKU
    24 
    25 /* This is the Haiku implementation of the SDL joystick API */
    26 
    27 #include <os/support/String.h>
    28 #include <os/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  * Joystick 0 should be the system default joystick.
    57  * It should return 0, or -1 on an unrecoverable fatal error.
    58  */
    59     int SDL_SYS_JoystickInit(void)
    60     {
    61         BJoystick joystick;
    62         int i;
    63         int32 nports;
    64         char name[B_OS_NAME_LENGTH];
    65 
    66         /* Search for attached joysticks */
    67           nports = joystick.CountDevices();
    68           SDL_SYS_numjoysticks = 0;
    69           SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
    70           SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
    71         for (i = 0; (SDL_SYS_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i)
    72         {
    73             if (joystick.GetDeviceName(i, name) == B_OK) {
    74                 if (joystick.Open(name) != B_ERROR) {
    75                     BString stick_name;
    76                       joystick.GetControllerName(&stick_name);
    77                       SDL_joyport[SDL_SYS_numjoysticks] = strdup(name);
    78                       SDL_joyname[SDL_SYS_numjoysticks] = strdup(stick_name.String());
    79                       SDL_SYS_numjoysticks++;
    80                       joystick.Close();
    81                 }
    82             }
    83         }
    84         return (SDL_SYS_numjoysticks);
    85     }
    86 
    87     int SDL_SYS_NumJoysticks()
    88     {
    89         return SDL_SYS_numjoysticks;
    90     }
    91 
    92     void SDL_SYS_JoystickDetect()
    93     {
    94     }
    95 
    96 /* Function to get the device-dependent name of a joystick */
    97     const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index)
    98     {
    99         return SDL_joyname[device_index];
   100     }
   101 
   102 /* Function to perform the mapping from device index to the instance id for this index */
   103     SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   104     {
   105         return device_index;
   106     }
   107 
   108 /* Function to open a joystick for use.
   109    The joystick to open is specified by the device index.
   110    This should fill the nbuttons and naxes fields of the joystick structure.
   111    It returns 0, or -1 if there is an error.
   112  */
   113     int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   114     {
   115         BJoystick *stick;
   116 
   117         /* Create the joystick data structure */
   118         joystick->instance_id = device_index;
   119         joystick->hwdata = (struct joystick_hwdata *)
   120             SDL_malloc(sizeof(*joystick->hwdata));
   121         if (joystick->hwdata == NULL) {
   122             return SDL_OutOfMemory();
   123         }
   124         SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
   125         stick = new BJoystick;
   126         joystick->hwdata->stick = stick;
   127 
   128         /* Open the requested joystick for use */
   129         if (stick->Open(SDL_joyport[device_index]) == B_ERROR) {
   130             SDL_SYS_JoystickClose(joystick);
   131             return SDL_SetError("Unable to open joystick");
   132         }
   133 
   134         /* Set the joystick to calibrated mode */
   135         stick->EnableCalibration();
   136 
   137         /* Get the number of buttons, hats, and axes on the joystick */
   138         joystick->nbuttons = stick->CountButtons();
   139         joystick->naxes = stick->CountAxes();
   140         joystick->nhats = stick->CountHats();
   141 
   142         joystick->hwdata->new_axes = (int16 *)
   143             SDL_malloc(joystick->naxes * sizeof(int16));
   144         joystick->hwdata->new_hats = (uint8 *)
   145             SDL_malloc(joystick->nhats * sizeof(uint8));
   146         if (!joystick->hwdata->new_hats || !joystick->hwdata->new_axes) {
   147             SDL_SYS_JoystickClose(joystick);
   148             return SDL_OutOfMemory();
   149         }
   150 
   151         /* We're done! */
   152         return (0);
   153     }
   154 
   155 /* Function to determine is this joystick is attached to the system right now */
   156     SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
   157     {
   158         return SDL_TRUE;
   159     }
   160 
   161 /* Function to update the state of a joystick - called as a device poll.
   162  * This function shouldn't update the joystick structure directly,
   163  * but instead should call SDL_PrivateJoystick*() to deliver events
   164  * and update joystick device state.
   165  */
   166     void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   167     {
   168         static const Uint8 hat_map[9] = {
   169             SDL_HAT_CENTERED,
   170             SDL_HAT_UP,
   171             SDL_HAT_RIGHTUP,
   172             SDL_HAT_RIGHT,
   173             SDL_HAT_RIGHTDOWN,
   174             SDL_HAT_DOWN,
   175             SDL_HAT_LEFTDOWN,
   176             SDL_HAT_LEFT,
   177             SDL_HAT_LEFTUP
   178         };
   179         const int JITTER = (32768 / 10);        /* 10% jitter threshold (ok?) */
   180 
   181         BJoystick *stick;
   182         int i, change;
   183         int16 *axes;
   184         uint8 *hats;
   185         uint32 buttons;
   186 
   187         /* Set up data pointers */
   188         stick = joystick->hwdata->stick;
   189         axes = joystick->hwdata->new_axes;
   190         hats = joystick->hwdata->new_hats;
   191 
   192         /* Get the new joystick state */
   193         stick->Update();
   194         stick->GetAxisValues(axes);
   195         stick->GetHatValues(hats);
   196         buttons = stick->ButtonValues();
   197 
   198         /* Generate axis motion events */
   199         for (i = 0; i < joystick->naxes; ++i) {
   200             change = ((int32) axes[i] - joystick->axes[i]);
   201             if ((change > JITTER) || (change < -JITTER)) {
   202                 SDL_PrivateJoystickAxis(joystick, i, axes[i]);
   203             }
   204         }
   205 
   206         /* Generate hat change events */
   207         for (i = 0; i < joystick->nhats; ++i) {
   208             if (hats[i] != joystick->hats[i]) {
   209                 SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]);
   210             }
   211         }
   212 
   213         /* Generate button events */
   214         for (i = 0; i < joystick->nbuttons; ++i) {
   215             if ((buttons & 0x01) != joystick->buttons[i]) {
   216                 SDL_PrivateJoystickButton(joystick, i, (buttons & 0x01));
   217             }
   218             buttons >>= 1;
   219         }
   220     }
   221 
   222 /* Function to close a joystick after use */
   223     void SDL_SYS_JoystickClose(SDL_Joystick * joystick)
   224     {
   225         if (joystick->hwdata) {
   226             joystick->hwdata->stick->Close();
   227             delete joystick->hwdata->stick;
   228             SDL_free(joystick->hwdata->new_hats);
   229             SDL_free(joystick->hwdata->new_axes);
   230             SDL_free(joystick->hwdata);
   231         }
   232     }
   233 
   234 /* Function to perform any system-specific joystick related cleanup */
   235     void SDL_SYS_JoystickQuit(void)
   236     {
   237         int i;
   238 
   239         for (i = 0; SDL_joyport[i]; ++i) {
   240             SDL_free(SDL_joyport[i]);
   241         }
   242         SDL_joyport[0] = NULL;
   243 
   244         for (i = 0; SDL_joyname[i]; ++i) {
   245             SDL_free(SDL_joyname[i]);
   246         }
   247         SDL_joyname[0] = NULL;
   248     }
   249 
   250     SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   251     {
   252         SDL_JoystickGUID guid;
   253         /* the GUID is just the first 16 chars of the name for now */
   254         const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
   255         SDL_zero( guid );
   256         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   257         return guid;
   258     }
   259 
   260     SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   261     {
   262         SDL_JoystickGUID guid;
   263         /* the GUID is just the first 16 chars of the name for now */
   264         const char *name = joystick->name;
   265         SDL_zero( guid );
   266         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   267         return guid;
   268     }
   269 
   270 };                              // extern "C"
   271 
   272 #endif /* SDL_JOYSTICK_HAIKU */
   273 
   274 /* vi: set ts=4 sw=4 expandtab: */