1 /*
2 * E-UAE - The portable Amiga Emulator
3 *
4 * BeOS joystick driver
5 *
6 * (c) Richard Drummond 2005
7 */
8
9 extern "C" {
10 #include "sysconfig.h"
11 #include "sysdeps.h"
12
13 #include "options.h"
14 #include "memory_uae.h"
15 #include "custom.h"
16 #include "inputdevice.h"
17 }
18
19 #include <device/Joystick.h>
20 #include <support/String.h>
21
22 //#define DEBUG
23 #ifdef DEBUG
24 #define DEBUG_LOG write_log
25 #else
26 #define DEBUG_LOG(...) { }
27 #endif
28
29 extern "C" {
30 static int init_joysticks (void);
31 static void close_joysticks (void);
32 static int acquire_joy (unsigned int nr, int flags);
33 static void unacquire_joy (unsigned int nr);
34 static void read_joysticks (void);
35 static unsigned int get_joystick_count (void);
36 static const char *get_joystick_name (unsigned int nr);
37 static unsigned int get_joystick_widget_num (unsigned int nr);
38 static int get_joystick_widget_type (unsigned int nr, unsigned int num, char *name);
39 static int get_joystick_widget_first (unsigned int nr, int type);
40 };
41
42
43 /*
44 * The BJoystick class can't make up its mind whether it represents a joystick
45 * port or the device attached to a port.
46 *
47 * We choose to believe both and thus that there's at most one joystick attached
48 * to each port. Since USB ain't supported, I don't have any hardware which
49 * disproves that belief...
50 */
51
52 class UAEJoystick :public BJoystick
53 {
54 public:
55 UAEJoystick (unsigned int nr, const char *port_name);
56
57 private:
58 unsigned int nr; /* Device number that UAE assigns to a joystick */
59 BString port_name; /* Name used to open the joystick port */
60 BString name; /* Full name used to describe this joystick to the user */
61
62 public:
getName()63 const char *getName () { return name.String(); }
64
65 int acquire ();
66 void unacquire ();
67 void read ();
68 };
69
UAEJoystick(unsigned int nr,const char * port_name)70 UAEJoystick :: UAEJoystick (unsigned int nr, const char *port_name)
71 {
72 /* Create joystick name using both port and joystick name */
73 BString stick_name;
74
75 this->Open(port_name);
76 this->GetControllerName (&stick_name);
77 this->Close ();
78
79 this->name = port_name;
80 this->name += ":";
81 this->name += stick_name;
82
83 this->port_name = port_name;
84 this->nr = nr;
85 }
86
acquire()87 int UAEJoystick :: acquire ()
88 {
89 return this->Open (this->port_name.String());
90 }
91
unacquire()92 void UAEJoystick :: unacquire ()
93 {
94 this->Close ();
95 }
96
read()97 void UAEJoystick :: read ()
98 {
99 DEBUG_LOG ("read: polling joy:%d\n", this->nr);
100
101 if (this->Update () != B_ERROR) {
102
103 /* Read axis values */
104 {
105 unsigned int nr_axes = this->CountAxes ();
106 int16 values[nr_axes];
107 unsigned int axis;
108
109 this->GetAxisValues (values);
110
111 for (axis = 0; axis < nr_axes; axis++)
112 setjoystickstate (this->nr, axis, values[axis], 32767);
113 }
114
115 /* Read button values */
116 {
117 unsigned int nr_buttons = this->CountButtons ();
118 int32 values;
119 unsigned int button;
120
121 values = this->ButtonValues ();
122
123 for (button = 0; button < nr_buttons; button++) {
124 setjoybuttonstate (this->nr, button, values & 1);
125 values >>= 1;
126 }
127 }
128 }
129 }
130
131
132 /*
133 * Inputdevice API
134 */
135
136 #define MAX_JOYSTICKS MAX_INPUT_DEVICES
137
138 static unsigned int nr_joysticks;
139 static UAEJoystick *joysticks [MAX_JOYSTICKS];
140
141
init_joysticks(void)142 static int init_joysticks (void)
143 {
144 BJoystick joy;
145 unsigned int nr_ports;
146 unsigned int i;
147
148 nr_joysticks = 0;
149
150 nr_ports = joy.CountDevices ();
151 if (nr_ports > MAX_JOYSTICKS)
152 nr_ports = MAX_JOYSTICKS;
153
154 /*
155 * Enumerate joysticks
156 */
157
158 for (i = 0; i < nr_ports; i++) {
159
160 char port_name[B_OS_NAME_LENGTH];
161
162 joy.GetDeviceName (i, port_name);
163
164 if (joy.Open (port_name)) {
165 BString stick_name;
166
167 joy.Close ();
168
169 joysticks[nr_joysticks] = new UAEJoystick (nr_joysticks, port_name);
170
171 write_log ("BJoystick: device %d = %s\n", nr_joysticks,
172 joysticks[nr_joysticks]->getName ());
173
174 nr_joysticks++;
175 } else
176 DEBUG_LOG ("Failed to open port='%s'\n", port_name);
177
178 }
179
180 write_log ("BJoystick: Found %d joystick(s)\n", nr_joysticks);
181
182 return 1;
183 }
184
close_joysticks(void)185 static void close_joysticks (void)
186 {
187 unsigned int i;
188
189 for (i = 0; i < nr_joysticks; i++)
190 delete joysticks[i];
191
192 nr_joysticks = 0;
193 }
194
acquire_joy(unsigned int nr,int flags)195 static int acquire_joy (unsigned int nr, int flags)
196 {
197 int result = 0;
198
199 DEBUG_LOG ("acquire_joy (%d)...\n", nr);
200
201 if (nr < nr_joysticks)
202 result = joysticks[nr]->acquire ();
203
204 DEBUG_LOG ("%s\n", result ? "okay" : "failed");
205
206 return result;
207 }
208
unacquire_joy(unsigned int nr)209 static void unacquire_joy (unsigned int nr)
210 {
211 DEBUG_LOG ("unacquire_joy (%d)\n", nr);
212
213 if (nr < nr_joysticks)
214 joysticks[nr]->unacquire ();
215 }
216
read_joysticks(void)217 static void read_joysticks (void)
218 {
219 unsigned int i;
220
221 for (i = 0; i < get_joystick_count (); i++) {
222 /* In compatibility mode, don't read joystick unless it's selected in the prefs */
223 if (currprefs.input_selected_setting == 0) {
224 if (jsem_isjoy (0, &currprefs) != (int)i && jsem_isjoy (1, &currprefs) != (int)i)
225 continue;
226 }
227 joysticks[i]->read ();
228 }
229 }
230
get_joystick_num(void)231 static unsigned int get_joystick_num (void)
232 {
233 return nr_joysticks;
234 }
235
get_joystick_friendlyname(unsigned int nr)236 static const char *get_joystick_friendlyname (unsigned int nr)
237 {
238 return joysticks[nr]->getName ();
239 }
240
get_joystick_uniquename(unsigned int nr)241 static const char *get_joystick_uniquename (unsigned int nr)
242 {
243 return joysticks[nr]->getName ();
244 }
245
get_joystick_widget_num(unsigned int nr)246 static unsigned int get_joystick_widget_num (unsigned int nr)
247 {
248 return joysticks[nr]->CountAxes () + joysticks[nr]->CountButtons ();
249 }
250
get_joystick_widget_type(unsigned int nr,unsigned int widget_num,char * name,uae_u32 * what)251 static int get_joystick_widget_type (unsigned int nr, unsigned int widget_num, char *name, uae_u32 *what)
252 {
253 unsigned int nr_axes = joysticks[nr]->CountAxes ();
254 unsigned int nr_buttons = joysticks[nr]->CountButtons ();
255
256 if (widget_num >= nr_axes && widget_num < nr_axes + nr_buttons) {
257 if (name)
258 sprintf (name, "Button %d", widget_num + 1 - nr_axes);
259 return IDEV_WIDGET_BUTTON;
260 } else if (widget_num < nr_axes) {
261 if (name)
262 sprintf (name, "Axis %d", widget_num + 1);
263 return IDEV_WIDGET_AXIS;
264 }
265 return IDEV_WIDGET_NONE;
266 }
267
get_joystick_widget_first(unsigned int nr,int type)268 static int get_joystick_widget_first (unsigned int nr, int type)
269 {
270 switch (type) {
271 case IDEV_WIDGET_BUTTON:
272 return joysticks[nr]->CountAxes ();
273 case IDEV_WIDGET_AXIS:
274 return 0;
275 }
276
277 return -1;
278 }
279
get_joystick_flags(int num)280 static int get_joystick_flags (int num)
281 {
282 return 0;
283 }
284
285 struct inputdevice_functions inputdevicefunc_joystick = {
286 init_joysticks,
287 close_joysticks,
288 acquire_joy,
289 unacquire_joy,
290 read_joysticks,
291 get_joystick_num,
292 get_joystick_friendlyname,
293 get_joystick_uniquename,
294 get_joystick_widget_num,
295 get_joystick_widget_type,
296 get_joystick_widget_first,
297 get_joystick_flags
298 };
299
300 /*
301 * Set default inputdevice config for joysticks
302 */
input_get_default_joystick(struct uae_input_device * uid,int num,int port,int cd32)303 int input_get_default_joystick (struct uae_input_device *uid, int num, int port, int cd32)
304 {
305 unsigned int i, port;
306
307 for (i = 0; i < nr_joysticks; i++) {
308 port = i & 1;
309 uid[i].eventid[ID_AXIS_OFFSET + 0][0] = port ? INPUTEVENT_JOY2_HORIZ : INPUTEVENT_JOY1_HORIZ;
310 uid[i].eventid[ID_AXIS_OFFSET + 1][0] = port ? INPUTEVENT_JOY2_VERT : INPUTEVENT_JOY1_VERT;
311 uid[i].eventid[ID_BUTTON_OFFSET + 0][0] = port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON;
312 uid[i].eventid[ID_BUTTON_OFFSET + 1][0] = port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON;
313 uid[i].eventid[ID_BUTTON_OFFSET + 2][0] = port ? INPUTEVENT_JOY2_3RD_BUTTON : INPUTEVENT_JOY1_3RD_BUTTON;
314 }
315 uid[0].enabled = 1;
316 if (i == 0)
317 return 1;
318 return 0;
319 }
320