src/joystick/haiku/SDL_haikujoystick.cc
author Sam Lantinga <slouken@libsdl.org>
Thu, 09 Aug 2018 16:03:50 -0700
changeset 12090 c3209fca27b2
parent 11811 5d94cb6b24d3
child 12107 7c7cee9f2bc4
permissions -rw-r--r--
Worked around bug with Sony PS Now PS3 controller where DirectInput polling will continue to return success after the controller is unplugged.
The code is now reliant on SDL_PrivateJoystickAdded() and SDL_PrivateJoystickRemoved() being called correctly when devices are added or removed on Windows
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2018 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 <support/String.h>
    28 #include <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] = SDL_strdup(name);
    78                       SDL_joyname[SDL_SYS_numjoysticks] = SDL_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(void)
    88     {
    89         return SDL_SYS_numjoysticks;
    90     }
    91 
    92     void SDL_SYS_JoystickDetect(void)
    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 update the state of a joystick - called as a device poll.
   156  * This function shouldn't update the joystick structure directly,
   157  * but instead should call SDL_PrivateJoystick*() to deliver events
   158  * and update joystick device state.
   159  */
   160     void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   161     {
   162         static const Uint8 hat_map[9] = {
   163             SDL_HAT_CENTERED,
   164             SDL_HAT_UP,
   165             SDL_HAT_RIGHTUP,
   166             SDL_HAT_RIGHT,
   167             SDL_HAT_RIGHTDOWN,
   168             SDL_HAT_DOWN,
   169             SDL_HAT_LEFTDOWN,
   170             SDL_HAT_LEFT,
   171             SDL_HAT_LEFTUP
   172         };
   173 
   174         BJoystick *stick;
   175         int i;
   176         int16 *axes;
   177         uint8 *hats;
   178         uint32 buttons;
   179 
   180         /* Set up data pointers */
   181         stick = joystick->hwdata->stick;
   182         axes = joystick->hwdata->new_axes;
   183         hats = joystick->hwdata->new_hats;
   184 
   185         /* Get the new joystick state */
   186         stick->Update();
   187         stick->GetAxisValues(axes);
   188         stick->GetHatValues(hats);
   189         buttons = stick->ButtonValues();
   190 
   191         /* Generate axis motion events */
   192         for (i = 0; i < joystick->naxes; ++i) {
   193             SDL_PrivateJoystickAxis(joystick, i, axes[i]);
   194         }
   195 
   196         /* Generate hat change events */
   197         for (i = 0; i < joystick->nhats; ++i) {
   198             SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]);
   199         }
   200 
   201         /* Generate button events */
   202         for (i = 0; i < joystick->nbuttons; ++i) {
   203             SDL_PrivateJoystickButton(joystick, i, (buttons & 0x01));
   204             buttons >>= 1;
   205         }
   206     }
   207 
   208 /* Function to close a joystick after use */
   209     void SDL_SYS_JoystickClose(SDL_Joystick * joystick)
   210     {
   211         if (joystick->hwdata) {
   212             joystick->hwdata->stick->Close();
   213             delete joystick->hwdata->stick;
   214             SDL_free(joystick->hwdata->new_hats);
   215             SDL_free(joystick->hwdata->new_axes);
   216             SDL_free(joystick->hwdata);
   217         }
   218     }
   219 
   220 /* Function to perform any system-specific joystick related cleanup */
   221     void SDL_SYS_JoystickQuit(void)
   222     {
   223         int i;
   224 
   225         for (i = 0; i < SDL_SYS_numjoysticks; ++i) {
   226             SDL_free(SDL_joyport[i]);
   227         }
   228         SDL_joyport[0] = NULL;
   229 
   230         for (i = 0; i < SDL_SYS_numjoysticks; ++i) {
   231             SDL_free(SDL_joyname[i]);
   232         }
   233         SDL_joyname[0] = NULL;
   234     }
   235 
   236     SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   237     {
   238         SDL_JoystickGUID guid;
   239         /* the GUID is just the first 16 chars of the name for now */
   240         const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
   241         SDL_zero( guid );
   242         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   243         return guid;
   244     }
   245 
   246     SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   247     {
   248         SDL_JoystickGUID guid;
   249         /* the GUID is just the first 16 chars of the name for now */
   250         const char *name = joystick->name;
   251         SDL_zero( guid );
   252         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   253         return guid;
   254     }
   255 
   256 };                              // extern "C"
   257 
   258 #endif /* SDL_JOYSTICK_HAIKU */
   259 
   260 /* vi: set ts=4 sw=4 expandtab: */