Remove old files from SDL external
They were already removed in SDL upstream but the update mechanism did not remove them in this repository. They were causing build failures when the SDL external was used.
This commit is contained in:
784
externals/SDL/src/joystick/bsd/SDL_sysjoystick.c
vendored
784
externals/SDL/src/joystick/bsd/SDL_sysjoystick.c
vendored
@@ -1,784 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_USBHID
|
||||
|
||||
/*
|
||||
* Joystick driver for the uhid(4) interface found in OpenBSD,
|
||||
* NetBSD and FreeBSD.
|
||||
*
|
||||
* Maintainer: <vedge at csoft.org>
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef __FreeBSD_kernel_version
|
||||
#define __FreeBSD_kernel_version __FreeBSD_version
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_USB_H)
|
||||
#include <usb.h>
|
||||
#endif
|
||||
#ifdef __DragonFly__
|
||||
#include <bus/usb/usb.h>
|
||||
#include <bus/usb/usbhid.h>
|
||||
#else
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbhid.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_USBHID_H)
|
||||
#include <usbhid.h>
|
||||
#elif defined(HAVE_LIBUSB_H)
|
||||
#include <libusb.h>
|
||||
#elif defined(HAVE_LIBUSBHID_H)
|
||||
#include <libusbhid.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FREEBSD__) || defined(__FreeBSD_kernel__)
|
||||
#ifndef __DragonFly__
|
||||
#include <osreldate.h>
|
||||
#endif
|
||||
#if __FreeBSD_kernel_version > 800063
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#endif
|
||||
#include <sys/joystick.h>
|
||||
#endif
|
||||
|
||||
#if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
|
||||
#include <machine/joystick.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_joystick.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#define MAX_UHID_JOYS 64
|
||||
#define MAX_JOY_JOYS 2
|
||||
#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
|
||||
#define HUG_DPAD_UP 0x90
|
||||
#define HUG_DPAD_DOWN 0x91
|
||||
#define HUG_DPAD_RIGHT 0x92
|
||||
#define HUG_DPAD_LEFT 0x93
|
||||
|
||||
#define HAT_CENTERED 0x00
|
||||
#define HAT_UP 0x01
|
||||
#define HAT_RIGHT 0x02
|
||||
#define HAT_DOWN 0x04
|
||||
#define HAT_LEFT 0x08
|
||||
#define HAT_RIGHTUP (HAT_RIGHT|HAT_UP)
|
||||
#define HAT_RIGHTDOWN (HAT_RIGHT|HAT_DOWN)
|
||||
#define HAT_LEFTUP (HAT_LEFT|HAT_UP)
|
||||
#define HAT_LEFTDOWN (HAT_LEFT|HAT_DOWN)
|
||||
|
||||
/* calculate the value from the state of the dpad */
|
||||
int
|
||||
dpad_to_sdl(Sint32 *dpad)
|
||||
{
|
||||
if (dpad[2]) {
|
||||
if (dpad[0])
|
||||
return HAT_RIGHTUP;
|
||||
else if (dpad[1])
|
||||
return HAT_RIGHTDOWN;
|
||||
else
|
||||
return HAT_RIGHT;
|
||||
} else if (dpad[3]) {
|
||||
if (dpad[0])
|
||||
return HAT_LEFTUP;
|
||||
else if (dpad[1])
|
||||
return HAT_LEFTDOWN;
|
||||
else
|
||||
return HAT_LEFT;
|
||||
} else if (dpad[0]) {
|
||||
return HAT_UP;
|
||||
} else if (dpad[1]) {
|
||||
return HAT_DOWN;
|
||||
}
|
||||
return HAT_CENTERED;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct report
|
||||
{
|
||||
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
|
||||
void *buf; /* Buffer */
|
||||
#elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
|
||||
struct usb_gen_descriptor *buf; /* Buffer */
|
||||
#else
|
||||
struct usb_ctl_report *buf; /* Buffer */
|
||||
#endif
|
||||
size_t size; /* Buffer size */
|
||||
int rid; /* Report ID */
|
||||
enum
|
||||
{
|
||||
SREPORT_UNINIT,
|
||||
SREPORT_CLEAN,
|
||||
SREPORT_DIRTY
|
||||
} status;
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
int uhid_report;
|
||||
hid_kind_t kind;
|
||||
const char *name;
|
||||
} const repinfo[] = {
|
||||
{UHID_INPUT_REPORT, hid_input, "input"},
|
||||
{UHID_OUTPUT_REPORT, hid_output, "output"},
|
||||
{UHID_FEATURE_REPORT, hid_feature, "feature"}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REPORT_INPUT = 0,
|
||||
REPORT_OUTPUT = 1,
|
||||
REPORT_FEATURE = 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
JOYAXE_X,
|
||||
JOYAXE_Y,
|
||||
JOYAXE_Z,
|
||||
JOYAXE_SLIDER,
|
||||
JOYAXE_WHEEL,
|
||||
JOYAXE_RX,
|
||||
JOYAXE_RY,
|
||||
JOYAXE_RZ,
|
||||
JOYAXE_count
|
||||
};
|
||||
|
||||
struct joystick_hwdata
|
||||
{
|
||||
int fd;
|
||||
char *path;
|
||||
enum
|
||||
{
|
||||
BSDJOY_UHID, /* uhid(4) */
|
||||
BSDJOY_JOY /* joy(4) */
|
||||
} type;
|
||||
struct report_desc *repdesc;
|
||||
struct report inreport;
|
||||
int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */
|
||||
};
|
||||
|
||||
static char *joynames[MAX_JOYS];
|
||||
static char *joydevnames[MAX_JOYS];
|
||||
|
||||
static int report_alloc(struct report *, struct report_desc *, int);
|
||||
static void report_free(struct report *);
|
||||
|
||||
#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063)
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
|
||||
#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000))
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf)
|
||||
#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
|
||||
#else
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf->data)
|
||||
#endif
|
||||
|
||||
static int numjoysticks = 0;
|
||||
|
||||
static int BSD_JoystickOpen(SDL_Joystick * joy, int device_index);
|
||||
static void BSD_JoystickClose(SDL_Joystick * joy);
|
||||
|
||||
static int
|
||||
BSD_JoystickInit(void)
|
||||
{
|
||||
char s[16];
|
||||
int i, fd;
|
||||
|
||||
numjoysticks = 0;
|
||||
|
||||
SDL_memset(joynames, 0, sizeof(joynames));
|
||||
SDL_memset(joydevnames, 0, sizeof(joydevnames));
|
||||
|
||||
for (i = 0; i < MAX_UHID_JOYS; i++) {
|
||||
SDL_Joystick nj;
|
||||
|
||||
SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
|
||||
|
||||
joynames[numjoysticks] = SDL_strdup(s);
|
||||
|
||||
if (BSD_JoystickOpen(&nj, numjoysticks) == 0) {
|
||||
BSD_JoystickClose(&nj);
|
||||
numjoysticks++;
|
||||
} else {
|
||||
SDL_free(joynames[numjoysticks]);
|
||||
joynames[numjoysticks] = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_JOY_JOYS; i++) {
|
||||
SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
|
||||
fd = open(s, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
joynames[numjoysticks++] = SDL_strdup(s);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the default USB HID usage table. */
|
||||
hid_init(NULL);
|
||||
|
||||
return (numjoysticks);
|
||||
}
|
||||
|
||||
static int
|
||||
BSD_JoystickGetCount(void)
|
||||
{
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
static void
|
||||
BSD_JoystickDetect(void)
|
||||
{
|
||||
}
|
||||
|
||||
static const char *
|
||||
BSD_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
if (joydevnames[device_index] != NULL) {
|
||||
return (joydevnames[device_index]);
|
||||
}
|
||||
return (joynames[device_index]);
|
||||
}
|
||||
|
||||
static int
|
||||
BSD_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
{
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
static SDL_JoystickID
|
||||
BSD_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
return device_index;
|
||||
}
|
||||
|
||||
static int
|
||||
usage_to_joyaxe(unsigned usage)
|
||||
{
|
||||
int joyaxe;
|
||||
switch (usage) {
|
||||
case HUG_X:
|
||||
joyaxe = JOYAXE_X;
|
||||
break;
|
||||
case HUG_Y:
|
||||
joyaxe = JOYAXE_Y;
|
||||
break;
|
||||
case HUG_Z:
|
||||
joyaxe = JOYAXE_Z;
|
||||
break;
|
||||
case HUG_SLIDER:
|
||||
joyaxe = JOYAXE_SLIDER;
|
||||
break;
|
||||
case HUG_WHEEL:
|
||||
joyaxe = JOYAXE_WHEEL;
|
||||
break;
|
||||
case HUG_RX:
|
||||
joyaxe = JOYAXE_RX;
|
||||
break;
|
||||
case HUG_RY:
|
||||
joyaxe = JOYAXE_RY;
|
||||
break;
|
||||
case HUG_RZ:
|
||||
joyaxe = JOYAXE_RZ;
|
||||
break;
|
||||
default:
|
||||
joyaxe = -1;
|
||||
}
|
||||
return joyaxe;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
hatval_to_sdl(Sint32 hatval)
|
||||
{
|
||||
static const unsigned hat_dir_map[8] = {
|
||||
SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN,
|
||||
SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP
|
||||
};
|
||||
unsigned result;
|
||||
if ((hatval & 7) == hatval)
|
||||
result = hat_dir_map[hatval];
|
||||
else
|
||||
result = SDL_HAT_CENTERED;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
BSD_JoystickOpen(SDL_Joystick * joy, int device_index)
|
||||
{
|
||||
char *path = joynames[device_index];
|
||||
struct joystick_hwdata *hw;
|
||||
struct hid_item hitem;
|
||||
struct hid_data *hdata;
|
||||
struct report *rep = NULL;
|
||||
#if defined(__NetBSD__)
|
||||
usb_device_descriptor_t udd;
|
||||
struct usb_string_desc usd;
|
||||
#endif
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return SDL_SetError("%s: %s", path, strerror(errno));
|
||||
}
|
||||
|
||||
joy->instance_id = device_index;
|
||||
hw = (struct joystick_hwdata *)
|
||||
SDL_malloc(sizeof(struct joystick_hwdata));
|
||||
if (hw == NULL) {
|
||||
close(fd);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
joy->hwdata = hw;
|
||||
hw->fd = fd;
|
||||
hw->path = SDL_strdup(path);
|
||||
if (!SDL_strncmp(path, "/dev/joy", 8)) {
|
||||
hw->type = BSDJOY_JOY;
|
||||
joy->naxes = 2;
|
||||
joy->nbuttons = 2;
|
||||
joy->nhats = 0;
|
||||
joy->nballs = 0;
|
||||
joydevnames[device_index] = SDL_strdup("Gameport joystick");
|
||||
goto usbend;
|
||||
} else {
|
||||
hw->type = BSDJOY_UHID;
|
||||
}
|
||||
|
||||
{
|
||||
int ax;
|
||||
for (ax = 0; ax < JOYAXE_count; ax++)
|
||||
hw->axis_map[ax] = -1;
|
||||
}
|
||||
hw->repdesc = hid_get_report_desc(fd);
|
||||
if (hw->repdesc == NULL) {
|
||||
SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
|
||||
strerror(errno));
|
||||
goto usberr;
|
||||
}
|
||||
rep = &hw->inreport;
|
||||
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
|
||||
rep->rid = hid_get_report_id(fd);
|
||||
if (rep->rid < 0) {
|
||||
#else
|
||||
if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
|
||||
#endif
|
||||
rep->rid = -1; /* XXX */
|
||||
}
|
||||
#if defined(__NetBSD__)
|
||||
if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
|
||||
goto desc_failed;
|
||||
|
||||
/* Get default language */
|
||||
usd.usd_string_index = USB_LANGUAGE_TABLE;
|
||||
usd.usd_language_id = 0;
|
||||
if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) {
|
||||
usd.usd_language_id = 0;
|
||||
} else {
|
||||
usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
|
||||
}
|
||||
|
||||
usd.usd_string_index = udd.iProduct;
|
||||
if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
|
||||
char str[128];
|
||||
char *new_name = NULL;
|
||||
int i;
|
||||
for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) {
|
||||
str[i] = UGETW(usd.usd_desc.bString[i]);
|
||||
}
|
||||
str[i] = '\0';
|
||||
asprintf(&new_name, "%s @ %s", str, path);
|
||||
if (new_name != NULL) {
|
||||
SDL_free(joydevnames[numjoysticks]);
|
||||
joydevnames[numjoysticks] = new_name;
|
||||
}
|
||||
}
|
||||
desc_failed:
|
||||
#endif
|
||||
if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
|
||||
goto usberr;
|
||||
}
|
||||
if (rep->size <= 0) {
|
||||
SDL_SetError("%s: Input report descriptor has invalid length",
|
||||
hw->path);
|
||||
goto usberr;
|
||||
}
|
||||
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
|
||||
hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
|
||||
#else
|
||||
hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
|
||||
#endif
|
||||
if (hdata == NULL) {
|
||||
SDL_SetError("%s: Cannot start HID parser", hw->path);
|
||||
goto usberr;
|
||||
}
|
||||
joy->naxes = 0;
|
||||
joy->nbuttons = 0;
|
||||
joy->nhats = 0;
|
||||
joy->nballs = 0;
|
||||
for (i = 0; i < JOYAXE_count; i++)
|
||||
hw->axis_map[i] = -1;
|
||||
|
||||
while (hid_get_item(hdata, &hitem) > 0) {
|
||||
char *sp;
|
||||
const char *s;
|
||||
|
||||
switch (hitem.kind) {
|
||||
case hid_collection:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
switch (HID_USAGE(hitem.usage)) {
|
||||
case HUG_JOYSTICK:
|
||||
case HUG_GAME_PAD:
|
||||
s = hid_usage_in_page(hitem.usage);
|
||||
sp = SDL_malloc(SDL_strlen(s) + 5);
|
||||
SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
|
||||
s, device_index);
|
||||
joydevnames[device_index] = sp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case hid_input:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
{
|
||||
unsigned usage = HID_USAGE(hitem.usage);
|
||||
int joyaxe = usage_to_joyaxe(usage);
|
||||
if (joyaxe >= 0) {
|
||||
hw->axis_map[joyaxe] = 1;
|
||||
} else if (usage == HUG_HAT_SWITCH
|
||||
#ifdef __OpenBSD__
|
||||
|| usage == HUG_DPAD_UP
|
||||
#endif
|
||||
) {
|
||||
joy->nhats++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HUP_BUTTON:
|
||||
joy->nbuttons++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
hid_end_parse(hdata);
|
||||
for (i = 0; i < JOYAXE_count; i++)
|
||||
if (hw->axis_map[i] > 0)
|
||||
hw->axis_map[i] = joy->naxes++;
|
||||
|
||||
if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) {
|
||||
SDL_SetError("%s: Not a joystick, ignoring", hw->path);
|
||||
goto usberr;
|
||||
}
|
||||
|
||||
usbend:
|
||||
/* The poll blocks the event thread. */
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
#ifdef __NetBSD__
|
||||
/* Flush pending events */
|
||||
if (rep) {
|
||||
while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
usberr:
|
||||
close(hw->fd);
|
||||
SDL_free(hw->path);
|
||||
SDL_free(hw);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
BSD_JoystickUpdate(SDL_Joystick * joy)
|
||||
{
|
||||
struct hid_item hitem;
|
||||
struct hid_data *hdata;
|
||||
struct report *rep;
|
||||
int nbutton, naxe = -1;
|
||||
Sint32 v;
|
||||
#ifdef __OpenBSD__
|
||||
Sint32 dpad[4] = {0, 0, 0, 0};
|
||||
#endif
|
||||
|
||||
#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
|
||||
struct joystick gameport;
|
||||
static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
|
||||
|
||||
if (joy->hwdata->type == BSDJOY_JOY) {
|
||||
while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
|
||||
if (abs(x - gameport.x) > 8) {
|
||||
x = gameport.x;
|
||||
if (x < xmin) {
|
||||
xmin = x;
|
||||
}
|
||||
if (x > xmax) {
|
||||
xmax = x;
|
||||
}
|
||||
if (xmin == xmax) {
|
||||
xmin--;
|
||||
xmax++;
|
||||
}
|
||||
v = (Sint32) x;
|
||||
v -= (xmax + xmin + 1) / 2;
|
||||
v *= 32768 / ((xmax - xmin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 0, v);
|
||||
}
|
||||
if (abs(y - gameport.y) > 8) {
|
||||
y = gameport.y;
|
||||
if (y < ymin) {
|
||||
ymin = y;
|
||||
}
|
||||
if (y > ymax) {
|
||||
ymax = y;
|
||||
}
|
||||
if (ymin == ymax) {
|
||||
ymin--;
|
||||
ymax++;
|
||||
}
|
||||
v = (Sint32) y;
|
||||
v -= (ymax + ymin + 1) / 2;
|
||||
v *= 32768 / ((ymax - ymin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 1, v);
|
||||
}
|
||||
SDL_PrivateJoystickButton(joy, 0, gameport.b1);
|
||||
SDL_PrivateJoystickButton(joy, 1, gameport.b2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
|
||||
|
||||
rep = &joy->hwdata->inreport;
|
||||
|
||||
while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
|
||||
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
|
||||
#else
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
|
||||
#endif
|
||||
if (hdata == NULL) {
|
||||
/*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
|
||||
continue;
|
||||
}
|
||||
|
||||
for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
|
||||
switch (hitem.kind) {
|
||||
case hid_input:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
{
|
||||
unsigned usage = HID_USAGE(hitem.usage);
|
||||
int joyaxe = usage_to_joyaxe(usage);
|
||||
if (joyaxe >= 0) {
|
||||
naxe = joy->hwdata->axis_map[joyaxe];
|
||||
/* scaleaxe */
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
v -= (hitem.logical_maximum +
|
||||
hitem.logical_minimum + 1) / 2;
|
||||
v *= 32768 /
|
||||
((hitem.logical_maximum -
|
||||
hitem.logical_minimum + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, naxe, v);
|
||||
} else if (usage == HUG_HAT_SWITCH) {
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0,
|
||||
hatval_to_sdl(v) -
|
||||
hitem.logical_minimum);
|
||||
}
|
||||
#ifdef __OpenBSD__
|
||||
else if (usage == HUG_DPAD_UP) {
|
||||
dpad[0] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
|
||||
}
|
||||
else if (usage == HUG_DPAD_DOWN) {
|
||||
dpad[1] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
|
||||
}
|
||||
else if (usage == HUG_DPAD_RIGHT) {
|
||||
dpad[2] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
|
||||
}
|
||||
else if (usage == HUG_DPAD_LEFT) {
|
||||
dpad[3] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case HUP_BUTTON:
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickButton(joy, nbutton, v);
|
||||
nbutton++;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
hid_end_parse(hdata);
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
static void
|
||||
BSD_JoystickClose(SDL_Joystick * joy)
|
||||
{
|
||||
if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
|
||||
report_free(&joy->hwdata->inreport);
|
||||
hid_dispose_report_desc(joy->hwdata->repdesc);
|
||||
}
|
||||
close(joy->hwdata->fd);
|
||||
SDL_free(joy->hwdata->path);
|
||||
SDL_free(joy->hwdata);
|
||||
}
|
||||
|
||||
static void
|
||||
BSD_JoystickQuit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_JOYS; i++) {
|
||||
SDL_free(joynames[i]);
|
||||
SDL_free(joydevnames[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
BSD_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
const char *name = BSD_JoystickGetDeviceName( device_index );
|
||||
SDL_zero( guid );
|
||||
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
|
||||
return guid;
|
||||
}
|
||||
|
||||
static int
|
||||
report_alloc(struct report *r, struct report_desc *rd, int repind)
|
||||
{
|
||||
int len;
|
||||
|
||||
#ifdef __DragonFly__
|
||||
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
|
||||
#elif __FREEBSD__
|
||||
# if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
|
||||
# if (__FreeBSD_kernel_version <= 500111)
|
||||
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
|
||||
# else
|
||||
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
|
||||
# endif
|
||||
# else
|
||||
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
|
||||
# endif
|
||||
#else
|
||||
# ifdef USBHID_NEW
|
||||
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
|
||||
# else
|
||||
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (len < 0) {
|
||||
return SDL_SetError("Negative HID report size");
|
||||
}
|
||||
r->size = len;
|
||||
|
||||
if (r->size > 0) {
|
||||
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
|
||||
r->buf = SDL_malloc(r->size);
|
||||
#else
|
||||
r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
|
||||
r->size);
|
||||
#endif
|
||||
if (r->buf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
} else {
|
||||
r->buf = NULL;
|
||||
}
|
||||
|
||||
r->status = SREPORT_CLEAN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
report_free(struct report *r)
|
||||
{
|
||||
SDL_free(r->buf);
|
||||
r->status = SREPORT_UNINIT;
|
||||
}
|
||||
|
||||
static int
|
||||
BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_BSD_JoystickDriver =
|
||||
{
|
||||
BSD_JoystickInit,
|
||||
BSD_JoystickGetCount,
|
||||
BSD_JoystickDetect,
|
||||
BSD_JoystickGetDeviceName,
|
||||
BSD_JoystickGetDevicePlayerIndex,
|
||||
BSD_JoystickSetDevicePlayerIndex,
|
||||
BSD_JoystickGetDeviceGUID,
|
||||
BSD_JoystickGetDeviceInstanceID,
|
||||
BSD_JoystickOpen,
|
||||
BSD_JoystickRumble,
|
||||
BSD_JoystickUpdate,
|
||||
BSD_JoystickClose,
|
||||
BSD_JoystickQuit,
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_USBHID */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
1066
externals/SDL/src/joystick/darwin/SDL_sysjoystick.c
vendored
1066
externals/SDL/src/joystick/darwin/SDL_sysjoystick.c
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_JOYSTICK_IOKIT_H
|
||||
#define SDL_JOYSTICK_IOKIT_H
|
||||
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <ForceFeedback/ForceFeedback.h>
|
||||
#include <ForceFeedback/ForceFeedbackConstants.h>
|
||||
|
||||
struct recElement
|
||||
{
|
||||
IOHIDElementRef elementRef;
|
||||
IOHIDElementCookie cookie;
|
||||
uint32_t usagePage, usage; /* HID usage */
|
||||
SInt32 min; /* reported min value possible */
|
||||
SInt32 max; /* reported max value possible */
|
||||
|
||||
/* runtime variables used for auto-calibration */
|
||||
SInt32 minReport; /* min returned value */
|
||||
SInt32 maxReport; /* max returned value */
|
||||
|
||||
struct recElement *pNext; /* next element in list */
|
||||
};
|
||||
typedef struct recElement recElement;
|
||||
|
||||
struct joystick_hwdata
|
||||
{
|
||||
IOHIDDeviceRef deviceRef; /* HIDManager device handle */
|
||||
io_service_t ffservice; /* Interface for force feedback, 0 = no ff */
|
||||
FFDeviceObjectReference ffdevice;
|
||||
FFEFFECT *ffeffect;
|
||||
FFEffectObjectReference ffeffect_ref;
|
||||
SDL_bool ff_initialized;
|
||||
|
||||
char product[256]; /* name of product */
|
||||
uint32_t usage; /* usage page from IOUSBHID Parser.h which defines general usage */
|
||||
uint32_t usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */
|
||||
|
||||
int axes; /* number of axis (calculated, not reported by device) */
|
||||
int buttons; /* number of buttons (calculated, not reported by device) */
|
||||
int hats; /* number of hat switches (calculated, not reported by device) */
|
||||
int elements; /* number of total elements (should be total of above) (calculated, not reported by device) */
|
||||
|
||||
recElement *firstAxis;
|
||||
recElement *firstButton;
|
||||
recElement *firstHat;
|
||||
|
||||
SDL_bool removed;
|
||||
|
||||
int instance_id;
|
||||
SDL_JoystickGUID guid;
|
||||
|
||||
struct joystick_hwdata *pNext; /* next device */
|
||||
};
|
||||
typedef struct joystick_hwdata recDevice;
|
||||
|
||||
#endif /* SDL_JOYSTICK_IOKIT_H */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
@@ -1,863 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
/* This is the iOS implementation of the SDL joystick API */
|
||||
#include "SDL_sysjoystick_c.h"
|
||||
|
||||
/* needed for SDL_IPHONE_MAX_GFORCE macro */
|
||||
#include "../../../include/SDL_config_iphoneos.h"
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#import <CoreMotion/CoreMotion.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
#import <GameController/GameController.h>
|
||||
|
||||
static id connectObserver = nil;
|
||||
static id disconnectObserver = nil;
|
||||
|
||||
#include <Availability.h>
|
||||
#include <objc/message.h>
|
||||
|
||||
/* remove compilation warnings for strict builds by defining these selectors, even though
|
||||
* they are only ever used indirectly through objc_msgSend
|
||||
*/
|
||||
@interface GCExtendedGamepad (SDL)
|
||||
#if (__IPHONE_OS_VERSION_MAX_ALLOWED < 121000) || (__APPLETV_OS_VERSION_MAX_ALLOWED < 121000) || (__MAC_OS_VERSION_MAX_ALLOWED < 1401000)
|
||||
@property (nonatomic, readonly, nullable) GCControllerButtonInput *leftThumbstickButton;
|
||||
@property (nonatomic, readonly, nullable) GCControllerButtonInput *rightThumbstickButton;
|
||||
#endif
|
||||
#if (__IPHONE_OS_VERSION_MAX_ALLOWED < 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED < 130000) || (__MAC_OS_VERSION_MAX_ALLOWED < 1500000)
|
||||
@property (nonatomic, readonly) GCControllerButtonInput *buttonMenu;
|
||||
@property (nonatomic, readonly, nullable) GCControllerButtonInput *buttonOptions;
|
||||
#endif
|
||||
@end
|
||||
@interface GCMicroGamepad (SDL)
|
||||
#if (__IPHONE_OS_VERSION_MAX_ALLOWED < 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED < 130000) || (__MAC_OS_VERSION_MAX_ALLOWED < 1500000)
|
||||
@property (nonatomic, readonly) GCControllerButtonInput *buttonMenu;
|
||||
#endif
|
||||
@end
|
||||
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
static const char *accelerometerName = "iOS Accelerometer";
|
||||
static CMMotionManager *motionManager = nil;
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
static SDL_JoystickDeviceItem *deviceList = NULL;
|
||||
|
||||
static int numjoysticks = 0;
|
||||
int SDL_AppleTVRemoteOpenedAsJoystick = 0;
|
||||
|
||||
static SDL_JoystickDeviceItem *
|
||||
GetDeviceForIndex(int device_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = deviceList;
|
||||
int i = 0;
|
||||
|
||||
while (i < device_index) {
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
device = device->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
|
||||
{
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
const Uint16 VENDOR_APPLE = 0x05AC;
|
||||
const Uint16 VENDOR_MICROSOFT = 0x045e;
|
||||
const Uint16 VENDOR_SONY = 0x054C;
|
||||
Uint16 *guid16 = (Uint16 *)device->guid.data;
|
||||
Uint16 vendor = 0;
|
||||
Uint16 product = 0;
|
||||
Uint8 subtype = 0;
|
||||
|
||||
const char *name = NULL;
|
||||
/* Explicitly retain the controller because SDL_JoystickDeviceItem is a
|
||||
* struct, and ARC doesn't work with structs. */
|
||||
device->controller = (__bridge GCController *) CFBridgingRetain(controller);
|
||||
|
||||
if (controller.vendorName) {
|
||||
name = controller.vendorName.UTF8String;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
name = "MFi Gamepad";
|
||||
}
|
||||
|
||||
device->name = SDL_strdup(name);
|
||||
|
||||
if (controller.extendedGamepad) {
|
||||
GCExtendedGamepad *gamepad = controller.extendedGamepad;
|
||||
BOOL is_xbox = [controller.vendorName containsString: @"Xbox"];
|
||||
BOOL is_ps4 = [controller.vendorName containsString: @"DUALSHOCK"];
|
||||
#if TARGET_OS_TV
|
||||
BOOL is_MFi = (!is_xbox && !is_ps4);
|
||||
#endif
|
||||
int nbuttons = 0;
|
||||
|
||||
/* These buttons are part of the original MFi spec */
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_Y);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
nbuttons += 6;
|
||||
|
||||
/* These buttons are available on some newer controllers */
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
if ([gamepad respondsToSelector:@selector(leftThumbstickButton)] && gamepad.leftThumbstickButton) {
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||
++nbuttons;
|
||||
}
|
||||
if ([gamepad respondsToSelector:@selector(rightThumbstickButton)] && gamepad.rightThumbstickButton) {
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
||||
++nbuttons;
|
||||
}
|
||||
if ([gamepad respondsToSelector:@selector(buttonOptions)] && gamepad.buttonOptions) {
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_BACK);
|
||||
++nbuttons;
|
||||
}
|
||||
BOOL has_direct_menu = [gamepad respondsToSelector:@selector(buttonMenu)] && gamepad.buttonMenu;
|
||||
#if TARGET_OS_TV
|
||||
/* On tvOS MFi controller menu button brings you to the home screen */
|
||||
if (is_MFi) {
|
||||
has_direct_menu = FALSE;
|
||||
}
|
||||
#endif
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
|
||||
++nbuttons;
|
||||
if (!has_direct_menu) {
|
||||
device->uses_pause_handler = SDL_TRUE;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if (is_xbox) {
|
||||
vendor = VENDOR_MICROSOFT;
|
||||
product = 0x02E0; /* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
|
||||
} else if (is_ps4) {
|
||||
vendor = VENDOR_SONY;
|
||||
product = 0x09CC; /* Assume DS4 Slim unless/until GCController flows VID/PID */
|
||||
} else {
|
||||
vendor = VENDOR_APPLE;
|
||||
product = 1;
|
||||
subtype = 1;
|
||||
}
|
||||
|
||||
device->naxes = 6; /* 2 thumbsticks and 2 triggers */
|
||||
device->nhats = 1; /* d-pad */
|
||||
device->nbuttons = nbuttons;
|
||||
|
||||
} else if (controller.gamepad) {
|
||||
int nbuttons = 0;
|
||||
|
||||
/* These buttons are part of the original MFi spec */
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_Y);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
|
||||
nbuttons += 7;
|
||||
device->uses_pause_handler = SDL_TRUE;
|
||||
|
||||
vendor = VENDOR_APPLE;
|
||||
product = 2;
|
||||
subtype = 2;
|
||||
device->naxes = 0; /* no traditional analog inputs */
|
||||
device->nhats = 1; /* d-pad */
|
||||
device->nbuttons = nbuttons;
|
||||
}
|
||||
#if TARGET_OS_TV
|
||||
else if (controller.microGamepad) {
|
||||
int nbuttons = 0;
|
||||
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); /* Button X on microGamepad */
|
||||
nbuttons += 2;
|
||||
|
||||
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
|
||||
++nbuttons;
|
||||
device->uses_pause_handler = SDL_TRUE;
|
||||
|
||||
vendor = VENDOR_APPLE;
|
||||
product = 3;
|
||||
subtype = 3;
|
||||
device->naxes = 2; /* treat the touch surface as two axes */
|
||||
device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
|
||||
device->nbuttons = nbuttons;
|
||||
|
||||
controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE);
|
||||
}
|
||||
#endif /* TARGET_OS_TV */
|
||||
|
||||
/* We only need 16 bits for each of these; space them out to fill 128. */
|
||||
/* Byteswap so devices get same GUID on little/big endian platforms. */
|
||||
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
|
||||
*guid16++ = 0;
|
||||
*guid16++ = SDL_SwapLE16(vendor);
|
||||
*guid16++ = 0;
|
||||
*guid16++ = SDL_SwapLE16(product);
|
||||
*guid16++ = 0;
|
||||
|
||||
*guid16++ = SDL_SwapLE16(device->button_mask);
|
||||
|
||||
if (subtype != 0) {
|
||||
/* Note that this is an MFI controller and what subtype it is */
|
||||
device->guid.data[14] = 'm';
|
||||
device->guid.data[15] = subtype;
|
||||
}
|
||||
|
||||
/* This will be set when the first button press of the controller is
|
||||
* detected. */
|
||||
controller.playerIndex = -1;
|
||||
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = deviceList;
|
||||
|
||||
#if TARGET_OS_TV
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
|
||||
/* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
|
||||
if (controller && !controller.extendedGamepad && !controller.gamepad && controller.microGamepad) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (device != NULL) {
|
||||
if (device->controller == controller) {
|
||||
return;
|
||||
}
|
||||
device = device->next;
|
||||
}
|
||||
|
||||
device = (SDL_JoystickDeviceItem *) SDL_calloc(1, sizeof(SDL_JoystickDeviceItem));
|
||||
if (device == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
device->accelerometer = accelerometer;
|
||||
device->instance_id = SDL_GetNextJoystickInstanceID();
|
||||
|
||||
if (accelerometer) {
|
||||
#if TARGET_OS_TV
|
||||
SDL_free(device);
|
||||
return;
|
||||
#else
|
||||
device->name = SDL_strdup(accelerometerName);
|
||||
device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
|
||||
device->nhats = 0;
|
||||
device->nbuttons = 0;
|
||||
|
||||
/* Use the accelerometer name as a GUID. */
|
||||
SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
|
||||
#endif /* TARGET_OS_TV */
|
||||
} else if (controller) {
|
||||
IOS_AddMFIJoystickDevice(device, controller);
|
||||
}
|
||||
|
||||
if (deviceList == NULL) {
|
||||
deviceList = device;
|
||||
} else {
|
||||
SDL_JoystickDeviceItem *lastdevice = deviceList;
|
||||
while (lastdevice->next != NULL) {
|
||||
lastdevice = lastdevice->next;
|
||||
}
|
||||
lastdevice->next = device;
|
||||
}
|
||||
|
||||
++numjoysticks;
|
||||
|
||||
SDL_PrivateJoystickAdded(device->instance_id);
|
||||
}
|
||||
|
||||
static SDL_JoystickDeviceItem *
|
||||
IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
|
||||
{
|
||||
SDL_JoystickDeviceItem *prev = NULL;
|
||||
SDL_JoystickDeviceItem *next = NULL;
|
||||
SDL_JoystickDeviceItem *item = deviceList;
|
||||
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
next = device->next;
|
||||
|
||||
while (item != NULL) {
|
||||
if (item == device) {
|
||||
break;
|
||||
}
|
||||
prev = item;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
/* Unlink the device item from the device list. */
|
||||
if (prev) {
|
||||
prev->next = device->next;
|
||||
} else if (device == deviceList) {
|
||||
deviceList = device->next;
|
||||
}
|
||||
|
||||
if (device->joystick) {
|
||||
device->joystick->hwdata = NULL;
|
||||
}
|
||||
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
@autoreleasepool {
|
||||
if (device->controller) {
|
||||
/* The controller was explicitly retained in the struct, so it
|
||||
* should be explicitly released before freeing the struct. */
|
||||
GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
|
||||
controller.controllerPausedHandler = nil;
|
||||
device->controller = nil;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
|
||||
--numjoysticks;
|
||||
|
||||
SDL_PrivateJoystickRemoved(device->instance_id);
|
||||
|
||||
SDL_free(device->name);
|
||||
SDL_free(device);
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV
|
||||
static void SDLCALL
|
||||
SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue)
|
||||
{
|
||||
BOOL allowRotation = newValue != NULL && *newValue != '0';
|
||||
|
||||
@autoreleasepool {
|
||||
for (GCController *controller in [GCController controllers]) {
|
||||
if (controller.microGamepad) {
|
||||
controller.microGamepad.allowsRotation = allowRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* TARGET_OS_TV */
|
||||
|
||||
static int
|
||||
IOS_JoystickInit(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) {
|
||||
/* Default behavior, accelerometer as joystick */
|
||||
IOS_AddJoystickDevice(nil, SDL_TRUE);
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
/* GameController.framework was added in iOS 7. */
|
||||
if (![GCController class]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (GCController *controller in [GCController controllers]) {
|
||||
IOS_AddJoystickDevice(controller, SDL_FALSE);
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV
|
||||
SDL_AddHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
|
||||
SDL_AppleTVRemoteRotationHintChanged, NULL);
|
||||
#endif /* TARGET_OS_TV */
|
||||
|
||||
connectObserver = [center addObserverForName:GCControllerDidConnectNotification
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification *note) {
|
||||
GCController *controller = note.object;
|
||||
IOS_AddJoystickDevice(controller, SDL_FALSE);
|
||||
}];
|
||||
|
||||
disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification *note) {
|
||||
GCController *controller = note.object;
|
||||
SDL_JoystickDeviceItem *device = deviceList;
|
||||
while (device != NULL) {
|
||||
if (device->controller == controller) {
|
||||
IOS_RemoveJoystickDevice(device);
|
||||
break;
|
||||
}
|
||||
device = device->next;
|
||||
}
|
||||
}];
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickGetCount(void)
|
||||
{
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_JoystickDetect(void)
|
||||
{
|
||||
}
|
||||
|
||||
static const char *
|
||||
IOS_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
return device ? device->name : "Unknown";
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
return device ? (int)device->controller.playerIndex : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
if (device) {
|
||||
device->controller.playerIndex = player_index;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
IOS_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
SDL_JoystickGUID guid;
|
||||
if (device) {
|
||||
guid = device->guid;
|
||||
} else {
|
||||
SDL_zero(guid);
|
||||
}
|
||||
return guid;
|
||||
}
|
||||
|
||||
static SDL_JoystickID
|
||||
IOS_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
return device ? device->instance_id : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
if (device == NULL) {
|
||||
return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
|
||||
}
|
||||
|
||||
joystick->hwdata = device;
|
||||
joystick->instance_id = device->instance_id;
|
||||
|
||||
joystick->naxes = device->naxes;
|
||||
joystick->nhats = device->nhats;
|
||||
joystick->nbuttons = device->nbuttons;
|
||||
joystick->nballs = 0;
|
||||
|
||||
device->joystick = joystick;
|
||||
|
||||
@autoreleasepool {
|
||||
if (device->accelerometer) {
|
||||
#if !TARGET_OS_TV
|
||||
if (motionManager == nil) {
|
||||
motionManager = [[CMMotionManager alloc] init];
|
||||
}
|
||||
|
||||
/* Shorter times between updates can significantly increase CPU usage. */
|
||||
motionManager.accelerometerUpdateInterval = 0.1;
|
||||
[motionManager startAccelerometerUpdates];
|
||||
#endif /* !TARGET_OS_TV */
|
||||
} else {
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
if (device->uses_pause_handler) {
|
||||
GCController *controller = device->controller;
|
||||
controller.controllerPausedHandler = ^(GCController *c) {
|
||||
if (joystick->hwdata) {
|
||||
++joystick->hwdata->num_pause_presses;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
}
|
||||
}
|
||||
if (device->remote) {
|
||||
++SDL_AppleTVRemoteOpenedAsJoystick;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_AccelerometerUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
const float maxgforce = SDL_IPHONE_MAX_GFORCE;
|
||||
const SInt16 maxsint16 = 0x7FFF;
|
||||
CMAcceleration accel;
|
||||
|
||||
@autoreleasepool {
|
||||
if (!motionManager.isAccelerometerActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
accel = motionManager.accelerometerData.acceleration;
|
||||
}
|
||||
|
||||
/*
|
||||
Convert accelerometer data from floating point to Sint16, which is what
|
||||
the joystick system expects.
|
||||
|
||||
To do the conversion, the data is first clamped onto the interval
|
||||
[-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
|
||||
by MAX_SINT16 so that it is mapped to the full range of an Sint16.
|
||||
|
||||
You can customize the clamped range of this function by modifying the
|
||||
SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
|
||||
|
||||
Once converted to Sint16, the accelerometer data no longer has coherent
|
||||
units. You can convert the data back to units of g-force by multiplying
|
||||
it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
|
||||
*/
|
||||
|
||||
/* clamp the data */
|
||||
accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
|
||||
accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
|
||||
accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
|
||||
|
||||
/* pass in data mapped to range of SInt16 */
|
||||
SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
|
||||
SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
|
||||
SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
|
||||
#endif /* !TARGET_OS_TV */
|
||||
}
|
||||
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
static Uint8
|
||||
IOS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
|
||||
{
|
||||
Uint8 hat = 0;
|
||||
|
||||
if (dpad.up.isPressed) {
|
||||
hat |= SDL_HAT_UP;
|
||||
} else if (dpad.down.isPressed) {
|
||||
hat |= SDL_HAT_DOWN;
|
||||
}
|
||||
|
||||
if (dpad.left.isPressed) {
|
||||
hat |= SDL_HAT_LEFT;
|
||||
} else if (dpad.right.isPressed) {
|
||||
hat |= SDL_HAT_RIGHT;
|
||||
}
|
||||
|
||||
if (hat == 0) {
|
||||
return SDL_HAT_CENTERED;
|
||||
}
|
||||
|
||||
return hat;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
#if SDL_JOYSTICK_MFI
|
||||
@autoreleasepool {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
Uint8 hatstate = SDL_HAT_CENTERED;
|
||||
int i;
|
||||
int pause_button_index = 0;
|
||||
|
||||
if (controller.extendedGamepad) {
|
||||
GCExtendedGamepad *gamepad = controller.extendedGamepad;
|
||||
|
||||
/* Axis order matches the XInput Windows mappings. */
|
||||
Sint16 axes[] = {
|
||||
(Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
|
||||
(Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
|
||||
(Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
|
||||
(Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
|
||||
(Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
|
||||
(Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
|
||||
};
|
||||
|
||||
/* Button order matches the XInput Windows mappings. */
|
||||
Uint8 buttons[joystick->nbuttons];
|
||||
int button_count = 0;
|
||||
|
||||
/* These buttons are part of the original MFi spec */
|
||||
buttons[button_count++] = gamepad.buttonA.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonB.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonX.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonY.isPressed;
|
||||
buttons[button_count++] = gamepad.leftShoulder.isPressed;
|
||||
buttons[button_count++] = gamepad.rightShoulder.isPressed;
|
||||
|
||||
/* These buttons are available on some newer controllers */
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) {
|
||||
buttons[button_count++] = gamepad.leftThumbstickButton.isPressed;
|
||||
}
|
||||
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) {
|
||||
buttons[button_count++] = gamepad.rightThumbstickButton.isPressed;
|
||||
}
|
||||
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
|
||||
buttons[button_count++] = gamepad.buttonOptions.isPressed;
|
||||
}
|
||||
/* This must be the last button, so we can optionally handle it with pause_button_index below */
|
||||
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
|
||||
if (joystick->hwdata->uses_pause_handler) {
|
||||
pause_button_index = button_count;
|
||||
buttons[button_count++] = joystick->delayed_guide_button;
|
||||
} else {
|
||||
buttons[button_count++] = gamepad.buttonMenu.isPressed;
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
|
||||
|
||||
for (i = 0; i < SDL_arraysize(axes); i++) {
|
||||
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < button_count; i++) {
|
||||
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
|
||||
}
|
||||
} else if (controller.gamepad) {
|
||||
GCGamepad *gamepad = controller.gamepad;
|
||||
|
||||
/* Button order matches the XInput Windows mappings. */
|
||||
Uint8 buttons[joystick->nbuttons];
|
||||
int button_count = 0;
|
||||
buttons[button_count++] = gamepad.buttonA.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonB.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonX.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonY.isPressed;
|
||||
buttons[button_count++] = gamepad.leftShoulder.isPressed;
|
||||
buttons[button_count++] = gamepad.rightShoulder.isPressed;
|
||||
pause_button_index = button_count;
|
||||
buttons[button_count++] = joystick->delayed_guide_button;
|
||||
|
||||
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
|
||||
|
||||
for (i = 0; i < button_count; i++) {
|
||||
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
|
||||
}
|
||||
}
|
||||
#if TARGET_OS_TV
|
||||
else if (controller.microGamepad) {
|
||||
GCMicroGamepad *gamepad = controller.microGamepad;
|
||||
|
||||
Sint16 axes[] = {
|
||||
(Sint16) (gamepad.dpad.xAxis.value * 32767),
|
||||
(Sint16) (gamepad.dpad.yAxis.value * -32767),
|
||||
};
|
||||
|
||||
for (i = 0; i < SDL_arraysize(axes); i++) {
|
||||
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
|
||||
}
|
||||
|
||||
Uint8 buttons[joystick->nbuttons];
|
||||
int button_count = 0;
|
||||
buttons[button_count++] = gamepad.buttonA.isPressed;
|
||||
buttons[button_count++] = gamepad.buttonX.isPressed;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
|
||||
/* This must be the last button, so we can optionally handle it with pause_button_index below */
|
||||
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
|
||||
if (joystick->hwdata->uses_pause_handler) {
|
||||
pause_button_index = button_count;
|
||||
buttons[button_count++] = joystick->delayed_guide_button;
|
||||
} else {
|
||||
buttons[button_count++] = gamepad.buttonMenu.isPressed;
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
for (i = 0; i < button_count; i++) {
|
||||
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
|
||||
}
|
||||
}
|
||||
#endif /* TARGET_OS_TV */
|
||||
|
||||
if (joystick->nhats > 0) {
|
||||
SDL_PrivateJoystickHat(joystick, 0, hatstate);
|
||||
}
|
||||
|
||||
if (joystick->hwdata->uses_pause_handler) {
|
||||
for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
|
||||
SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_PRESSED);
|
||||
SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_RELEASED);
|
||||
}
|
||||
joystick->hwdata->num_pause_presses = 0;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->accelerometer) {
|
||||
IOS_AccelerometerUpdate(joystick);
|
||||
} else if (device->controller) {
|
||||
IOS_MFIJoystickUpdate(joystick);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
device->joystick = NULL;
|
||||
|
||||
@autoreleasepool {
|
||||
if (device->accelerometer) {
|
||||
#if !TARGET_OS_TV
|
||||
[motionManager stopAccelerometerUpdates];
|
||||
#endif /* !TARGET_OS_TV */
|
||||
} else if (device->controller) {
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
GCController *controller = device->controller;
|
||||
controller.controllerPausedHandler = nil;
|
||||
controller.playerIndex = -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (device->remote) {
|
||||
--SDL_AppleTVRemoteOpenedAsJoystick;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IOS_JoystickQuit(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
#ifdef SDL_JOYSTICK_MFI
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
if (connectObserver) {
|
||||
[center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
|
||||
connectObserver = nil;
|
||||
}
|
||||
|
||||
if (disconnectObserver) {
|
||||
[center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
|
||||
disconnectObserver = nil;
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV
|
||||
SDL_DelHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
|
||||
SDL_AppleTVRemoteRotationHintChanged, NULL);
|
||||
#endif /* TARGET_OS_TV */
|
||||
#endif /* SDL_JOYSTICK_MFI */
|
||||
|
||||
while (deviceList != NULL) {
|
||||
IOS_RemoveJoystickDevice(deviceList);
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
motionManager = nil;
|
||||
#endif /* !TARGET_OS_TV */
|
||||
}
|
||||
|
||||
numjoysticks = 0;
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_IOS_JoystickDriver =
|
||||
{
|
||||
IOS_JoystickInit,
|
||||
IOS_JoystickGetCount,
|
||||
IOS_JoystickDetect,
|
||||
IOS_JoystickGetDeviceName,
|
||||
IOS_JoystickGetDevicePlayerIndex,
|
||||
IOS_JoystickSetDevicePlayerIndex,
|
||||
IOS_JoystickGetDeviceGUID,
|
||||
IOS_JoystickGetDeviceInstanceID,
|
||||
IOS_JoystickOpen,
|
||||
IOS_JoystickRumble,
|
||||
IOS_JoystickUpdate,
|
||||
IOS_JoystickClose,
|
||||
IOS_JoystickQuit,
|
||||
};
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_JOYSTICK_IOS_H
|
||||
#define SDL_JOYSTICK_IOS_H
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
|
||||
@class GCController;
|
||||
|
||||
typedef struct joystick_hwdata
|
||||
{
|
||||
SDL_bool accelerometer;
|
||||
SDL_bool remote;
|
||||
|
||||
GCController __unsafe_unretained *controller;
|
||||
SDL_bool uses_pause_handler;
|
||||
int num_pause_presses;
|
||||
Uint32 pause_button_down_time;
|
||||
|
||||
char *name;
|
||||
SDL_Joystick *joystick;
|
||||
SDL_JoystickID instance_id;
|
||||
SDL_JoystickGUID guid;
|
||||
|
||||
int naxes;
|
||||
int nbuttons;
|
||||
int nhats;
|
||||
Uint16 button_mask;
|
||||
|
||||
struct joystick_hwdata *next;
|
||||
} joystick_hwdata;
|
||||
|
||||
typedef joystick_hwdata SDL_JoystickDeviceItem;
|
||||
|
||||
#endif /* SDL_JOYSTICK_IOS_H */
|
||||
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
515
externals/SDL/src/joystick/windows/SDL_mmjoystick.c
vendored
515
externals/SDL/src/joystick/windows/SDL_mmjoystick.c
vendored
@@ -1,515 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_WINMM
|
||||
|
||||
/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include <mmsystem.h>
|
||||
#include <regstr.h>
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#ifdef REGSTR_VAL_JOYOEMNAME
|
||||
#undef REGSTR_VAL_JOYOEMNAME
|
||||
#endif
|
||||
#define REGSTR_VAL_JOYOEMNAME "OEMName"
|
||||
|
||||
#define MAX_JOYSTICKS 16
|
||||
#define MAX_AXES 6 /* each joystick can have up to 6 axes */
|
||||
#define MAX_BUTTONS 32 /* and 32 buttons */
|
||||
#define JOY_BUTTON_FLAG(n) (1<<n)
|
||||
|
||||
|
||||
/* array to hold joystick ID values */
|
||||
static UINT SYS_JoystickID[MAX_JOYSTICKS];
|
||||
static JOYCAPSA SYS_Joystick[MAX_JOYSTICKS];
|
||||
static char *SYS_JoystickName[MAX_JOYSTICKS];
|
||||
|
||||
/* The private structure used to keep track of a joystick */
|
||||
struct joystick_hwdata
|
||||
{
|
||||
/* joystick ID */
|
||||
UINT id;
|
||||
|
||||
/* values used to translate device-specific coordinates into
|
||||
SDL-standard ranges */
|
||||
struct _transaxis
|
||||
{
|
||||
int offset;
|
||||
float scale;
|
||||
} transaxis[6];
|
||||
};
|
||||
|
||||
/* Convert a Windows Multimedia API return code to a text message */
|
||||
static void SetMMerror(char *function, int code);
|
||||
|
||||
|
||||
static char *
|
||||
GetJoystickName(int index, const char *szRegKey)
|
||||
{
|
||||
/* added 7/24/2004 by Eckhard Stolberg */
|
||||
/*
|
||||
see if there is a joystick for the current
|
||||
index (1-16) listed in the registry
|
||||
*/
|
||||
char *name = NULL;
|
||||
HKEY hTopKey;
|
||||
HKEY hKey;
|
||||
DWORD regsize;
|
||||
LONG regresult;
|
||||
char regkey[256];
|
||||
char regvalue[256];
|
||||
char regname[256];
|
||||
|
||||
SDL_snprintf(regkey, SDL_arraysize(regkey),
|
||||
#ifdef UNICODE
|
||||
"%S\\%s\\%S",
|
||||
#else
|
||||
"%s\\%s\\%s",
|
||||
#endif
|
||||
REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR);
|
||||
hTopKey = HKEY_LOCAL_MACHINE;
|
||||
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
hTopKey = HKEY_CURRENT_USER;
|
||||
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
|
||||
}
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find the registry key name for the joystick's properties */
|
||||
regsize = sizeof(regname);
|
||||
SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index + 1,
|
||||
REGSTR_VAL_JOYOEMNAME);
|
||||
regresult =
|
||||
RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE) regname, ®size);
|
||||
RegCloseKey(hKey);
|
||||
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open that registry key */
|
||||
SDL_snprintf(regkey, SDL_arraysize(regkey),
|
||||
#ifdef UNICODE
|
||||
"%S\\%s",
|
||||
#else
|
||||
"%s\\%s",
|
||||
#endif
|
||||
REGSTR_PATH_JOYOEM, regname);
|
||||
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find the size for the OEM name text */
|
||||
regsize = sizeof(regvalue);
|
||||
regresult =
|
||||
RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, ®size);
|
||||
if (regresult == ERROR_SUCCESS) {
|
||||
/* allocate enough memory for the OEM name text ... */
|
||||
name = (char *) SDL_malloc(regsize);
|
||||
if (name) {
|
||||
/* ... and read it from the registry */
|
||||
regresult = RegQueryValueExA(hKey,
|
||||
REGSTR_VAL_JOYOEMNAME, 0, 0,
|
||||
(LPBYTE) name, ®size);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return (name);
|
||||
}
|
||||
|
||||
static int numjoysticks = 0;
|
||||
|
||||
/* Function to scan the system for joysticks.
|
||||
* Joystick 0 should be the system default joystick.
|
||||
* It should return 0, or -1 on an unrecoverable fatal error.
|
||||
*/
|
||||
static int
|
||||
WINMM_JoystickInit(void)
|
||||
{
|
||||
int i;
|
||||
int maxdevs;
|
||||
JOYINFOEX joyinfo;
|
||||
JOYCAPSA joycaps;
|
||||
MMRESULT result;
|
||||
|
||||
/* Reset the joystick ID & name mapping tables */
|
||||
for (i = 0; i < MAX_JOYSTICKS; ++i) {
|
||||
SYS_JoystickID[i] = 0;
|
||||
SYS_JoystickName[i] = NULL;
|
||||
}
|
||||
|
||||
/* Loop over all potential joystick devices */
|
||||
numjoysticks = 0;
|
||||
maxdevs = joyGetNumDevs();
|
||||
for (i = JOYSTICKID1; i < maxdevs && numjoysticks < MAX_JOYSTICKS; ++i) {
|
||||
|
||||
joyinfo.dwSize = sizeof(joyinfo);
|
||||
joyinfo.dwFlags = JOY_RETURNALL;
|
||||
result = joyGetPosEx(i, &joyinfo);
|
||||
if (result == JOYERR_NOERROR) {
|
||||
result = joyGetDevCapsA(i, &joycaps, sizeof(joycaps));
|
||||
if (result == JOYERR_NOERROR) {
|
||||
SYS_JoystickID[numjoysticks] = i;
|
||||
SYS_Joystick[numjoysticks] = joycaps;
|
||||
SYS_JoystickName[numjoysticks] =
|
||||
GetJoystickName(i, joycaps.szRegKey);
|
||||
numjoysticks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
static int
|
||||
WINMM_NumJoysticks(void)
|
||||
{
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
static void
|
||||
WINMM_JoystickDetect(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *
|
||||
WINMM_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
if (SYS_JoystickName[device_index] != NULL) {
|
||||
return (SYS_JoystickName[device_index]);
|
||||
} else {
|
||||
return (SYS_Joystick[device_index].szPname);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
WINMM_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
WINMM_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
{
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID WINMM_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
const char *name = WINMM_JoystickGetDeviceName(device_index);
|
||||
SDL_zero(guid);
|
||||
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
|
||||
return guid;
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
static SDL_JoystickID WINMM_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
return device_index;
|
||||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
static int
|
||||
WINMM_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
{
|
||||
int index, i;
|
||||
int caps_flags[MAX_AXES - 2] =
|
||||
{ JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV };
|
||||
int axis_min[MAX_AXES], axis_max[MAX_AXES];
|
||||
|
||||
/* shortcut */
|
||||
index = device_index;
|
||||
axis_min[0] = SYS_Joystick[index].wXmin;
|
||||
axis_max[0] = SYS_Joystick[index].wXmax;
|
||||
axis_min[1] = SYS_Joystick[index].wYmin;
|
||||
axis_max[1] = SYS_Joystick[index].wYmax;
|
||||
axis_min[2] = SYS_Joystick[index].wZmin;
|
||||
axis_max[2] = SYS_Joystick[index].wZmax;
|
||||
axis_min[3] = SYS_Joystick[index].wRmin;
|
||||
axis_max[3] = SYS_Joystick[index].wRmax;
|
||||
axis_min[4] = SYS_Joystick[index].wUmin;
|
||||
axis_max[4] = SYS_Joystick[index].wUmax;
|
||||
axis_min[5] = SYS_Joystick[index].wVmin;
|
||||
axis_max[5] = SYS_Joystick[index].wVmax;
|
||||
|
||||
/* allocate memory for system specific hardware data */
|
||||
joystick->instance_id = device_index;
|
||||
joystick->hwdata =
|
||||
(struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
|
||||
if (joystick->hwdata == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
|
||||
|
||||
/* set hardware data */
|
||||
joystick->hwdata->id = SYS_JoystickID[index];
|
||||
for (i = 0; i < MAX_AXES; ++i) {
|
||||
if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) {
|
||||
joystick->hwdata->transaxis[i].offset = SDL_JOYSTICK_AXIS_MIN - axis_min[i];
|
||||
joystick->hwdata->transaxis[i].scale =
|
||||
(float) (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) / (axis_max[i] - axis_min[i]);
|
||||
} else {
|
||||
joystick->hwdata->transaxis[i].offset = 0;
|
||||
joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
|
||||
}
|
||||
}
|
||||
|
||||
/* fill nbuttons, naxes, and nhats fields */
|
||||
joystick->nbuttons = SYS_Joystick[index].wNumButtons;
|
||||
joystick->naxes = SYS_Joystick[index].wNumAxes;
|
||||
if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) {
|
||||
joystick->nhats = 1;
|
||||
} else {
|
||||
joystick->nhats = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static Uint8
|
||||
TranslatePOV(DWORD value)
|
||||
{
|
||||
Uint8 pos;
|
||||
|
||||
pos = SDL_HAT_CENTERED;
|
||||
if (value != JOY_POVCENTERED) {
|
||||
if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) {
|
||||
pos |= SDL_HAT_UP;
|
||||
}
|
||||
if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) {
|
||||
pos |= SDL_HAT_RIGHT;
|
||||
}
|
||||
if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) {
|
||||
pos |= SDL_HAT_DOWN;
|
||||
}
|
||||
if (value > JOY_POVBACKWARD) {
|
||||
pos |= SDL_HAT_LEFT;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
|
||||
static int
|
||||
WINMM_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
WINMM_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool WINMM_JoystickHasLED(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
WINMM_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
WINMM_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int WINMM_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
/* Function to update the state of a joystick - called as a device poll.
|
||||
* This function shouldn't update the joystick structure directly,
|
||||
* but instead should call SDL_PrivateJoystick*() to deliver events
|
||||
* and update joystick device state.
|
||||
*/
|
||||
static void
|
||||
WINMM_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
MMRESULT result;
|
||||
int i;
|
||||
DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ,
|
||||
JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
|
||||
};
|
||||
DWORD pos[MAX_AXES];
|
||||
struct _transaxis *transaxis;
|
||||
int value;
|
||||
JOYINFOEX joyinfo;
|
||||
|
||||
joyinfo.dwSize = sizeof(joyinfo);
|
||||
joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS;
|
||||
if (!joystick->hats) {
|
||||
joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS);
|
||||
}
|
||||
result = joyGetPosEx(joystick->hwdata->id, &joyinfo);
|
||||
if (result != JOYERR_NOERROR) {
|
||||
SetMMerror("joyGetPosEx", result);
|
||||
return;
|
||||
}
|
||||
|
||||
/* joystick motion events */
|
||||
pos[0] = joyinfo.dwXpos;
|
||||
pos[1] = joyinfo.dwYpos;
|
||||
pos[2] = joyinfo.dwZpos;
|
||||
pos[3] = joyinfo.dwRpos;
|
||||
pos[4] = joyinfo.dwUpos;
|
||||
pos[5] = joyinfo.dwVpos;
|
||||
|
||||
transaxis = joystick->hwdata->transaxis;
|
||||
for (i = 0; i < joystick->naxes; i++) {
|
||||
if (joyinfo.dwFlags & flags[i]) {
|
||||
value = (int) (((float) pos[i] + transaxis[i].offset) * transaxis[i].scale);
|
||||
SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value);
|
||||
}
|
||||
}
|
||||
|
||||
/* joystick button events */
|
||||
if (joyinfo.dwFlags & JOY_RETURNBUTTONS) {
|
||||
for (i = 0; i < joystick->nbuttons; ++i) {
|
||||
if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) {
|
||||
SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_PRESSED);
|
||||
} else {
|
||||
SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* joystick hat events */
|
||||
if (joyinfo.dwFlags & JOY_RETURNPOV) {
|
||||
SDL_PrivateJoystickHat(joystick, 0, TranslatePOV(joyinfo.dwPOV));
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
static void
|
||||
WINMM_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_free(joystick->hwdata);
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
static void
|
||||
WINMM_JoystickQuit(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_JOYSTICKS; i++) {
|
||||
SDL_free(SYS_JoystickName[i]);
|
||||
SYS_JoystickName[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WINMM_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* implementation functions */
|
||||
void
|
||||
SetMMerror(char *function, int code)
|
||||
{
|
||||
static char *error;
|
||||
static char errbuf[1024];
|
||||
|
||||
errbuf[0] = 0;
|
||||
switch (code) {
|
||||
case MMSYSERR_NODRIVER:
|
||||
error = "Joystick driver not present";
|
||||
break;
|
||||
|
||||
case MMSYSERR_INVALPARAM:
|
||||
case JOYERR_PARMS:
|
||||
error = "Invalid parameter(s)";
|
||||
break;
|
||||
|
||||
case MMSYSERR_BADDEVICEID:
|
||||
error = "Bad device ID";
|
||||
break;
|
||||
|
||||
case JOYERR_UNPLUGGED:
|
||||
error = "Joystick not attached";
|
||||
break;
|
||||
|
||||
case JOYERR_NOCANDO:
|
||||
error = "Can't capture joystick input";
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
|
||||
"%s: Unknown Multimedia system error: 0x%x",
|
||||
function, code);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!errbuf[0]) {
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
|
||||
error);
|
||||
}
|
||||
SDL_SetError("%s", errbuf);
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_WINMM_JoystickDriver =
|
||||
{
|
||||
WINMM_JoystickInit,
|
||||
WINMM_NumJoysticks,
|
||||
WINMM_JoystickDetect,
|
||||
WINMM_JoystickGetDeviceName,
|
||||
WINMM_JoystickGetDevicePlayerIndex,
|
||||
WINMM_JoystickSetDevicePlayerIndex,
|
||||
WINMM_JoystickGetDeviceGUID,
|
||||
WINMM_JoystickGetDeviceInstanceID,
|
||||
WINMM_JoystickOpen,
|
||||
WINMM_JoystickRumble,
|
||||
WINMM_JoystickRumbleTriggers,
|
||||
WINMM_JoystickHasLED,
|
||||
WINMM_JoystickSetLED,
|
||||
WINMM_JoystickSendEffect,
|
||||
WINMM_JoystickSetSensorsEnabled,
|
||||
WINMM_JoystickUpdate,
|
||||
WINMM_JoystickClose,
|
||||
WINMM_JoystickQuit,
|
||||
WINMM_JoystickGetGamepadMapping
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_WINMM */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
Reference in New Issue
Block a user