--- uae/src/od-linux/joystick.c 2018/04/24 17:13:42 1.1.1.5 +++ uae/src/od-linux/joystick.c 2018/04/24 17:17:48 1.1.1.7 @@ -1,21 +1,27 @@ - /* + /* * UAE - The Un*x Amiga Emulator - * + * * Joystick emulation for Linux and BSD. They share too much code to * split this file. - * + * + * This uses the deprecated 0.x Linux joystick API. + * * Copyright 1997 Bernd Schmidt * Copyright 1998 Krister Walfridsson + * Copyright 2003-2004 Richard Drummond + * Copyright 2004 Nick Seow (Alternative Linux joystick device path) */ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "options.h" #include "memory.h" #include "custom.h" -#include "joystick.h" +#include "inputdevice.h" + +#define JS_MAXPATHLEN 20 // Longest device name would be "/dev/input/js" +char js_prefix[JS_MAXPATHLEN]; // Joystick device, which varies, except number #ifdef HAVE_MACHINE_JOYSTICK_H @@ -40,80 +46,103 @@ typedef struct int y; } uae_joystick_t; -#define JS_DEVNAME_PREFIX "js" +#define JS_DEVNAME_PREFIX "js" // Try this first #endif -int nr_joysticks; +/* Hard code these for the old joystick API */ +#define MAX_BUTTONS 2 +#define MAX_AXLES 2 +#define FIRST_AXLE 0 +#define FIRST_BUTTON 2 + +static int nr_joysticks; static int js0, js1; struct joy_range { int minx, maxx, miny, maxy; + int centrex, centrey; } range0, range1; -void read_joystick(int nr, unsigned int *dir, int *button) +static void read_joy(int nr) { - static int minx = INT_MAX, maxx = INT_MIN; - static int miny = INT_MAX, maxy = INT_MIN; - int left = 0, right = 0, top = 0, bot = 0; uae_joystick_t buffer; int len; int fd = nr == 0 ? js0 : js1; struct joy_range *r = nr == 0 ? &range0 : &range1; - *dir = 0; - *button = 0; if (nr >= nr_joysticks) - return; - + return; + len = read(fd, &buffer, sizeof(buffer)); - if (len != sizeof(buffer)) - return; - + if (len != sizeof(buffer)) + return; + + /* According to old 0.x JS API, we don't know the range + * or the centre for either axis, so we try to work these + * out as we go along. + * + * Must be a better way to do this . . . + */ if (buffer.x < r->minx) r->minx = buffer.x; if (buffer.y < r->miny) r->miny = buffer.y; if (buffer.x > r->maxx) r->maxx = buffer.x; if (buffer.y > r->maxy) r->maxy = buffer.y; - - if (buffer.x < (r->minx + (r->maxx - r->minx)/3)) - left = 1; - else if (buffer.x > (r->minx + 2*(r->maxx - r->minx)/3)) - right = 1; - - if (buffer.y < (r->miny + (r->maxy - r->miny)/3)) - top = 1; - else if (buffer.y > (r->miny + 2*(r->maxy - r->miny)/3)) - bot = 1; - - if (left) top = !top; - if (right) bot = !bot; - *dir = bot | (right << 1) | (top << 8) | (left << 9); + + r->centrex = (r->maxx-r->minx)/2 + r->minx; + r->centrey = (r->maxy-r->miny)/2 + r->miny; + + /* Translate these values to be centred on 0 and + * feed 'em to the inputdevice system */ + setjoystickstate (nr, 0, buffer.x - r->centrex, r->centrex); + setjoystickstate (nr, 1, buffer.y - r->centrey, r->centrey); + #ifdef HAVE_MACHINE_JOYSTICK_H - *button = buffer.b1 || buffer.b2; + setjoybuttonstate (nr, 0, buffer.b1); + setjoybuttonstate (nr, 1, buffer.b2); #else - *button = buffer.buttons & 7; + setjoybuttonstate (nr, 0, buffer.buttons & 1); + setjoybuttonstate (nr, 1, buffer.buttons & 2); #endif } -void init_joystick(void) +static int init_joysticks(void) { nr_joysticks = 0; js0 = -1; js1 = -1; - js0 = open("/dev/" JS_DEVNAME_PREFIX "0", O_RDONLY); - if (js0 < 0) { - write_log ("No joysticks found\n"); - return; - } - nr_joysticks = 1; - js1 = open("/dev/" JS_DEVNAME_PREFIX "1", O_RDONLY); - if (js1 < 0) { - write_log ("Found one joystick\n"); - return; + char js_path[JS_MAXPATHLEN]; // temporary buffer for device name + + snprintf (js_prefix, JS_MAXPATHLEN, "/dev/%s", JS_DEVNAME_PREFIX); + + snprintf (js_path, JS_MAXPATHLEN, "%s0", js_prefix); + if ((js0 = open (js_path, O_RDONLY)) >= 0) + nr_joysticks++; + + snprintf (js_path, JS_MAXPATHLEN, "%s1", js_prefix); + if ((js1 = open (js_path, O_RDONLY)) >= 0) + nr_joysticks++; + +#ifdef __linux__ + if (nr_joysticks == 0) { + /* + * If we haven't found any joysticks yet, + * look for /dev/input/js* nodes + */ + sprintf (js_prefix, "/dev/input/%s", JS_DEVNAME_PREFIX); + + snprintf (js_path, JS_MAXPATHLEN, "%s0", js_prefix); + if ((js0 = open (js_path, O_RDONLY)) >= 0) + nr_joysticks++; + + snprintf (js_path, JS_MAXPATHLEN, "%s1", js_prefix); + if ((js1 = open (js_path, O_RDONLY)) >= 0) + nr_joysticks++; } - write_log ("Found two joysticks\n"); - nr_joysticks = 2; +#endif + + write_log ("Found %d joystick(s)\n", nr_joysticks); range0.minx = INT_MAX; range0.maxx = INT_MIN; @@ -123,12 +152,104 @@ void init_joystick(void) range1.maxx = INT_MIN; range1.miny = INT_MAX; range1.maxy = INT_MIN; + range0.centrex = 0; + range1.centrey = 0; + return 1; } -void close_joystick(void) +static void close_joysticks(void) { if (js0 >= 0) close (js0); if (js1 >= 0) close (js1); } + +static int acquire_joy (int num, int flags) +{ + return 1; +} + +static void unacquire_joy (int num) +{ +} + +static int get_joystick_num (void) +{ + return nr_joysticks; +} + +static void read_joysticks (void) +{ + int i; + for (i = 0; i < get_joystick_num (); i++) { + if (currprefs.input_selected_setting == 0) { + if (jsem_isjoy (0, &currprefs) != i && jsem_isjoy (1, &currprefs) != i) + continue; + } + read_joy (i); + } +} + +static char *get_joystick_name (int joy) +{ + static char name[100]; + sprintf (name, "%d: %s%d", joy + 1, js_prefix, joy); + return name; +} + +static int get_joystick_widget_num (int joy) +{ + return MAX_AXLES + MAX_BUTTONS; +} + +static int get_joystick_widget_type (int joy, int num, char *name, uae_u32 *dummy) +{ + if (num >= MAX_AXLES && num < MAX_AXLES+MAX_BUTTONS) { + if (name) + sprintf (name, "Button %d", num + 1 - MAX_AXLES); + return IDEV_WIDGET_BUTTON; + } else if (num < MAX_AXLES) { + if (name) + sprintf (name, "Axis %d", num + 1); + return IDEV_WIDGET_AXIS; + } + return IDEV_WIDGET_NONE; +} + +static int get_joystick_widget_first (int joy, int type) +{ + switch (type) { + case IDEV_WIDGET_BUTTON: + return FIRST_BUTTON; + case IDEV_WIDGET_AXIS: + return FIRST_AXLE; + } + + return -1; +} + +struct inputdevice_functions inputdevicefunc_joystick = { + init_joysticks, close_joysticks, acquire_joy, unacquire_joy, + read_joysticks, get_joystick_num, get_joystick_name, + get_joystick_widget_num, get_joystick_widget_type, + get_joystick_widget_first +}; + +/* + * Set default inputdevice config for joysticks + */ +void input_get_default_joystick (struct uae_input_device *uid) +{ + int i, port; + + for (i = 0; i < nr_joysticks; i++) { + port = i & 1; + uid[i].eventid[ID_AXIS_OFFSET + 0][0] = port ? INPUTEVENT_JOY2_HORIZ : INPUTEVENT_JOY1_HORIZ; + uid[i].eventid[ID_AXIS_OFFSET + 1][0] = port ? INPUTEVENT_JOY2_VERT : INPUTEVENT_JOY1_VERT; + uid[i].eventid[ID_BUTTON_OFFSET + 0][0] = port ? INPUTEVENT_JOY2_FIRE_BUTTON : INPUTEVENT_JOY1_FIRE_BUTTON; + uid[i].eventid[ID_BUTTON_OFFSET + 1][0] = port ? INPUTEVENT_JOY2_2ND_BUTTON : INPUTEVENT_JOY1_2ND_BUTTON; + uid[i].eventid[ID_BUTTON_OFFSET + 2][0] = port ? INPUTEVENT_JOY2_3RD_BUTTON : INPUTEVENT_JOY1_3RD_BUTTON; + } + uid[0].enabled = 1; +}