SDL-1.2.14
[sdl_omap.git] / src / joystick / beos / SDL_bejoystick.cc
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #ifdef SDL_JOYSTICK_BEOS
25
26 /* This is the system specific header for the SDL joystick API */
27
28 #include <be/support/String.h>
29 #include <be/device/Joystick.h>
30
31 extern "C" {
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         BJoystick *stick;
48         uint8 *new_hats;
49         int16 *new_axes;
50 };
51
52 /* Function to scan the system for joysticks.
53  * This function should set SDL_numjoysticks to the number of available
54  * joysticks.  Joystick 0 should be the system default joystick.
55  * It should return 0, or -1 on an unrecoverable fatal error.
56  */
57 int SDL_SYS_JoystickInit(void)
58 {
59         BJoystick joystick;
60         int numjoysticks;
61         int i;
62         int32 nports;
63         char name[B_OS_NAME_LENGTH];
64         
65         /* Search for attached joysticks */
66         nports = joystick.CountDevices();
67         numjoysticks = 0;
68         SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
69         SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
70         for ( i=0; (SDL_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i ) {
71                 if ( joystick.GetDeviceName(i, name) == B_OK ) {
72                         if ( joystick.Open(name) != B_ERROR ) {
73                                 BString stick_name;
74                                 joystick.GetControllerName(&stick_name);
75                                 SDL_joyport[numjoysticks] = strdup(name);
76                                 SDL_joyname[numjoysticks] =
77                                                    strdup(stick_name.String());
78                                 numjoysticks++;
79                                 joystick.Close();
80                         }
81                 }
82         }
83         return(numjoysticks);
84 }
85
86 /* Function to get the device-dependent name of a joystick */
87 const char *SDL_SYS_JoystickName(int index)
88 {
89         return SDL_joyname[index];
90 }
91
92 /* Function to open a joystick for use.
93    The joystick to open is specified by the index field of the joystick.
94    This should fill the nbuttons and naxes fields of the joystick structure.
95    It returns 0, or -1 if there is an error.
96  */
97 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
98 {
99         BJoystick *stick;
100
101         /* Create the joystick data structure */
102         joystick->hwdata = (struct joystick_hwdata *)
103                            SDL_malloc(sizeof(*joystick->hwdata));
104         if ( joystick->hwdata == NULL ) {
105                 SDL_OutOfMemory();
106                 return(-1);
107         }
108         SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
109         stick = new BJoystick;
110         joystick->hwdata->stick = stick;
111
112         /* Open the requested joystick for use */
113         if ( stick->Open(SDL_joyport[joystick->index]) == B_ERROR ) {
114                 SDL_SetError("Unable to open joystick");
115                 SDL_SYS_JoystickClose(joystick);
116                 return(-1);
117         }
118
119         /* Set the joystick to calibrated mode */
120         stick->EnableCalibration();
121
122         /* Get the number of buttons, hats, and axes on the joystick */
123         joystick->nbuttons = stick->CountButtons();
124         joystick->naxes = stick->CountAxes();
125         joystick->nhats = stick->CountHats();
126
127         joystick->hwdata->new_axes = (int16 *)
128                           SDL_malloc(joystick->naxes*sizeof(int16));
129         joystick->hwdata->new_hats = (uint8 *)
130                           SDL_malloc(joystick->nhats*sizeof(uint8));
131         if ( ! joystick->hwdata->new_hats || ! joystick->hwdata->new_axes ) {
132                 SDL_OutOfMemory();
133                 SDL_SYS_JoystickClose(joystick);
134                 return(-1);
135         }
136
137         /* We're done! */
138         return(0);
139 }
140
141 /* Function to update the state of a joystick - called as a device poll.
142  * This function shouldn't update the joystick structure directly,
143  * but instead should call SDL_PrivateJoystick*() to deliver events
144  * and update joystick device state.
145  */
146 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
147 {
148         static const Uint8 hat_map[9] = {
149              SDL_HAT_CENTERED,
150              SDL_HAT_UP,
151              SDL_HAT_RIGHTUP,
152              SDL_HAT_RIGHT,
153              SDL_HAT_RIGHTDOWN,
154              SDL_HAT_DOWN,
155              SDL_HAT_LEFTDOWN,
156              SDL_HAT_LEFT,
157              SDL_HAT_LEFTUP
158         };
159         const int JITTER = (32768/10);  /* 10% jitter threshold (ok?) */
160
161         BJoystick *stick;
162         int i, change;
163         int16 *axes;
164         uint8 *hats;
165         uint32 buttons;
166
167         /* Set up data pointers */
168         stick = joystick->hwdata->stick;
169         axes = joystick->hwdata->new_axes;
170         hats = joystick->hwdata->new_hats;
171
172         /* Get the new joystick state */
173         stick->Update();
174         stick->GetAxisValues(axes);
175         stick->GetHatValues(hats);
176         buttons = stick->ButtonValues();
177
178         /* Generate axis motion events */
179         for ( i=0; i<joystick->naxes; ++i ) {
180                 change = ((int32)axes[i] - joystick->axes[i]);
181                 if ( (change > JITTER) || (change < -JITTER) ) {
182                         SDL_PrivateJoystickAxis(joystick, i, axes[i]);
183                 }
184         }
185
186         /* Generate hat change events */
187         for ( i=0; i<joystick->nhats; ++i ) {
188                 if ( hats[i] != joystick->hats[i] ) {
189                         SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]);
190                 }
191         }
192
193         /* Generate button events */
194         for ( i=0; i<joystick->nbuttons; ++i ) {
195                 if ( (buttons&0x01) != joystick->buttons[i] ) {
196                         SDL_PrivateJoystickButton(joystick, i, (buttons&0x01));
197                 }
198                 buttons >>= 1;
199         }
200 }
201
202 /* Function to close a joystick after use */
203 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
204 {
205         if ( joystick->hwdata ) {
206                 joystick->hwdata->stick->Close();
207                 delete joystick->hwdata->stick;
208                 if ( joystick->hwdata->new_hats ) {
209                         SDL_free(joystick->hwdata->new_hats);
210                 }
211                 if ( joystick->hwdata->new_axes ) {
212                         SDL_free(joystick->hwdata->new_axes);
213                 }
214                 SDL_free(joystick->hwdata);
215                 joystick->hwdata = NULL;
216         }
217 }
218
219 /* Function to perform any system-specific joystick related cleanup */
220 void SDL_SYS_JoystickQuit(void)
221 {
222         int i;
223
224         for ( i=0; SDL_joyport[i]; ++i ) {
225                 SDL_free(SDL_joyport[i]);
226         }
227         SDL_joyport[0] = NULL;
228
229         for ( i=0; SDL_joyname[i]; ++i ) {
230                 SDL_free(SDL_joyname[i]);
231         }
232         SDL_joyname[0] = NULL;
233 }
234
235 }; // extern "C"
236
237 #endif /* SDL_JOYSTICK_BEOS */