2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
21 #include "../../SDL_internal.h"
23 #ifdef SDL_JOYSTICK_HAIKU
25 /* This is the Haiku implementation of the SDL joystick API */
27 #include <os/support/String.h>
28 #include <os/device/Joystick.h>
33 #include "SDL_joystick.h"
34 #include "../SDL_sysjoystick.h"
35 #include "../SDL_joystick_c.h"
38 /* The maximum number of joysticks we'll detect */
39 #define MAX_JOYSTICKS 16
41 /* A list of available joysticks */
42 static char *SDL_joyport[MAX_JOYSTICKS];
43 static char *SDL_joyname[MAX_JOYSTICKS];
45 /* The private structure used to keep track of a joystick */
46 struct joystick_hwdata
53 static int SDL_SYS_numjoysticks = 0;
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.
59 int SDL_SYS_JoystickInit(void)
64 char name[B_OS_NAME_LENGTH];
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)
73 if (joystick.GetDeviceName(i, name) == B_OK) {
74 if (joystick.Open(name) != B_ERROR) {
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++;
84 return (SDL_SYS_numjoysticks);
87 int SDL_SYS_NumJoysticks()
89 return SDL_SYS_numjoysticks;
92 void SDL_SYS_JoystickDetect()
96 /* Function to get the device-dependent name of a joystick */
97 const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index)
99 return SDL_joyname[device_index];
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)
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.
113 int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
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();
124 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
125 stick = new BJoystick;
126 joystick->hwdata->stick = stick;
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");
134 /* Set the joystick to calibrated mode */
135 stick->EnableCalibration();
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();
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();
155 /* Function to determine if this joystick is attached to the system right now */
156 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
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.
166 void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
168 static const Uint8 hat_map[9] = {
179 const int JITTER = (32768 / 10); /* 10% jitter threshold (ok?) */
187 /* Set up data pointers */
188 stick = joystick->hwdata->stick;
189 axes = joystick->hwdata->new_axes;
190 hats = joystick->hwdata->new_hats;
192 /* Get the new joystick state */
194 stick->GetAxisValues(axes);
195 stick->GetHatValues(hats);
196 buttons = stick->ButtonValues();
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]);
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]]);
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));
222 /* Function to close a joystick after use */
223 void SDL_SYS_JoystickClose(SDL_Joystick * joystick)
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);
234 /* Function to perform any system-specific joystick related cleanup */
235 void SDL_SYS_JoystickQuit(void)
239 for (i = 0; SDL_joyport[i]; ++i) {
240 SDL_free(SDL_joyport[i]);
242 SDL_joyport[0] = NULL;
244 for (i = 0; SDL_joyname[i]; ++i) {
245 SDL_free(SDL_joyname[i]);
247 SDL_joyname[0] = NULL;
250 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
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 );
256 SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
260 SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
262 SDL_JoystickGUID guid;
263 /* the GUID is just the first 16 chars of the name for now */
264 const char *name = joystick->name;
266 SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
272 #endif /* SDL_JOYSTICK_HAIKU */
274 /* vi: set ts=4 sw=4 expandtab: */