mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-01-03 16:46:51 +00:00
Added support for /dev/input/js* on Linux
Added the hint SDL_HINT_LINUX_JOYSTICK_CLASSIC to control whether /dev/input/js* or /dev/input/event* are used as joystick devices Added the hint SDL_HINT_JOYSTICK_DEVICE to allow the user to specify devices t hat will be opened in addition to the normal joystick detection Fixes https://github.com/libsdl-org/SDL/issues/1314 Fixes https://github.com/libsdl-org/SDL/issues/1727 Fixes https://github.com/libsdl-org/SDL/issues/1981 Closes https://github.com/libsdl-org/SDL/pull/4727
This commit is contained in:
parent
65a50b2430
commit
1c78b08007
|
@ -5,6 +5,10 @@ This is a list of major changes in SDL's version history.
|
||||||
2.0.18:
|
2.0.18:
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
* Added the hint SDL_HINT_LINUX_JOYSTICK_CLASSIC to control whether /dev/input/js* or /dev/input/event* are used as joystick devices
|
||||||
|
* Added the hint SDL_HINT_JOYSTICK_DEVICE to allow the user to specify devices that will be opened in addition to the normal joystick detection
|
||||||
|
|
||||||
Android:
|
Android:
|
||||||
* Added support for audio output and capture using AAudio on Android 8.1 and newer
|
* Added support for audio output and capture using AAudio on Android 8.1 and newer
|
||||||
|
|
||||||
|
|
|
@ -816,6 +816,24 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER"
|
#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief A comma separated list of devices to open as joysticks
|
||||||
|
*
|
||||||
|
* This variable is currently only used by the Linux joystick driver.
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux
|
||||||
|
*
|
||||||
|
* This variable can be set to the following values:
|
||||||
|
* "0" - Use /dev/input/event*
|
||||||
|
* "1" - Use /dev/input/js*
|
||||||
|
*
|
||||||
|
* By default the /dev/input/event* interfaces are used
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_LINUX_JOYSTICK_CLASSIC "SDL_LINUX_JOYSTICK_CLASSIC"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values.
|
* \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values.
|
||||||
*
|
*
|
||||||
|
|
|
@ -85,6 +85,7 @@ typedef enum
|
||||||
|
|
||||||
static EnumerationMethod enumeration_method = ENUMERATION_UNSET;
|
static EnumerationMethod enumeration_method = ENUMERATION_UNSET;
|
||||||
|
|
||||||
|
static SDL_bool IsJoystickDeviceNode(const char *node);
|
||||||
static int MaybeAddDevice(const char *path);
|
static int MaybeAddDevice(const char *path);
|
||||||
static int MaybeRemoveDevice(const char *path);
|
static int MaybeRemoveDevice(const char *path);
|
||||||
|
|
||||||
|
@ -105,6 +106,7 @@ typedef struct SDL_joylist_item
|
||||||
SDL_GamepadMapping *mapping;
|
SDL_GamepadMapping *mapping;
|
||||||
} SDL_joylist_item;
|
} SDL_joylist_item;
|
||||||
|
|
||||||
|
static SDL_bool SDL_classic_joysticks = SDL_TRUE;
|
||||||
static SDL_joylist_item *SDL_joylist = NULL;
|
static SDL_joylist_item *SDL_joylist = NULL;
|
||||||
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
||||||
static int numjoysticks = 0;
|
static int numjoysticks = 0;
|
||||||
|
@ -183,17 +185,22 @@ IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid)
|
||||||
char *name;
|
char *name;
|
||||||
char product_string[128];
|
char product_string[128];
|
||||||
|
|
||||||
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) >= 0) {
|
||||||
if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) {
|
inpid.vendor = 0;
|
||||||
return 0;
|
inpid.product = 0;
|
||||||
}
|
} else {
|
||||||
|
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
||||||
|
if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(fd, EVIOCGID, &inpid) < 0) {
|
if (ioctl(fd, EVIOCGID, &inpid) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
|
if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string);
|
name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string);
|
||||||
|
@ -213,7 +220,7 @@ IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid)
|
||||||
FixupDeviceInfoForMapping(fd, &inpid);
|
FixupDeviceInfoForMapping(fd, &inpid);
|
||||||
|
|
||||||
#ifdef DEBUG_JOYSTICK
|
#ifdef DEBUG_JOYSTICK
|
||||||
printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_memset(guid->data, 0, sizeof(guid->data));
|
SDL_memset(guid->data, 0, sizeof(guid->data));
|
||||||
|
@ -254,6 +261,9 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas
|
||||||
if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (SDL_classic_joysticks && !IsJoystickDeviceNode(devpath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
MaybeAddDevice(devpath);
|
MaybeAddDevice(devpath);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -308,7 +318,7 @@ MaybeAddDevice(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Checking %s\n", path);
|
SDL_Log("Checking %s\n", path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
isstick = IsJoystick(fd, &name, &guid);
|
isstick = IsJoystick(fd, &name, &guid);
|
||||||
|
@ -507,6 +517,20 @@ StrIsInteger(const char *string)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_bool
|
||||||
|
IsJoystickDeviceNode(const char *node)
|
||||||
|
{
|
||||||
|
const char *last_slash = SDL_strrchr(node, '/');
|
||||||
|
if (last_slash) {
|
||||||
|
node = last_slash + 1;
|
||||||
|
}
|
||||||
|
if (SDL_classic_joysticks) {
|
||||||
|
return (StrHasPrefix(node, "js") && StrIsInteger(node + 2));
|
||||||
|
} else {
|
||||||
|
return (StrHasPrefix(node, "event") && StrIsInteger(node + 5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
LINUX_InotifyJoystickDetect(void)
|
LINUX_InotifyJoystickDetect(void)
|
||||||
{
|
{
|
||||||
|
@ -519,6 +543,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
size_t remain = 0;
|
size_t remain = 0;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
bytes = read(inotify_fd, &buf, sizeof (buf));
|
bytes = read(inotify_fd, &buf, sizeof (buf));
|
||||||
|
|
||||||
|
@ -528,10 +553,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||||
|
|
||||||
while (remain > 0) {
|
while (remain > 0) {
|
||||||
if (buf.event.len > 0) {
|
if (buf.event.len > 0) {
|
||||||
if (StrHasPrefix(buf.event.name, "event") &&
|
if (IsJoystickDeviceNode(buf.event.name)) {
|
||||||
StrIsInteger(buf.event.name + SDL_strlen ("event"))) {
|
|
||||||
char path[PATH_MAX];
|
|
||||||
|
|
||||||
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name);
|
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name);
|
||||||
|
|
||||||
if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) {
|
if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) {
|
||||||
|
@ -560,7 +582,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||||
static int
|
static int
|
||||||
filter_entries(const struct dirent *entry)
|
filter_entries(const struct dirent *entry)
|
||||||
{
|
{
|
||||||
return (SDL_strlen(entry->d_name) > 5 && SDL_strncmp(entry->d_name, "event", 5) == 0);
|
return IsJoystickDeviceNode(entry->d_name);
|
||||||
}
|
}
|
||||||
static int
|
static int
|
||||||
sort_entries(const struct dirent **a, const struct dirent **b)
|
sort_entries(const struct dirent **a, const struct dirent **b)
|
||||||
|
@ -627,7 +649,9 @@ LINUX_JoystickDetect(void)
|
||||||
static int
|
static int
|
||||||
LINUX_JoystickInit(void)
|
LINUX_JoystickInit(void)
|
||||||
{
|
{
|
||||||
const char *devices = SDL_GetHint("SDL_JOYSTICK_DEVICE");
|
const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE);
|
||||||
|
|
||||||
|
SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
|
||||||
|
|
||||||
#if SDL_USE_LIBUDEV
|
#if SDL_USE_LIBUDEV
|
||||||
if (enumeration_method == ENUMERATION_UNSET) {
|
if (enumeration_method == ENUMERATION_UNSET) {
|
||||||
|
@ -824,6 +848,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
|
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
|
||||||
unsigned long relbit[NBITS(REL_MAX)] = { 0 };
|
unsigned long relbit[NBITS(REL_MAX)] = { 0 };
|
||||||
unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
|
unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
|
||||||
|
Uint8 key_pam_size, abs_pam_size;
|
||||||
SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE);
|
SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE);
|
||||||
|
|
||||||
/* See if this device uses the new unified event API */
|
/* See if this device uses the new unified event API */
|
||||||
|
@ -835,7 +860,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
|
for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
|
||||||
if (test_bit(i, keybit)) {
|
if (test_bit(i, keybit)) {
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Joystick has button: 0x%x\n", i);
|
SDL_Log("Joystick has button: 0x%x\n", i);
|
||||||
#endif
|
#endif
|
||||||
joystick->hwdata->key_map[i] = joystick->nbuttons;
|
joystick->hwdata->key_map[i] = joystick->nbuttons;
|
||||||
joystick->hwdata->has_key[i] = SDL_TRUE;
|
joystick->hwdata->has_key[i] = SDL_TRUE;
|
||||||
|
@ -845,7 +870,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
for (i = 0; i < BTN_JOYSTICK; ++i) {
|
for (i = 0; i < BTN_JOYSTICK; ++i) {
|
||||||
if (test_bit(i, keybit)) {
|
if (test_bit(i, keybit)) {
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Joystick has button: 0x%x\n", i);
|
SDL_Log("Joystick has button: 0x%x\n", i);
|
||||||
#endif
|
#endif
|
||||||
joystick->hwdata->key_map[i] = joystick->nbuttons;
|
joystick->hwdata->key_map[i] = joystick->nbuttons;
|
||||||
joystick->hwdata->has_key[i] = SDL_TRUE;
|
joystick->hwdata->has_key[i] = SDL_TRUE;
|
||||||
|
@ -866,10 +891,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Joystick has absolute axis: 0x%.2x\n", i);
|
SDL_Log("Joystick has absolute axis: 0x%.2x\n", i);
|
||||||
printf("Values = { %d, %d, %d, %d, %d }\n",
|
SDL_Log("Values = { %d, %d, %d, %d, %d }\n",
|
||||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||||
absinfo.fuzz, absinfo.flat);
|
absinfo.fuzz, absinfo.flat);
|
||||||
#endif /* DEBUG_INPUT_EVENTS */
|
#endif /* DEBUG_INPUT_EVENTS */
|
||||||
joystick->hwdata->abs_map[i] = joystick->naxes;
|
joystick->hwdata->abs_map[i] = joystick->naxes;
|
||||||
joystick->hwdata->has_abs[i] = SDL_TRUE;
|
joystick->hwdata->has_abs[i] = SDL_TRUE;
|
||||||
|
@ -906,10 +931,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Joystick has hat %d\n", hat_index);
|
SDL_Log("Joystick has hat %d\n", hat_index);
|
||||||
printf("Values = { %d, %d, %d, %d, %d }\n",
|
SDL_Log("Values = { %d, %d, %d, %d, %d }\n",
|
||||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||||
absinfo.fuzz, absinfo.flat);
|
absinfo.fuzz, absinfo.flat);
|
||||||
#endif /* DEBUG_INPUT_EVENTS */
|
#endif /* DEBUG_INPUT_EVENTS */
|
||||||
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
|
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
|
||||||
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
||||||
|
@ -919,17 +944,73 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
++joystick->nballs;
|
++joystick->nballs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate data to keep track of these thingamajigs */
|
} else if ((ioctl(fd, JSIOCGBUTTONS, &key_pam_size, sizeof(key_pam_size)) >= 0) &&
|
||||||
if (joystick->nhats > 0) {
|
(ioctl(fd, JSIOCGAXES, &abs_pam_size, sizeof(abs_pam_size)) >= 0)) {
|
||||||
if (allocate_hatdata(joystick) < 0) {
|
size_t len;
|
||||||
joystick->nhats = 0;
|
|
||||||
|
joystick->hwdata->classic = SDL_TRUE;
|
||||||
|
|
||||||
|
len = (KEY_MAX - BTN_MISC + 1) * sizeof(*joystick->hwdata->key_pam);
|
||||||
|
joystick->hwdata->key_pam = (Uint16 *)SDL_calloc(1, len);
|
||||||
|
if (joystick->hwdata->key_pam) {
|
||||||
|
if (ioctl(fd, JSIOCGBTNMAP, joystick->hwdata->key_pam, len) < 0) {
|
||||||
|
SDL_free(joystick->hwdata->key_pam);
|
||||||
|
joystick->hwdata->key_pam = NULL;
|
||||||
|
key_pam_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (joystick->nballs > 0) {
|
for (i = 0; i < key_pam_size; ++i) {
|
||||||
if (allocate_balldata(joystick) < 0) {
|
Uint16 code = joystick->hwdata->key_pam[i];
|
||||||
joystick->nballs = 0;
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
|
SDL_Log("Joystick has button: 0x%x\n", code);
|
||||||
|
#endif
|
||||||
|
joystick->hwdata->key_map[code] = joystick->nbuttons;
|
||||||
|
joystick->hwdata->has_key[code] = SDL_TRUE;
|
||||||
|
++joystick->nbuttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ABS_CNT * sizeof(*joystick->hwdata->abs_pam);
|
||||||
|
joystick->hwdata->abs_pam = (Uint8 *)SDL_calloc(1, len);
|
||||||
|
if (joystick->hwdata->abs_pam) {
|
||||||
|
if (ioctl(fd, JSIOCGAXMAP, joystick->hwdata->abs_pam, len) < 0) {
|
||||||
|
SDL_free(joystick->hwdata->abs_pam);
|
||||||
|
joystick->hwdata->abs_pam = NULL;
|
||||||
|
abs_pam_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < abs_pam_size; ++i) {
|
||||||
|
Uint8 code = joystick->hwdata->abs_pam[i];
|
||||||
|
|
||||||
|
if (code >= ABS_HAT0X && code <= ABS_HAT3Y) {
|
||||||
|
int hat_index = (code - ABS_HAT0X) / 2;
|
||||||
|
if (!joystick->hwdata->has_hat[hat_index]) {
|
||||||
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
|
SDL_Log("Joystick has hat %d\n", hat_index);
|
||||||
|
#endif
|
||||||
|
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
|
||||||
|
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
|
SDL_Log("Joystick has absolute axis: 0x%.2x\n", code);
|
||||||
|
#endif
|
||||||
|
joystick->hwdata->abs_map[code] = joystick->naxes;
|
||||||
|
joystick->hwdata->has_abs[code] = SDL_TRUE;
|
||||||
|
++joystick->naxes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate data to keep track of these thingamajigs */
|
||||||
|
if (joystick->nhats > 0) {
|
||||||
|
if (allocate_hatdata(joystick) < 0) {
|
||||||
|
joystick->nhats = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (joystick->nballs > 0) {
|
||||||
|
if (allocate_balldata(joystick) < 0) {
|
||||||
|
joystick->nballs = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) {
|
if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) {
|
||||||
|
@ -955,6 +1036,7 @@ PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
|
||||||
joystick->hwdata->guid = item->guid;
|
joystick->hwdata->guid = item->guid;
|
||||||
joystick->hwdata->effect.id = -1;
|
joystick->hwdata->effect.id = -1;
|
||||||
joystick->hwdata->m_bSteamController = item->m_bSteamController;
|
joystick->hwdata->m_bSteamController = item->m_bSteamController;
|
||||||
|
SDL_memset(joystick->hwdata->key_map, 0xFF, sizeof(joystick->hwdata->key_map));
|
||||||
SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
|
SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
|
||||||
|
|
||||||
if (item->m_bSteamController) {
|
if (item->m_bSteamController) {
|
||||||
|
@ -1098,7 +1180,7 @@ LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||||
return SDL_Unsupported();
|
return SDL_Unsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_INLINE void
|
static void
|
||||||
HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
||||||
{
|
{
|
||||||
struct hwdata_hat *the_hat;
|
struct hwdata_hat *the_hat;
|
||||||
|
@ -1123,14 +1205,14 @@ HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_INLINE void
|
static void
|
||||||
HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
|
HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
|
||||||
{
|
{
|
||||||
stick->hwdata->balls[ball].axis[axis] += value;
|
stick->hwdata->balls[ball].axis[axis] += value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SDL_INLINE int
|
static int
|
||||||
AxisCorrect(SDL_Joystick *joystick, int which, int value)
|
AxisCorrect(SDL_Joystick *joystick, int which, int value)
|
||||||
{
|
{
|
||||||
struct axis_correct *correct;
|
struct axis_correct *correct;
|
||||||
|
@ -1164,7 +1246,7 @@ AxisCorrect(SDL_Joystick *joystick, int which, int value)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_INLINE void
|
static void
|
||||||
PollAllValues(SDL_Joystick *joystick)
|
PollAllValues(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
struct input_absinfo absinfo;
|
struct input_absinfo absinfo;
|
||||||
|
@ -1182,7 +1264,7 @@ PollAllValues(SDL_Joystick *joystick)
|
||||||
absinfo.value = AxisCorrect(joystick, i, absinfo.value);
|
absinfo.value = AxisCorrect(joystick, i, absinfo.value);
|
||||||
|
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Joystick : Re-read Axis %d (%d) val= %d\n",
|
SDL_Log("Joystick : Re-read Axis %d (%d) val= %d\n",
|
||||||
joystick->hwdata->abs_map[i], i, absinfo.value);
|
joystick->hwdata->abs_map[i], i, absinfo.value);
|
||||||
#endif
|
#endif
|
||||||
SDL_PrivateJoystickAxis(joystick,
|
SDL_PrivateJoystickAxis(joystick,
|
||||||
|
@ -1212,7 +1294,7 @@ PollAllValues(SDL_Joystick *joystick)
|
||||||
if (joystick->hwdata->has_key[i]) {
|
if (joystick->hwdata->has_key[i]) {
|
||||||
const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED;
|
const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED;
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Joystick : Re-read Button %d (%d) val= %d\n",
|
SDL_Log("Joystick : Re-read Button %d (%d) val= %d\n",
|
||||||
joystick->hwdata->key_map[i], i, value);
|
joystick->hwdata->key_map[i], i, value);
|
||||||
#endif
|
#endif
|
||||||
SDL_PrivateJoystickButton(joystick,
|
SDL_PrivateJoystickButton(joystick,
|
||||||
|
@ -1224,12 +1306,11 @@ PollAllValues(SDL_Joystick *joystick)
|
||||||
/* Joyballs are relative input, so there's no poll state. Events only! */
|
/* Joyballs are relative input, so there's no poll state. Events only! */
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_INLINE void
|
static void
|
||||||
HandleInputEvents(SDL_Joystick *joystick)
|
HandleInputEvents(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
struct input_event events[32];
|
struct input_event events[32];
|
||||||
int i, len;
|
int i, len, code;
|
||||||
int code;
|
|
||||||
|
|
||||||
if (joystick->hwdata->fresh) {
|
if (joystick->hwdata->fresh) {
|
||||||
PollAllValues(joystick);
|
PollAllValues(joystick);
|
||||||
|
@ -1268,13 +1349,10 @@ HandleInputEvents(SDL_Joystick *joystick)
|
||||||
HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value);
|
HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (joystick->hwdata->abs_map[code] != 0xFF) {
|
events[i].value = AxisCorrect(joystick, code, events[i].value);
|
||||||
events[i].value =
|
SDL_PrivateJoystickAxis(joystick,
|
||||||
AxisCorrect(joystick, code, events[i].value);
|
joystick->hwdata->abs_map[code],
|
||||||
SDL_PrivateJoystickAxis(joystick,
|
events[i].value);
|
||||||
joystick->hwdata->abs_map[code],
|
|
||||||
events[i].value);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1293,7 +1371,7 @@ HandleInputEvents(SDL_Joystick *joystick)
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case SYN_DROPPED :
|
case SYN_DROPPED :
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Event SYN_DROPPED detected\n");
|
SDL_Log("Event SYN_DROPPED detected\n");
|
||||||
#endif
|
#endif
|
||||||
joystick->hwdata->recovering_from_dropped = SDL_TRUE;
|
joystick->hwdata->recovering_from_dropped = SDL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -1318,6 +1396,48 @@ HandleInputEvents(SDL_Joystick *joystick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
HandleClassicEvents(SDL_Joystick *joystick)
|
||||||
|
{
|
||||||
|
struct js_event events[32];
|
||||||
|
int i, len, code;
|
||||||
|
|
||||||
|
joystick->hwdata->fresh = SDL_FALSE;
|
||||||
|
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
||||||
|
len /= sizeof(events[0]);
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
switch (events[i].type) {
|
||||||
|
case JS_EVENT_BUTTON:
|
||||||
|
code = joystick->hwdata->key_pam[events[i].number];
|
||||||
|
SDL_PrivateJoystickButton(joystick,
|
||||||
|
joystick->hwdata->key_map[code],
|
||||||
|
events[i].value);
|
||||||
|
break;
|
||||||
|
case JS_EVENT_AXIS:
|
||||||
|
code = joystick->hwdata->abs_pam[events[i].number];
|
||||||
|
switch (code) {
|
||||||
|
case ABS_HAT0X:
|
||||||
|
case ABS_HAT0Y:
|
||||||
|
case ABS_HAT1X:
|
||||||
|
case ABS_HAT1Y:
|
||||||
|
case ABS_HAT2X:
|
||||||
|
case ABS_HAT2Y:
|
||||||
|
case ABS_HAT3X:
|
||||||
|
case ABS_HAT3Y:
|
||||||
|
code -= ABS_HAT0X;
|
||||||
|
HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_PrivateJoystickAxis(joystick,
|
||||||
|
joystick->hwdata->abs_map[code],
|
||||||
|
events[i].value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
|
@ -1328,7 +1448,11 @@ LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleInputEvents(joystick);
|
if (joystick->hwdata->classic) {
|
||||||
|
HandleClassicEvents(joystick);
|
||||||
|
} else {
|
||||||
|
HandleInputEvents(joystick);
|
||||||
|
}
|
||||||
|
|
||||||
/* Deliver ball motion updates */
|
/* Deliver ball motion updates */
|
||||||
for (i = 0; i < joystick->nballs; ++i) {
|
for (i = 0; i < joystick->nballs; ++i) {
|
||||||
|
@ -1359,6 +1483,8 @@ LINUX_JoystickClose(SDL_Joystick *joystick)
|
||||||
if (joystick->hwdata->item) {
|
if (joystick->hwdata->item) {
|
||||||
joystick->hwdata->item->hwdata = NULL;
|
joystick->hwdata->item->hwdata = NULL;
|
||||||
}
|
}
|
||||||
|
SDL_free(joystick->hwdata->key_pam);
|
||||||
|
SDL_free(joystick->hwdata->abs_pam);
|
||||||
SDL_free(joystick->hwdata->hats);
|
SDL_free(joystick->hwdata->hats);
|
||||||
SDL_free(joystick->hwdata->balls);
|
SDL_free(joystick->hwdata->balls);
|
||||||
SDL_free(joystick->hwdata->fname);
|
SDL_free(joystick->hwdata->fname);
|
||||||
|
@ -1525,20 +1651,20 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||||
out->lefttrigger.target = hat | 0x4;
|
out->lefttrigger.target = hat | 0x4;
|
||||||
out->righttrigger.target = hat | 0x2;
|
out->righttrigger.target = hat | 0x2;
|
||||||
} else {
|
} else {
|
||||||
if (joystick->hwdata->has_key[BTN_TL2]) {
|
if (joystick->hwdata->has_abs[ABS_Z]) {
|
||||||
out->lefttrigger.kind = EMappingKind_Button;
|
|
||||||
out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
|
|
||||||
} else if (joystick->hwdata->has_abs[ABS_Z]) {
|
|
||||||
out->lefttrigger.kind = EMappingKind_Axis;
|
out->lefttrigger.kind = EMappingKind_Axis;
|
||||||
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
|
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
|
||||||
|
} else if (joystick->hwdata->has_key[BTN_TL2]) {
|
||||||
|
out->lefttrigger.kind = EMappingKind_Button;
|
||||||
|
out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (joystick->hwdata->has_key[BTN_TR2]) {
|
if (joystick->hwdata->has_abs[ABS_RZ]) {
|
||||||
out->righttrigger.kind = EMappingKind_Button;
|
|
||||||
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
|
|
||||||
} else if (joystick->hwdata->has_abs[ABS_RZ]) {
|
|
||||||
out->righttrigger.kind = EMappingKind_Axis;
|
out->righttrigger.kind = EMappingKind_Axis;
|
||||||
out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
|
out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
|
||||||
|
} else if (joystick->hwdata->has_key[BTN_TR2]) {
|
||||||
|
out->righttrigger.kind = EMappingKind_Button;
|
||||||
|
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,11 @@ struct joystick_hwdata
|
||||||
SDL_bool has_key[KEY_MAX];
|
SDL_bool has_key[KEY_MAX];
|
||||||
SDL_bool has_abs[ABS_MAX];
|
SDL_bool has_abs[ABS_MAX];
|
||||||
|
|
||||||
|
/* Support for the classic joystick interface */
|
||||||
|
SDL_bool classic;
|
||||||
|
Uint16 *key_pam;
|
||||||
|
Uint8 *abs_pam;
|
||||||
|
|
||||||
struct axis_correct
|
struct axis_correct
|
||||||
{
|
{
|
||||||
SDL_bool use_deadzones;
|
SDL_bool use_deadzones;
|
||||||
|
|
Loading…
Reference in a new issue