src/joystick/haiku/SDL_haikujoystick.cc
author Ryan C. Gordon <icculus@icculus.org>
Sat, 14 Jun 2014 23:31:23 -0400
changeset 8860 c4133d635375
parent 8149 681eb46b8ac4
child 9311 a4b031e28de8
permissions -rw-r--r--
Removed SDL_SYS_JoystickNeedsPolling().

It was simpler to just have the polling (actually: hotplug detection)
functions return immediately if it's not an appropriate time to poll.

Note that previously, if any joystick/controller was opened, we would poll
every time anyhow, skipping this function.
     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  * 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 /* Function to get the device-dependent name of a joystick */
    98     const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index)
    99     {
   100         return SDL_joyname[device_index];
   101     }
   102 
   103 /* Function to perform the mapping from device index to the instance id for this index */
   104     SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   105     {
   106         return device_index;
   107     }
   108 
   109 /* Function to open a joystick for use.
   110    The joystick to open is specified by the index field of the joystick.
   111    This should fill the nbuttons and naxes fields of the joystick structure.
   112    It returns 0, or -1 if there is an error.
   113  */
   114     int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
   115     {
   116         BJoystick *stick;
   117 
   118         /* Create the joystick data structure */
   119         joystick->instance_id = device_index;
   120         joystick->hwdata = (struct joystick_hwdata *)
   121             SDL_malloc(sizeof(*joystick->hwdata));
   122         if (joystick->hwdata == NULL) {
   123             return SDL_OutOfMemory();
   124         }
   125         SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
   126         stick = new BJoystick;
   127         joystick->hwdata->stick = stick;
   128 
   129         /* Open the requested joystick for use */
   130         if (stick->Open(SDL_joyport[device_index]) == B_ERROR) {
   131             SDL_SYS_JoystickClose(joystick);
   132             return SDL_SetError("Unable to open joystick");
   133         }
   134 
   135         /* Set the joystick to calibrated mode */
   136         stick->EnableCalibration();
   137 
   138         /* Get the number of buttons, hats, and axes on the joystick */
   139         joystick->nbuttons = stick->CountButtons();
   140         joystick->naxes = stick->CountAxes();
   141         joystick->nhats = stick->CountHats();
   142 
   143         joystick->hwdata->new_axes = (int16 *)
   144             SDL_malloc(joystick->naxes * sizeof(int16));
   145         joystick->hwdata->new_hats = (uint8 *)
   146             SDL_malloc(joystick->nhats * sizeof(uint8));
   147         if (!joystick->hwdata->new_hats || !joystick->hwdata->new_axes) {
   148             SDL_SYS_JoystickClose(joystick);
   149             return SDL_OutOfMemory();
   150         }
   151 
   152         /* We're done! */
   153         return (0);
   154     }
   155 
   156 /* Function to determine is this joystick is attached to the system right now */
   157     SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
   158     {
   159         return SDL_TRUE;
   160     }
   161 
   162 /* Function to update the state of a joystick - called as a device poll.
   163  * This function shouldn't update the joystick structure directly,
   164  * but instead should call SDL_PrivateJoystick*() to deliver events
   165  * and update joystick device state.
   166  */
   167     void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   168     {
   169         static const Uint8 hat_map[9] = {
   170             SDL_HAT_CENTERED,
   171             SDL_HAT_UP,
   172             SDL_HAT_RIGHTUP,
   173             SDL_HAT_RIGHT,
   174             SDL_HAT_RIGHTDOWN,
   175             SDL_HAT_DOWN,
   176             SDL_HAT_LEFTDOWN,
   177             SDL_HAT_LEFT,
   178             SDL_HAT_LEFTUP
   179         };
   180         const int JITTER = (32768 / 10);        /* 10% jitter threshold (ok?) */
   181 
   182         BJoystick *stick;
   183         int i, change;
   184         int16 *axes;
   185         uint8 *hats;
   186         uint32 buttons;
   187 
   188         /* Set up data pointers */
   189         stick = joystick->hwdata->stick;
   190         axes = joystick->hwdata->new_axes;
   191         hats = joystick->hwdata->new_hats;
   192 
   193         /* Get the new joystick state */
   194         stick->Update();
   195         stick->GetAxisValues(axes);
   196         stick->GetHatValues(hats);
   197         buttons = stick->ButtonValues();
   198 
   199         /* Generate axis motion events */
   200         for (i = 0; i < joystick->naxes; ++i) {
   201             change = ((int32) axes[i] - joystick->axes[i]);
   202             if ((change > JITTER) || (change < -JITTER)) {
   203                 SDL_PrivateJoystickAxis(joystick, i, axes[i]);
   204             }
   205         }
   206 
   207         /* Generate hat change events */
   208         for (i = 0; i < joystick->nhats; ++i) {
   209             if (hats[i] != joystick->hats[i]) {
   210                 SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]);
   211             }
   212         }
   213 
   214         /* Generate button events */
   215         for (i = 0; i < joystick->nbuttons; ++i) {
   216             if ((buttons & 0x01) != joystick->buttons[i]) {
   217                 SDL_PrivateJoystickButton(joystick, i, (buttons & 0x01));
   218             }
   219             buttons >>= 1;
   220         }
   221     }
   222 
   223 /* Function to close a joystick after use */
   224     void SDL_SYS_JoystickClose(SDL_Joystick * joystick)
   225     {
   226         if (joystick->hwdata) {
   227             joystick->hwdata->stick->Close();
   228             delete joystick->hwdata->stick;
   229             SDL_free(joystick->hwdata->new_hats);
   230             SDL_free(joystick->hwdata->new_axes);
   231             SDL_free(joystick->hwdata);
   232             joystick->hwdata = NULL;
   233         }
   234     }
   235 
   236 /* Function to perform any system-specific joystick related cleanup */
   237     void SDL_SYS_JoystickQuit(void)
   238     {
   239         int i;
   240 
   241         for (i = 0; SDL_joyport[i]; ++i) {
   242             SDL_free(SDL_joyport[i]);
   243         }
   244         SDL_joyport[0] = NULL;
   245 
   246         for (i = 0; SDL_joyname[i]; ++i) {
   247             SDL_free(SDL_joyname[i]);
   248         }
   249         SDL_joyname[0] = NULL;
   250     }
   251 
   252     SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   253     {
   254         SDL_JoystickGUID guid;
   255         /* the GUID is just the first 16 chars of the name for now */
   256         const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
   257         SDL_zero( guid );
   258         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   259         return guid;
   260     }
   261 
   262     SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   263     {
   264         SDL_JoystickGUID guid;
   265         /* the GUID is just the first 16 chars of the name for now */
   266         const char *name = joystick->name;
   267         SDL_zero( guid );
   268         SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
   269         return guid;
   270     }
   271 
   272 };                              // extern "C"
   273 
   274 #endif /* SDL_JOYSTICK_HAIKU */
   275 
   276 /* vi: set ts=4 sw=4 expandtab: */