SDL_haikujoystick.cc (8998B)
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 30extern "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: */