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