summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/src/joystick
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/src/joystick')
-rw-r--r--apps/plugins/sdl/src/joystick/beos/SDL_bejoystick.cc237
-rw-r--r--apps/plugins/sdl/src/joystick/bsd/SDL_sysjoystick.c608
-rw-r--r--apps/plugins/sdl/src/joystick/darwin/SDL_sysjoystick.c842
-rw-r--r--apps/plugins/sdl/src/joystick/dc/SDL_sysjoystick.c193
-rw-r--r--apps/plugins/sdl/src/joystick/linux/SDL_sysjoystick.c1218
-rw-r--r--apps/plugins/sdl/src/joystick/macos/SDL_sysjoystick.c320
-rw-r--r--apps/plugins/sdl/src/joystick/mint/SDL_sysjoystick.c826
-rw-r--r--apps/plugins/sdl/src/joystick/nds/SDL_sysjoystick.c150
-rw-r--r--apps/plugins/sdl/src/joystick/riscos/SDL_sysjoystick.c176
-rw-r--r--apps/plugins/sdl/src/joystick/win32/SDL_mmjoystick.c407
10 files changed, 0 insertions, 4977 deletions
diff --git a/apps/plugins/sdl/src/joystick/beos/SDL_bejoystick.cc b/apps/plugins/sdl/src/joystick/beos/SDL_bejoystick.cc
deleted file mode 100644
index af8a34164b..0000000000
--- a/apps/plugins/sdl/src/joystick/beos/SDL_bejoystick.cc
+++ /dev/null
@@ -1,237 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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
31extern "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 */
42static char *SDL_joyport[MAX_JOYSTICKS];
43static char *SDL_joyname[MAX_JOYSTICKS];
44
45/* The private structure used to keep track of a joystick */
46struct 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 */
57int 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 */
87const 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 */
97int 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 */
146void 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 */
203void 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 */
220void 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 */
diff --git a/apps/plugins/sdl/src/joystick/bsd/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/bsd/SDL_sysjoystick.c
deleted file mode 100644
index 500fc62951..0000000000
--- a/apps/plugins/sdl/src/joystick/bsd/SDL_sysjoystick.c
+++ /dev/null
@@ -1,608 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_USBHID
25
26/*
27 * Joystick driver for the uhid(4) interface found in OpenBSD,
28 * NetBSD and FreeBSD.
29 *
30 * Maintainer: <vedge at csoft.org>
31 */
32
33#include <sys/param.h>
34
35#include <unistd.h>
36#include <fcntl.h>
37#include <errno.h>
38
39#ifndef __FreeBSD_kernel_version
40#define __FreeBSD_kernel_version __FreeBSD_version
41#endif
42
43#if defined(HAVE_USB_H)
44#include <usb.h>
45#endif
46#ifdef __DragonFly__
47#include <bus/usb/usb.h>
48#include <bus/usb/usbhid.h>
49#else
50#include <dev/usb/usb.h>
51#include <dev/usb/usbhid.h>
52#endif
53
54#if defined(HAVE_USBHID_H)
55#include <usbhid.h>
56#elif defined(HAVE_LIBUSB_H)
57#include <libusb.h>
58#elif defined(HAVE_LIBUSBHID_H)
59#include <libusbhid.h>
60#endif
61
62#if defined(__FREEBSD__) || defined(__FreeBSD_kernel__)
63#ifndef __DragonFly__
64#include <osreldate.h>
65#endif
66#if __FreeBSD_kernel_version > 800063
67#include <dev/usb/usb_ioctl.h>
68#endif
69#include <sys/joystick.h>
70#endif
71
72#if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
73#include <machine/joystick.h>
74#endif
75
76#include "SDL_joystick.h"
77#include "../SDL_sysjoystick.h"
78#include "../SDL_joystick_c.h"
79
80#define MAX_UHID_JOYS 4
81#define MAX_JOY_JOYS 2
82#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
83
84struct report {
85#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
86 struct usb_gen_descriptor *buf; /* Buffer */
87#else
88 struct usb_ctl_report *buf; /* Buffer */
89#endif
90 size_t size; /* Buffer size */
91 int rid; /* Report ID */
92 enum {
93 SREPORT_UNINIT,
94 SREPORT_CLEAN,
95 SREPORT_DIRTY
96 } status;
97};
98
99static struct {
100 int uhid_report;
101 hid_kind_t kind;
102 const char *name;
103} const repinfo[] = {
104 { UHID_INPUT_REPORT, hid_input, "input" },
105 { UHID_OUTPUT_REPORT, hid_output, "output" },
106 { UHID_FEATURE_REPORT, hid_feature, "feature" }
107};
108
109enum {
110 REPORT_INPUT = 0,
111 REPORT_OUTPUT = 1,
112 REPORT_FEATURE = 2
113};
114
115enum {
116 JOYAXE_X,
117 JOYAXE_Y,
118 JOYAXE_Z,
119 JOYAXE_SLIDER,
120 JOYAXE_WHEEL,
121 JOYAXE_RX,
122 JOYAXE_RY,
123 JOYAXE_RZ,
124 JOYAXE_count
125};
126
127struct joystick_hwdata {
128 int fd;
129 char *path;
130 enum {
131 BSDJOY_UHID, /* uhid(4) */
132 BSDJOY_JOY /* joy(4) */
133 } type;
134 struct report_desc *repdesc;
135 struct report inreport;
136 int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,..*/
137 int x;
138 int y;
139 int xmin;
140 int ymin;
141 int xmax;
142 int ymax;
143};
144
145static char *joynames[MAX_JOYS];
146static char *joydevnames[MAX_JOYS];
147
148static int report_alloc(struct report *, struct report_desc *, int);
149static void report_free(struct report *);
150
151#if defined(USBHID_UCR_DATA) || defined(__FreeBSD_kernel__)
152#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
153#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
154#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
155#else
156#define REP_BUF_DATA(rep) ((rep)->buf->data)
157#endif
158
159int
160SDL_SYS_JoystickInit(void)
161{
162 char s[16];
163 int i, fd;
164
165 SDL_numjoysticks = 0;
166
167 SDL_memset(joynames, 0, sizeof(joynames));
168 SDL_memset(joydevnames, 0, sizeof(joydevnames));
169
170 for (i = 0; i < MAX_UHID_JOYS; i++) {
171 SDL_Joystick nj;
172
173 SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
174
175 nj.index = SDL_numjoysticks;
176 joynames[nj.index] = strdup(s);
177
178 if (SDL_SYS_JoystickOpen(&nj) == 0) {
179 SDL_SYS_JoystickClose(&nj);
180 SDL_numjoysticks++;
181 } else {
182 SDL_free(joynames[nj.index]);
183 joynames[nj.index] = NULL;
184 }
185 }
186 for (i = 0; i < MAX_JOY_JOYS; i++) {
187 SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
188 fd = open(s, O_RDONLY);
189 if (fd != -1) {
190 joynames[SDL_numjoysticks++] = strdup(s);
191 close(fd);
192 }
193 }
194
195 /* Read the default USB HID usage table. */
196 hid_init(NULL);
197
198 return (SDL_numjoysticks);
199}
200
201const char *
202SDL_SYS_JoystickName(int index)
203{
204 if (joydevnames[index] != NULL) {
205 return (joydevnames[index]);
206 }
207 return (joynames[index]);
208}
209
210static int
211usage_to_joyaxe(unsigned usage)
212{
213 int joyaxe;
214 switch (usage) {
215 case HUG_X:
216 joyaxe = JOYAXE_X; break;
217 case HUG_Y:
218 joyaxe = JOYAXE_Y; break;
219 case HUG_Z:
220 joyaxe = JOYAXE_Z; break;
221 case HUG_SLIDER:
222 joyaxe = JOYAXE_SLIDER; break;
223 case HUG_WHEEL:
224 joyaxe = JOYAXE_WHEEL; break;
225 case HUG_RX:
226 joyaxe = JOYAXE_RX; break;
227 case HUG_RY:
228 joyaxe = JOYAXE_RY; break;
229 case HUG_RZ:
230 joyaxe = JOYAXE_RZ; break;
231 default:
232 joyaxe = -1;
233 }
234 return joyaxe;
235}
236
237static unsigned
238hatval_to_sdl(Sint32 hatval)
239{
240 static const unsigned hat_dir_map[8] = {
241 SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN,
242 SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP
243 };
244 unsigned result;
245 if ((hatval & 7) == hatval)
246 result = hat_dir_map[hatval];
247 else
248 result = SDL_HAT_CENTERED;
249 return result;
250}
251
252
253int
254SDL_SYS_JoystickOpen(SDL_Joystick *joy)
255{
256 char *path = joynames[joy->index];
257 struct joystick_hwdata *hw;
258 struct hid_item hitem;
259 struct hid_data *hdata;
260 struct report *rep;
261 int fd;
262 int i;
263
264 fd = open(path, O_RDONLY);
265 if (fd == -1) {
266 SDL_SetError("%s: %s", path, strerror(errno));
267 return (-1);
268 }
269
270 hw = (struct joystick_hwdata *)SDL_malloc(sizeof(struct joystick_hwdata));
271 if (hw == NULL) {
272 SDL_OutOfMemory();
273 close(fd);
274 return (-1);
275 }
276 joy->hwdata = hw;
277 hw->fd = fd;
278 hw->path = strdup(path);
279 hw->x = 0;
280 hw->y = 0;
281 hw->xmin = 0xffff;
282 hw->ymin = 0xffff;
283 hw->xmax = 0;
284 hw->ymax = 0;
285 if (! SDL_strncmp(path, "/dev/joy", 8)) {
286 hw->type = BSDJOY_JOY;
287 joy->naxes = 2;
288 joy->nbuttons = 2;
289 joy->nhats = 0;
290 joy->nballs = 0;
291 joydevnames[joy->index] = strdup("Gameport joystick");
292 goto usbend;
293 } else {
294 hw->type = BSDJOY_UHID;
295 }
296
297 {
298 int ax;
299 for (ax = 0; ax < JOYAXE_count; ax++)
300 hw->axis_map[ax] = -1;
301 }
302 hw->repdesc = hid_get_report_desc(fd);
303 if (hw->repdesc == NULL) {
304 SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
305 strerror(errno));
306 goto usberr;
307 }
308 rep = &hw->inreport;
309#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
310 rep->rid = hid_get_report_id(fd);
311 if (rep->rid < 0) {
312#else
313 if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
314#endif
315 rep->rid = -1; /* XXX */
316 }
317 if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
318 goto usberr;
319 }
320 if (rep->size <= 0) {
321 SDL_SetError("%s: Input report descriptor has invalid length",
322 hw->path);
323 goto usberr;
324 }
325
326#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
327 hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
328#else
329 hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
330#endif
331 if (hdata == NULL) {
332 SDL_SetError("%s: Cannot start HID parser", hw->path);
333 goto usberr;
334 }
335 joy->naxes = 0;
336 joy->nbuttons = 0;
337 joy->nhats = 0;
338 joy->nballs = 0;
339 for (i=0; i<JOYAXE_count; i++)
340 hw->axis_map[i] = -1;
341
342 while (hid_get_item(hdata, &hitem) > 0) {
343 char *sp;
344 const char *s;
345
346 switch (hitem.kind) {
347 case hid_collection:
348 switch (HID_PAGE(hitem.usage)) {
349 case HUP_GENERIC_DESKTOP:
350 switch (HID_USAGE(hitem.usage)) {
351 case HUG_JOYSTICK:
352 case HUG_GAME_PAD:
353 s = hid_usage_in_page(hitem.usage);
354 sp = SDL_malloc(SDL_strlen(s) + 5);
355 SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", s,
356 joy->index);
357 joydevnames[joy->index] = sp;
358 }
359 }
360 break;
361 case hid_input:
362 switch (HID_PAGE(hitem.usage)) {
363 case HUP_GENERIC_DESKTOP: {
364 unsigned usage = HID_USAGE(hitem.usage);
365 int joyaxe = usage_to_joyaxe(usage);
366 if (joyaxe >= 0) {
367 hw->axis_map[joyaxe] = 1;
368 } else if (usage == HUG_HAT_SWITCH) {
369 joy->nhats++;
370 }
371 break;
372 }
373 case HUP_BUTTON:
374 joy->nbuttons++;
375 break;
376 default:
377 break;
378 }
379 break;
380 default:
381 break;
382 }
383 }
384 hid_end_parse(hdata);
385 for (i=0; i<JOYAXE_count; i++)
386 if (hw->axis_map[i] > 0)
387 hw->axis_map[i] = joy->naxes++;
388
389usbend:
390 /* The poll blocks the event thread. */
391 fcntl(fd, F_SETFL, O_NONBLOCK);
392
393 return (0);
394usberr:
395 close(hw->fd);
396 SDL_free(hw->path);
397 SDL_free(hw);
398 return (-1);
399}
400
401void
402SDL_SYS_JoystickUpdate(SDL_Joystick *joy)
403{
404 struct hid_item hitem;
405 struct hid_data *hdata;
406 struct report *rep;
407 int nbutton, naxe = -1;
408 Sint32 v;
409
410#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
411 struct joystick gameport;
412
413 if (joy->hwdata->type == BSDJOY_JOY) {
414 if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport)
415 return;
416 if (abs(joy->hwdata->x - gameport.x) > 8) {
417 joy->hwdata->x = gameport.x;
418 if (joy->hwdata->x < joy->hwdata->xmin) {
419 joy->hwdata->xmin = joy->hwdata->x;
420 }
421 if (joy->hwdata->x > joy->hwdata->xmax) {
422 joy->hwdata->xmax = joy->hwdata->x;
423 }
424 if (joy->hwdata->xmin == joy->hwdata->xmax) {
425 joy->hwdata->xmin--;
426 joy->hwdata->xmax++;
427 }
428 v = (Sint32)joy->hwdata->x;
429 v -= (joy->hwdata->xmax + joy->hwdata->xmin + 1)/2;
430 v *= 32768/((joy->hwdata->xmax - joy->hwdata->xmin + 1)/2);
431 SDL_PrivateJoystickAxis(joy, 0, v);
432 }
433 if (abs(joy->hwdata->y - gameport.y) > 8) {
434 joy->hwdata->y = gameport.y;
435 if (joy->hwdata->y < joy->hwdata->ymin) {
436 joy->hwdata->ymin = joy->hwdata->y;
437 }
438 if (joy->hwdata->y > joy->hwdata->ymax) {
439 joy->hwdata->ymax = joy->hwdata->y;
440 }
441 if (joy->hwdata->ymin == joy->hwdata->ymax) {
442 joy->hwdata->ymin--;
443 joy->hwdata->ymax++;
444 }
445 v = (Sint32)joy->hwdata->y;
446 v -= (joy->hwdata->ymax + joy->hwdata->ymin + 1)/2;
447 v *= 32768/((joy->hwdata->ymax - joy->hwdata->ymin + 1)/2);
448 SDL_PrivateJoystickAxis(joy, 1, v);
449 }
450 if (gameport.b1 != joy->buttons[0]) {
451 SDL_PrivateJoystickButton(joy, 0, gameport.b1);
452 }
453 if (gameport.b2 != joy->buttons[1]) {
454 SDL_PrivateJoystickButton(joy, 1, gameport.b2);
455 }
456 return;
457 }
458#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
459
460 rep = &joy->hwdata->inreport;
461
462 if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) {
463 return;
464 }
465#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
466 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
467#else
468 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
469#endif
470 if (hdata == NULL) {
471 fprintf(stderr, "%s: Cannot start HID parser\n",
472 joy->hwdata->path);
473 return;
474 }
475
476 for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
477 switch (hitem.kind) {
478 case hid_input:
479 switch (HID_PAGE(hitem.usage)) {
480 case HUP_GENERIC_DESKTOP: {
481 unsigned usage = HID_USAGE(hitem.usage);
482 int joyaxe = usage_to_joyaxe(usage);
483 if (joyaxe >= 0) {
484 naxe = joy->hwdata->axis_map[joyaxe];
485 /* scaleaxe */
486 v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
487 &hitem);
488 v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2;
489 v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2);
490 if (v != joy->axes[naxe]) {
491 SDL_PrivateJoystickAxis(joy, naxe, v);
492 }
493 } else if (usage == HUG_HAT_SWITCH) {
494 v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
495 &hitem);
496 SDL_PrivateJoystickHat(joy, 0,
497 hatval_to_sdl(v)-hitem.logical_minimum);
498 }
499 break;
500 }
501 case HUP_BUTTON:
502 v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
503 &hitem);
504 if (joy->buttons[nbutton] != v) {
505 SDL_PrivateJoystickButton(joy,
506 nbutton, v);
507 }
508 nbutton++;
509 break;
510 default:
511 continue;
512 }
513 break;
514 default:
515 break;
516 }
517 }
518 hid_end_parse(hdata);
519
520 return;
521}
522
523/* Function to close a joystick after use */
524void
525SDL_SYS_JoystickClose(SDL_Joystick *joy)
526{
527 if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
528 report_free(&joy->hwdata->inreport);
529 hid_dispose_report_desc(joy->hwdata->repdesc);
530 }
531 close(joy->hwdata->fd);
532 SDL_free(joy->hwdata->path);
533 SDL_free(joy->hwdata);
534
535 return;
536}
537
538void
539SDL_SYS_JoystickQuit(void)
540{
541 int i;
542
543 for (i = 0; i < MAX_JOYS; i++) {
544 if (joynames[i] != NULL)
545 SDL_free(joynames[i]);
546 if (joydevnames[i] != NULL)
547 SDL_free(joydevnames[i]);
548 }
549
550 return;
551}
552
553static int
554report_alloc(struct report *r, struct report_desc *rd, int repind)
555{
556 int len;
557
558#ifdef __DragonFly__
559 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
560#elif __FREEBSD__
561# if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
562# if (__FreeBSD_kernel_version <= 500111)
563 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
564# else
565 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
566# endif
567# else
568 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
569# endif
570#else
571# ifdef USBHID_NEW
572 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
573# else
574 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
575# endif
576#endif
577
578 if (len < 0) {
579 SDL_SetError("Negative HID report size");
580 return (-1);
581 }
582 r->size = len;
583
584 if (r->size > 0) {
585 r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
586 r->size);
587 if (r->buf == NULL) {
588 SDL_OutOfMemory();
589 return (-1);
590 }
591 } else {
592 r->buf = NULL;
593 }
594
595 r->status = SREPORT_CLEAN;
596 return (0);
597}
598
599static void
600report_free(struct report *r)
601{
602 if (r->buf != NULL) {
603 SDL_free(r->buf);
604 }
605 r->status = SREPORT_UNINIT;
606}
607
608#endif /* SDL_JOYSTICK_USBHID */
diff --git a/apps/plugins/sdl/src/joystick/darwin/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/darwin/SDL_sysjoystick.c
deleted file mode 100644
index a9ccb35fad..0000000000
--- a/apps/plugins/sdl/src/joystick/darwin/SDL_sysjoystick.c
+++ /dev/null
@@ -1,842 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#ifdef SDL_JOYSTICK_IOKIT
25
26/* SDL joystick driver for Darwin / Mac OS X, based on the IOKit HID API */
27/* Written 2001 by Max Horn */
28
29#include <unistd.h>
30#include <ctype.h>
31#include <sysexits.h>
32#include <mach/mach.h>
33#include <mach/mach_error.h>
34#include <IOKit/IOKitLib.h>
35#include <IOKit/IOCFPlugIn.h>
36#ifdef MACOS_10_0_4
37#include <IOKit/hidsystem/IOHIDUsageTables.h>
38#else
39/* The header was moved here in Mac OS X 10.1 */
40#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
41#endif
42#include <IOKit/hid/IOHIDLib.h>
43#include <IOKit/hid/IOHIDKeys.h>
44#include <CoreFoundation/CoreFoundation.h>
45#include <Carbon/Carbon.h> /* for NewPtrClear, DisposePtr */
46
47#include "SDL_joystick.h"
48#include "../SDL_sysjoystick.h"
49#include "../SDL_joystick_c.h"
50
51struct recElement
52{
53 IOHIDElementCookie cookie; /* unique value which identifies element, will NOT change */
54 long min; /* reported min value possible */
55 long max; /* reported max value possible */
56#if 0
57 /* TODO: maybe should handle the following stuff somehow? */
58
59 long scaledMin; /* reported scaled min value possible */
60 long scaledMax; /* reported scaled max value possible */
61 long size; /* size in bits of data return from element */
62 Boolean relative; /* are reports relative to last report (deltas) */
63 Boolean wrapping; /* does element wrap around (one value higher than max is min) */
64 Boolean nonLinear; /* are the values reported non-linear relative to element movement */
65 Boolean preferredState; /* does element have a preferred state (such as a button) */
66 Boolean nullState; /* does element have null state */
67#endif /* 0 */
68
69 /* runtime variables used for auto-calibration */
70 long minReport; /* min returned value */
71 long maxReport; /* max returned value */
72
73 struct recElement * pNext; /* next element in list */
74};
75typedef struct recElement recElement;
76
77struct joystick_hwdata
78{
79 IOHIDDeviceInterface ** interface; /* interface to device, NULL = no interface */
80
81 char product[256]; /* name of product */
82 long usage; /* usage page from IOUSBHID Parser.h which defines general usage */
83 long usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */
84
85 long axes; /* number of axis (calculated, not reported by device) */
86 long buttons; /* number of buttons (calculated, not reported by device) */
87 long hats; /* number of hat switches (calculated, not reported by device) */
88 long elements; /* number of total elements (shouldbe total of above) (calculated, not reported by device) */
89
90 recElement* firstAxis;
91 recElement* firstButton;
92 recElement* firstHat;
93
94 int removed;
95 int uncentered;
96
97 struct joystick_hwdata* pNext; /* next device */
98};
99typedef struct joystick_hwdata recDevice;
100
101
102/* Linked list of all available devices */
103static recDevice *gpDeviceList = NULL;
104
105
106static void HIDReportErrorNum (char * strError, long numError)
107{
108 SDL_SetError(strError);
109}
110
111static void HIDGetCollectionElements (CFMutableDictionaryRef deviceProperties, recDevice *pDevice);
112
113/* returns current value for element, polling element
114 * will return 0 on error conditions which should be accounted for by application
115 */
116
117static SInt32 HIDGetElementValue (recDevice *pDevice, recElement *pElement)
118{
119 IOReturn result = kIOReturnSuccess;
120 IOHIDEventStruct hidEvent;
121 hidEvent.value = 0;
122
123 if (NULL != pDevice && NULL != pElement && NULL != pDevice->interface)
124 {
125 result = (*(pDevice->interface))->getElementValue(pDevice->interface, pElement->cookie, &hidEvent);
126 if (kIOReturnSuccess == result)
127 {
128 /* record min and max for auto calibration */
129 if (hidEvent.value < pElement->minReport)
130 pElement->minReport = hidEvent.value;
131 if (hidEvent.value > pElement->maxReport)
132 pElement->maxReport = hidEvent.value;
133 }
134 }
135
136 /* auto user scale */
137 return hidEvent.value;
138}
139
140static SInt32 HIDScaledCalibratedValue (recDevice *pDevice, recElement *pElement, long min, long max)
141{
142 float deviceScale = max - min;
143 float readScale = pElement->maxReport - pElement->minReport;
144 SInt32 value = HIDGetElementValue(pDevice, pElement);
145 if (readScale == 0)
146 return value; /* no scaling at all */
147 else
148 return ((value - pElement->minReport) * deviceScale / readScale) + min;
149}
150
151
152static void HIDRemovalCallback(void * target,
153 IOReturn result,
154 void * refcon,
155 void * sender)
156{
157 recDevice *device = (recDevice *) refcon;
158 device->removed = 1;
159 device->uncentered = 1;
160}
161
162
163
164/* Create and open an interface to device, required prior to extracting values or building queues.
165 * Note: appliction now owns the device and must close and release it prior to exiting
166 */
167
168static IOReturn HIDCreateOpenDeviceInterface (io_object_t hidDevice, recDevice *pDevice)
169{
170 IOReturn result = kIOReturnSuccess;
171 HRESULT plugInResult = S_OK;
172 SInt32 score = 0;
173 IOCFPlugInInterface ** ppPlugInInterface = NULL;
174
175 if (NULL == pDevice->interface)
176 {
177 result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID,
178 kIOCFPlugInInterfaceID, &ppPlugInInterface, &score);
179 if (kIOReturnSuccess == result)
180 {
181 /* Call a method of the intermediate plug-in to create the device interface */
182 plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface,
183 CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface));
184 if (S_OK != plugInResult)
185 HIDReportErrorNum ("CouldnÕt query HID class device interface from plugInInterface", plugInResult);
186 (*ppPlugInInterface)->Release (ppPlugInInterface);
187 }
188 else
189 HIDReportErrorNum ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", result);
190 }
191 if (NULL != pDevice->interface)
192 {
193 result = (*(pDevice->interface))->open (pDevice->interface, 0);
194 if (kIOReturnSuccess != result)
195 HIDReportErrorNum ("Failed to open pDevice->interface via open.", result);
196 else
197 (*(pDevice->interface))->setRemovalCallback (pDevice->interface, HIDRemovalCallback, pDevice, pDevice);
198
199 }
200 return result;
201}
202
203/* Closes and releases interface to device, should be done prior to exting application
204 * Note: will have no affect if device or interface do not exist
205 * application will "own" the device if interface is not closed
206 * (device may have to be plug and re-plugged in different location to get it working again without a restart)
207 */
208
209static IOReturn HIDCloseReleaseInterface (recDevice *pDevice)
210{
211 IOReturn result = kIOReturnSuccess;
212
213 if ((NULL != pDevice) && (NULL != pDevice->interface))
214 {
215 /* close the interface */
216 result = (*(pDevice->interface))->close (pDevice->interface);
217 if (kIOReturnNotOpen == result)
218 {
219 /* do nothing as device was not opened, thus can't be closed */
220 }
221 else if (kIOReturnSuccess != result)
222 HIDReportErrorNum ("Failed to close IOHIDDeviceInterface.", result);
223 /* release the interface */
224 result = (*(pDevice->interface))->Release (pDevice->interface);
225 if (kIOReturnSuccess != result)
226 HIDReportErrorNum ("Failed to release IOHIDDeviceInterface.", result);
227 pDevice->interface = NULL;
228 }
229 return result;
230}
231
232/* extracts actual specific element information from each element CF dictionary entry */
233
234static void HIDGetElementInfo (CFTypeRef refElement, recElement *pElement)
235{
236 long number;
237 CFTypeRef refType;
238
239 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementCookieKey));
240 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
241 pElement->cookie = (IOHIDElementCookie) number;
242 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMinKey));
243 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
244 pElement->minReport = pElement->min = number;
245 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMaxKey));
246 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
247 pElement->maxReport = pElement->max = number;
248/*
249 TODO: maybe should handle the following stuff somehow?
250
251 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMinKey));
252 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
253 pElement->scaledMin = number;
254 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMaxKey));
255 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
256 pElement->scaledMax = number;
257 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementSizeKey));
258 if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number))
259 pElement->size = number;
260 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsRelativeKey));
261 if (refType)
262 pElement->relative = CFBooleanGetValue (refType);
263 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsWrappingKey));
264 if (refType)
265 pElement->wrapping = CFBooleanGetValue (refType);
266 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsNonLinearKey));
267 if (refType)
268 pElement->nonLinear = CFBooleanGetValue (refType);
269 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasPreferedStateKey));
270 if (refType)
271 pElement->preferredState = CFBooleanGetValue (refType);
272 refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasNullStateKey));
273 if (refType)
274 pElement->nullState = CFBooleanGetValue (refType);
275*/
276}
277
278/* examines CF dictionary vlaue in device element hierarchy to determine if it is element of interest or a collection of more elements
279 * if element of interest allocate storage, add to list and retrieve element specific info
280 * if collection then pass on to deconstruction collection into additional individual elements
281 */
282
283static void HIDAddElement (CFTypeRef refElement, recDevice* pDevice)
284{
285 recElement* element = NULL;
286 recElement** headElement = NULL;
287 long elementType, usagePage, usage;
288 CFTypeRef refElementType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementTypeKey));
289 CFTypeRef refUsagePage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsagePageKey));
290 CFTypeRef refUsage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsageKey));
291
292
293 if ((refElementType) && (CFNumberGetValue (refElementType, kCFNumberLongType, &elementType)))
294 {
295 /* look at types of interest */
296 if ((elementType == kIOHIDElementTypeInput_Misc) || (elementType == kIOHIDElementTypeInput_Button) ||
297 (elementType == kIOHIDElementTypeInput_Axis))
298 {
299 if (refUsagePage && CFNumberGetValue (refUsagePage, kCFNumberLongType, &usagePage) &&
300 refUsage && CFNumberGetValue (refUsage, kCFNumberLongType, &usage))
301 {
302 switch (usagePage) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */
303 {
304 case kHIDPage_GenericDesktop:
305 {
306 switch (usage) /* look at usage to determine function */
307 {
308 case kHIDUsage_GD_X:
309 case kHIDUsage_GD_Y:
310 case kHIDUsage_GD_Z:
311 case kHIDUsage_GD_Rx:
312 case kHIDUsage_GD_Ry:
313 case kHIDUsage_GD_Rz:
314 case kHIDUsage_GD_Slider:
315 case kHIDUsage_GD_Dial:
316 case kHIDUsage_GD_Wheel:
317 element = (recElement *) NewPtrClear (sizeof (recElement));
318 if (element)
319 {
320 pDevice->axes++;
321 headElement = &(pDevice->firstAxis);
322 }
323 break;
324 case kHIDUsage_GD_Hatswitch:
325 element = (recElement *) NewPtrClear (sizeof (recElement));
326 if (element)
327 {
328 pDevice->hats++;
329 headElement = &(pDevice->firstHat);
330 }
331 break;
332 }
333 }
334 break;
335 case kHIDPage_Button:
336 element = (recElement *) NewPtrClear (sizeof (recElement));
337 if (element)
338 {
339 pDevice->buttons++;
340 headElement = &(pDevice->firstButton);
341 }
342 break;
343 default:
344 break;
345 }
346 }
347 }
348 else if (kIOHIDElementTypeCollection == elementType)
349 HIDGetCollectionElements ((CFMutableDictionaryRef) refElement, pDevice);
350 }
351
352 if (element && headElement) /* add to list */
353 {
354 pDevice->elements++;
355 if (NULL == *headElement)
356 *headElement = element;
357 else
358 {
359 recElement *elementPrevious, *elementCurrent;
360 elementCurrent = *headElement;
361 while (elementCurrent)
362 {
363 elementPrevious = elementCurrent;
364 elementCurrent = elementPrevious->pNext;
365 }
366 elementPrevious->pNext = element;
367 }
368 element->pNext = NULL;
369 HIDGetElementInfo (refElement, element);
370 }
371}
372
373/* collects information from each array member in device element list (each array memeber = element) */
374
375static void HIDGetElementsCFArrayHandler (const void * value, void * parameter)
376{
377 if (CFGetTypeID (value) == CFDictionaryGetTypeID ())
378 HIDAddElement ((CFTypeRef) value, (recDevice *) parameter);
379}
380
381/* handles retrieval of element information from arrays of elements in device IO registry information */
382
383static void HIDGetElements (CFTypeRef refElementCurrent, recDevice *pDevice)
384{
385 CFTypeID type = CFGetTypeID (refElementCurrent);
386 if (type == CFArrayGetTypeID()) /* if element is an array */
387 {
388 CFRange range = {0, CFArrayGetCount (refElementCurrent)};
389 /* CountElementsCFArrayHandler called for each array member */
390 CFArrayApplyFunction (refElementCurrent, range, HIDGetElementsCFArrayHandler, pDevice);
391 }
392}
393
394/* handles extracting element information from element collection CF types
395 * used from top level element decoding and hierarchy deconstruction to flatten device element list
396 */
397
398static void HIDGetCollectionElements (CFMutableDictionaryRef deviceProperties, recDevice *pDevice)
399{
400 CFTypeRef refElementTop = CFDictionaryGetValue (deviceProperties, CFSTR(kIOHIDElementKey));
401 if (refElementTop)
402 HIDGetElements (refElementTop, pDevice);
403}
404
405/* use top level element usage page and usage to discern device usage page and usage setting appropriate vlaues in device record */
406
407static void HIDTopLevelElementHandler (const void * value, void * parameter)
408{
409 CFTypeRef refCF = 0;
410 if (CFGetTypeID (value) != CFDictionaryGetTypeID ())
411 return;
412 refCF = CFDictionaryGetValue (value, CFSTR(kIOHIDElementUsagePageKey));
413 if (!CFNumberGetValue (refCF, kCFNumberLongType, &((recDevice *) parameter)->usagePage))
414 SDL_SetError ("CFNumberGetValue error retrieving pDevice->usagePage.");
415 refCF = CFDictionaryGetValue (value, CFSTR(kIOHIDElementUsageKey));
416 if (!CFNumberGetValue (refCF, kCFNumberLongType, &((recDevice *) parameter)->usage))
417 SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage.");
418}
419
420/* extracts device info from CF dictionary records in IO registry */
421
422static void HIDGetDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef hidProperties, recDevice *pDevice)
423{
424 CFMutableDictionaryRef usbProperties = 0;
425 io_registry_entry_t parent1, parent2;
426
427 /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
428 * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
429 */
430 if ((KERN_SUCCESS == IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) &&
431 (KERN_SUCCESS == IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2)) &&
432 (KERN_SUCCESS == IORegistryEntryCreateCFProperties (parent2, &usbProperties, kCFAllocatorDefault, kNilOptions)))
433 {
434 if (usbProperties)
435 {
436 CFTypeRef refCF = 0;
437 /* get device info
438 * try hid dictionary first, if fail then go to usb dictionary
439 */
440
441
442 /* get product name */
443 refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey));
444 if (!refCF)
445 refCF = CFDictionaryGetValue (usbProperties, CFSTR("USB Product Name"));
446 if (refCF)
447 {
448 if (!CFStringGetCString (refCF, pDevice->product, 256, CFStringGetSystemEncoding ()))
449 SDL_SetError ("CFStringGetCString error retrieving pDevice->product.");
450 }
451
452 /* get usage page and usage */
453 refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
454 if (refCF)
455 {
456 if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage))
457 SDL_SetError ("CFNumberGetValue error retrieving pDevice->usagePage.");
458 refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey));
459 if (refCF)
460 if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage))
461 SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage.");
462 }
463
464 if (NULL == refCF) /* get top level element HID usage page or usage */
465 {
466 /* use top level element instead */
467 CFTypeRef refCFTopElement = 0;
468 refCFTopElement = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey));
469 {
470 /* refCFTopElement points to an array of element dictionaries */
471 CFRange range = {0, CFArrayGetCount (refCFTopElement)};
472 CFArrayApplyFunction (refCFTopElement, range, HIDTopLevelElementHandler, pDevice);
473 }
474 }
475
476 CFRelease (usbProperties);
477 }
478 else
479 SDL_SetError ("IORegistryEntryCreateCFProperties failed to create usbProperties.");
480
481 if (kIOReturnSuccess != IOObjectRelease (parent2))
482 SDL_SetError ("IOObjectRelease error with parent2.");
483 if (kIOReturnSuccess != IOObjectRelease (parent1))
484 SDL_SetError ("IOObjectRelease error with parent1.");
485 }
486}
487
488
489static recDevice *HIDBuildDevice (io_object_t hidDevice)
490{
491 recDevice *pDevice = (recDevice *) NewPtrClear (sizeof (recDevice));
492 if (pDevice)
493 {
494 /* get dictionary for HID properties */
495 CFMutableDictionaryRef hidProperties = 0;
496 kern_return_t result = IORegistryEntryCreateCFProperties (hidDevice, &hidProperties, kCFAllocatorDefault, kNilOptions);
497 if ((result == KERN_SUCCESS) && hidProperties)
498 {
499 /* create device interface */
500 result = HIDCreateOpenDeviceInterface (hidDevice, pDevice);
501 if (kIOReturnSuccess == result)
502 {
503 HIDGetDeviceInfo (hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */
504 HIDGetCollectionElements (hidProperties, pDevice);
505 }
506 else
507 {
508 DisposePtr((Ptr)pDevice);
509 pDevice = NULL;
510 }
511 CFRelease (hidProperties);
512 }
513 else
514 {
515 DisposePtr((Ptr)pDevice);
516 pDevice = NULL;
517 }
518 }
519 return pDevice;
520}
521
522/* disposes of the element list associated with a device and the memory associated with the list
523 */
524
525static void HIDDisposeElementList (recElement **elementList)
526{
527 recElement *pElement = *elementList;
528 while (pElement)
529 {
530 recElement *pElementNext = pElement->pNext;
531 DisposePtr ((Ptr) pElement);
532 pElement = pElementNext;
533 }
534 *elementList = NULL;
535}
536
537/* disposes of a single device, closing and releaseing interface, freeing memory fro device and elements, setting device pointer to NULL
538 * all your device no longer belong to us... (i.e., you do not 'own' the device anymore)
539 */
540
541static recDevice *HIDDisposeDevice (recDevice **ppDevice)
542{
543 kern_return_t result = KERN_SUCCESS;
544 recDevice *pDeviceNext = NULL;
545 if (*ppDevice)
546 {
547 /* save next device prior to disposing of this device */
548 pDeviceNext = (*ppDevice)->pNext;
549
550 /* free element lists */
551 HIDDisposeElementList (&(*ppDevice)->firstAxis);
552 HIDDisposeElementList (&(*ppDevice)->firstButton);
553 HIDDisposeElementList (&(*ppDevice)->firstHat);
554
555 result = HIDCloseReleaseInterface (*ppDevice); /* function sanity checks interface value (now application does not own device) */
556 if (kIOReturnSuccess != result)
557 HIDReportErrorNum ("HIDCloseReleaseInterface failed when trying to dipose device.", result);
558 DisposePtr ((Ptr)*ppDevice);
559 *ppDevice = NULL;
560 }
561 return pDeviceNext;
562}
563
564
565/* Function to scan the system for joysticks.
566 * Joystick 0 should be the system default joystick.
567 * This function should return the number of available joysticks, or -1
568 * on an unrecoverable fatal error.
569 */
570int SDL_SYS_JoystickInit(void)
571{
572 IOReturn result = kIOReturnSuccess;
573 mach_port_t masterPort = 0;
574 io_iterator_t hidObjectIterator = 0;
575 CFMutableDictionaryRef hidMatchDictionary = NULL;
576 recDevice *device, *lastDevice;
577 io_object_t ioHIDDeviceObject = 0;
578
579 SDL_numjoysticks = 0;
580
581 if (gpDeviceList)
582 {
583 SDL_SetError("Joystick: Device list already inited.");
584 return -1;
585 }
586
587 result = IOMasterPort (bootstrap_port, &masterPort);
588 if (kIOReturnSuccess != result)
589 {
590 SDL_SetError("Joystick: IOMasterPort error with bootstrap_port.");
591 return -1;
592 }
593
594 /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */
595 hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey);
596 if (hidMatchDictionary)
597 {
598 /* Add key for device type (joystick, in this case) to refine the matching dictionary. */
599
600 /* NOTE: we now perform this filtering later
601 UInt32 usagePage = kHIDPage_GenericDesktop;
602 UInt32 usage = kHIDUsage_GD_Joystick;
603 CFNumberRef refUsage = NULL, refUsagePage = NULL;
604
605 refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage);
606 CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage);
607 refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage);
608 CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage);
609 */
610 }
611 else
612 {
613 SDL_SetError("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
614 return -1;
615 }
616
617 /*/ Now search I/O Registry for matching devices. */
618 result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator);
619 /* Check for errors */
620 if (kIOReturnSuccess != result)
621 {
622 SDL_SetError("Joystick: Couldn't create a HID object iterator.");
623 return -1;
624 }
625 if (!hidObjectIterator) /* there are no joysticks */
626 {
627 gpDeviceList = NULL;
628 SDL_numjoysticks = 0;
629 return 0;
630 }
631 /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */
632
633 /* build flat linked list of devices from device iterator */
634
635 gpDeviceList = lastDevice = NULL;
636
637 while ((ioHIDDeviceObject = IOIteratorNext (hidObjectIterator)))
638 {
639 /* build a device record */
640 device = HIDBuildDevice (ioHIDDeviceObject);
641 if (!device)
642 continue;
643
644 /* dump device object, it is no longer needed */
645 result = IOObjectRelease (ioHIDDeviceObject);
646/* if (KERN_SUCCESS != result)
647 HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result);
648*/
649
650 /* Filter device list to non-keyboard/mouse stuff */
651 if ( (device->usagePage != kHIDPage_GenericDesktop) ||
652 ((device->usage != kHIDUsage_GD_Joystick &&
653 device->usage != kHIDUsage_GD_GamePad &&
654 device->usage != kHIDUsage_GD_MultiAxisController)) ) {
655
656 /* release memory for the device */
657 HIDDisposeDevice (&device);
658 DisposePtr((Ptr)device);
659 continue;
660 }
661
662 /* Add device to the end of the list */
663 if (lastDevice)
664 lastDevice->pNext = device;
665 else
666 gpDeviceList = device;
667 lastDevice = device;
668 }
669 result = IOObjectRelease (hidObjectIterator); /* release the iterator */
670
671 /* Count the total number of devices we found */
672 device = gpDeviceList;
673 while (device)
674 {
675 SDL_numjoysticks++;
676 device = device->pNext;
677 }
678
679 return SDL_numjoysticks;
680}
681
682/* Function to get the device-dependent name of a joystick */
683const char *SDL_SYS_JoystickName(int index)
684{
685 recDevice *device = gpDeviceList;
686
687 for (; index > 0; index--)
688 device = device->pNext;
689
690 return device->product;
691}
692
693/* Function to open a joystick for use.
694 * The joystick to open is specified by the index field of the joystick.
695 * This should fill the nbuttons and naxes fields of the joystick structure.
696 * It returns 0, or -1 if there is an error.
697 */
698int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
699{
700 recDevice *device = gpDeviceList;
701 int index;
702
703 for (index = joystick->index; index > 0; index--)
704 device = device->pNext;
705
706 joystick->hwdata = device;
707 joystick->name = device->product;
708
709 joystick->naxes = device->axes;
710 joystick->nhats = device->hats;
711 joystick->nballs = 0;
712 joystick->nbuttons = device->buttons;
713
714 return 0;
715}
716
717/* Function to update the state of a joystick - called as a device poll.
718 * This function shouldn't update the joystick structure directly,
719 * but instead should call SDL_PrivateJoystick*() to deliver events
720 * and update joystick device state.
721 */
722void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
723{
724 recDevice *device = joystick->hwdata;
725 recElement *element;
726 SInt32 value, range;
727 int i;
728
729 if (device->removed) /* device was unplugged; ignore it. */
730 {
731 if (device->uncentered)
732 {
733 device->uncentered = 0;
734
735 /* Tell the app that everything is centered/unpressed... */
736 for (i = 0; i < device->axes; i++)
737 SDL_PrivateJoystickAxis(joystick, i, 0);
738
739 for (i = 0; i < device->buttons; i++)
740 SDL_PrivateJoystickButton(joystick, i, 0);
741
742 for (i = 0; i < device->hats; i++)
743 SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED);
744 }
745
746 return;
747 }
748
749 element = device->firstAxis;
750 i = 0;
751 while (element)
752 {
753 value = HIDScaledCalibratedValue(device, element, -32768, 32767);
754 if ( value != joystick->axes[i] )
755 SDL_PrivateJoystickAxis(joystick, i, value);
756 element = element->pNext;
757 ++i;
758 }
759
760 element = device->firstButton;
761 i = 0;
762 while (element)
763 {
764 value = HIDGetElementValue(device, element);
765 if (value > 1) /* handle pressure-sensitive buttons */
766 value = 1;
767 if ( value != joystick->buttons[i] )
768 SDL_PrivateJoystickButton(joystick, i, value);
769 element = element->pNext;
770 ++i;
771 }
772
773 element = device->firstHat;
774 i = 0;
775 while (element)
776 {
777 Uint8 pos = 0;
778
779 range = (element->max - element->min + 1);
780 value = HIDGetElementValue(device, element) - element->min;
781 if (range == 4) /* 4 position hatswitch - scale up value */
782 value *= 2;
783 else if (range != 8) /* Neither a 4 nor 8 positions - fall back to default position (centered) */
784 value = -1;
785 switch(value)
786 {
787 case 0:
788 pos = SDL_HAT_UP;
789 break;
790 case 1:
791 pos = SDL_HAT_RIGHTUP;
792 break;
793 case 2:
794 pos = SDL_HAT_RIGHT;
795 break;
796 case 3:
797 pos = SDL_HAT_RIGHTDOWN;
798 break;
799 case 4:
800 pos = SDL_HAT_DOWN;
801 break;
802 case 5:
803 pos = SDL_HAT_LEFTDOWN;
804 break;
805 case 6:
806 pos = SDL_HAT_LEFT;
807 break;
808 case 7:
809 pos = SDL_HAT_LEFTUP;
810 break;
811 default:
812 /* Every other value is mapped to center. We do that because some
813 * joysticks use 8 and some 15 for this value, and apparently
814 * there are even more variants out there - so we try to be generous.
815 */
816 pos = SDL_HAT_CENTERED;
817 break;
818 }
819 if ( pos != joystick->hats[i] )
820 SDL_PrivateJoystickHat(joystick, i, pos);
821 element = element->pNext;
822 ++i;
823 }
824
825 return;
826}
827
828/* Function to close a joystick after use */
829void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
830{
831 /* Should we do anything here? */
832 return;
833}
834
835/* Function to perform any system-specific joystick related cleanup */
836void SDL_SYS_JoystickQuit(void)
837{
838 while (NULL != gpDeviceList)
839 gpDeviceList = HIDDisposeDevice (&gpDeviceList);
840}
841
842#endif /* SDL_JOYSTICK_IOKIT */
diff --git a/apps/plugins/sdl/src/joystick/dc/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/dc/SDL_sysjoystick.c
deleted file mode 100644
index dc089e7bf0..0000000000
--- a/apps/plugins/sdl/src/joystick/dc/SDL_sysjoystick.c
+++ /dev/null
@@ -1,193 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_DC
25
26#include "SDL_events.h"
27#include "SDL_joystick.h"
28#include "../SDL_sysjoystick.h"
29#include "../SDL_joystick_c.h"
30
31#include <dc/maple.h>
32#include <dc/maple/controller.h>
33
34#define MAX_JOYSTICKS 8 /* only 2 are supported in the multimedia API */
35#define MAX_AXES 6 /* each joystick can have up to 6 axes */
36#define MAX_BUTTONS 8 /* and 8 buttons */
37#define MAX_HATS 2
38
39#define JOYNAMELEN 8
40
41/* array to hold joystick ID values */
42static uint8 SYS_Joystick_addr[MAX_JOYSTICKS];
43
44/* The private structure used to keep track of a joystick */
45struct joystick_hwdata
46{
47 cont_cond_t prev_cond;
48 int prev_buttons;
49};
50
51/* Function to scan the system for joysticks.
52 * This function should set SDL_numjoysticks to the number of available
53 * joysticks. Joystick 0 should be the system default joystick.
54 * It should return 0, or -1 on an unrecoverable fatal error.
55 */
56int SDL_SYS_JoystickInit(void)
57{
58 int numdevs;
59
60 int p,u;
61
62 numdevs = 0;
63 for(p=0;p<MAPLE_PORT_COUNT;p++) {
64 for(u=0;u<MAPLE_UNIT_COUNT;u++) {
65 if (maple_device_func(p,u)&MAPLE_FUNC_CONTROLLER) {
66 SYS_Joystick_addr[numdevs] = maple_addr(p,u);
67 numdevs++;
68 }
69 }
70 }
71
72 return(numdevs);
73}
74
75/* Function to get the device-dependent name of a joystick */
76const char *SDL_SYS_JoystickName(int index)
77{
78 maple_device_t *dev;
79 if (maple_compat_resolve(SYS_Joystick_addr[index],&dev,MAPLE_FUNC_CONTROLLER)!=0) return NULL;
80 return dev->info.product_name;
81}
82
83/* Function to open a joystick for use.
84 The joystick to open is specified by the index field of the joystick.
85 This should fill the nbuttons and naxes fields of the joystick structure.
86 It returns 0, or -1 if there is an error.
87 */
88int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
89{
90 /* allocate memory for system specific hardware data */
91 joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
92 if (joystick->hwdata == NULL)
93 {
94 SDL_OutOfMemory();
95 return(-1);
96 }
97 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
98
99 /* fill nbuttons, naxes, and nhats fields */
100 joystick->nbuttons = MAX_BUTTONS;
101 joystick->naxes = MAX_AXES;
102 joystick->nhats = MAX_HATS;
103 return(0);
104}
105
106
107/* Function to update the state of a joystick - called as a device poll.
108 * This function shouldn't update the joystick structure directly,
109 * but instead should call SDL_PrivateJoystick*() to deliver events
110 * and update joystick device state.
111 */
112
113void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
114{
115const int sdl_buttons[] = {
116 CONT_C,
117 CONT_B,
118 CONT_A,
119 CONT_START,
120 CONT_Z,
121 CONT_Y,
122 CONT_X,
123 CONT_D
124};
125
126 uint8 addr;
127 cont_cond_t cond,*prev_cond;
128 int buttons,prev_buttons,i,changed;
129
130 addr = SYS_Joystick_addr[joystick->index];
131 if (cont_get_cond(addr,&cond)<0) return;
132
133 buttons = cond.buttons;
134 prev_buttons = joystick->hwdata->prev_buttons;
135 changed = buttons^prev_buttons;
136
137 if ((changed)&(CONT_DPAD_UP|CONT_DPAD_DOWN|CONT_DPAD_LEFT|CONT_DPAD_RIGHT)) {
138 int hat = SDL_HAT_CENTERED;
139 if (buttons&CONT_DPAD_UP) hat|=SDL_HAT_UP;
140 if (buttons&CONT_DPAD_DOWN) hat|=SDL_HAT_DOWN;
141 if (buttons&CONT_DPAD_LEFT) hat|=SDL_HAT_LEFT;
142 if (buttons&CONT_DPAD_RIGHT) hat|=SDL_HAT_RIGHT;
143 SDL_PrivateJoystickHat(joystick, 0, hat);
144 }
145 if ((changed)&(CONT_DPAD2_UP|CONT_DPAD2_DOWN|CONT_DPAD2_LEFT|CONT_DPAD2_RIGHT)) {
146 int hat = SDL_HAT_CENTERED;
147 if (buttons&CONT_DPAD2_UP) hat|=SDL_HAT_UP;
148 if (buttons&CONT_DPAD2_DOWN) hat|=SDL_HAT_DOWN;
149 if (buttons&CONT_DPAD2_LEFT) hat|=SDL_HAT_LEFT;
150 if (buttons&CONT_DPAD2_RIGHT) hat|=SDL_HAT_RIGHT;
151 SDL_PrivateJoystickHat(joystick, 1, hat);
152 }
153
154 for(i=0;i<sizeof(sdl_buttons)/sizeof(sdl_buttons[0]);i++) {
155 if (changed & sdl_buttons[i]) {
156 SDL_PrivateJoystickButton(joystick, i, (buttons & sdl_buttons[i])?SDL_PRESSED:SDL_RELEASED);
157 }
158 }
159
160 prev_cond = &joystick->hwdata->prev_cond;
161 if (cond.joyx!=prev_cond->joyx)
162 SDL_PrivateJoystickAxis(joystick, 0, cond.joyx-128);
163 if (cond.joyy!=prev_cond->joyy)
164 SDL_PrivateJoystickAxis(joystick, 1, cond.joyy-128);
165 if (cond.rtrig!=prev_cond->rtrig)
166 SDL_PrivateJoystickAxis(joystick, 2, cond.rtrig);
167 if (cond.ltrig!=prev_cond->ltrig)
168 SDL_PrivateJoystickAxis(joystick, 3, cond.ltrig);
169 if (cond.joy2x!=prev_cond->joy2x)
170 SDL_PrivateJoystickAxis(joystick, 4, cond.joy2x-128);
171 if (cond.joy2y!=prev_cond->joy2y)
172 SDL_PrivateJoystickAxis(joystick, 5, cond.joy2y-128);
173
174 joystick->hwdata->prev_buttons = buttons;
175 joystick->hwdata->prev_cond = cond;
176}
177
178/* Function to close a joystick after use */
179void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
180{
181 if (joystick->hwdata != NULL) {
182 /* free system specific hardware data */
183 SDL_free(joystick->hwdata);
184 }
185}
186
187/* Function to perform any system-specific joystick related cleanup */
188void SDL_SYS_JoystickQuit(void)
189{
190 return;
191}
192
193#endif /* SDL_JOYSTICK_DC */
diff --git a/apps/plugins/sdl/src/joystick/linux/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/linux/SDL_sysjoystick.c
deleted file mode 100644
index ee43974789..0000000000
--- a/apps/plugins/sdl/src/joystick/linux/SDL_sysjoystick.c
+++ /dev/null
@@ -1,1218 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_LINUX
25
26/* This is the system specific header for the SDL joystick API */
27
28#include <sys/stat.h>
29#include <unistd.h>
30#include <fcntl.h>
31#include <sys/ioctl.h>
32#include <limits.h> /* For the definition of PATH_MAX */
33#include <linux/joystick.h>
34#if SDL_INPUT_LINUXEV
35#include <linux/input.h>
36#endif
37
38#include "SDL_joystick.h"
39#include "../SDL_sysjoystick.h"
40#include "../SDL_joystick_c.h"
41
42/* Special joystick configurations */
43static struct {
44 const char *name;
45 int naxes;
46 int nhats;
47 int nballs;
48} special_joysticks[] = {
49 { "MadCatz Panther XL", 3, 2, 1 }, /* We don't handle rudder (axis 8) */
50 { "SideWinder Precision Pro", 4, 1, 0 },
51 { "SideWinder 3D Pro", 4, 1, 0 },
52 { "Microsoft SideWinder 3D Pro", 4, 1, 0 },
53 { "Microsoft SideWinder Precision Pro", 4, 1, 0 },
54 { "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0 },
55 { "WingMan Interceptor", 3, 3, 0 },
56 { "WingMan Extreme Digital 3D", 4, 1, 0 },
57 { "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0 },
58 { "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0 },
59 { "Saitek Saitek X45", 6, 1, 0 }
60};
61
62/* It looks like newer kernels have the logical mapping at the driver level */
63#define NO_LOGICAL_JOYSTICKS
64
65#ifndef NO_LOGICAL_JOYSTICKS
66
67/*
68 Some USB HIDs show up as a single joystick even though they actually
69 control 2 or more joysticks.
70*/
71/*
72 This code handles the MP-8800 (Quad) and MP-8866 (Dual), which can
73 be identified by their transparent blue design. It's quite trivial
74 to add other joysticks with similar quirky behavior.
75 -id
76*/
77
78struct joystick_logical_mapping {
79 int njoy;
80 int nthing;
81};
82
83/*
84 {logical joy, logical axis},
85 {logical joy, logical hat},
86 {logical joy, logical ball},
87 {logical joy, logical button}
88*/
89
90static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = {
91 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5}
92};
93static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = {
94 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}
95};
96
97static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = {
98 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
99 {1,2},{1,3},{0,4},{0,5},{1,4},{1,5}
100};
101static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = {
102 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
103 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}
104};
105
106static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = {
107 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
108 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
109 {0,4},{0,5},{1,4},{1,5},{2,4},{2,5}
110};
111static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = {
112 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
113 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11},
114 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}
115};
116
117static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = {
118 {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
119 {1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
120 {3,0},{3,1},{3,2},{3,3},{0,4},{0,5},
121 {1,4},{1,5},{2,4},{2,5},{3,4},{3,5}
122};
123static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = {
124 {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
125 {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11},
126 {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11},
127 {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11}
128};
129
130struct joystick_logical_layout {
131 int naxes;
132 int nhats;
133 int nballs;
134 int nbuttons;
135};
136
137static struct joystick_logical_layout mp88xx_1_logical_layout[] = {
138 {6, 0, 0, 12}
139};
140static struct joystick_logical_layout mp88xx_2_logical_layout[] = {
141 {6, 0, 0, 12},
142 {6, 0, 0, 12}
143};
144static struct joystick_logical_layout mp88xx_3_logical_layout[] = {
145 {6, 0, 0, 12},
146 {6, 0, 0, 12},
147 {6, 0, 0, 12}
148};
149static struct joystick_logical_layout mp88xx_4_logical_layout[] = {
150 {6, 0, 0, 12},
151 {6, 0, 0, 12},
152 {6, 0, 0, 12},
153 {6, 0, 0, 12}
154};
155
156/*
157 This array sets up a means of mapping a single physical joystick to
158 multiple logical joysticks. (djm)
159
160 njoys
161 the number of logical joysticks
162
163 layouts
164 an array of layout structures, one to describe each logical joystick
165
166 axes, hats, balls, buttons
167 arrays that map a physical thingy to a logical thingy
168 */
169struct joystick_logicalmap {
170 const char *name;
171 int nbuttons;
172 int njoys;
173 struct joystick_logical_layout *layout;
174 struct joystick_logical_mapping *axismap;
175 struct joystick_logical_mapping *hatmap;
176 struct joystick_logical_mapping *ballmap;
177 struct joystick_logical_mapping *buttonmap;
178};
179
180static struct joystick_logicalmap joystick_logicalmap[] = {
181 {
182 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
183 12,
184 1,
185 mp88xx_1_logical_layout,
186 mp88xx_1_logical_axismap,
187 NULL,
188 NULL,
189 mp88xx_1_logical_buttonmap
190 },
191 {
192 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
193 24,
194 2,
195 mp88xx_2_logical_layout,
196 mp88xx_2_logical_axismap,
197 NULL,
198 NULL,
199 mp88xx_2_logical_buttonmap
200 },
201 {
202 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
203 12,
204 1,
205 mp88xx_1_logical_layout,
206 mp88xx_1_logical_axismap,
207 NULL,
208 NULL,
209 mp88xx_1_logical_buttonmap
210 },
211 {
212 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
213 24,
214 2,
215 mp88xx_2_logical_layout,
216 mp88xx_2_logical_axismap,
217 NULL,
218 NULL,
219 mp88xx_2_logical_buttonmap
220 },
221 {
222 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
223 36,
224 3,
225 mp88xx_3_logical_layout,
226 mp88xx_3_logical_axismap,
227 NULL,
228 NULL,
229 mp88xx_3_logical_buttonmap
230 },
231 {
232 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
233 48,
234 4,
235 mp88xx_4_logical_layout,
236 mp88xx_4_logical_axismap,
237 NULL,
238 NULL,
239 mp88xx_4_logical_buttonmap
240 }
241};
242
243/* find the head of a linked list, given a point in it
244 */
245#define SDL_joylist_head(i, start)\
246 for(i = start; SDL_joylist[i].fname == NULL;) i = SDL_joylist[i].prev;
247
248#define SDL_logical_joydecl(d) d
249
250
251#else
252
253#define SDL_logical_joydecl(d)
254
255#endif /* USE_LOGICAL_JOYSTICKS */
256
257/* The maximum number of joysticks we'll detect */
258#define MAX_JOYSTICKS 32
259
260/* A list of available joysticks */
261static struct
262{
263 char* fname;
264#ifndef NO_LOGICAL_JOYSTICKS
265 SDL_Joystick* joy;
266 struct joystick_logicalmap* map;
267 int prev;
268 int next;
269 int logicalno;
270#endif /* USE_LOGICAL_JOYSTICKS */
271} SDL_joylist[MAX_JOYSTICKS];
272
273
274/* The private structure used to keep track of a joystick */
275struct joystick_hwdata {
276 int fd;
277 /* The current linux joystick driver maps hats to two axes */
278 struct hwdata_hat {
279 int axis[2];
280 } *hats;
281 /* The current linux joystick driver maps balls to two axes */
282 struct hwdata_ball {
283 int axis[2];
284 } *balls;
285
286 /* Support for the Linux 2.4 unified input interface */
287#if SDL_INPUT_LINUXEV
288 SDL_bool is_hid;
289 Uint8 key_map[KEY_MAX-BTN_MISC];
290 Uint8 abs_map[ABS_MAX];
291 struct axis_correct {
292 int used;
293 int coef[3];
294 } abs_correct[ABS_MAX];
295#endif
296};
297
298
299#ifndef NO_LOGICAL_JOYSTICKS
300
301static int CountLogicalJoysticks(int max)
302{
303 register int i, j, k, ret, prev;
304 const char* name;
305 int nbuttons, fd;
306 unsigned char n;
307
308 ret = 0;
309
310 for(i = 0; i < max; i++) {
311 name = SDL_SYS_JoystickName(i);
312
313 fd = open(SDL_joylist[i].fname, O_RDONLY, 0);
314 if ( fd >= 0 ) {
315 if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
316 nbuttons = -1;
317 } else {
318 nbuttons = n;
319 }
320 close(fd);
321 }
322 else {
323 nbuttons=-1;
324 }
325
326 if (name) {
327 for(j = 0; j < SDL_arraysize(joystick_logicalmap); j++) {
328 if (!SDL_strcmp(name, joystick_logicalmap[j].name) && (nbuttons==-1 || nbuttons==joystick_logicalmap[j].nbuttons)) {
329 prev = i;
330 SDL_joylist[prev].map = &(joystick_logicalmap[j]);
331
332 for(k = 1; k < joystick_logicalmap[j].njoys; k++) {
333 SDL_joylist[prev].next = max + ret;
334 SDL_joylist[max+ret].prev = prev;
335
336 prev = max + ret;
337 SDL_joylist[prev].logicalno = k;
338 SDL_joylist[prev].map = &(joystick_logicalmap[j]);
339 ret++;
340 }
341
342 break;
343 }
344 }
345 }
346 }
347
348 return ret;
349}
350
351static void LogicalSuffix(int logicalno, char* namebuf, int len)
352{
353 register int slen;
354 const static char suffixs[] =
355 "01020304050607080910111213141516171819"
356 "20212223242526272829303132";
357 const char* suffix;
358 slen = SDL_strlen(namebuf);
359 suffix = NULL;
360
361 if (logicalno*2<sizeof(suffixs))
362 suffix = suffixs + (logicalno*2);
363
364 if (slen + 4 < len && suffix) {
365 namebuf[slen++] = ' ';
366 namebuf[slen++] = '#';
367 namebuf[slen++] = suffix[0];
368 namebuf[slen++] = suffix[1];
369 namebuf[slen++] = 0;
370 }
371}
372
373#endif /* USE_LOGICAL_JOYSTICKS */
374
375#if SDL_INPUT_LINUXEV
376#define test_bit(nr, addr) \
377 (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
378#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
379
380static int EV_IsJoystick(int fd)
381{
382 unsigned long evbit[NBITS(EV_MAX)] = { 0 };
383 unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
384 unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
385
386 if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
387 (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
388 (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) {
389 return(0);
390 }
391 if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
392 test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
393 (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0;
394 return(1);
395}
396
397#endif /* SDL_INPUT_LINUXEV */
398
399/* Function to scan the system for joysticks */
400int SDL_SYS_JoystickInit(void)
401{
402 /* The base path of the joystick devices */
403 const char *joydev_pattern[] = {
404#if SDL_INPUT_LINUXEV
405 "/dev/input/event%d",
406#endif
407 "/dev/input/js%d",
408 "/dev/js%d"
409 };
410 int numjoysticks;
411 int i, j;
412 int fd;
413 char path[PATH_MAX];
414 dev_t dev_nums[MAX_JOYSTICKS]; /* major/minor device numbers */
415 struct stat sb;
416 int n, duplicate;
417
418 numjoysticks = 0;
419
420 /* First see if the user specified one or more joysticks to use */
421 if ( SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL ) {
422 char *envcopy, *envpath, *delim;
423 envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE"));
424 envpath = envcopy;
425 while ( envpath != NULL ) {
426 delim = SDL_strchr(envpath, ':');
427 if ( delim != NULL ) {
428 *delim++ = '\0';
429 }
430 if ( stat(envpath, &sb) == 0 ) {
431 fd = open(envpath, O_RDONLY, 0);
432 if ( fd >= 0 ) {
433 /* Assume the user knows what they're doing. */
434 SDL_joylist[numjoysticks].fname = SDL_strdup(envpath);
435 if ( SDL_joylist[numjoysticks].fname ) {
436 dev_nums[numjoysticks] = sb.st_rdev;
437 ++numjoysticks;
438 }
439 close(fd);
440 }
441 }
442 envpath = delim;
443 }
444 SDL_free(envcopy);
445 }
446
447 for ( i=0; i<SDL_arraysize(joydev_pattern); ++i ) {
448 for ( j=0; j < MAX_JOYSTICKS; ++j ) {
449 SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j);
450
451 /* rcg06302000 replaced access(F_OK) call with stat().
452 * stat() will fail if the file doesn't exist, so it's
453 * equivalent behaviour.
454 */
455 if ( stat(path, &sb) == 0 ) {
456 /* Check to make sure it's not already in list.
457 * This happens when we see a stick via symlink.
458 */
459 duplicate = 0;
460 for (n=0; (n<numjoysticks) && !duplicate; ++n) {
461 if ( sb.st_rdev == dev_nums[n] ) {
462 duplicate = 1;
463 }
464 }
465 if (duplicate) {
466 continue;
467 }
468
469 fd = open(path, O_RDONLY, 0);
470 if ( fd < 0 ) {
471 continue;
472 }
473#if SDL_INPUT_LINUXEV
474#ifdef DEBUG_INPUT_EVENTS
475 printf("Checking %s\n", path);
476#endif
477 if ( (i == 0) && ! EV_IsJoystick(fd) ) {
478 close(fd);
479 continue;
480 }
481#endif
482 close(fd);
483
484 /* We're fine, add this joystick */
485 SDL_joylist[numjoysticks].fname = SDL_strdup(path);
486 if ( SDL_joylist[numjoysticks].fname ) {
487 dev_nums[numjoysticks] = sb.st_rdev;
488 ++numjoysticks;
489 }
490 }
491 }
492
493#if SDL_INPUT_LINUXEV
494 /* This is a special case...
495 If the event devices are valid then the joystick devices
496 will be duplicates but without extra information about their
497 hats or balls. Unfortunately, the event devices can't
498 currently be calibrated, so it's a win-lose situation.
499 So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
500 */
501 if ( (i == 0) && (numjoysticks > 0) )
502 break;
503#endif
504 }
505#ifndef NO_LOGICAL_JOYSTICKS
506 numjoysticks += CountLogicalJoysticks(numjoysticks);
507#endif
508
509 return(numjoysticks);
510}
511
512/* Function to get the device-dependent name of a joystick */
513const char *SDL_SYS_JoystickName(int index)
514{
515 int fd;
516 static char namebuf[128];
517 char *name;
518 SDL_logical_joydecl(int oindex = index);
519
520#ifndef NO_LOGICAL_JOYSTICKS
521 SDL_joylist_head(index, index);
522#endif
523 name = NULL;
524 fd = open(SDL_joylist[index].fname, O_RDONLY, 0);
525 if ( fd >= 0 ) {
526 if (
527#if SDL_INPUT_LINUXEV
528 (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&
529#endif
530 (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) {
531 name = SDL_joylist[index].fname;
532 } else {
533 name = namebuf;
534 }
535 close(fd);
536
537
538#ifndef NO_LOGICAL_JOYSTICKS
539 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex)
540 {
541 LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128);
542 }
543#endif
544 }
545 return name;
546}
547
548static int allocate_hatdata(SDL_Joystick *joystick)
549{
550 int i;
551
552 joystick->hwdata->hats = (struct hwdata_hat *)SDL_malloc(
553 joystick->nhats * sizeof(struct hwdata_hat));
554 if ( joystick->hwdata->hats == NULL ) {
555 return(-1);
556 }
557 for ( i=0; i<joystick->nhats; ++i ) {
558 joystick->hwdata->hats[i].axis[0] = 1;
559 joystick->hwdata->hats[i].axis[1] = 1;
560 }
561 return(0);
562}
563
564static int allocate_balldata(SDL_Joystick *joystick)
565{
566 int i;
567
568 joystick->hwdata->balls = (struct hwdata_ball *)SDL_malloc(
569 joystick->nballs * sizeof(struct hwdata_ball));
570 if ( joystick->hwdata->balls == NULL ) {
571 return(-1);
572 }
573 for ( i=0; i<joystick->nballs; ++i ) {
574 joystick->hwdata->balls[i].axis[0] = 0;
575 joystick->hwdata->balls[i].axis[1] = 0;
576 }
577 return(0);
578}
579
580static SDL_bool JS_ConfigJoystick(SDL_Joystick *joystick, int fd)
581{
582 SDL_bool handled;
583 unsigned char n;
584 int tmp_naxes, tmp_nhats, tmp_nballs;
585 const char *name;
586 char *env, env_name[128];
587 int i;
588
589 handled = SDL_FALSE;
590
591 /* Default joystick device settings */
592 if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) {
593 joystick->naxes = 2;
594 } else {
595 joystick->naxes = n;
596 }
597 if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
598 joystick->nbuttons = 2;
599 } else {
600 joystick->nbuttons = n;
601 }
602
603 name = SDL_SYS_JoystickName(joystick->index);
604
605 /* Generic analog joystick support */
606 if ( SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat") ) {
607 if ( SDL_sscanf(name,"Analog %d-axis %*d-button %d-hat",
608 &tmp_naxes, &tmp_nhats) == 2 ) {
609
610 joystick->naxes = tmp_naxes;
611 joystick->nhats = tmp_nhats;
612
613 handled = SDL_TRUE;
614 }
615 }
616
617 /* Special joystick support */
618 for ( i=0; i < SDL_arraysize(special_joysticks); ++i ) {
619 if ( SDL_strcmp(name, special_joysticks[i].name) == 0 ) {
620
621 joystick->naxes = special_joysticks[i].naxes;
622 joystick->nhats = special_joysticks[i].nhats;
623 joystick->nballs = special_joysticks[i].nballs;
624
625 handled = SDL_TRUE;
626 break;
627 }
628 }
629
630 /* User environment joystick support */
631 if ( (env = SDL_getenv("SDL_LINUX_JOYSTICK")) ) {
632 *env_name = '\0';
633 if ( *env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1 )
634 env += SDL_strlen(env_name)+2;
635 else if ( SDL_sscanf(env, "%s", env_name) == 1 )
636 env += SDL_strlen(env_name);
637
638 if ( SDL_strcmp(name, env_name) == 0 ) {
639
640 if ( SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats,
641 &tmp_nballs) == 3 ) {
642
643 joystick->naxes = tmp_naxes;
644 joystick->nhats = tmp_nhats;
645 joystick->nballs = tmp_nballs;
646
647 handled = SDL_TRUE;
648 }
649 }
650 }
651
652 /* Remap hats and balls */
653 if (handled) {
654 if ( joystick->nhats > 0 ) {
655 if ( allocate_hatdata(joystick) < 0 ) {
656 joystick->nhats = 0;
657 }
658 }
659 if ( joystick->nballs > 0 ) {
660 if ( allocate_balldata(joystick) < 0 ) {
661 joystick->nballs = 0;
662 }
663 }
664 }
665
666 return(handled);
667}
668
669#if SDL_INPUT_LINUXEV
670
671static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd)
672{
673 int i, t;
674 unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
675 unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
676 unsigned long relbit[NBITS(REL_MAX)] = { 0 };
677
678 /* See if this device uses the new unified event API */
679 if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
680 (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
681 (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) {
682 joystick->hwdata->is_hid = SDL_TRUE;
683
684 /* Get the number of buttons, axes, and other thingamajigs */
685 for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) {
686 if ( test_bit(i, keybit) ) {
687#ifdef DEBUG_INPUT_EVENTS
688 printf("Joystick has button: 0x%x\n", i);
689#endif
690 joystick->hwdata->key_map[i-BTN_MISC] =
691 joystick->nbuttons;
692 ++joystick->nbuttons;
693 }
694 }
695 for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) {
696 if ( test_bit(i, keybit) ) {
697#ifdef DEBUG_INPUT_EVENTS
698 printf("Joystick has button: 0x%x\n", i);
699#endif
700 joystick->hwdata->key_map[i-BTN_MISC] =
701 joystick->nbuttons;
702 ++joystick->nbuttons;
703 }
704 }
705 for ( i=0; i<ABS_MISC; ++i ) {
706 /* Skip hats */
707 if ( i == ABS_HAT0X ) {
708 i = ABS_HAT3Y;
709 continue;
710 }
711 if ( test_bit(i, absbit) ) {
712 struct input_absinfo absinfo;
713
714 if ( ioctl(fd, EVIOCGABS(i), &absinfo) < 0 )
715 continue;
716#ifdef DEBUG_INPUT_EVENTS
717 printf("Joystick has absolute axis: %x\n", i);
718 printf("Values = { %d, %d, %d, %d, %d }\n",
719 absinfo.value, absinfo.minimum,
720 absinfo.maximum, absinfo.fuzz, absinfo.flat);
721#endif /* DEBUG_INPUT_EVENTS */
722 joystick->hwdata->abs_map[i] = joystick->naxes;
723 if ( absinfo.minimum == absinfo.maximum ) {
724 joystick->hwdata->abs_correct[i].used = 0;
725 } else {
726 joystick->hwdata->abs_correct[i].used = 1;
727 joystick->hwdata->abs_correct[i].coef[0] =
728 (absinfo.maximum + absinfo.minimum) / 2 - absinfo.flat;
729 joystick->hwdata->abs_correct[i].coef[1] =
730 (absinfo.maximum + absinfo.minimum) / 2 + absinfo.flat;
731 t = ((absinfo.maximum - absinfo.minimum) / 2 - 2 * absinfo.flat);
732 if ( t != 0 ) {
733 joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / t;
734 } else {
735 joystick->hwdata->abs_correct[i].coef[2] = 0;
736 }
737 }
738 ++joystick->naxes;
739 }
740 }
741 for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) {
742 if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) {
743#ifdef DEBUG_INPUT_EVENTS
744 printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2);
745#endif
746 ++joystick->nhats;
747 }
748 }
749 if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) {
750 ++joystick->nballs;
751 }
752
753 /* Allocate data to keep track of these thingamajigs */
754 if ( joystick->nhats > 0 ) {
755 if ( allocate_hatdata(joystick) < 0 ) {
756 joystick->nhats = 0;
757 }
758 }
759 if ( joystick->nballs > 0 ) {
760 if ( allocate_balldata(joystick) < 0 ) {
761 joystick->nballs = 0;
762 }
763 }
764 }
765 return(joystick->hwdata->is_hid);
766}
767
768#endif /* SDL_INPUT_LINUXEV */
769
770#ifndef NO_LOGICAL_JOYSTICKS
771static void ConfigLogicalJoystick(SDL_Joystick *joystick)
772{
773 struct joystick_logical_layout* layout;
774
775 layout = SDL_joylist[joystick->index].map->layout +
776 SDL_joylist[joystick->index].logicalno;
777
778 joystick->nbuttons = layout->nbuttons;
779 joystick->nhats = layout->nhats;
780 joystick->naxes = layout->naxes;
781 joystick->nballs = layout->nballs;
782}
783#endif
784
785
786/* Function to open a joystick for use.
787 The joystick to open is specified by the index field of the joystick.
788 This should fill the nbuttons and naxes fields of the joystick structure.
789 It returns 0, or -1 if there is an error.
790 */
791int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
792{
793 int fd;
794 SDL_logical_joydecl(int realindex);
795 SDL_logical_joydecl(SDL_Joystick *realjoy = NULL);
796
797 /* Open the joystick and set the joystick file descriptor */
798#ifndef NO_LOGICAL_JOYSTICKS
799 if (SDL_joylist[joystick->index].fname == NULL) {
800 SDL_joylist_head(realindex, joystick->index);
801 realjoy = SDL_JoystickOpen(realindex);
802
803 if (realjoy == NULL)
804 return(-1);
805
806 fd = realjoy->hwdata->fd;
807
808 } else {
809 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
810 }
811 SDL_joylist[joystick->index].joy = joystick;
812#else
813 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
814#endif
815
816 if ( fd < 0 ) {
817 SDL_SetError("Unable to open %s\n",
818 SDL_joylist[joystick->index]);
819 return(-1);
820 }
821 joystick->hwdata = (struct joystick_hwdata *)
822 SDL_malloc(sizeof(*joystick->hwdata));
823 if ( joystick->hwdata == NULL ) {
824 SDL_OutOfMemory();
825 close(fd);
826 return(-1);
827 }
828 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
829 joystick->hwdata->fd = fd;
830
831 /* Set the joystick to non-blocking read mode */
832 fcntl(fd, F_SETFL, O_NONBLOCK);
833
834 /* Get the number of buttons and axes on the joystick */
835#ifndef NO_LOGICAL_JOYSTICKS
836 if (realjoy)
837 ConfigLogicalJoystick(joystick);
838 else
839#endif
840#if SDL_INPUT_LINUXEV
841 if ( ! EV_ConfigJoystick(joystick, fd) )
842#endif
843 JS_ConfigJoystick(joystick, fd);
844
845 return(0);
846}
847
848#ifndef NO_LOGICAL_JOYSTICKS
849
850static SDL_Joystick* FindLogicalJoystick(
851 SDL_Joystick *joystick, struct joystick_logical_mapping* v)
852{
853 SDL_Joystick *logicaljoy;
854 register int i;
855
856 i = joystick->index;
857 logicaljoy = NULL;
858
859 /* get the fake joystick that will receive the event
860 */
861 for(;;) {
862
863 if (SDL_joylist[i].logicalno == v->njoy) {
864 logicaljoy = SDL_joylist[i].joy;
865 break;
866 }
867
868 if (SDL_joylist[i].next == 0)
869 break;
870
871 i = SDL_joylist[i].next;
872
873 }
874
875 return logicaljoy;
876}
877
878static int LogicalJoystickButton(
879 SDL_Joystick *joystick, Uint8 button, Uint8 state){
880 struct joystick_logical_mapping* buttons;
881 SDL_Joystick *logicaljoy = NULL;
882
883 /* if there's no map then this is just a regular joystick
884 */
885 if (SDL_joylist[joystick->index].map == NULL)
886 return 0;
887
888 /* get the logical joystick that will receive the event
889 */
890 buttons = SDL_joylist[joystick->index].map->buttonmap+button;
891 logicaljoy = FindLogicalJoystick(joystick, buttons);
892
893 if (logicaljoy == NULL)
894 return 1;
895
896 SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state);
897
898 return 1;
899}
900
901static int LogicalJoystickAxis(
902 SDL_Joystick *joystick, Uint8 axis, Sint16 value)
903{
904 struct joystick_logical_mapping* axes;
905 SDL_Joystick *logicaljoy = NULL;
906
907 /* if there's no map then this is just a regular joystick
908 */
909 if (SDL_joylist[joystick->index].map == NULL)
910 return 0;
911
912 /* get the logical joystick that will receive the event
913 */
914 axes = SDL_joylist[joystick->index].map->axismap+axis;
915 logicaljoy = FindLogicalJoystick(joystick, axes);
916
917 if (logicaljoy == NULL)
918 return 1;
919
920 SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value);
921
922 return 1;
923}
924#endif /* USE_LOGICAL_JOYSTICKS */
925
926static __inline__
927void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
928{
929 struct hwdata_hat *the_hat;
930 const Uint8 position_map[3][3] = {
931 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
932 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
933 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
934 };
935 SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL);
936 SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL);
937
938 if (stick->nhats <= hat) {
939 return; /* whoops, that shouldn't happen! */
940 }
941
942 the_hat = &stick->hwdata->hats[hat];
943 if ( value < 0 ) {
944 value = 0;
945 } else
946 if ( value == 0 ) {
947 value = 1;
948 } else
949 if ( value > 0 ) {
950 value = 2;
951 }
952 if ( value != the_hat->axis[axis] ) {
953 the_hat->axis[axis] = value;
954
955#ifndef NO_LOGICAL_JOYSTICKS
956 /* if there's no map then this is just a regular joystick
957 */
958 if (SDL_joylist[stick->index].map != NULL) {
959
960 /* get the fake joystick that will receive the event
961 */
962 hats = SDL_joylist[stick->index].map->hatmap+hat;
963 logicaljoy = FindLogicalJoystick(stick, hats);
964 }
965
966 if (logicaljoy) {
967 stick = logicaljoy;
968 hat = hats->nthing;
969 }
970#endif /* USE_LOGICAL_JOYSTICKS */
971
972 SDL_PrivateJoystickHat(stick, hat,
973 position_map[the_hat->axis[1]][the_hat->axis[0]]);
974 }
975}
976
977static __inline__
978void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
979{
980 if ((stick->nballs <= ball) || (axis >= 2)) {
981 return; /* whoops, that shouldn't happen! */
982 }
983 stick->hwdata->balls[ball].axis[axis] += value;
984}
985
986/* Function to update the state of a joystick - called as a device poll.
987 * This function shouldn't update the joystick structure directly,
988 * but instead should call SDL_PrivateJoystick*() to deliver events
989 * and update joystick device state.
990 */
991static __inline__ void JS_HandleEvents(SDL_Joystick *joystick)
992{
993 struct js_event events[32];
994 int i, len;
995 Uint8 other_axis;
996
997#ifndef NO_LOGICAL_JOYSTICKS
998 if (SDL_joylist[joystick->index].fname == NULL) {
999 SDL_joylist_head(i, joystick->index);
1000 JS_HandleEvents(SDL_joylist[i].joy);
1001 return;
1002 }
1003#endif
1004
1005 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
1006 len /= sizeof(events[0]);
1007 for ( i=0; i<len; ++i ) {
1008 switch (events[i].type & ~JS_EVENT_INIT) {
1009 case JS_EVENT_AXIS:
1010 if ( events[i].number < joystick->naxes ) {
1011#ifndef NO_LOGICAL_JOYSTICKS
1012 if (!LogicalJoystickAxis(joystick,
1013 events[i].number, events[i].value))
1014#endif
1015 SDL_PrivateJoystickAxis(joystick,
1016 events[i].number, events[i].value);
1017 break;
1018 }
1019 events[i].number -= joystick->naxes;
1020 other_axis = (events[i].number / 2);
1021 if ( other_axis < joystick->nhats ) {
1022 HandleHat(joystick, other_axis,
1023 events[i].number%2,
1024 events[i].value);
1025 break;
1026 }
1027 events[i].number -= joystick->nhats*2;
1028 other_axis = (events[i].number / 2);
1029 if ( other_axis < joystick->nballs ) {
1030 HandleBall(joystick, other_axis,
1031 events[i].number%2,
1032 events[i].value);
1033 break;
1034 }
1035 break;
1036 case JS_EVENT_BUTTON:
1037#ifndef NO_LOGICAL_JOYSTICKS
1038 if (!LogicalJoystickButton(joystick,
1039 events[i].number, events[i].value))
1040#endif
1041 SDL_PrivateJoystickButton(joystick,
1042 events[i].number, events[i].value);
1043 break;
1044 default:
1045 /* ?? */
1046 break;
1047 }
1048 }
1049 }
1050}
1051#if SDL_INPUT_LINUXEV
1052static __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value)
1053{
1054 struct axis_correct *correct;
1055
1056 correct = &joystick->hwdata->abs_correct[which];
1057 if ( correct->used ) {
1058 if ( value > correct->coef[0] ) {
1059 if ( value < correct->coef[1] ) {
1060 return 0;
1061 }
1062 value -= correct->coef[1];
1063 } else {
1064 value -= correct->coef[0];
1065 }
1066 value *= correct->coef[2];
1067 value >>= 14;
1068 }
1069
1070 /* Clamp and return */
1071 if ( value < -32768 ) return -32768;
1072 if ( value > 32767 ) return 32767;
1073
1074 return value;
1075}
1076
1077static __inline__ void EV_HandleEvents(SDL_Joystick *joystick)
1078{
1079 struct input_event events[32];
1080 int i, len;
1081 int code;
1082
1083#ifndef NO_LOGICAL_JOYSTICKS
1084 if (SDL_joylist[joystick->index].fname == NULL) {
1085 SDL_joylist_head(i, joystick->index);
1086 return EV_HandleEvents(SDL_joylist[i].joy);
1087 }
1088#endif
1089
1090 while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
1091 len /= sizeof(events[0]);
1092 for ( i=0; i<len; ++i ) {
1093 code = events[i].code;
1094 switch (events[i].type) {
1095 case EV_KEY:
1096 if ( code >= BTN_MISC ) {
1097 code -= BTN_MISC;
1098#ifndef NO_LOGICAL_JOYSTICKS
1099 if (!LogicalJoystickButton(joystick,
1100 joystick->hwdata->key_map[code],
1101 events[i].value))
1102#endif
1103 SDL_PrivateJoystickButton(joystick,
1104 joystick->hwdata->key_map[code],
1105 events[i].value);
1106 }
1107 break;
1108 case EV_ABS:
1109 switch (code) {
1110 case ABS_HAT0X:
1111 case ABS_HAT0Y:
1112 case ABS_HAT1X:
1113 case ABS_HAT1Y:
1114 case ABS_HAT2X:
1115 case ABS_HAT2Y:
1116 case ABS_HAT3X:
1117 case ABS_HAT3Y:
1118 code -= ABS_HAT0X;
1119 HandleHat(joystick, code/2, code%2,
1120 events[i].value);
1121 break;
1122 default:
1123 events[i].value = EV_AxisCorrect(joystick, code, events[i].value);
1124#ifndef NO_LOGICAL_JOYSTICKS
1125 if (!LogicalJoystickAxis(joystick,
1126 joystick->hwdata->abs_map[code],
1127 events[i].value))
1128#endif
1129 SDL_PrivateJoystickAxis(joystick,
1130 joystick->hwdata->abs_map[code],
1131 events[i].value);
1132 break;
1133 }
1134 break;
1135 case EV_REL:
1136 switch (code) {
1137 case REL_X:
1138 case REL_Y:
1139 code -= REL_X;
1140 HandleBall(joystick, code/2, code%2,
1141 events[i].value);
1142 break;
1143 default:
1144 break;
1145 }
1146 break;
1147 default:
1148 break;
1149 }
1150 }
1151 }
1152}
1153#endif /* SDL_INPUT_LINUXEV */
1154
1155void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
1156{
1157 int i;
1158
1159#if SDL_INPUT_LINUXEV
1160 if ( joystick->hwdata->is_hid )
1161 EV_HandleEvents(joystick);
1162 else
1163#endif
1164 JS_HandleEvents(joystick);
1165
1166 /* Deliver ball motion updates */
1167 for ( i=0; i<joystick->nballs; ++i ) {
1168 int xrel, yrel;
1169
1170 xrel = joystick->hwdata->balls[i].axis[0];
1171 yrel = joystick->hwdata->balls[i].axis[1];
1172 if ( xrel || yrel ) {
1173 joystick->hwdata->balls[i].axis[0] = 0;
1174 joystick->hwdata->balls[i].axis[1] = 0;
1175 SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel);
1176 }
1177 }
1178}
1179
1180/* Function to close a joystick after use */
1181void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
1182{
1183#ifndef NO_LOGICAL_JOYSTICKS
1184 register int i;
1185 if (SDL_joylist[joystick->index].fname == NULL) {
1186 SDL_joylist_head(i, joystick->index);
1187 SDL_JoystickClose(SDL_joylist[i].joy);
1188 }
1189#endif
1190
1191 if ( joystick->hwdata ) {
1192#ifndef NO_LOGICAL_JOYSTICKS
1193 if (SDL_joylist[joystick->index].fname != NULL)
1194#endif
1195 close(joystick->hwdata->fd);
1196 if ( joystick->hwdata->hats ) {
1197 SDL_free(joystick->hwdata->hats);
1198 }
1199 if ( joystick->hwdata->balls ) {
1200 SDL_free(joystick->hwdata->balls);
1201 }
1202 SDL_free(joystick->hwdata);
1203 joystick->hwdata = NULL;
1204 }
1205}
1206
1207/* Function to perform any system-specific joystick related cleanup */
1208void SDL_SYS_JoystickQuit(void)
1209{
1210 int i;
1211
1212 for ( i=0; SDL_joylist[i].fname; ++i ) {
1213 SDL_free(SDL_joylist[i].fname);
1214 SDL_joylist[i].fname = NULL;
1215 }
1216}
1217
1218#endif /* SDL_JOYSTICK_LINUX */
diff --git a/apps/plugins/sdl/src/joystick/macos/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/macos/SDL_sysjoystick.c
deleted file mode 100644
index 3645dbd014..0000000000
--- a/apps/plugins/sdl/src/joystick/macos/SDL_sysjoystick.c
+++ /dev/null
@@ -1,320 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_MACOS
25
26/* SDL stuff -- "SDL_sysjoystick.c"
27 MacOS joystick functions by Frederick Reitberger
28
29 The code that follows is meant for SDL. Use at your own risk.
30*/
31
32#include <InputSprocket.h>
33
34#include "SDL_joystick.h"
35#include "../SDL_sysjoystick.h"
36#include "../SDL_joystick_c.h"
37
38
39/* The max number of joysticks we will detect */
40#define MAX_JOYSTICKS 16
41/* Limit ourselves to 32 elements per device */
42#define kMaxReferences 32
43
44#define ISpSymmetricAxisToFloat(axis) ((((float) axis) - kISpAxisMiddle) / (kISpAxisMaximum-kISpAxisMiddle))
45#define ISpAsymmetricAxisToFloat(axis) (((float) axis) / (kISpAxisMaximum))
46
47
48static ISpDeviceReference SYS_Joysticks[MAX_JOYSTICKS];
49static ISpElementListReference SYS_Elements[MAX_JOYSTICKS];
50static ISpDeviceDefinition SYS_DevDef[MAX_JOYSTICKS];
51
52struct joystick_hwdata
53{
54 char name[64];
55/* Uint8 id;*/
56 ISpElementReference refs[kMaxReferences];
57 /* gonna need some sort of mapping info */
58};
59
60
61/* Function to scan the system for joysticks.
62 * Joystick 0 should be the system default joystick.
63 * This function should return the number of available joysticks, or -1
64 * on an unrecoverable fatal error.
65 */
66int SDL_SYS_JoystickInit(void)
67{
68 static ISpDeviceClass classes[4] = {
69 kISpDeviceClass_Joystick,
70 #if kISpDeviceClass_Gamepad
71 kISpDeviceClass_Gamepad,
72 #endif
73 kISpDeviceClass_Wheel,
74 0
75 };
76 OSErr err;
77 int i;
78 UInt32 count, numJoysticks;
79
80 if ( (Ptr)0 == (Ptr)ISpStartup ) {
81 SDL_SetError("InputSprocket not installed");
82 return -1; // InputSprocket not installed
83 }
84
85 if( (Ptr)0 == (Ptr)ISpGetVersion ) {
86 SDL_SetError("InputSprocket not version 1.1 or newer");
87 return -1; // old version of ISp (not at least 1.1)
88 }
89
90 ISpStartup();
91
92 /* Get all the joysticks */
93 numJoysticks = 0;
94 for ( i=0; classes[i]; ++i ) {
95 count = 0;
96 err = ISpDevices_ExtractByClass(
97 classes[i],
98 MAX_JOYSTICKS-numJoysticks,
99 &count,
100 &SYS_Joysticks[numJoysticks]);
101 numJoysticks += count;
102 }
103
104 for(i = 0; i < numJoysticks; i++)
105 {
106 ISpDevice_GetDefinition(
107 SYS_Joysticks[i], sizeof(ISpDeviceDefinition),
108 &SYS_DevDef[i]);
109
110 err = ISpElementList_New(
111 0, NULL,
112 &SYS_Elements[i], 0);
113
114 if (err) {
115 SDL_OutOfMemory();
116 return -1;
117 }
118
119 ISpDevice_GetElementList(
120 SYS_Joysticks[i],
121 &SYS_Elements[i]);
122 }
123
124 ISpDevices_Deactivate(numJoysticks, SYS_Joysticks);
125
126 return numJoysticks;
127}
128
129/* Function to get the device-dependent name of a joystick */
130const char *SDL_SYS_JoystickName(int index)
131{
132 static char name[64];
133 int len;
134
135 /* convert pascal string to c-string */
136 len = SYS_DevDef[index].deviceName[0];
137 if ( len >= sizeof(name) ) {
138 len = (sizeof(name) - 1);
139 }
140 SDL_memcpy(name, &SYS_DevDef[index].deviceName[1], len);
141 name[len] = '\0';
142
143 return name;
144}
145
146/* Function to open a joystick for use.
147 The joystick to open is specified by the index field of the joystick.
148 This should fill the nbuttons and naxes fields of the joystick structure.
149 It returns 0, or -1 if there is an error.
150 */
151int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
152{
153 int index;
154 UInt32 count, gotCount, count2;
155 long numAxis, numButtons, numHats, numBalls;
156
157 count = kMaxReferences;
158 count2 = 0;
159 numAxis = numButtons = numHats = numBalls = 0;
160
161 index = joystick->index;
162
163 /* allocate memory for system specific hardware data */
164 joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
165 if (joystick->hwdata == NULL)
166 {
167 SDL_OutOfMemory();
168 return(-1);
169 }
170 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
171 SDL_strlcpy(joystick->hwdata->name, SDL_SYS_JoystickName(index), SDL_arraysize(joystick->hwdata->name));
172 joystick->name = joystick->hwdata->name;
173
174 ISpElementList_ExtractByKind(
175 SYS_Elements[index],
176 kISpElementKind_Axis,
177 count,
178 &gotCount,
179 joystick->hwdata->refs);
180
181 numAxis = gotCount;
182 count -= gotCount;
183 count2 += gotCount;
184
185 ISpElementList_ExtractByKind(
186 SYS_Elements[index],
187 kISpElementKind_DPad,
188 count,
189 &gotCount,
190 &(joystick->hwdata->refs[count2]));
191
192 numHats = gotCount;
193 count -= gotCount;
194 count2 += gotCount;
195
196 ISpElementList_ExtractByKind(
197 SYS_Elements[index],
198 kISpElementKind_Button,
199 count,
200 &gotCount,
201 &(joystick->hwdata->refs[count2]));
202
203 numButtons = gotCount;
204 count -= gotCount;
205 count2 += gotCount;
206
207 joystick->naxes = numAxis;
208 joystick->nhats = numHats;
209 joystick->nballs = numBalls;
210 joystick->nbuttons = numButtons;
211
212 ISpDevices_Activate(
213 1,
214 &SYS_Joysticks[index]);
215
216 return 0;
217}
218
219/* Function to update the state of a joystick - called as a device poll.
220 * This function shouldn't update the joystick structure directly,
221 * but instead should call SDL_PrivateJoystick*() to deliver events
222 * and update joystick device state.
223 */
224void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
225{
226 int i, j;
227 ISpAxisData a;
228 ISpDPadData b;
229 //ISpDeltaData c;
230 ISpButtonData d;
231
232 for(i = 0, j = 0; i < joystick->naxes; i++, j++)
233 {
234 Sint16 value;
235
236 ISpElement_GetSimpleState(
237 joystick->hwdata->refs[j],
238 &a);
239 value = (ISpSymmetricAxisToFloat(a)* 32767.0);
240 if ( value != joystick->axes[i] ) {
241 SDL_PrivateJoystickAxis(joystick, i, value);
242 }
243 }
244
245 for(i = 0; i < joystick->nhats; i++, j++)
246 {
247 Uint8 pos;
248
249 ISpElement_GetSimpleState(
250 joystick->hwdata->refs[j],
251 &b);
252 switch(b) {
253 case kISpPadIdle:
254 pos = SDL_HAT_CENTERED;
255 break;
256 case kISpPadLeft:
257 pos = SDL_HAT_LEFT;
258 break;
259 case kISpPadUpLeft:
260 pos = SDL_HAT_LEFTUP;
261 break;
262 case kISpPadUp:
263 pos = SDL_HAT_UP;
264 break;
265 case kISpPadUpRight:
266 pos = SDL_HAT_RIGHTUP;
267 break;
268 case kISpPadRight:
269 pos = SDL_HAT_RIGHT;
270 break;
271 case kISpPadDownRight:
272 pos = SDL_HAT_RIGHTDOWN;
273 break;
274 case kISpPadDown:
275 pos = SDL_HAT_DOWN;
276 break;
277 case kISpPadDownLeft:
278 pos = SDL_HAT_LEFTDOWN;
279 break;
280 }
281 if ( pos != joystick->hats[i] ) {
282 SDL_PrivateJoystickHat(joystick, i, pos);
283 }
284 }
285
286 for(i = 0; i < joystick->nballs; i++, j++)
287 {
288 /* ignore balls right now */
289 }
290
291 for(i = 0; i < joystick->nbuttons; i++, j++)
292 {
293 ISpElement_GetSimpleState(
294 joystick->hwdata->refs[j],
295 &d);
296 if ( d != joystick->buttons[i] ) {
297 SDL_PrivateJoystickButton(joystick, i, d);
298 }
299 }
300}
301
302/* Function to close a joystick after use */
303void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
304{
305 int index;
306
307 index = joystick->index;
308
309 ISpDevices_Deactivate(
310 1,
311 &SYS_Joysticks[index]);
312}
313
314/* Function to perform any system-specific joystick related cleanup */
315void SDL_SYS_JoystickQuit(void)
316{
317 ISpShutdown();
318}
319
320#endif /* SDL_JOYSTICK_MACOS */
diff --git a/apps/plugins/sdl/src/joystick/mint/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/mint/SDL_sysjoystick.c
deleted file mode 100644
index 9a36152927..0000000000
--- a/apps/plugins/sdl/src/joystick/mint/SDL_sysjoystick.c
+++ /dev/null
@@ -1,826 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_MINT
25
26/*
27 * Atari Joystick/Joypad drivers
28 *
29 * Patrice Mandin
30 */
31
32#include <mint/cookie.h>
33#include <mint/osbind.h>
34
35#include "SDL_events.h"
36#include "../SDL_sysjoystick.h"
37#include "../SDL_joystick_c.h"
38
39#include "../../video/ataricommon/SDL_ikbdinterrupt_s.h"
40#include "../../video/ataricommon/SDL_xbiosevents_c.h"
41#include "../../video/ataricommon/SDL_xbiosinterrupt_s.h"
42
43/*--- Const ---*/
44
45/* We can have:
46 1 joystick on IKBD port 1, read via hardware I/O
47 or same joystick on IKBD port 1, read via xbios
48 1 joypad on port A (up to 4 with teamtap)
49 or 2 joysticks on joypad port A
50 or 1 analog paddle on joypad port A
51 or 1 lightpen on joypad port A
52 1 joypad on port B (up to 4 with teamtap)
53 or 2 joysticks on joypad port B
54 or 1 analog paddle on joypad port B
55 2 joysticks on parallel port
56*/
57
58enum {
59 IKBD_JOY1=0,
60 XBIOS_JOY1,
61 PORTA_PAD0,
62 PORTA_PAD1,
63 PORTA_PAD2,
64 PORTA_PAD3,
65 PORTB_PAD0,
66 PORTB_PAD1,
67 PORTB_PAD2,
68 PORTB_PAD3,
69 PORTA_JOY0,
70 PORTA_JOY1,
71 PORTB_JOY0,
72 PORTB_JOY1,
73 PORTA_LP,
74 PORTA_ANPAD,
75 PORTB_ANPAD,
76#if 0
77 PARA_JOY0,
78 PARA_JOY1,
79#endif
80 MAX_JOYSTICKS
81};
82
83enum {
84 MCH_ST=0,
85 MCH_STE,
86 MCH_TT,
87 MCH_F30,
88 MCH_CLONE,
89 MCH_ARANYM
90};
91
92/* Joypad buttons
93 * Procontroller note:
94 * L,R are connected to 4,6
95 * X,Y,Z are connected to 7,8,9
96 */
97
98enum {
99 JP_UP=0, JP_DOWN, JP_LEFT, JP_RIGHT,
100 JP_KPMULT, JP_KP7, JP_KP4, JP_KP1,
101 JP_KP0, JP_KP8, JP_KP5, JP_KP2,
102 JP_KPNUM, JP_KP9, JP_KP6, JP_KP3,
103 JP_PAUSE, JP_FIRE0, JP_UNDEF0, JP_FIRE1,
104 JP_UNDEF1, JP_FIRE2, JP_UNDEF2, JP_OPTION
105};
106
107#define JP_NUM_BUTTONS 17
108
109#define PORT_JS_RIGHT (1<<0)
110#define PORT_JS_LEFT (1<<1)
111#define PORT_JS_DOWN (1<<2)
112#define PORT_JS_UP (1<<3)
113#define PORT_JS_FIRE (1<<4)
114
115enum {
116 TEAMTAP_MAYBE=0,
117 TEAMTAP_YES,
118 TEAMTAP_NO
119};
120
121/* Teamtap detection values */
122static const Uint32 teamtap_ghosts[20][4]={
123 {1<<JP_UP, /* for this event on joypad 0, port X */
124 (1<<JP_UP)|(1<<JP_KP0), /* we get this on joypad 1 */
125 (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KP0), /* this on joypad 2 */
126 (1<<JP_KPMULT)|(1<<JP_KP0)}, /* this on joypad 3 */
127 {1<<JP_DOWN,
128 (1<<JP_DOWN)|(1<<JP_KP8),
129 (1<<JP_DOWN)|(1<<JP_KP9)|(1<<JP_KP8),
130 (1<<JP_KP7)|(1<<JP_KP8)},
131 {1<<JP_LEFT,
132 (1<<JP_LEFT)|(1<<JP_KP5),
133 (1<<JP_LEFT)|(1<<JP_KP6)|(1<<JP_KP5),
134 (1<<JP_KP4)|(1<<JP_KP5)},
135 {1<<JP_RIGHT,
136 (1<<JP_RIGHT)|(1<<JP_KP2),
137 (1<<JP_RIGHT)|(1<<JP_KP3)|(1<<JP_KP2),
138 (1<<JP_KP1)|(1<<JP_KP2)},
139 {1<<JP_OPTION,
140 (1<<JP_OPTION)|(1<<JP_FIRE1)|(1<<JP_FIRE2),
141 (1<<JP_FIRE0)|(1<<JP_FIRE1)|(1<<JP_FIRE2),
142 0},
143 {1<<JP_FIRE0,
144 (1<<JP_FIRE2)|(1<<JP_FIRE0),
145 (1<<JP_FIRE0)|(1<<JP_OPTION)|(1<<JP_FIRE2),
146 (1<<JP_FIRE1)|(1<<JP_FIRE2)},
147 {1<<JP_FIRE1,
148 (1<<JP_FIRE0),
149 (1<<JP_OPTION)|(1<<JP_FIRE0)|(1<<JP_FIRE1),
150 (1<<JP_FIRE0)|(1<<JP_FIRE2)},
151 {1<<JP_FIRE2,
152 (1<<JP_OPTION)|(1<<JP_FIRE0)|(1<<JP_FIRE1)|(1<<JP_FIRE2),
153 (1<<JP_OPTION),
154 (1<<JP_FIRE0)|(1<<JP_FIRE1)},
155 {1<<JP_KP1,
156 (1<<JP_RIGHT)|(1<<JP_KP1),
157 (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP3),
158 (1<<JP_RIGHT)|(1<<JP_KP2)},
159 {1<<JP_KP2,
160 (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2)|(1<<JP_KP3),
161 (1<<JP_KP3),
162 (1<<JP_RIGHT)|(1<<JP_KP1)},
163 {1<<JP_KP3,
164 (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2)|(1<<JP_KP3),
165 (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2),
166 0},
167 {1<<JP_KP4,
168 (1<<JP_LEFT)|(1<<JP_KP4),
169 (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP6),
170 (1<<JP_LEFT)|(1<<JP_KP5)},
171 {1<<JP_KP5,
172 (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5)|(1<<JP_KP6),
173 (1<<JP_KP6),
174 (1<<JP_LEFT)|(1<<JP_KP4)},
175 {1<<JP_KP6,
176 (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5)|(1<<JP_KP6),
177 (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5),
178 0},
179 {1<<JP_KP7,
180 (1<<JP_DOWN)|(1<<JP_KP7),
181 (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP9),
182 (1<<JP_DOWN)|(1<<JP_KP8)},
183 {1<<JP_KP8,
184 (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8)|(1<<JP_KP9),
185 (1<<JP_KP9),
186 (1<<JP_DOWN)|(1<<JP_KP7)},
187 {1<<JP_KP9,
188 (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8)|(1<<JP_KP9),
189 (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8),
190 0},
191 {1<<JP_KPMULT,
192 (1<<JP_UP)|(1<<JP_KPMULT),
193 (1<<JP_UP)|(1<<JP_KPNUM),
194 (1<<JP_UP)|(1<<JP_KP0)},
195 {1<<JP_KP0,
196 (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KPMULT)|(1<<JP_KP0),
197 1<<JP_KPNUM,
198 (1<<JP_UP)|(1<<JP_KPMULT)},
199 {1<<JP_KPNUM,
200 (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KPMULT)|(1<<JP_KP0),
201 (1<<JP_UP)|(1<<JP_KPMULT)|(1<<JP_KP0),
202 0},
203};
204
205/*--- Types ---*/
206
207typedef struct {
208 SDL_bool enabled;
209 char *name;
210 Uint32 prevstate;
211} atarijoy_t;
212
213/*--- Variables ---*/
214
215static atarijoy_t atarijoysticks[MAX_JOYSTICKS]={
216 {SDL_FALSE,"IKBD joystick port 1",0},
217 {SDL_FALSE,"Xbios joystick port 1",0},
218 {SDL_FALSE,"Joypad 0 port A",0},
219 {SDL_FALSE,"Joypad 1 port A",0},
220 {SDL_FALSE,"Joypad 2 port A",0},
221 {SDL_FALSE,"Joypad 3 port A",0},
222 {SDL_FALSE,"Joypad 0 port B",0},
223 {SDL_FALSE,"Joypad 1 port B",0},
224 {SDL_FALSE,"Joypad 2 port B",0},
225 {SDL_FALSE,"Joypad 3 port B",0},
226 {SDL_FALSE,"Joystick 0 port A",0},
227 {SDL_FALSE,"Joystick 1 port A",0},
228 {SDL_FALSE,"Joystick 0 port B",0},
229 {SDL_FALSE,"Joystick 1 port B",0},
230 {SDL_FALSE,"Lightpen port A",0},
231 {SDL_FALSE,"Analog paddle port A",0},
232 {SDL_FALSE,"Analog paddle port B",0}
233#if 0
234 ,{SDL_FALSE,"Joystick 0 parallel port",0},
235 {SDL_FALSE,"Joystick 1 parallel port",0}
236#endif
237};
238
239static const int jp_buttons[JP_NUM_BUTTONS]={
240 JP_FIRE0, JP_FIRE1, JP_FIRE2, JP_PAUSE,
241 JP_OPTION, JP_KPMULT, JP_KPNUM, JP_KP0,
242 JP_KP1, JP_KP2, JP_KP3, JP_KP4,
243 JP_KP5, JP_KP6, JP_KP7, JP_KP8,
244 JP_KP9
245};
246
247static SDL_bool joypad_ports_enabled=SDL_FALSE;
248static int has_teamtap[2]={TEAMTAP_MAYBE,TEAMTAP_MAYBE};
249
250/* Updated joypad ports */
251static Uint16 jp_paddles[4];
252static Uint16 jp_lightpens[2];
253static Uint16 jp_directions;
254static Uint16 jp_fires;
255static Uint32 jp_joypads[8];
256
257/*--- Functions prototypes ---*/
258
259static int GetEnabledAtariJoystick(int index);
260static void UpdateJoypads(void);
261
262/*--- Functions ---*/
263
264int SDL_SYS_JoystickInit(void)
265{
266 int i;
267 long cookie_mch;
268 const char *envr=SDL_getenv("SDL_JOYSTICK_ATARI");
269
270#define TEST_JOY_ENABLED(env,idstring,num) \
271 if (SDL_strstr(env,idstring"-off")) { \
272 atarijoysticks[num].enabled=SDL_FALSE; \
273 } \
274 if (SDL_strstr(env,idstring"-on")) { \
275 atarijoysticks[num].enabled=SDL_TRUE; \
276 }
277
278 /* Cookie _MCH present ? if not, assume ST machine */
279 if (Getcookie(C__MCH, &cookie_mch) != C_FOUND) {
280 cookie_mch = MCH_ST << 16;
281 }
282
283 /* Enable some default joysticks */
284 if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) ||
285 (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16) ||
286 (cookie_mch == MCH_ARANYM<<16))
287 {
288 atarijoysticks[IKBD_JOY1].enabled=(SDL_AtariIkbd_enabled!=0);
289 }
290 if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16) ||
291 (cookie_mch == MCH_ARANYM<<16))
292 {
293 atarijoysticks[PORTA_PAD0].enabled =
294 atarijoysticks[PORTA_PAD1].enabled =
295 atarijoysticks[PORTA_PAD2].enabled =
296 atarijoysticks[PORTA_PAD3].enabled =
297 atarijoysticks[PORTB_PAD0].enabled =
298 atarijoysticks[PORTB_PAD1].enabled =
299 atarijoysticks[PORTB_PAD2].enabled =
300 atarijoysticks[PORTB_PAD3].enabled = SDL_TRUE;
301 }
302 if (!atarijoysticks[IKBD_JOY1].enabled) {
303 atarijoysticks[XBIOS_JOY1].enabled=(SDL_AtariXbios_enabled!=0);
304 }
305
306 /* Read environment for joysticks to enable */
307 if (envr) {
308 /* IKBD on any Atari, maybe clones */
309 if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) ||
310 (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16) ||
311 (cookie_mch == MCH_ARANYM<<16)) {
312 if (SDL_AtariIkbd_enabled!=0) {
313 TEST_JOY_ENABLED(envr, "ikbd-joy1", IKBD_JOY1);
314 }
315 }
316 /* Joypads ports on STE, Falcon and maybe others */
317 if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16) ||
318 (cookie_mch == MCH_ARANYM<<16)) {
319 TEST_JOY_ENABLED(envr, "porta-pad", PORTA_PAD0);
320 if (!atarijoysticks[PORTA_PAD0].enabled) {
321 TEST_JOY_ENABLED(envr, "porta-joy0", PORTA_JOY0);
322 TEST_JOY_ENABLED(envr, "porta-joy1", PORTA_JOY1);
323 if (!(atarijoysticks[PORTA_JOY0].enabled) && !(atarijoysticks[PORTA_JOY1].enabled)) {
324 TEST_JOY_ENABLED(envr, "porta-lp", PORTA_LP);
325 if (!atarijoysticks[PORTA_LP].enabled) {
326 TEST_JOY_ENABLED(envr, "porta-anpad", PORTA_ANPAD);
327 }
328 }
329 }
330
331 TEST_JOY_ENABLED(envr, "portb-pad", PORTB_PAD0);
332 if (!atarijoysticks[PORTB_PAD0].enabled) {
333 TEST_JOY_ENABLED(envr, "portb-joy0", PORTB_JOY0);
334 TEST_JOY_ENABLED(envr, "portb-joy1", PORTB_JOY1);
335 if (!(atarijoysticks[PORTB_JOY0].enabled) && !(atarijoysticks[PORTB_JOY1].enabled)) {
336 TEST_JOY_ENABLED(envr, "portb-anpad", PORTB_ANPAD);
337 }
338 }
339 }
340
341 if (!atarijoysticks[IKBD_JOY1].enabled) {
342 if (SDL_AtariXbios_enabled!=0) {
343 TEST_JOY_ENABLED(envr, "xbios-joy1", XBIOS_JOY1);
344 }
345 }
346#if 0
347 /* Parallel port on any Atari, maybe clones */
348 if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) ||
349 (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16)) {
350 TEST_JOY_ENABLED(envr, "para-joy0", PARA_JOY0);
351 TEST_JOY_ENABLED(envr, "para-joy1", PARA_JOY1);
352 }
353#endif
354 }
355
356 /* Need to update joypad ports ? */
357 joypad_ports_enabled=SDL_FALSE;
358 for (i=PORTA_PAD0;i<=PORTB_ANPAD;i++) {
359 if (atarijoysticks[i].enabled) {
360 joypad_ports_enabled=SDL_TRUE;
361 break;
362 }
363 }
364
365 SDL_numjoysticks = 0;
366 for (i=0;i<MAX_JOYSTICKS;i++) {
367 if (atarijoysticks[i].enabled) {
368 ++SDL_numjoysticks;
369 }
370 }
371
372 return(SDL_numjoysticks);
373}
374
375static int GetEnabledAtariJoystick(int index)
376{
377 int i,j;
378
379 /* Return the nth'index' enabled atari joystick */
380 j=0;
381 for (i=0;i<MAX_JOYSTICKS;i++) {
382 if (!atarijoysticks[i].enabled) {
383 continue;
384 }
385
386 if (j==index) {
387 break;
388 }
389
390 ++j;
391 }
392 if (i==MAX_JOYSTICKS)
393 return -1;
394
395 return i;
396}
397
398const char *SDL_SYS_JoystickName(int index)
399{
400 int numjoystick;
401
402 numjoystick=GetEnabledAtariJoystick(index);
403 if (numjoystick==-1)
404 return NULL;
405
406 return(atarijoysticks[numjoystick].name);
407}
408
409int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
410{
411 int numjoystick;
412
413 numjoystick=GetEnabledAtariJoystick(joystick->index);
414 if (numjoystick==-1)
415 return -1;
416
417 joystick->naxes=0;
418 joystick->nhats=0;
419 joystick->nballs=0;
420
421 switch(numjoystick) {
422 case PORTA_PAD0:
423 case PORTA_PAD1:
424 case PORTA_PAD2:
425 case PORTA_PAD3:
426 case PORTB_PAD0:
427 case PORTB_PAD1:
428 case PORTB_PAD2:
429 case PORTB_PAD3:
430 joystick->nhats=1;
431 joystick->nbuttons=JP_NUM_BUTTONS;
432 break;
433 case PORTA_LP:
434 case PORTA_ANPAD:
435 case PORTB_ANPAD:
436 joystick->naxes=2;
437 joystick->nbuttons=2;
438 break;
439 default:
440 joystick->nhats=1;
441 joystick->nbuttons=1;
442 break;
443 }
444
445 return(0);
446}
447
448/* Detect Teamtap using ghost events */
449static void detect_teamtap(int num_port)
450{
451 int i,j;
452
453 /* Check if joypad 1,2,3 triggered but not 0 */
454 for (i=1; i<4; i++) {
455 if (jp_joypads[num_port*4+i] && (jp_joypads[num_port*4]==0)) {
456 has_teamtap[num_port] = TEAMTAP_YES;
457 return;
458 }
459 }
460
461 /* Check if joypad 0 on a given port triggered ghost events for
462 * other joypads
463 */
464 for (i=0; i<20; i++) {
465 int with_teamtap=1;
466
467 if (jp_joypads[num_port*4]!=teamtap_ghosts[i][0])
468 continue;
469
470 /* If any button on first joypad pressed, check other pads */
471 for (j=1; j<4; j++) {
472 if ((jp_joypads[num_port*4+j] & teamtap_ghosts[i][j])
473 ==teamtap_ghosts[i][j])
474 {
475 with_teamtap = 0;
476 }
477 }
478
479 has_teamtap[num_port] = (with_teamtap ? TEAMTAP_YES : TEAMTAP_NO);
480 break;
481 }
482}
483
484void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
485{
486 int numjoystick;
487 Uint8 hatstate;
488 Uint32 curstate,prevstate;
489
490 numjoystick=GetEnabledAtariJoystick(joystick->index);
491 if (numjoystick==-1)
492 return;
493
494 prevstate = atarijoysticks[numjoystick].prevstate;
495
496 if (joypad_ports_enabled) {
497 Supexec(UpdateJoypads);
498 }
499
500 switch (numjoystick) {
501 case IKBD_JOY1:
502 case XBIOS_JOY1:
503 {
504 curstate = 0;
505
506 if (numjoystick==IKBD_JOY1) {
507 curstate = SDL_AtariIkbd_joystick & 0xff;
508 }
509 if (numjoystick==XBIOS_JOY1) {
510 curstate = SDL_AtariXbios_joystick & 0xff;
511 }
512
513 if (curstate != prevstate) {
514 hatstate = SDL_HAT_CENTERED;
515 if (curstate & IKBD_JOY_LEFT) {
516 hatstate |= SDL_HAT_LEFT;
517 }
518 if (curstate & IKBD_JOY_RIGHT) {
519 hatstate |= SDL_HAT_RIGHT;
520 }
521 if (curstate & IKBD_JOY_UP) {
522 hatstate |= SDL_HAT_UP;
523 }
524 if (curstate & IKBD_JOY_DOWN) {
525 hatstate |= SDL_HAT_DOWN;
526 }
527 SDL_PrivateJoystickHat(joystick, 0, hatstate);
528
529 /* Button */
530 if ((curstate & IKBD_JOY_FIRE) && !(prevstate & IKBD_JOY_FIRE)) {
531 SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED);
532 }
533 if (!(curstate & IKBD_JOY_FIRE) && (prevstate & IKBD_JOY_FIRE)) {
534 SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED);
535 }
536 }
537 atarijoysticks[numjoystick].prevstate = curstate;
538 }
539 break;
540 case PORTA_PAD0:
541 case PORTA_PAD1:
542 case PORTA_PAD2:
543 case PORTA_PAD3:
544 case PORTB_PAD0:
545 case PORTB_PAD1:
546 case PORTB_PAD2:
547 case PORTB_PAD3:
548 {
549 int numjoypad,i,numport;
550
551 numjoypad = numport = 0;
552 switch(numjoystick) {
553 case PORTA_PAD0:
554 numjoypad = 0; break;
555 case PORTA_PAD1:
556 numjoypad = 1; break;
557 case PORTA_PAD2:
558 numjoypad = 2; break;
559 case PORTA_PAD3:
560 numjoypad = 3; break;
561 case PORTB_PAD0:
562 numjoypad = 4; numport = 1; break;
563 case PORTB_PAD1:
564 numjoypad = 5; numport = 1; break;
565 case PORTB_PAD2:
566 numjoypad = 6; numport = 1; break;
567 case PORTB_PAD3:
568 numjoypad = 7; numport = 1; break;
569 }
570
571 jp_joypads[numjoypad] &= 0xabffff;
572
573 if (has_teamtap[numport]==TEAMTAP_MAYBE) {
574 detect_teamtap(numport);
575 }
576 /* No events for PORTX_PAD[1,2,3] if no teamtap detected */
577 if (has_teamtap[numport] == TEAMTAP_NO) {
578 if ((numjoypad & 3)!=0) {
579 return;
580 }
581 }
582
583 curstate=jp_joypads[numjoypad];
584 if (curstate!=prevstate) {
585 hatstate = SDL_HAT_CENTERED;
586 if (curstate & (1<<JP_LEFT)) {
587 hatstate |= SDL_HAT_LEFT;
588 }
589 if (curstate & (1<<JP_RIGHT)) {
590 hatstate |= SDL_HAT_RIGHT;
591 }
592 if (curstate & (1<<JP_UP)) {
593 hatstate |= SDL_HAT_UP;
594 }
595 if (curstate & (1<<JP_DOWN)) {
596 hatstate |= SDL_HAT_DOWN;
597 }
598 SDL_PrivateJoystickHat(joystick, 0, hatstate);
599
600 /* Buttons */
601 for (i=0;i<JP_NUM_BUTTONS;i++) {
602 int button;
603
604 button=1<<jp_buttons[i];
605
606 if ((curstate & button) && !(prevstate & button)) {
607 SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
608 }
609 if (!(curstate & button) && (prevstate & button)) {
610 SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
611 }
612 }
613 }
614 atarijoysticks[numjoystick].prevstate = curstate;
615 }
616 break;
617 case PORTA_JOY0:
618 case PORTA_JOY1:
619 case PORTB_JOY0:
620 case PORTB_JOY1:
621 {
622 int fire_shift=0,dir_shift=0;
623
624 if (numjoystick==PORTA_JOY0) { fire_shift=0; dir_shift=0; }
625 if (numjoystick==PORTA_JOY1) { fire_shift=1; dir_shift=4; }
626 if (numjoystick==PORTB_JOY0) { fire_shift=2; dir_shift=8; }
627 if (numjoystick==PORTB_JOY1) { fire_shift=3; dir_shift=12; }
628
629 curstate = (jp_directions>>dir_shift) & 15;
630 curstate |= ((jp_fires>>fire_shift) & 1)<<4;
631
632 if (curstate != prevstate) {
633 hatstate = SDL_HAT_CENTERED;
634 if (curstate & PORT_JS_LEFT) {
635 hatstate |= SDL_HAT_LEFT;
636 }
637 if (curstate & PORT_JS_RIGHT) {
638 hatstate |= SDL_HAT_RIGHT;
639 }
640 if (curstate & PORT_JS_UP) {
641 hatstate |= SDL_HAT_UP;
642 }
643 if (curstate & PORT_JS_DOWN) {
644 hatstate |= SDL_HAT_DOWN;
645 }
646 SDL_PrivateJoystickHat(joystick, 0, hatstate);
647
648 /* Button */
649 if ((curstate & PORT_JS_FIRE) && !(prevstate & PORT_JS_FIRE)) {
650 SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED);
651 }
652 if (!(curstate & PORT_JS_FIRE) && (prevstate & PORT_JS_FIRE)) {
653 SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED);
654 }
655 }
656 atarijoysticks[numjoystick].prevstate = curstate;
657 }
658 break;
659 case PORTA_LP:
660 {
661 int i;
662
663 curstate = jp_lightpens[0]>>1;
664 curstate |= (jp_lightpens[1]>>1)<<15;
665 curstate |= (jp_fires & 3)<<30;
666
667 if (curstate != prevstate) {
668 /* X axis */
669 SDL_PrivateJoystickAxis(joystick,0,jp_lightpens[0] ^ 0x8000);
670 /* Y axis */
671 SDL_PrivateJoystickAxis(joystick,1,jp_lightpens[1] ^ 0x8000);
672 /* Buttons */
673 for (i=0;i<2;i++) {
674 int button;
675
676 button=1<<(30+i);
677
678 if ((curstate & button) && !(prevstate & button)) {
679 SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
680 }
681 if (!(curstate & button) && (prevstate & button)) {
682 SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
683 }
684 }
685 }
686 atarijoysticks[numjoystick].prevstate = curstate;
687 }
688 break;
689 case PORTA_ANPAD:
690 case PORTB_ANPAD:
691 {
692 int numpaddle, i;
693
694 numpaddle=0<<1;
695 if (numjoystick==PORTB_ANPAD) numpaddle=1<<1;
696
697 curstate = jp_paddles[numpaddle]>>1;
698 curstate |= (jp_paddles[numpaddle+1]>>1)<<15;
699 curstate |= ((jp_fires>>numpaddle) & 3)<<30;
700
701 if (curstate != prevstate) {
702 /* X axis */
703 SDL_PrivateJoystickAxis(joystick,0,jp_paddles[numpaddle] ^ 0x8000);
704 /* Y axis */
705 SDL_PrivateJoystickAxis(joystick,1,jp_paddles[numpaddle+1] ^ 0x8000);
706 /* Buttons */
707 for (i=0;i<2;i++) {
708 int button;
709
710 button=1<<(30+i);
711
712 if ((curstate & button) && !(prevstate & button)) {
713 SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
714 }
715 if (!(curstate & button) && (prevstate & button)) {
716 SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
717 }
718 }
719 }
720 atarijoysticks[numjoystick].prevstate = curstate;
721 }
722 break;
723#if 0
724 case PARA_JOY0:
725 case PARA_JOY1:
726 break;
727#endif
728 };
729
730 return;
731}
732
733void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
734{
735 return;
736}
737
738void SDL_SYS_JoystickQuit(void)
739{
740 SDL_numjoysticks=0;
741 return;
742}
743
744/*--- Joypad I/O read/write interface ---*/
745
746#define JOYPAD_IO_BASE (0xffff9200)
747struct JOYPAD_IO_S {
748 Uint16 fires;
749 Uint16 directions;
750 Uint16 dummy1[6];
751 Uint16 paddles[4];
752 Uint16 dummy2[4];
753 Uint16 lightpens[2];
754};
755#define JOYPAD_IO ((*(volatile struct JOYPAD_IO_S *)JOYPAD_IO_BASE))
756
757static const Uint16 joypad_masks[8*4]={
758 0xfffe, 0xfffd, 0xfffb, 0xfff7,
759 0xfff0, 0xfff1, 0xfff2, 0xfff3,
760 0xfff4, 0xfff5, 0xfff6, 0xfff8,
761 0xfff9, 0xfffa, 0xfffc, 0xffff,
762 0xffef, 0xffdf, 0xffbf, 0xff7f,
763 0xff0f, 0xff1f, 0xff2f, 0xff3f,
764 0xff4f, 0xff5f, 0xff6f, 0xff8f,
765 0xff9f, 0xffaf, 0xffcf, 0xffff
766};
767
768static void UpdateJoypads(void)
769{
770 Uint16 tmp, i, j;
771 Uint32 cur_fire, cur_dir;
772
773 /*--- This function is called in supervisor mode ---*/
774
775 /* Update joysticks */
776 jp_fires = (~(JOYPAD_IO.fires)) & 15;
777 jp_directions = (~(JOYPAD_IO.directions));
778
779 /* Update lightpen */
780 tmp = JOYPAD_IO.lightpens[0] & 1023;
781 jp_lightpens[0] = (tmp<<6) | (tmp>>4);
782 tmp = JOYPAD_IO.lightpens[1] & 1023;
783 jp_lightpens[1] = (tmp<<6) | (tmp>>4);
784
785 /* Update paddles */
786 tmp = (JOYPAD_IO.paddles[0] & 255);
787 jp_paddles[0] = (tmp<<8) | tmp;
788 tmp = (JOYPAD_IO.paddles[1] & 255);
789 jp_paddles[1] = (tmp<<8) | tmp;
790 tmp = (JOYPAD_IO.paddles[2] & 255);
791 jp_paddles[2] = (tmp<<8) | tmp;
792 tmp = (JOYPAD_IO.paddles[3] & 255);
793 jp_paddles[3] = (tmp<<8) | tmp;
794
795 /* Update joypads on teamtap port A */
796 for (i=0; i<4; i++) {
797 jp_joypads[i] = 0;
798 for (j=0; j<4; j++) {
799 JOYPAD_IO.directions = joypad_masks[(i*4)+j];
800
801 cur_fire = (~(JOYPAD_IO.fires) & 3)<<16;
802 cur_dir = (~(JOYPAD_IO.directions)>>8) & 15;
803
804 jp_joypads[i] |= cur_fire<<(j*2);
805 jp_joypads[i] |= cur_dir<<(j*4);
806 }
807 }
808
809 /* Update joypads on teamtap port B */
810 for (i=4; i<8; i++) {
811 jp_joypads[i] = 0;
812 for (j=0; j<4; j++) {
813 JOYPAD_IO.directions = joypad_masks[(i*4)+j];
814
815 cur_fire = (~(JOYPAD_IO.fires) & 0xc)<<14;
816 cur_dir = (~(JOYPAD_IO.directions)>>12) & 15;
817
818 jp_joypads[i] |= cur_fire<<(j*2);
819 jp_joypads[i] |= cur_dir<<(j*4);
820 }
821 }
822
823 JOYPAD_IO.directions=0xffff;
824}
825
826#endif /* SDL_JOYSTICK_MINT */
diff --git a/apps/plugins/sdl/src/joystick/nds/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/nds/SDL_sysjoystick.c
deleted file mode 100644
index 122f48d863..0000000000
--- a/apps/plugins/sdl/src/joystick/nds/SDL_sysjoystick.c
+++ /dev/null
@@ -1,150 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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/* This is the system specific header for the SDL joystick API */
25#include <nds.h>
26//#include <nds/registers_alt.h>
27
28#include "SDL_error.h"
29#include "SDL_events.h"
30#include "SDL_joystick.h"
31#include "../SDL_sysjoystick.h"
32#include "../SDL_joystick_c.h"
33
34#include "../../video/nds/SDL_ndsevents_c.h"
35
36/* Function to scan the system for joysticks.
37 * This function should set SDL_numjoysticks to the number of available
38 * joysticks. Joystick 0 should be the system default joystick.
39 * It should return 0, or -1 on an unrecoverable fatal error.
40 */
41int SDL_SYS_JoystickInit(void)
42{
43 SDL_numjoysticks = 1;
44 //keysInit();
45
46 return(1);
47}
48
49/* Function to get the device-dependent name of a joystick */
50const char *SDL_SYS_JoystickName(int index)
51{
52 if(!index)
53 return "NDS builtin joypad";
54 SDL_SetError("No joystick available with that index");
55 return (NULL);
56}
57
58/* Function to open a joystick for use.
59 The joystick to open is specified by the index field of the joystick.
60 This should fill the nbuttons and naxes fields of the joystick structure.
61 It returns 0, or -1 if there is an error.
62 */
63int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
64{
65 joystick->nbuttons=8;
66 joystick->nhats=0;
67 joystick->nballs=0;
68 joystick->naxes=2;
69 return 0;
70}
71
72
73/* Function to update the state of a joystick - called as a device poll.
74 * This function shouldn't update the joystick structure directly,
75 * but instead should call SDL_PrivateJoystick*() to deliver events
76 * and update joystick device state.
77 */
78
79int prevbutton=0;
80int prevkey=0;
81
82int dc=0;int ldc=0;
83u32 keysd,keysu=0;
84void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
85{
86 //dc=keysd;
87 //if (dc)
88 //{
89 //fprintf(stderr,"heartbeat= %d\n",REG_VCOUNT);
90 //swiWaitForVBlank();
91 //scanKeys();
92 //keysd = keysDown();
93 //keysu = keysUp();
94 //ldc=keysd;
95
96 //}
97 /*if (prevkey && prevbutton)
98 {
99 scanKeys();
100 }
101 */
102
103 //scanKeys();
104 keysd = keysDown();
105 keysu = keysUp();
106
107
108 short ax=0,v=0,h=0;
109 if((keysd&KEY_UP)) {ax=1;v=-10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_UP;}//fprintf(stderr,"KEY_UP\n");}
110 if((keysd&KEY_DOWN)) {ax=1;v=10;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=KEY_DOWN;}//fprintf(stderr,"KEY_DOWN\n");}
111 if((keysd&KEY_LEFT)) {ax=0;h=-10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_LEFT;}//fprintf(stderr,"KEY_LEFT\n");}
112 if((keysd&KEY_RIGHT)) {ax=0;h=10;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=KEY_RIGHT;}//fprintf(stderr,"KEY_RIGHT\n");}
113
114 if((keysu&KEY_UP)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=0;}//fprintf(stderr,"KEY_UP\n");}
115 if((keysu&KEY_DOWN)) {ax=1;v=0;SDL_PrivateJoystickAxis(joystick,ax,v);prevkey=0;}//fprintf(stderr,"KEY_DOWN\n");}
116 if((keysu&KEY_LEFT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=0;}//fprintf(stderr,"KEY_LEFT\n");}
117 if((keysu&KEY_RIGHT)) {ax=0;h=0;SDL_PrivateJoystickAxis(joystick,ax,h);prevkey=0;}//fprintf(stderr,"KEY_RIGHT\n");}
118
119 if((keysd&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED);prevbutton=KEY_A;}
120 if((keysd&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_PRESSED);prevbutton=KEY_B;}
121 if((keysd&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_PRESSED);prevbutton=KEY_X;}
122 if((keysd&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_PRESSED);prevbutton=KEY_Y;}
123 if((keysd&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_PRESSED);prevbutton=KEY_SELECT;}
124 if((keysd&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_PRESSED);prevbutton=KEY_START;}
125 if((keysd&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_PRESSED);prevbutton=KEY_L;}
126 if((keysd&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_PRESSED);prevbutton=KEY_R;}
127
128 if((keysu&KEY_A)) {SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED);prevbutton=0;}
129 if((keysu&KEY_B)) {SDL_PrivateJoystickButton(joystick,1,SDL_RELEASED);prevbutton=0;}
130 if((keysu&KEY_X)) {SDL_PrivateJoystickButton(joystick,2,SDL_RELEASED);prevbutton=0;}
131 if((keysu&KEY_Y)) {SDL_PrivateJoystickButton(joystick,3,SDL_RELEASED);prevbutton=0;}
132 if((keysu&KEY_SELECT)) {SDL_PrivateJoystickButton(joystick,6,SDL_RELEASED);prevbutton=0;}
133 if((keysu&KEY_START)) {SDL_PrivateJoystickButton(joystick,7,SDL_RELEASED);prevbutton=0;}
134 if((keysu&KEY_L)) {SDL_PrivateJoystickButton(joystick,4,SDL_RELEASED);prevbutton=0;}
135 if((keysu&KEY_R)) {SDL_PrivateJoystickButton(joystick,5,SDL_RELEASED);prevbutton=0;}
136
137
138
139}
140
141/* Function to close a joystick after use */
142void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
143{
144}
145
146/* Function to perform any system-specific joystick related cleanup */
147void SDL_SYS_JoystickQuit(void)
148{
149}
150
diff --git a/apps/plugins/sdl/src/joystick/riscos/SDL_sysjoystick.c b/apps/plugins/sdl/src/joystick/riscos/SDL_sysjoystick.c
deleted file mode 100644
index 214d4c7474..0000000000
--- a/apps/plugins/sdl/src/joystick/riscos/SDL_sysjoystick.c
+++ /dev/null
@@ -1,176 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_RISCOS
25
26/*
27 RISC OS - Joystick support by Alan Buckley (alan_baa@hotmail.com) - 10 April 2003
28
29 Note: Currently assumes joystick is present if joystick module is loaded
30 and that there is one joystick with four buttons.
31*/
32
33/* This is the system specific header for the SDL joystick API */
34
35#include "SDL_events.h"
36#include "SDL_joystick.h"
37#include "../SDL_sysjoystick.h"
38#include "../SDL_joystick_c.h"
39
40#include "kernel.h"
41
42#define JOYSTICK_READ 0x43F40
43
44struct joystick_hwdata
45{
46 int joystate;
47};
48
49
50/* Function to scan the system for joysticks.
51 * This function should set SDL_numjoysticks to the number of available
52 * joysticks. Joystick 0 should be the system default joystick.
53 * It should return number of joysticks, or -1 on an unrecoverable fatal error.
54 */
55int SDL_SYS_JoystickInit(void)
56{
57 _kernel_swi_regs regs;
58
59 /* Try to read joystick 0 */
60 regs.r[0] = 0;
61 if (_kernel_swi(JOYSTICK_READ, &regs, &regs) == NULL)
62 {
63 /* Switch works so assume we've got a joystick */
64 return 1;
65 }
66 /* Switch fails so it looks like there's no joystick here */
67
68 return(0);
69}
70
71/* Function to get the device-dependent name of a joystick */
72const char *SDL_SYS_JoystickName(int index)
73{
74 if (index == 0)
75 {
76 return "RISC OS Joystick 0";
77 }
78
79 SDL_SetError("No joystick available with that index");
80 return(NULL);
81}
82
83/* Function to open a joystick for use.
84 The joystick to open is specified by the index field of the joystick.
85 This should fill the nbuttons and naxes fields of the joystick structure.
86 It returns 0, or -1 if there is an error.
87 */
88int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
89{
90 _kernel_swi_regs regs;
91
92 if(!(joystick->hwdata=SDL_malloc(sizeof(struct joystick_hwdata))))
93 return -1;
94
95 regs.r[0] = joystick->index;
96
97 /* Don't know how to get exact count of buttons so assume max of 4 for now */
98 joystick->nbuttons=4;
99
100 joystick->nhats=0;
101 joystick->nballs=0;
102 joystick->naxes=2;
103 joystick->hwdata->joystate=0;
104
105 return 0;
106
107}
108
109/* Function to update the state of a joystick - called as a device poll.
110 * This function shouldn't update the joystick structure directly,
111 * but instead should call SDL_PrivateJoystick*() to deliver events
112 * and update joystick device state.
113 */
114void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
115{
116 _kernel_swi_regs regs;
117 regs.r[0] = joystick->index;
118
119 if (_kernel_swi(JOYSTICK_READ, &regs, &regs) == NULL)
120 {
121 int newstate = regs.r[0];
122 int oldstate = joystick->hwdata->joystate;
123 if (newstate != oldstate)
124 {
125 if ((newstate & 0xFF) != (oldstate & 0xFF))
126 {
127 int y = regs.r[0] & 0xFF;
128 /* Convert to signed values */
129 if (y >= 128) y -= 256;
130 SDL_PrivateJoystickAxis(joystick,1,-y * 256); /* Up and down opposite to result in SDL */
131 }
132 if ((newstate & 0xFF00) != (oldstate & 0xFF00))
133 {
134 int x = (regs.r[0] & 0xFF00) >> 8;
135 if (x >= 128) x -= 256;
136 SDL_PrivateJoystickAxis(joystick,0,x * 256);
137 }
138
139 if ((newstate & 0xFF0000) != (oldstate & 0xFF0000))
140 {
141 int buttons = (regs.r[0] & 0xFF0000) >> 16;
142 int oldbuttons = (oldstate & 0xFF0000) >> 16;
143 int i;
144 for (i = 0; i < joystick->nbuttons; i++)
145 {
146 if ((buttons & (1<<i)) != (oldbuttons & (1<<i)))
147 {
148 if (buttons & (1<<i)) SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
149 else SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
150 }
151 }
152 }
153 joystick->hwdata->joystate = newstate;
154 }
155 }
156
157 return;
158}
159
160/* Function to close a joystick after use */
161void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
162{
163 if(joystick->hwdata)
164 SDL_free(joystick->hwdata);
165 return;
166}
167
168/* Function to perform any system-specific joystick related cleanup */
169void SDL_SYS_JoystickQuit(void)
170{
171 SDL_numjoysticks=0;
172
173 return;
174}
175
176#endif /* SDL_JOYSTICK_RISCOS */
diff --git a/apps/plugins/sdl/src/joystick/win32/SDL_mmjoystick.c b/apps/plugins/sdl/src/joystick/win32/SDL_mmjoystick.c
deleted file mode 100644
index 8c53f9e3dd..0000000000
--- a/apps/plugins/sdl/src/joystick/win32/SDL_mmjoystick.c
+++ /dev/null
@@ -1,407 +0,0 @@
1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2012 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_WINMM
25
26/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */
27
28#define WIN32_LEAN_AND_MEAN
29#include <windows.h>
30#include <mmsystem.h>
31#include <regstr.h>
32
33#include "SDL_events.h"
34#include "SDL_joystick.h"
35#include "../SDL_sysjoystick.h"
36#include "../SDL_joystick_c.h"
37
38#define MAX_JOYSTICKS 16
39#define MAX_AXES 6 /* each joystick can have up to 6 axes */
40#define MAX_BUTTONS 32 /* and 32 buttons */
41#define AXIS_MIN -32768 /* minimum value for axis coordinate */
42#define AXIS_MAX 32767 /* maximum value for axis coordinate */
43/* limit axis to 256 possible positions to filter out noise */
44#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256)
45#define JOY_BUTTON_FLAG(n) (1<<n)
46
47
48/* array to hold joystick ID values */
49static UINT SYS_JoystickID[MAX_JOYSTICKS];
50static JOYCAPS SYS_Joystick[MAX_JOYSTICKS];
51static char *SYS_JoystickName[MAX_JOYSTICKS];
52
53/* The private structure used to keep track of a joystick */
54struct joystick_hwdata
55{
56 /* joystick ID */
57 UINT id;
58
59 /* values used to translate device-specific coordinates into
60 SDL-standard ranges */
61 struct _transaxis {
62 int offset;
63 float scale;
64 } transaxis[6];
65};
66
67/* Convert a win32 Multimedia API return code to a text message */
68static void SetMMerror(char *function, int code);
69
70
71static char *GetJoystickName(int index, const char *szRegKey)
72{
73 /* added 7/24/2004 by Eckhard Stolberg */
74 /*
75 see if there is a joystick for the current
76 index (1-16) listed in the registry
77 */
78 char *name = NULL;
79 HKEY hTopKey;
80 HKEY hKey;
81 DWORD regsize;
82 LONG regresult;
83 char regkey[256];
84 char regvalue[256];
85 char regname[256];
86
87 SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s\\%s",
88 REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR);
89 hTopKey = HKEY_LOCAL_MACHINE;
90 regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
91 if (regresult != ERROR_SUCCESS) {
92 hTopKey = HKEY_CURRENT_USER;
93 regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
94 }
95 if (regresult != ERROR_SUCCESS) {
96 return NULL;
97 }
98
99 /* find the registry key name for the joystick's properties */
100 regsize = sizeof(regname);
101 SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index+1, REGSTR_VAL_JOYOEMNAME);
102 regresult = RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE)regname, &regsize);
103 RegCloseKey(hKey);
104
105 if (regresult != ERROR_SUCCESS) {
106 return NULL;
107 }
108
109 /* open that registry key */
110 SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s", REGSTR_PATH_JOYOEM, regname);
111 regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
112 if (regresult != ERROR_SUCCESS) {
113 return NULL;
114 }
115
116 /* find the size for the OEM name text */
117 regsize = sizeof(regvalue);
118 regresult = RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, &regsize);
119 if (regresult == ERROR_SUCCESS) {
120 /* allocate enough memory for the OEM name text ... */
121 name = (char *) SDL_malloc(regsize);
122 if ( name ) {
123 /* ... and read it from the registry */
124 regresult = RegQueryValueExA(hKey,
125 REGSTR_VAL_JOYOEMNAME, 0, 0,
126 (LPBYTE) name, &regsize);
127 }
128 }
129 RegCloseKey(hKey);
130
131 return(name);
132}
133
134/* Function to scan the system for joysticks.
135 * This function should set SDL_numjoysticks to the number of available
136 * joysticks. Joystick 0 should be the system default joystick.
137 * It should return 0, or -1 on an unrecoverable fatal error.
138 */
139int SDL_SYS_JoystickInit(void)
140{
141 int i;
142 int maxdevs;
143 int numdevs;
144 JOYINFOEX joyinfo;
145 JOYCAPS joycaps;
146 MMRESULT result;
147
148 /* Reset the joystick ID & name mapping tables */
149 for ( i = 0; i < MAX_JOYSTICKS; ++i ) {
150 SYS_JoystickID[i] = 0;
151 SYS_JoystickName[i] = NULL;
152 }
153
154 /* Loop over all potential joystick devices */
155 numdevs = 0;
156 maxdevs = joyGetNumDevs();
157 for ( i = JOYSTICKID1; i < maxdevs && numdevs < MAX_JOYSTICKS; ++i ) {
158
159 joyinfo.dwSize = sizeof(joyinfo);
160 joyinfo.dwFlags = JOY_RETURNALL;
161 result = joyGetPosEx(i, &joyinfo);
162 if ( result == JOYERR_NOERROR ) {
163 result = joyGetDevCaps(i, &joycaps, sizeof(joycaps));
164 if ( result == JOYERR_NOERROR ) {
165 SYS_JoystickID[numdevs] = i;
166 SYS_Joystick[numdevs] = joycaps;
167 SYS_JoystickName[numdevs] = GetJoystickName(i, joycaps.szRegKey);
168 numdevs++;
169 }
170 }
171 }
172 return(numdevs);
173}
174
175/* Function to get the device-dependent name of a joystick */
176const char *SDL_SYS_JoystickName(int index)
177{
178 if ( SYS_JoystickName[index] != NULL ) {
179 return(SYS_JoystickName[index]);
180 } else {
181 return(SYS_Joystick[index].szPname);
182 }
183}
184
185/* Function to open a joystick for use.
186 The joystick to open is specified by the index field of the joystick.
187 This should fill the nbuttons and naxes fields of the joystick structure.
188 It returns 0, or -1 if there is an error.
189 */
190int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
191{
192 int index, i;
193 int caps_flags[MAX_AXES-2] =
194 { JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV };
195 int axis_min[MAX_AXES], axis_max[MAX_AXES];
196
197
198 /* shortcut */
199 index = joystick->index;
200 axis_min[0] = SYS_Joystick[index].wXmin;
201 axis_max[0] = SYS_Joystick[index].wXmax;
202 axis_min[1] = SYS_Joystick[index].wYmin;
203 axis_max[1] = SYS_Joystick[index].wYmax;
204 axis_min[2] = SYS_Joystick[index].wZmin;
205 axis_max[2] = SYS_Joystick[index].wZmax;
206 axis_min[3] = SYS_Joystick[index].wRmin;
207 axis_max[3] = SYS_Joystick[index].wRmax;
208 axis_min[4] = SYS_Joystick[index].wUmin;
209 axis_max[4] = SYS_Joystick[index].wUmax;
210 axis_min[5] = SYS_Joystick[index].wVmin;
211 axis_max[5] = SYS_Joystick[index].wVmax;
212
213 /* allocate memory for system specific hardware data */
214 joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
215 if (joystick->hwdata == NULL)
216 {
217 SDL_OutOfMemory();
218 return(-1);
219 }
220 SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
221
222 /* set hardware data */
223 joystick->hwdata->id = SYS_JoystickID[index];
224 for ( i = 0; i < MAX_AXES; ++i ) {
225 if ( (i<2) || (SYS_Joystick[index].wCaps & caps_flags[i-2]) ) {
226 joystick->hwdata->transaxis[i].offset =
227 AXIS_MIN - axis_min[i];
228 joystick->hwdata->transaxis[i].scale =
229 (float)(AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]);
230 } else {
231 joystick->hwdata->transaxis[i].offset = 0;
232 joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
233 }
234 }
235
236 /* fill nbuttons, naxes, and nhats fields */
237 joystick->nbuttons = SYS_Joystick[index].wNumButtons;
238 joystick->naxes = SYS_Joystick[index].wNumAxes;
239 if ( SYS_Joystick[index].wCaps & JOYCAPS_HASPOV ) {
240 joystick->nhats = 1;
241 } else {
242 joystick->nhats = 0;
243 }
244 return(0);
245}
246
247static Uint8 TranslatePOV(DWORD value)
248{
249 Uint8 pos;
250
251 pos = SDL_HAT_CENTERED;
252 if ( value != JOY_POVCENTERED ) {
253 if ( (value > JOY_POVLEFT) || (value < JOY_POVRIGHT) ) {
254 pos |= SDL_HAT_UP;
255 }
256 if ( (value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD) ) {
257 pos |= SDL_HAT_RIGHT;
258 }
259 if ( (value > JOY_POVRIGHT) && (value < JOY_POVLEFT) ) {
260 pos |= SDL_HAT_DOWN;
261 }
262 if ( value > JOY_POVBACKWARD ) {
263 pos |= SDL_HAT_LEFT;
264 }
265 }
266 return(pos);
267}
268
269/* Function to update the state of a joystick - called as a device poll.
270 * This function shouldn't update the joystick structure directly,
271 * but instead should call SDL_PrivateJoystick*() to deliver events
272 * and update joystick device state.
273 */
274void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
275{
276 MMRESULT result;
277 int i;
278 DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ,
279 JOY_RETURNR, JOY_RETURNU, JOY_RETURNV };
280 DWORD pos[MAX_AXES];
281 struct _transaxis *transaxis;
282 int value, change;
283 JOYINFOEX joyinfo;
284
285 joyinfo.dwSize = sizeof(joyinfo);
286 joyinfo.dwFlags = JOY_RETURNALL|JOY_RETURNPOVCTS;
287 if ( ! joystick->hats ) {
288 joyinfo.dwFlags &= ~(JOY_RETURNPOV|JOY_RETURNPOVCTS);
289 }
290 result = joyGetPosEx(joystick->hwdata->id, &joyinfo);
291 if ( result != JOYERR_NOERROR ) {
292 SetMMerror("joyGetPosEx", result);
293 return;
294 }
295
296 /* joystick motion events */
297 pos[0] = joyinfo.dwXpos;
298 pos[1] = joyinfo.dwYpos;
299 pos[2] = joyinfo.dwZpos;
300 pos[3] = joyinfo.dwRpos;
301 pos[4] = joyinfo.dwUpos;
302 pos[5] = joyinfo.dwVpos;
303
304 transaxis = joystick->hwdata->transaxis;
305 for (i = 0; i < joystick->naxes; i++) {
306 if (joyinfo.dwFlags & flags[i]) {
307 value = (int)(((float)pos[i] + transaxis[i].offset) * transaxis[i].scale);
308 change = (value - joystick->axes[i]);
309 if ( (change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD) ) {
310 SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value);
311 }
312 }
313 }
314
315 /* joystick button events */
316 if ( joyinfo.dwFlags & JOY_RETURNBUTTONS ) {
317 for ( i = 0; i < joystick->nbuttons; ++i ) {
318 if ( joyinfo.dwButtons & JOY_BUTTON_FLAG(i) ) {
319 if ( ! joystick->buttons[i] ) {
320 SDL_PrivateJoystickButton(joystick, (Uint8)i, SDL_PRESSED);
321 }
322 } else {
323 if ( joystick->buttons[i] ) {
324 SDL_PrivateJoystickButton(joystick, (Uint8)i, SDL_RELEASED);
325 }
326 }
327 }
328 }
329
330 /* joystick hat events */
331 if ( joyinfo.dwFlags & JOY_RETURNPOV ) {
332 Uint8 pos;
333
334 pos = TranslatePOV(joyinfo.dwPOV);
335 if ( pos != joystick->hats[0] ) {
336 SDL_PrivateJoystickHat(joystick, 0, pos);
337 }
338 }
339}
340
341/* Function to close a joystick after use */
342void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
343{
344 if (joystick->hwdata != NULL) {
345 /* free system specific hardware data */
346 SDL_free(joystick->hwdata);
347 joystick->hwdata = NULL;
348 }
349}
350
351/* Function to perform any system-specific joystick related cleanup */
352void SDL_SYS_JoystickQuit(void)
353{
354 int i;
355 for (i = 0; i < MAX_JOYSTICKS; i++) {
356 if ( SYS_JoystickName[i] != NULL ) {
357 SDL_free(SYS_JoystickName[i]);
358 SYS_JoystickName[i] = NULL;
359 }
360 }
361}
362
363
364/* implementation functions */
365void SetMMerror(char *function, int code)
366{
367 static char *error;
368 static char errbuf[1024];
369
370 errbuf[0] = 0;
371 switch (code)
372 {
373 case MMSYSERR_NODRIVER:
374 error = "Joystick driver not present";
375 break;
376
377 case MMSYSERR_INVALPARAM:
378 case JOYERR_PARMS:
379 error = "Invalid parameter(s)";
380 break;
381
382 case MMSYSERR_BADDEVICEID:
383 error = "Bad device ID";
384 break;
385
386 case JOYERR_UNPLUGGED:
387 error = "Joystick not attached";
388 break;
389
390 case JOYERR_NOCANDO:
391 error = "Can't capture joystick input";
392 break;
393
394 default:
395 SDL_snprintf(errbuf, SDL_arraysize(errbuf),
396 "%s: Unknown Multimedia system error: 0x%x",
397 function, code);
398 break;
399 }
400
401 if ( ! errbuf[0] ) {
402 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error);
403 }
404 SDL_SetError("%s", errbuf);
405}
406
407#endif /* SDL_JOYSTICK_WINMM */