|
1 /* |
|
2 SDL - Simple DirectMedia Layer |
|
3 Copyright (C) 1997-2006 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 */ |