1 /** \file joy-unix.c
2 * \brief Linux/BSD joystick support
3 *
4 * \author Bernhard Kuhn <kuhn@eikon.e-technik.tu-muenchen.de>
5 * \author Ulmer Lionel <ulmer@poly.polytechnique.fr>
6 * \author Marco van den Heuvel <blackystardust68@yahoo.com>
7 * \author Daniel Sladic <sladic@eecg.toronto.edu>
8 * \author Krister Walfridsson <cato@df.lth.se>
9 * \author Luca Montecchiani <m.luca@usa.net> (http://i.am/m.luca)
10 */
11
12 /*
13 * This file is part of VICE, the Versatile Commodore Emulator.
14 * See README for copyright notice.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 * 02111-1307 USA.
30 *
31 */
32
33 #include "vice.h"
34 #include "archdep_defs.h"
35
36 #if defined(UNIX_COMPILE) && !defined(MACOSX_SUPPORT)
37
38 #include <fcntl.h>
39 #include <stdio.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <unistd.h>
43
44 #include "cmdline.h"
45 #include "joy.h"
46 #include "joyport.h"
47 #include "joystick.h"
48 #include "keyboard.h"
49 #include "log.h"
50 #include "resources.h"
51 #include "types.h"
52
joy_arch_set_device(int port,int new_dev)53 int joy_arch_set_device(int port, int new_dev)
54 {
55 if (new_dev < 0 || new_dev > JOYDEV_MAX) {
56 return -1;
57 }
58
59 return 0;
60 }
61
62 /* Resources. */
63
64
joy_arch_resources_init(void)65 int joy_arch_resources_init(void)
66 {
67 return 0;
68 }
69
70 /* Command-line options. */
71
72 #if 0
73 static const cmdline_option_t joydev1cmdline_options[] =
74 {
75 { "-joydev1", SET_RESOURCE, CMDLINE_ATTRIB_NEED_ARGS,
76 NULL, NULL, "JoyDevice1", NULL,
77 #ifdef HAS_USB_JOYSTICK
78 "<0-13>", "Set device for joystick port 1 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1, 12: USB joystick 0, 13: USB joystick 1)" },
79 #else
80 # ifdef HAS_DIGITAL_JOYSTICK
81 "<0-11>", "Set device for joystick port 1 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1)" },
82 # else
83 "<0-9>", "Set device for joystick port 1 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5)" },
84 # endif
85 #endif
86 CMDLINE_LIST_END
87 };
88
89 static const cmdline_option_t joydev2cmdline_options[] =
90 {
91 { "-joydev2", SET_RESOURCE, CMDLINE_ATTRIB_NEED_ARGS,
92 NULL, NULL, "JoyDevice2", NULL,
93 #ifdef HAS_USB_JOYSTICK
94 "<0-13>", "Set device for joystick port 2 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1, 12: USB joystick 0, 13: USB joystick 1)" },
95 #else
96 # ifdef HAS_DIGITAL_JOYSTICK
97 "<0-11>", "Set device for joystick port 2 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1)" },
98 # else
99 "<0-9>", "Set device for joystick port 2 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5)" },
100 # endif
101 #endif
102 CMDLINE_LIST_END
103 };
104
105 static const cmdline_option_t joydev3cmdline_options[] =
106 {
107 { "-extrajoydev1", SET_RESOURCE, CMDLINE_ATTRIB_NEED_ARGS,
108 NULL, NULL, "JoyDevice3", NULL,
109
110 #ifdef HAS_USB_JOYSTICK
111 "<0-13>", "Set device for extra joystick port 1 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1, 12: USB joystick 0, 13: USB joystick 1)" },
112 #else
113 # ifdef HAS_DIGITAL_JOYSTICK
114 "<0-11>", "Set device for extra joystick port 1 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1)" },
115 # else
116 "<0-9>", "Set device for extra joystick port 1 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5)" },
117 # endif
118 #endif
119 CMDLINE_LIST_END
120 };
121
122 static const cmdline_option_t joydev4cmdline_options[] =
123 {
124 { "-extrajoydev2", SET_RESOURCE, CMDLINE_ATTRIB_NEED_ARGS,
125 NULL, NULL, "JoyDevice4", NULL,
126 #ifdef HAS_USB_JOYSTICK
127 "<0-13>", "Set device for extra joystick port 2 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1, 12: USB joystick 0, 13: USB joystick 1)" },
128 #else
129 # ifdef HAS_DIGITAL_JOYSTICK
130 "<0-11>", "Set device for extra joystick port 2 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1)" },
131 # else
132 "<0-9>", "Set device for extra joystick port 2 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5)" },
133 # endif
134 #endif
135 CMDLINE_LIST_END
136 };
137
138 static const cmdline_option_t joydev5cmdline_options[] =
139 {
140 { "-extrajoydev3", SET_RESOURCE, CMDLINE_ATTRIB_NEED_ARGS,
141 NULL, NULL, "JoyDevice5", NULL,
142 #ifdef HAS_USB_JOYSTICK
143 "<0-13>", "Set device for extra joystick port 3 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1, 12: USB joystick 0, 13: USB joystick 1)" },
144 #else
145 # ifdef HAS_DIGITAL_JOYSTICK
146 "<0-11>", "Set device for extra joystick port 3 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5, 10: Digital joystick 0, 11: Digital joystick 1)" },
147 # else
148 "<0-9>", "Set device for extra joystick port 3 (0: None, 1: Numpad, 2: Keyset 1, 3: Keyset 2, 4: Analog joystick 0, 5: Analog joystick 1, 6: Analog joystick 2, 7: Analog joystick 3, 8: Analog joystick 4, 9: Analog joystick 5)" },
149 # endif
150 #endif
151 CMDLINE_LIST_END
152 };
153 #endif
154
155
joy_arch_cmdline_options_init(void)156 int joy_arch_cmdline_options_init(void)
157 {
158 /* NOP */
159 return 0;
160 }
161 #if 0
162 if (joyport_get_port_name(JOYPORT_1)) {
163 if (cmdline_register_options(joydev1cmdline_options) < 0) {
164 return -1;
165 }
166 }
167 if (joyport_get_port_name(JOYPORT_2)) {
168 if (cmdline_register_options(joydev2cmdline_options) < 0) {
169 return -1;
170 }
171 }
172 if (joyport_get_port_name(JOYPORT_3)) {
173 if (cmdline_register_options(joydev3cmdline_options) < 0) {
174 return -1;
175 }
176 }
177 if (joyport_get_port_name(JOYPORT_4)) {
178 if (cmdline_register_options(joydev4cmdline_options) < 0) {
179 return -1;
180 }
181 }
182 if (joyport_get_port_name(JOYPORT_5)) {
183 if (cmdline_register_options(joydev5cmdline_options) < 0) {
184 return -1;
185 }
186 }
187
188 return 0;
189 }
190 #endif
191
192 /* ------------------------------------------------------------------------- */
193
194 # ifdef LINUX_JOYSTICK
195 # include <linux/joystick.h>
196
197 /* Compile time New 1.1.xx API presence check */
198 # ifdef JS_VERSION
199 # include <sys/ioctl.h>
200 # include <errno.h>
201 # define NEW_JOYSTICK 1
202 # undef HAS_DIGITAL_JOYSTICK
203 static int use_old_api=0; /**< FIXME: make this a #define? */
204 # else
205 static int use_old_api=1;
206 # endif
207
208 # elif defined(BSD_JOYSTICK)
209 # ifdef HAVE_MACHINE_JOYSTICK_H
210 # include <machine/joystick.h>
211 # endif
212 # ifdef HAVE_SYS_JOYSTICK_H
213 # include <sys/joystick.h>
214 # endif
215 # define JS_DATA_TYPE joystick
216 # define JS_RETURN sizeof(struct joystick)
217 int use_old_api=1;
218 # else
219 # error Unknown Joystick
220 # endif
221
222 # define ANALOG_JOY_NUM (JOYDEV_ANALOG_7 - JOYDEV_ANALOG_0 + 1)
223
224 /* file handles for the joystick device files */
225
226 static int ajoyfd[ANALOG_JOY_NUM] = { -1, -1, -1, -1, -1, -1, -1, -1 };
227 static int djoyfd[2] = { -1, -1 };
228
229 # define JOYCALLOOPS 100
230 # define JOYSENSITIVITY 5
231 static int joyxcal[2];
232 static int joyycal[2];
233 static int joyxmin[2];
234 static int joyxmax[2];
235 static int joyymin[2];
236 static int joyymax[2];
237
238 log_t joystick_log = LOG_ERR;
239
240 /* ------------------------------------------------------------------------- */
241
242 /**********************************************************
243 * Generic high level joy routine *
244 **********************************************************/
joy_arch_init(void)245 int joy_arch_init(void)
246 {
247 if (use_old_api) {
248 old_joystick_init();
249 } else {
250 new_joystick_init();
251 }
252 # ifdef HAS_USB_JOYSTICK
253 usb_joystick_init();
254 # endif
255 return 0;
256 }
257
joystick_close(void)258 void joystick_close(void)
259 {
260 if (use_old_api) {
261 old_joystick_close();
262 } else {
263 new_joystick_close();
264 }
265 # ifdef HAS_USB_JOYSTICK
266 usb_joystick_close();
267 # endif
268 }
269
joystick(void)270 void joystick(void)
271 {
272 if (use_old_api) {
273 old_joystick();
274 } else {
275 new_joystick();
276 }
277 # ifdef HAS_USB_JOYSTICK
278 usb_joystick();
279 # endif
280 }
281
282 /** \brief Struct containing device name and id
283 */
284 typedef struct device_info_s {
285 const char *name; /**< device name */
286 int id; /**< device ID (\see joy.h) */
287 } device_info_t;
288
289 static device_info_t predefined_device_list[] = {
290 { "Analog joystick 0", JOYDEV_ANALOG_0 },
291 { "Analog joystick 1", JOYDEV_ANALOG_1 },
292 { "Analog joystick 2", JOYDEV_ANALOG_2 },
293 { "Analog joystick 3", JOYDEV_ANALOG_3 },
294 { "Analog joystick 4", JOYDEV_ANALOG_4 },
295 { "Analog joystick 5", JOYDEV_ANALOG_5 },
296 { "Analog joystick 6", JOYDEV_ANALOG_6 },
297 { "Analog joystick 7", JOYDEV_ANALOG_7 },
298 #ifdef HAS_DIGITAL_JOYSTICK
299 { "Digital joystick 0", JOYDEV_DIGITAL_0 },
300 { "Digital joystick 1", JOYDEV_DIGITAL_1 },
301 #endif
302 #ifdef HAS_USB_JOYSTICK
303 { "USB joystick 0", JOYDEV_USB_0 },
304 { "USB joystick 1", JOYDEV_USB_1 },
305 #endif
306 { NULL, -1 }
307 };
308
309 static int joystickdeviceidx = 0;
310
joystick_ui_reset_device_list(void)311 void joystick_ui_reset_device_list(void)
312 {
313 joystickdeviceidx = 0;
314 }
315
316 /* FIXME: proper device names will be returned only when using the "new" API
317 and only for "analog" joysticks. */
joystick_ui_get_next_device_name(int * id)318 const char *joystick_ui_get_next_device_name(int *id)
319 {
320 const char *name;
321 #ifndef ARCHDEP_OS_BSD
322 static char jname[0x80];
323 int idx;
324 #endif
325
326 /* printf("joystick_ui_get_next_device_name id: %d\n", joystickdeviceidx); */
327
328 if ((name = predefined_device_list[joystickdeviceidx].name)) {
329 *id = predefined_device_list[joystickdeviceidx].id;
330 joystickdeviceidx++;
331
332 if (!use_old_api) {
333 #ifndef ARCHDEP_OS_BSD
334 if ((*id >= JOYDEV_ANALOG_0) && (*id <= JOYDEV_ANALOG_5)) {
335 idx = *id - JOYDEV_ANALOG_0;
336 if (ajoyfd[idx] >= 0) {
337 sprintf(jname, "%d: ", idx);
338 ioctl(ajoyfd[idx], JSIOCGNAME (sizeof (jname) - 4), &jname[3]);
339 *id = idx + JOYDEV_ANALOG_0;
340 /* printf("joystick_ui_get_next_device_name got name: %d: %s: %s\n", *id, name, jname); */
341 return jname;
342 } else {
343 /* no joystick at this port */
344 return NULL;
345 }
346 }
347 #endif /* BSD */
348 }
349 /* return name from the predefined list instead */
350 return name;
351 }
352 return NULL;
353 }
354
355 /**********************************************************
356 * Older Joystick routine 0.8x Linux/BSD driver *
357 **********************************************************/
old_joystick_init(void)358 void old_joystick_init(void)
359 {
360 int i;
361
362 joystick_log = log_open("Joystick");
363
364 /* close all device files */
365 for (i = 0; i < 2; i++) {
366 if (ajoyfd[i] != -1) {
367 close(ajoyfd[i]);
368 }
369 if (djoyfd[i] != -1) {
370 close(djoyfd[i]);
371 }
372 }
373
374 /* open analog device files */
375 for (i = 0; i < 2; i++) {
376
377 const char *dev;
378 # ifdef LINUX_JOYSTICK
379 dev = (i == 0) ? "/dev/js0" : "/dev/js1";
380 # elif defined(BSD_JOYSTICK)
381 dev = (i == 0) ? "/dev/joy0" : "/dev/joy1";
382 # endif
383
384 ajoyfd[i] = open(dev, O_RDONLY);
385 if (ajoyfd[i] < 0) {
386 log_warning(joystick_log, "Cannot open joystick device `%s'.", dev);
387 } else {
388 int j;
389
390 /* calibration loop */
391 for (j = 0; j < JOYCALLOOPS; j++) {
392 struct JS_DATA_TYPE js;
393 ssize_t status = read(ajoyfd[i], &js, JS_RETURN);
394
395 if (status != JS_RETURN) {
396 log_warning(joystick_log, "Error reading joystick device `%s'.", dev);
397 } else {
398 /* determine average */
399 joyxcal[i] += js.x;
400 joyycal[i] += js.y;
401 }
402 }
403
404 /* correct average */
405 joyxcal[i] /= JOYCALLOOPS;
406 joyycal[i] /= JOYCALLOOPS;
407
408 /* determine tresholds */
409 joyxmin[i] = joyxcal[i] - joyxcal[i] / JOYSENSITIVITY;
410 joyxmax[i] = joyxcal[i] + joyxcal[i] / JOYSENSITIVITY;
411 joyymin[i] = joyycal[i] - joyycal[i] / JOYSENSITIVITY;
412 joyymax[i] = joyycal[i] + joyycal[i] / JOYSENSITIVITY;
413
414 log_message(joystick_log, "Hardware joystick calibration for device `%s':", dev);
415 log_message(joystick_log, " X: min: %i , mid: %i , max: %i.", joyxmin[i], joyxcal[i], joyxmax[i]);
416 log_message(joystick_log, " Y: min: %i , mid: %i , max: %i.", joyymin[i], joyycal[i], joyymax[i]);
417 }
418 }
419
420 # ifdef HAS_DIGITAL_JOYSTICK
421 /* open device files for digital joystick */
422 for (i = 0; i < 2; i++) {
423 const char *dev;
424 dev = (i == 0) ? "/dev/djs0" : "/dev/djs1";
425
426 djoyfd[i] = open(dev, O_RDONLY);
427 if (djoyfd[i] < 0) {
428 log_message(joystick_log, "Cannot open joystick device `%s'.", dev);
429 }
430 }
431 # endif
432 }
433
old_joystick_close(void)434 void old_joystick_close(void)
435 {
436 if (ajoyfd[0] > 0) {
437 close(ajoyfd[0]);
438 }
439 if (ajoyfd[1] > 0) {
440 close(ajoyfd[1]);
441 }
442 if (djoyfd[0] > 0) {
443 close(djoyfd[0]);
444 }
445 if (djoyfd[1] > 0) {
446 close(djoyfd[1]);
447 }
448 }
449
old_joystick(void)450 void old_joystick(void)
451 {
452 int i;
453
454 for (i = 1; i <= 5; i++) {
455 int joyport = joystick_port_map[i - 1];
456
457 # ifdef HAS_DIGITAL_JOYSTICK
458 if (joyport == JOYDEV_DIGITAL_0 || joyport == JOYDEV_DIGITAL_1) {
459 int status;
460 struct DJS_DATA_TYPE djs;
461 int djoyport = joyport - JOYDEV_DIGITAL_0;
462
463 if (djoyfd[djoyport] > 0) {
464 status = read(djoyfd[djoyport], &djs, DJS_RETURN);
465 if (status != DJS_RETURN) {
466 log_error(joystick_log, "Error reading digital joystick device.");
467 } else {
468 BYTE newval;
469
470 newval = ((joystick_get_value_absolute & 0xe0) | ((~(djs.switches >> 3)) & 0x1f));
471 joystick_set_value_absolute(i, newval);
472 }
473 }
474 } else
475 # endif
476 if (joyport == JOYDEV_ANALOG_0 || joyport == JOYDEV_ANALOG_1) {
477 ssize_t status;
478 struct JS_DATA_TYPE js;
479 int ajoyport = joyport - JOYDEV_ANALOG_0;
480
481 if (ajoyfd[ajoyport] > 0) {
482 status = read(ajoyfd[ajoyport], &js, JS_RETURN);
483 if (status != JS_RETURN) {
484 log_error(joystick_log, "Error reading joystick device.");
485 } else {
486 joystick_set_value_absolute(i, 0);
487
488 if (js.y < joyymin[ajoyport]) {
489 joystick_set_value_or(i, 1);
490 }
491 if (js.y > joyymax[ajoyport]) {
492 joystick_set_value_or(i, 2);
493 }
494 if (js.x < joyxmin[ajoyport]) {
495 joystick_set_value_or(i, 4);
496 }
497 if (js.x > joyxmax[ajoyport]) {
498 joystick_set_value_or(i, 8);
499 }
500 # ifdef LINUX_JOYSTICK
501 if (js.buttons) {
502 joystick_set_value_or(i, 16);
503 }
504 # elif defined(BSD_JOYSTICK)
505 if (js.b1 || js.b2) {
506 joystick_set_value_or(i, 16);
507 }
508 # endif
509 }
510 }
511 }
512 }
513 }
514
515 # ifndef NEW_JOYSTICK
new_joystick_init(void)516 void new_joystick_init(void)
517 {
518 }
519
new_joystick_close(void)520 void new_joystick_close(void)
521 {
522 }
523
new_joystick(void)524 void new_joystick(void)
525 {
526 }
527 # else /* NEW_JOYSTICK */
new_joystick_init(void)528 void new_joystick_init(void)
529 {
530 int i;
531 int ver = 0;
532 int axes, buttons;
533 char name[60];
534 struct JS_DATA_TYPE js;
535
536 const char *joydevs[ANALOG_JOY_NUM][2] = {
537 { "/dev/js0", "/dev/input/js0" },
538 { "/dev/js1", "/dev/input/js1" },
539 { "/dev/js2", "/dev/input/js2" },
540 { "/dev/js3", "/dev/input/js3" },
541 { "/dev/js4", "/dev/input/js4" },
542 { "/dev/js5", "/dev/input/js5" },
543 { "/dev/js6", "/dev/input/js6" },
544 { "/dev/js7", "/dev/input/js7" }
545 };
546
547 if (joystick_log == LOG_ERR) {
548 joystick_log = log_open("Joystick");
549 }
550
551 log_message(joystick_log, "Linux joystick interface initialization...");
552 /* close all device files */
553 for (i = 0; i < ANALOG_JOY_NUM; i++) {
554 if (ajoyfd[i] != -1) {
555 close (ajoyfd[i]);
556 }
557 }
558
559 /* open analog device files */
560
561 for (i = 0; i < ANALOG_JOY_NUM; i++) {
562 const char *dev;
563 int j;
564 for (j = 0; j < 2; j++) {
565 dev = joydevs[i][j];
566 ajoyfd[i] = open(dev, O_RDONLY);
567 if (ajoyfd[i] >= 0) {
568 break;
569 }
570 }
571
572 if (ajoyfd[i] >= 0) {
573 if (read (ajoyfd[i], &js, sizeof(struct JS_DATA_TYPE)) < 0) {
574 close (ajoyfd[i]);
575 ajoyfd[i] = -1;
576 continue;
577 }
578 if (ioctl(ajoyfd[i], JSIOCGVERSION, &ver)) {
579 log_message(joystick_log, "%s unknown type", dev);
580 log_message(joystick_log, "Built in driver version: %d.%d.%d", JS_VERSION >> 16, (JS_VERSION >> 8) & 0xff, JS_VERSION & 0xff);
581 log_message(joystick_log, "Kernel driver version : 0.8 ??");
582 log_message(joystick_log, "Please update your Joystick driver!");
583 log_message(joystick_log, "Fall back to old api routine");
584 use_old_api = 1;
585 old_joystick_init();
586 return;
587 }
588 ioctl(ajoyfd[i], JSIOCGVERSION, &ver);
589 ioctl(ajoyfd[i], JSIOCGAXES, &axes);
590 ioctl(ajoyfd[i], JSIOCGBUTTONS, &buttons);
591 ioctl(ajoyfd[i], JSIOCGNAME (sizeof (name)), name);
592 log_message(joystick_log, "%s is %s", dev, name);
593 log_message(joystick_log, "Built in driver version: %d.%d.%d", JS_VERSION >> 16, (JS_VERSION >> 8) & 0xff, JS_VERSION & 0xff);
594 log_message(joystick_log, "Kernel driver version : %d.%d.%d", ver >> 16, (ver >> 8) & 0xff, ver & 0xff);
595 fcntl(ajoyfd[i], F_SETFL, O_NONBLOCK);
596 } else {
597 log_warning(joystick_log, "Cannot open joystick device `%s'.", dev);
598 }
599 }
600 }
601
new_joystick_close(void)602 void new_joystick_close(void)
603 {
604 int i;
605
606 for (i = 0; i < ANALOG_JOY_NUM; ++i) {
607 if (ajoyfd[i] > 0) {
608 close (ajoyfd[i]);
609 }
610 }
611 }
612
new_joystick(void)613 void new_joystick(void)
614 {
615 int i;
616 struct js_event e;
617 int ajoyport;
618
619 for (i = 1; i <= ANALOG_JOY_NUM; i++) {
620 int joyport = joystick_port_map[i - 1];
621
622 if ((joyport < JOYDEV_ANALOG_0) || (joyport > JOYDEV_ANALOG_7)) {
623 continue;
624 }
625
626 ajoyport = joyport - JOYDEV_ANALOG_0;
627
628 if (ajoyfd[ajoyport] < 0) {
629 continue;
630 }
631
632 /* Read all queued events. */
633 while (read(ajoyfd[ajoyport], &e, sizeof(struct js_event)) == sizeof(struct js_event)) {
634 switch (e.type & ~JS_EVENT_INIT) {
635 case JS_EVENT_BUTTON:
636 /* Generally, only the first few buttons are "fire" on a modern
637 joystick, the others being reserved for more esoteric things
638 like "SELECT", "START", "PAUSE", and directional movement.
639 The following treats only the first four buttons on a joystick
640 as fire buttons and ignores the rest.
641 */
642 /* printf("e.number: %d e.value: %d\n", e.number, e.value); */
643 /* FIXME: we need a gui to let the user map this, see SDL port */
644 if (! (e.number & ~3)) { /* only first four buttons are fire */
645 if (e.number == 0) {
646 /* regular fire button */
647 joystick_set_value_and(i, ~16); /* reset fire bit */
648 if (e.value) {
649 joystick_set_value_or(i, 16);
650 }
651 }
652 if (e.number == 1) {
653 /* 2nd fire button (POTX) */
654 joystick_set_value_and(i, ~32); /* reset fire bit */
655 if (e.value) {
656 joystick_set_value_or(i, 32);
657 }
658 }
659 if (e.number == 2) {
660 /* 3rd fire button (POTY) */
661 joystick_set_value_and(i, ~64); /* reset fire bit */
662 if (e.value) {
663 joystick_set_value_or(i, 64);
664 }
665 }
666 }
667 break;
668 case JS_EVENT_AXIS:
669 /* printf("JS_EVENT_AXIS e.number: %d e.value: %d\n", e.number, e.value); */
670 if (e.number == 0) {
671 joystick_set_value_and(i, 19); /* reset 2 bit */
672 if (e.value > 16384) {
673 joystick_set_value_or(i, 8);
674 } else if (e.value < -16384) {
675 joystick_set_value_or(i, 4);
676 }
677 }
678 if (e.number == 1) {
679 joystick_set_value_and(i, 28); /* reset 2 bit */
680 if (e.value > 16384) {
681 joystick_set_value_or(i, 2);
682 } else if (e.value < -16384) {
683 joystick_set_value_or(i, 1);
684 }
685 }
686 break;
687 }
688 }
689 }
690 }
691 # endif /* NEW_JOYSTICK */
692
693 #endif
694