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