mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 08:15:44 +00:00
* Adjustment: Update libsdl to address a bug in compilation on MacOS devices.
This commit is contained in:
parent
516163fd5d
commit
eab544c8f3
270 changed files with 9531 additions and 3704 deletions
|
|
@ -696,19 +696,20 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
|
|||
return s_pXInputMapping;
|
||||
}
|
||||
#endif
|
||||
if (!mapping) {
|
||||
if (SDL_IsJoystickHIDAPI(guid)) {
|
||||
mapping = SDL_CreateMappingForHIDAPIController(guid);
|
||||
} else if (SDL_IsJoystickRAWINPUT(guid)) {
|
||||
mapping = SDL_CreateMappingForRAWINPUTController(guid);
|
||||
} else if (SDL_IsJoystickWGI(guid)) {
|
||||
mapping = SDL_CreateMappingForWGIController(guid);
|
||||
} else if (SDL_IsJoystickVirtual(guid)) {
|
||||
/* We'll pick up a robust mapping in VIRTUAL_JoystickGetGamepadMapping */
|
||||
#ifdef __ANDROID__
|
||||
if (!mapping && !SDL_IsJoystickHIDAPI(guid)) {
|
||||
mapping = SDL_CreateMappingForAndroidController(guid);
|
||||
}
|
||||
} else {
|
||||
mapping = SDL_CreateMappingForAndroidController(guid);
|
||||
#endif
|
||||
if (!mapping && SDL_IsJoystickHIDAPI(guid)) {
|
||||
mapping = SDL_CreateMappingForHIDAPIController(guid);
|
||||
}
|
||||
if (!mapping && SDL_IsJoystickRAWINPUT(guid)) {
|
||||
mapping = SDL_CreateMappingForRAWINPUTController(guid);
|
||||
}
|
||||
if (!mapping && SDL_IsJoystickWGI(guid)) {
|
||||
mapping = SDL_CreateMappingForWGIController(guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapping;
|
||||
|
|
@ -1258,6 +1259,11 @@ static ControllerMapping_t *SDL_PrivateGenerateAutomaticControllerMapping(const
|
|||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpdown", &raw_map->dpdown);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpleft", &raw_map->dpleft);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpright", &raw_map->dpright);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "misc1", &raw_map->misc1);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle1", &raw_map->paddle1);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle2", &raw_map->paddle2);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle3", &raw_map->paddle3);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle4", &raw_map->paddle4);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftx", &raw_map->leftx);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "lefty", &raw_map->lefty);
|
||||
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightx", &raw_map->rightx);
|
||||
|
|
@ -1732,6 +1738,20 @@ SDL_GameControllerNameForIndex(int device_index)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the implementation dependent path of a controller
|
||||
*/
|
||||
const char *
|
||||
SDL_GameControllerPathForIndex(int device_index)
|
||||
{
|
||||
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
|
||||
if (pSupportedController) {
|
||||
return SDL_JoystickPathForIndex(device_index);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the type of a game controller.
|
||||
*/
|
||||
|
|
@ -2294,6 +2314,15 @@ SDL_GameControllerName(SDL_GameController *gamecontroller)
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GameControllerPath(SDL_GameController *gamecontroller)
|
||||
{
|
||||
if (!gamecontroller)
|
||||
return NULL;
|
||||
|
||||
return SDL_JoystickPath(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
SDL_GameControllerType
|
||||
SDL_GameControllerGetType(SDL_GameController *gamecontroller)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -748,8 +748,11 @@ static const char *s_ControllerMappings [] =
|
|||
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,",
|
||||
"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,",
|
||||
"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,",
|
||||
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
|
||||
|
|
@ -896,9 +899,6 @@ static const char *s_ControllerMappings [] =
|
|||
"050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
|
||||
"050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_VIRTUAL)
|
||||
"00000000000000000000000000007601,Virtual Joystick,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
|
||||
"default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -320,6 +320,28 @@ SDL_JoystickNameForIndex(int device_index)
|
|||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the implementation dependent path of a joystick
|
||||
*/
|
||||
const char *
|
||||
SDL_JoystickPathForIndex(int device_index)
|
||||
{
|
||||
SDL_JoystickDriver *driver;
|
||||
const char *path = NULL;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
|
||||
path = driver->GetDevicePath(device_index);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
/* FIXME: Really we should reference count this path so it doesn't go away after unlock */
|
||||
if (!path) {
|
||||
SDL_Unsupported();
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the player index of a joystick, or -1 if it's not available
|
||||
*/
|
||||
|
|
@ -386,6 +408,8 @@ SDL_JoystickOpen(int device_index)
|
|||
SDL_Joystick *joystick;
|
||||
SDL_Joystick *joysticklist;
|
||||
const char *joystickname = NULL;
|
||||
const char *joystickpath = NULL;
|
||||
SDL_JoystickPowerLevel initial_power_level;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
|
|
@ -435,6 +459,13 @@ SDL_JoystickOpen(int device_index)
|
|||
joystick->name = NULL;
|
||||
}
|
||||
|
||||
joystickpath = driver->GetDevicePath(device_index);
|
||||
if (joystickpath) {
|
||||
joystick->path = SDL_strdup(joystickpath);
|
||||
} else {
|
||||
joystick->path = NULL;
|
||||
}
|
||||
|
||||
joystick->guid = driver->GetDeviceGUID(device_index);
|
||||
|
||||
if (joystick->naxes > 0) {
|
||||
|
|
@ -478,6 +509,11 @@ SDL_JoystickOpen(int device_index)
|
|||
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
/* send initial battery event */
|
||||
initial_power_level = joystick->epowerlevel;
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, initial_power_level);
|
||||
|
||||
driver->Update(joystick);
|
||||
|
||||
return joystick;
|
||||
|
|
@ -486,9 +522,23 @@ SDL_JoystickOpen(int device_index)
|
|||
int
|
||||
SDL_JoystickAttachVirtual(SDL_JoystickType type,
|
||||
int naxes, int nbuttons, int nhats)
|
||||
{
|
||||
SDL_VirtualJoystickDesc desc;
|
||||
|
||||
SDL_zero(desc);
|
||||
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
|
||||
desc.type = (Uint16)type;
|
||||
desc.naxes = (Uint16)naxes;
|
||||
desc.nbuttons = (Uint16)nbuttons;
|
||||
desc.nhats = (Uint16)nhats;
|
||||
return SDL_JoystickAttachVirtualEx(&desc);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc)
|
||||
{
|
||||
#if SDL_JOYSTICK_VIRTUAL
|
||||
return SDL_JoystickAttachVirtualInner(type, naxes, nbuttons, nhats);
|
||||
return SDL_JoystickAttachVirtualInner(desc);
|
||||
#else
|
||||
return SDL_SetError("SDL not built with virtual-joystick support");
|
||||
#endif
|
||||
|
|
@ -834,6 +884,23 @@ SDL_JoystickName(SDL_Joystick *joystick)
|
|||
return joystick->name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the implementation dependent path of this joystick
|
||||
*/
|
||||
const char *
|
||||
SDL_JoystickPath(SDL_Joystick *joystick)
|
||||
{
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!joystick->path) {
|
||||
SDL_Unsupported();
|
||||
return NULL;
|
||||
}
|
||||
return joystick->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player index of an opened joystick, or -1 if it's not available
|
||||
*/
|
||||
|
|
@ -1006,14 +1073,13 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|||
SDL_LockJoysticks();
|
||||
|
||||
isfreshvalue = red != joystick->led_red ||
|
||||
green != joystick->led_green ||
|
||||
blue != joystick->led_blue;
|
||||
green != joystick->led_green ||
|
||||
blue != joystick->led_blue;
|
||||
|
||||
if ( isfreshvalue || SDL_TICKS_PASSED( SDL_GetTicks(), joystick->led_expiration ) ) {
|
||||
if (isfreshvalue || SDL_TICKS_PASSED(SDL_GetTicks(), joystick->led_expiration)) {
|
||||
result = joystick->driver->SetLED(joystick, red, green, blue);
|
||||
joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Avoid spamming the driver */
|
||||
result = 0;
|
||||
}
|
||||
|
|
@ -1100,6 +1166,7 @@ SDL_JoystickClose(SDL_Joystick *joystick)
|
|||
}
|
||||
|
||||
SDL_free(joystick->name);
|
||||
SDL_free(joystick->path);
|
||||
SDL_free(joystick->serial);
|
||||
|
||||
/* Free the data associated with this joystick */
|
||||
|
|
@ -2495,8 +2562,7 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (SDL_IsGameControllerNameAndGUID(name, guid) &&
|
||||
SDL_ShouldIgnoreGameController(name, guid)) {
|
||||
if (SDL_ShouldIgnoreGameController(name, guid)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -2721,7 +2787,19 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
|
|||
/* update the power level for this joystick */
|
||||
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
|
||||
{
|
||||
joystick->epowerlevel = ePowerLevel;
|
||||
SDL_assert(joystick->ref_count); /* make sure we are calling this only for update, not for initialisation */
|
||||
if (ePowerLevel != joystick->epowerlevel) {
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
if (SDL_GetEventState(SDL_JOYBATTERYUPDATED) == SDL_ENABLE) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_JOYBATTERYUPDATED;
|
||||
event.jbattery.which = joystick->instance_id;
|
||||
event.jbattery.level = ePowerLevel;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
joystick->epowerlevel = ePowerLevel;
|
||||
}
|
||||
}
|
||||
|
||||
/* return its power level */
|
||||
|
|
|
|||
|
|
@ -168,6 +168,11 @@ typedef struct _SDL_GamepadMapping
|
|||
SDL_InputMapping dpdown;
|
||||
SDL_InputMapping dpleft;
|
||||
SDL_InputMapping dpright;
|
||||
SDL_InputMapping misc1;
|
||||
SDL_InputMapping paddle1;
|
||||
SDL_InputMapping paddle2;
|
||||
SDL_InputMapping paddle3;
|
||||
SDL_InputMapping paddle4;
|
||||
SDL_InputMapping leftx;
|
||||
SDL_InputMapping lefty;
|
||||
SDL_InputMapping rightx;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ struct _SDL_Joystick
|
|||
{
|
||||
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
|
||||
char *name; /* Joystick name - system dependent */
|
||||
char *path; /* Joystick path - system dependent */
|
||||
char *serial; /* Joystick serial */
|
||||
SDL_JoystickGUID guid; /* Joystick guid */
|
||||
|
||||
|
|
@ -118,6 +119,7 @@ struct _SDL_Joystick
|
|||
};
|
||||
|
||||
/* Device bus definitions */
|
||||
#define SDL_HARDWARE_BUS_VIRTUAL 0x00
|
||||
#define SDL_HARDWARE_BUS_USB 0x03
|
||||
#define SDL_HARDWARE_BUS_BLUETOOTH 0x05
|
||||
|
||||
|
|
@ -146,6 +148,9 @@ typedef struct _SDL_JoystickDriver
|
|||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *(*GetDeviceName)(int device_index);
|
||||
|
||||
/* Function to get the device-dependent path of a joystick */
|
||||
const char *(*GetDevicePath)(int device_index);
|
||||
|
||||
/* Function to get the player index of a joystick */
|
||||
int (*GetDevicePlayerIndex)(int device_index);
|
||||
|
||||
|
|
|
|||
|
|
@ -558,6 +558,12 @@ ANDROID_JoystickGetDeviceName(int device_index)
|
|||
return JoystickByDevIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ANDROID_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
ANDROID_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -713,6 +719,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
|
|||
ANDROID_JoystickGetCount,
|
||||
ANDROID_JoystickDetect,
|
||||
ANDROID_JoystickGetDeviceName,
|
||||
ANDROID_JoystickGetDevicePath,
|
||||
ANDROID_JoystickGetDevicePlayerIndex,
|
||||
ANDROID_JoystickSetDevicePlayerIndex,
|
||||
ANDROID_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -268,9 +268,15 @@ static const char *
|
|||
BSD_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
if (joydevnames[device_index] != NULL) {
|
||||
return (joydevnames[device_index]);
|
||||
return joydevnames[device_index];
|
||||
}
|
||||
return (joynames[device_index]);
|
||||
return joynames[device_index];
|
||||
}
|
||||
|
||||
static const char *
|
||||
BSD_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return joynames[device_index];
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -807,6 +813,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
|
|||
BSD_JoystickGetCount,
|
||||
BSD_JoystickDetect,
|
||||
BSD_JoystickGetDeviceName,
|
||||
BSD_JoystickGetDevicePath,
|
||||
BSD_JoystickGetDevicePlayerIndex,
|
||||
BSD_JoystickSetDevicePlayerIndex,
|
||||
BSD_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
0
Engine/lib/sdl/src/joystick/check_8bitdo.sh
Normal file → Executable file
0
Engine/lib/sdl/src/joystick/check_8bitdo.sh
Normal file → Executable file
|
|
@ -744,7 +744,6 @@ DARWIN_JoystickDetect(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *
|
||||
DARWIN_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
|
|
@ -752,6 +751,12 @@ DARWIN_JoystickGetDeviceName(int device_index)
|
|||
return device ? device->product : "UNKNOWN";
|
||||
}
|
||||
|
||||
const char *
|
||||
DARWIN_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
DARWIN_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -1115,6 +1120,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
|
|||
DARWIN_JoystickGetCount,
|
||||
DARWIN_JoystickDetect,
|
||||
DARWIN_JoystickGetDeviceName,
|
||||
DARWIN_JoystickGetDevicePath,
|
||||
DARWIN_JoystickGetDevicePlayerIndex,
|
||||
DARWIN_JoystickSetDevicePlayerIndex,
|
||||
DARWIN_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ DUMMY_JoystickGetDeviceName(int device_index)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
DUMMY_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
DUMMY_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -146,6 +152,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
|
|||
DUMMY_JoystickGetCount,
|
||||
DUMMY_JoystickDetect,
|
||||
DUMMY_JoystickGetDeviceName,
|
||||
DUMMY_JoystickGetDevicePath,
|
||||
DUMMY_JoystickGetDevicePlayerIndex,
|
||||
DUMMY_JoystickSetDevicePlayerIndex,
|
||||
DUMMY_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -280,6 +280,12 @@ EMSCRIPTEN_JoystickGetDeviceName(int device_index)
|
|||
return JoystickByDeviceIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
EMSCRIPTEN_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -444,6 +450,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
|
|||
EMSCRIPTEN_JoystickGetCount,
|
||||
EMSCRIPTEN_JoystickDetect,
|
||||
EMSCRIPTEN_JoystickGetDeviceName,
|
||||
EMSCRIPTEN_JoystickGetDevicePath,
|
||||
EMSCRIPTEN_JoystickGetDevicePlayerIndex,
|
||||
EMSCRIPTEN_JoystickSetDevicePlayerIndex,
|
||||
EMSCRIPTEN_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -64,15 +64,15 @@ extern "C"
|
|||
char name[B_OS_NAME_LENGTH];
|
||||
|
||||
/* Search for attached joysticks */
|
||||
nports = joystick.CountDevices();
|
||||
numjoysticks = 0;
|
||||
SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
|
||||
SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
|
||||
nports = joystick.CountDevices();
|
||||
numjoysticks = 0;
|
||||
SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
|
||||
SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
|
||||
for (i = 0; (numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i)
|
||||
{
|
||||
if (joystick.GetDeviceName(i, name) == B_OK) {
|
||||
if (joystick.Open(name) != B_ERROR) {
|
||||
BString stick_name;
|
||||
BString stick_name;
|
||||
joystick.GetControllerName(&stick_name);
|
||||
SDL_joyport[numjoysticks] = SDL_strdup(name);
|
||||
SDL_joyname[numjoysticks] = SDL_CreateJoystickName(0, 0, NULL, stick_name.String());
|
||||
|
|
@ -93,12 +93,16 @@ extern "C"
|
|||
{
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *HAIKU_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
return SDL_joyname[device_index];
|
||||
}
|
||||
|
||||
static const char *HAIKU_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return SDL_joyport[device_index];
|
||||
}
|
||||
|
||||
static int HAIKU_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
|
|
@ -298,6 +302,7 @@ extern "C"
|
|||
HAIKU_JoystickGetCount,
|
||||
HAIKU_JoystickDetect,
|
||||
HAIKU_JoystickGetDeviceName,
|
||||
HAIKU_JoystickGetDevicePath,
|
||||
HAIKU_JoystickGetDevicePlayerIndex,
|
||||
HAIKU_JoystickSetDevicePlayerIndex,
|
||||
HAIKU_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -267,16 +267,16 @@ HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverL
|
|||
/* Battery level report */
|
||||
int level = data[1] * 100 / 0xFF;
|
||||
if (level == 0) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
|
||||
}
|
||||
else if (level <= 20) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
|
||||
}
|
||||
else if (level <= 70) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
|
||||
}
|
||||
else {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -801,18 +801,18 @@ HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
|
|||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
|
||||
|
||||
if (packet->ucBatteryLevel & 0x10) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
|
||||
} else {
|
||||
/* Battery level ranges from 0 to 10 */
|
||||
int level = (packet->ucBatteryLevel & 0xF);
|
||||
if (level == 0) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
|
||||
} else if (level <= 2) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
|
||||
} else if (level <= 7) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
|
||||
} else {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ typedef struct SDL_HIDAPI_RumbleContext
|
|||
|
||||
static SDL_HIDAPI_RumbleContext rumble_context;
|
||||
|
||||
static int SDL_HIDAPI_RumbleThread(void *data)
|
||||
static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
|
||||
{
|
||||
SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@
|
|||
#define SWITCH_GYRO_SCALE 14.2842f
|
||||
#define SWITCH_ACCEL_SCALE 4096.f
|
||||
|
||||
#define SWITCH_GYRO_SCALE_OFFSET 13371.0f
|
||||
#define SWITCH_GYRO_SCALE_MULT 936.0f
|
||||
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
|
||||
#define SWITCH_ACCEL_SCALE_MULT 4.0f
|
||||
|
||||
typedef enum {
|
||||
k_eSwitchInputReportIDs_SubcommandReply = 0x21,
|
||||
k_eSwitchInputReportIDs_FullControllerState = 0x30,
|
||||
|
|
@ -114,6 +119,14 @@ typedef enum {
|
|||
#define k_unSPIStickCalibrationEndOffset 0x604E
|
||||
#define k_unSPIStickCalibrationLength (k_unSPIStickCalibrationEndOffset - k_unSPIStickCalibrationStartOffset + 1)
|
||||
|
||||
#define k_unSPIIMUScaleStartOffset 0x6020
|
||||
#define k_unSPIIMUScaleEndOffset 0x6037
|
||||
#define k_unSPIIMUScaleLength (k_unSPIIMUScaleEndOffset - k_unSPIIMUScaleStartOffset + 1)
|
||||
|
||||
#define k_unSPIIMUUserScaleStartOffset 0x8026
|
||||
#define k_unSPIIMUUserScaleEndOffset 0x8039
|
||||
#define k_unSPIIMUUserScaleLength (k_unSPIIMUUserScaleEndOffset - k_unSPIIMUUserScaleStartOffset + 1)
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -266,6 +279,16 @@ typedef struct {
|
|||
Sint16 sMax;
|
||||
} axis[2];
|
||||
} m_StickExtents[2];
|
||||
|
||||
struct IMUScaleData {
|
||||
float fAccelScaleX;
|
||||
float fAccelScaleY;
|
||||
float fAccelScaleZ;
|
||||
|
||||
float fGyroScaleX;
|
||||
float fGyroScaleY;
|
||||
float fGyroScaleZ;
|
||||
} m_IMUScaleData;
|
||||
} SDL_DriverSwitch_Context;
|
||||
|
||||
|
||||
|
|
@ -769,6 +792,72 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context* ctx)
|
||||
{
|
||||
Uint8* pIMUScale;
|
||||
SwitchSubcommandInputPacket_t* reply = NULL;
|
||||
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
|
||||
|
||||
/* Read Calibration Info */
|
||||
SwitchSPIOpData_t readParams;
|
||||
readParams.unAddress = k_unSPIIMUScaleStartOffset;
|
||||
readParams.ucLength = k_unSPIIMUScaleLength;
|
||||
|
||||
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply)) {
|
||||
const float accelScale = SDL_STANDARD_GRAVITY / SWITCH_ACCEL_SCALE;
|
||||
const float gyroScale = (float)M_PI / 180.0f / SWITCH_GYRO_SCALE;
|
||||
|
||||
ctx->m_IMUScaleData.fAccelScaleX = accelScale;
|
||||
ctx->m_IMUScaleData.fAccelScaleY = accelScale;
|
||||
ctx->m_IMUScaleData.fAccelScaleZ = accelScale;
|
||||
|
||||
ctx->m_IMUScaleData.fGyroScaleX = gyroScale;
|
||||
ctx->m_IMUScaleData.fGyroScaleY = gyroScale;
|
||||
ctx->m_IMUScaleData.fGyroScaleZ = gyroScale;
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* IMU scale gives us multipliers for converting raw values to real world values */
|
||||
pIMUScale = reply->spiReadData.rgucReadData;
|
||||
|
||||
sAccelRawX = ((pIMUScale[1] << 8) & 0xF00) | pIMUScale[0];
|
||||
sAccelRawY = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2];
|
||||
sAccelRawZ = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4];
|
||||
|
||||
sGyroRawX = ((pIMUScale[13] << 8) & 0xF00) | pIMUScale[12];
|
||||
sGyroRawY = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14];
|
||||
sGyroRawZ = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16];
|
||||
|
||||
/* Check for user calibration data. If it's present and set, it'll override the factory settings */
|
||||
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
|
||||
readParams.ucLength = k_unSPIIMUUserScaleLength;
|
||||
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) {
|
||||
pIMUScale = reply->spiReadData.rgucReadData;
|
||||
|
||||
sAccelRawX = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2];
|
||||
sAccelRawY = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4];
|
||||
sAccelRawZ = ((pIMUScale[7] << 8) & 0xF00) | pIMUScale[6];
|
||||
|
||||
sGyroRawX = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14];
|
||||
sGyroRawY = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16];
|
||||
sGyroRawZ = ((pIMUScale[19] << 8) & 0xF00) | pIMUScale[18];
|
||||
}
|
||||
|
||||
/* Accelerometer scale */
|
||||
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
|
||||
|
||||
/* Gyro scale */
|
||||
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue, Sint16 sCenter)
|
||||
{
|
||||
sRawValue -= sCenter;
|
||||
|
|
@ -914,6 +1003,11 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!LoadIMUCalibration(ctx)) {
|
||||
SDL_SetError("Couldn't load sensor calibration");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!SetVibrationEnabled(ctx, 1)) {
|
||||
SDL_SetError("Couldn't enable vibration");
|
||||
goto error;
|
||||
|
|
@ -1146,20 +1240,6 @@ HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joy
|
|||
return 0;
|
||||
}
|
||||
|
||||
static float
|
||||
HIDAPI_DriverSwitch_ScaleGyro(Sint16 value)
|
||||
{
|
||||
float result = (value / SWITCH_GYRO_SCALE) * (float)M_PI / 180.0f;
|
||||
return result;
|
||||
}
|
||||
|
||||
static float
|
||||
HIDAPI_DriverSwitch_ScaleAccel(Sint16 value)
|
||||
{
|
||||
float result = (value / SWITCH_ACCEL_SCALE) * SDL_STANDARD_GRAVITY;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet)
|
||||
{
|
||||
Sint16 axis;
|
||||
|
|
@ -1357,13 +1437,13 @@ static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *c
|
|||
* users will want consistent axis mappings across devices.
|
||||
*/
|
||||
if (type == SDL_SENSOR_GYRO) {
|
||||
data[0] = -HIDAPI_DriverSwitch_ScaleGyro(values[1]);
|
||||
data[1] = HIDAPI_DriverSwitch_ScaleGyro(values[2]);
|
||||
data[2] = -HIDAPI_DriverSwitch_ScaleGyro(values[0]);
|
||||
data[0] = -(ctx->m_IMUScaleData.fGyroScaleY * (float)values[1]);
|
||||
data[1] = ctx->m_IMUScaleData.fGyroScaleZ * (float)values[2];
|
||||
data[2] = -(ctx->m_IMUScaleData.fGyroScaleX * (float)values[0]);
|
||||
} else {
|
||||
data[0] = -HIDAPI_DriverSwitch_ScaleAccel(values[1]);
|
||||
data[1] = HIDAPI_DriverSwitch_ScaleAccel(values[2]);
|
||||
data[2] = -HIDAPI_DriverSwitch_ScaleAccel(values[0]);
|
||||
data[0] = -(ctx->m_IMUScaleData.fAccelScaleY * (float)values[1]);
|
||||
data[1] = ctx->m_IMUScaleData.fAccelScaleZ * (float)values[2];
|
||||
data[2] = -(ctx->m_IMUScaleData.fAccelScaleX * (float)values[0]);
|
||||
}
|
||||
|
||||
/* Right Joy-Con flips some axes, so let's flip them back for consistency */
|
||||
|
|
@ -1440,20 +1520,20 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
|
|||
* LSB of connection nibble is USB/Switch connection status
|
||||
*/
|
||||
if (packet->controllerState.ucBatteryAndConnection & 0x1) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
|
||||
} else {
|
||||
/* LSB of the battery nibble is used to report charging.
|
||||
* The battery level is reported from 0(empty)-8(full)
|
||||
*/
|
||||
int level = (packet->controllerState.ucBatteryAndConnection & 0xE0) >> 4;
|
||||
if (level == 0) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
|
||||
} else if (level <= 2) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
|
||||
} else if (level <= 6) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
|
||||
} else {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,13 +81,13 @@ UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level)
|
|||
float normalized_level = (float)level / 255.0f;
|
||||
|
||||
if (normalized_level <= 0.05f) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
|
||||
} else if (normalized_level <= 0.20f) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
|
||||
} else if (normalized_level <= 0.70f) {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
|
||||
} else {
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,14 +134,8 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
|
|||
const Uint16 USAGE_MULTIAXISCONTROLLER = 0x0008;
|
||||
int i;
|
||||
SDL_GameControllerType type;
|
||||
SDL_JoystickGUID check_guid;
|
||||
|
||||
/* Make sure we have a generic GUID here, otherwise if we pass a HIDAPI
|
||||
guid, this call will create a game controller mapping for the device.
|
||||
*/
|
||||
check_guid = device->guid;
|
||||
check_guid.data[14] = 0;
|
||||
if (SDL_ShouldIgnoreJoystick(device->name, check_guid)) {
|
||||
if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -783,6 +777,21 @@ HIDAPI_JoystickGetDeviceName(int device_index)
|
|||
return name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
HIDAPI_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
const char *path = NULL;
|
||||
|
||||
device = HIDAPI_GetDeviceByIndex(device_index, NULL);
|
||||
if (device) {
|
||||
/* FIXME: The device could be freed after this path is returned... */
|
||||
path = device->path;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -1030,6 +1039,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
|
|||
HIDAPI_JoystickGetCount,
|
||||
HIDAPI_JoystickDetect,
|
||||
HIDAPI_JoystickGetDeviceName,
|
||||
HIDAPI_JoystickGetDevicePath,
|
||||
HIDAPI_JoystickGetDevicePlayerIndex,
|
||||
HIDAPI_JoystickSetDevicePlayerIndex,
|
||||
HIDAPI_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -180,6 +180,10 @@ IsControllerXbox(GCController *controller)
|
|||
static BOOL
|
||||
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
|
||||
{
|
||||
if ((@available(macOS 11.3, *)) && !GCController.shouldMonitorBackgroundEvents) {
|
||||
GCController.shouldMonitorBackgroundEvents = YES;
|
||||
}
|
||||
|
||||
Uint16 *guid16 = (Uint16 *)device->guid.data;
|
||||
Uint16 vendor = 0;
|
||||
Uint16 product = 0;
|
||||
|
|
@ -331,11 +335,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
|
|||
}
|
||||
|
||||
if (SDL_strcmp(name, "Backbone One") == 0) {
|
||||
/* The Backbone app uses the guide and share buttons */
|
||||
if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) != 0) {
|
||||
device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_GUIDE);
|
||||
--nbuttons;
|
||||
}
|
||||
/* The Backbone app uses share button */
|
||||
if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1)) != 0) {
|
||||
device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_MISC1);
|
||||
--nbuttons;
|
||||
|
|
@ -588,10 +588,6 @@ IOS_JoystickInit(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (@available(macOS 11.3, iOS 14.5, tvOS 14.5, *)) {
|
||||
GCController.shouldMonitorBackgroundEvents = YES;
|
||||
}
|
||||
|
||||
/* For whatever reason, this always returns an empty array on
|
||||
macOS 11.0.1 */
|
||||
for (GCController *controller in [GCController controllers]) {
|
||||
|
|
@ -651,6 +647,12 @@ IOS_JoystickGetDeviceName(int device_index)
|
|||
return device ? device->name : "Unknown";
|
||||
}
|
||||
|
||||
static const char *
|
||||
IOS_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -739,7 +741,7 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_MFI_SENSORS
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion && motion.hasRotationRate) {
|
||||
|
|
@ -752,7 +754,7 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
#endif /* ENABLE_MFI_SENSORS */
|
||||
|
||||
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
for (id key in controller.physicalInputProfile.buttons) {
|
||||
GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key];
|
||||
|
|
@ -964,7 +966,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_MFI_SENSORS
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion && motion.sensorsActive) {
|
||||
float data[3];
|
||||
|
|
@ -1057,7 +1059,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_MFI_BATTERY
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCDeviceBattery *battery = controller.battery;
|
||||
if (battery) {
|
||||
SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
|
|
@ -1098,8 +1100,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
#ifdef ENABLE_MFI_RUMBLE
|
||||
|
||||
@interface SDL_RumbleMotor : NSObject
|
||||
@property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
|
||||
@property(nonatomic,strong) id<CHHapticPatternPlayer> player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
|
||||
@property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0));
|
||||
@property(nonatomic,strong) id<CHHapticPatternPlayer> player API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0));
|
||||
@property bool active;
|
||||
@end
|
||||
|
||||
|
|
@ -1109,7 +1111,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
-(void)cleanup
|
||||
{
|
||||
@autoreleasepool {
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (self.player != nil) {
|
||||
[self.player cancelAndReturnError:nil];
|
||||
self.player = nil;
|
||||
|
|
@ -1125,7 +1127,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
-(int)setIntensity:(float)intensity
|
||||
{
|
||||
@autoreleasepool {
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
NSError *error = nil;
|
||||
|
||||
if (self.engine == nil) {
|
||||
|
|
@ -1171,7 +1173,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
}
|
||||
}
|
||||
|
||||
-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
||||
-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0))
|
||||
{
|
||||
@autoreleasepool {
|
||||
self = [super init];
|
||||
|
|
@ -1271,7 +1273,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
|||
static SDL_RumbleContext *IOS_JoystickInitRumble(GCController *controller)
|
||||
{
|
||||
@autoreleasepool {
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
SDL_RumbleMotor *low_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftHandle];
|
||||
SDL_RumbleMotor *high_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityRightHandle];
|
||||
SDL_RumbleMotor *left_trigger_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftTrigger];
|
||||
|
|
@ -1299,7 +1301,7 @@ IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
|
|||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (!device->rumble && device->controller && device->controller.haptics) {
|
||||
SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller);
|
||||
if (rumble) {
|
||||
|
|
@ -1329,7 +1331,7 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
|||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (!device->rumble && device->controller && device->controller.haptics) {
|
||||
SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller);
|
||||
if (rumble) {
|
||||
|
|
@ -1362,7 +1364,7 @@ IOS_JoystickGetCapabilities(SDL_Joystick *joystick)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = device->controller;
|
||||
#ifdef ENABLE_MFI_LIGHT
|
||||
if (controller.light) {
|
||||
|
|
@ -1399,7 +1401,7 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = device->controller;
|
||||
GCDeviceLight *light = controller.light;
|
||||
if (light) {
|
||||
|
|
@ -1432,7 +1434,7 @@ IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
|||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = device->controller;
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion) {
|
||||
|
|
@ -1495,7 +1497,7 @@ IOS_JoystickClose(SDL_Joystick *joystick)
|
|||
controller.playerIndex = -1;
|
||||
|
||||
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
for (id key in controller.physicalInputProfile.buttons) {
|
||||
GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key];
|
||||
if ([button isBoundToSystemGesture]) {
|
||||
|
|
@ -1593,7 +1595,7 @@ SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device)
|
|||
static void
|
||||
GetAppleSFSymbolsNameForElement(GCControllerElement *element, char *name)
|
||||
{
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (element) {
|
||||
[element.sfSymbolsName getCString: name maxLength: 255 encoding: NSASCIIStringEncoding];
|
||||
}
|
||||
|
|
@ -1627,7 +1629,7 @@ IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontrol
|
|||
elementName[0] = '\0';
|
||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
|
||||
if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) {
|
||||
if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller;
|
||||
if ([controller respondsToSelector:@selector(physicalInputProfile)]) {
|
||||
NSDictionary<NSString *,GCControllerElement *> *elements = controller.physicalInputProfile.elements;
|
||||
|
|
@ -1740,7 +1742,7 @@ IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontrolle
|
|||
elementName[0] = '\0';
|
||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
|
||||
if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) {
|
||||
if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) {
|
||||
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller;
|
||||
if ([controller respondsToSelector:@selector(physicalInputProfile)]) {
|
||||
NSDictionary<NSString *,GCControllerElement *> *elements = controller.physicalInputProfile.elements;
|
||||
|
|
@ -1781,6 +1783,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
|
|||
IOS_JoystickGetCount,
|
||||
IOS_JoystickDetect,
|
||||
IOS_JoystickGetDeviceName,
|
||||
IOS_JoystickGetDevicePath,
|
||||
IOS_JoystickGetDevicePlayerIndex,
|
||||
IOS_JoystickSetDevicePlayerIndex,
|
||||
IOS_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@
|
|||
#define DEBUG_INPUT_EVENTS 1
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define DEBUG_GAMEPAD_MAPPING 1
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ENUMERATION_UNSET,
|
||||
|
|
@ -493,21 +497,6 @@ static void SteamControllerDisconnectedCallback(int device_instance)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
#ifdef HAVE_INOTIFY_INIT1
|
||||
static int SDL_inotify_init1(void) {
|
||||
return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
}
|
||||
#else
|
||||
static int SDL_inotify_init1(void) {
|
||||
int fd = inotify_init();
|
||||
if (fd < 0) return -1;
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
StrHasPrefix(const char *string, const char *prefix)
|
||||
{
|
||||
|
|
@ -562,6 +551,21 @@ IsJoystickDeviceNode(const char *node)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
#ifdef HAVE_INOTIFY_INIT1
|
||||
static int SDL_inotify_init1(void) {
|
||||
return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
}
|
||||
#else
|
||||
static int SDL_inotify_init1(void) {
|
||||
int fd = inotify_init();
|
||||
if (fd < 0) return -1;
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
LINUX_InotifyJoystickDetect(void)
|
||||
{
|
||||
|
|
@ -854,13 +858,18 @@ JoystickByDevIndex(int device_index)
|
|||
return item;
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *
|
||||
LINUX_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
LINUX_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->path;
|
||||
}
|
||||
|
||||
static int
|
||||
LINUX_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -921,6 +930,37 @@ allocate_balldata(SDL_Joystick *joystick)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct input_absinfo *absinfo_y)
|
||||
{
|
||||
/* A "hat" is assumed to be a digital input with at most 9 possible states
|
||||
* (3 per axis: negative/zero/positive), as opposed to a true "axis" which
|
||||
* can report a continuous range of possible values. Unfortunately the Linux
|
||||
* joystick interface makes no distinction between digital hat axes and any
|
||||
* other continuous analog axis, so we have to guess. */
|
||||
|
||||
/* If both axes are missing, they're not anything. */
|
||||
if (!absinfo_x && !absinfo_y)
|
||||
return SDL_FALSE;
|
||||
|
||||
/* If the hint says so, treat all hats as digital. */
|
||||
if (SDL_GetHintBoolean(SDL_HINT_LINUX_DIGITAL_HATS, SDL_FALSE))
|
||||
return SDL_TRUE;
|
||||
|
||||
/* If both axes have ranges constrained between -1 and 1, they're definitely digital. */
|
||||
if ((!absinfo_x || (absinfo_x->minimum == -1 && absinfo_x->maximum == 1)) &&
|
||||
(!absinfo_y || (absinfo_y->minimum == -1 && absinfo_y->maximum == 1)))
|
||||
return SDL_TRUE;
|
||||
|
||||
/* If both axes lack fuzz, flat, and resolution values, they're probably digital. */
|
||||
if ((!absinfo_x || (!absinfo_x->fuzz && !absinfo_x->flat && !absinfo_x->resolution)) &&
|
||||
(!absinfo_y || (!absinfo_y->fuzz && !absinfo_y->flat && !absinfo_y->resolution)))
|
||||
return SDL_TRUE;
|
||||
|
||||
/* Otherwise, treat them as analog. */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
{
|
||||
|
|
@ -931,6 +971,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
|||
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_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE);
|
||||
|
||||
/* See if this device uses the new unified event API */
|
||||
if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
|
||||
|
|
@ -958,10 +999,45 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
|||
++joystick->nbuttons;
|
||||
}
|
||||
}
|
||||
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
|
||||
int hat_x = -1;
|
||||
int hat_y = -1;
|
||||
struct input_absinfo absinfo_x;
|
||||
struct input_absinfo absinfo_y;
|
||||
if (test_bit(i, absbit))
|
||||
hat_x = ioctl(fd, EVIOCGABS(i), &absinfo_x);
|
||||
if (test_bit(i + 1, absbit))
|
||||
hat_y = ioctl(fd, EVIOCGABS(i + 1), &absinfo_y);
|
||||
if (GuessIfAxesAreDigitalHat((hat_x < 0 ? (void*)0 : &absinfo_x),
|
||||
(hat_y < 0 ? (void*)0 : &absinfo_y))) {
|
||||
const int hat_index = (i - ABS_HAT0X) / 2;
|
||||
struct hat_axis_correct *correct = &joystick->hwdata->hat_correct[hat_index];
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
SDL_Log("Joystick has digital hat: #%d\n", hat_index);
|
||||
if (hat_x >= 0) {
|
||||
SDL_Log("X Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
|
||||
absinfo_x.value, absinfo_x.minimum, absinfo_x.maximum,
|
||||
absinfo_x.fuzz, absinfo_x.flat, absinfo_x.resolution);
|
||||
}
|
||||
if (hat_y >= 0) {
|
||||
SDL_Log("Y Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
|
||||
absinfo_y.value, absinfo_y.minimum, absinfo_y.maximum,
|
||||
absinfo_y.fuzz, absinfo_y.flat, absinfo_y.resolution);
|
||||
}
|
||||
#endif /* DEBUG_INPUT_EVENTS */
|
||||
joystick->hwdata->hats_indices[hat_index] = joystick->nhats;
|
||||
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
||||
correct->use_deadzones = use_hat_deadzones;
|
||||
correct->minimum[0] = (hat_x < 0) ? -1 : absinfo_x.minimum;
|
||||
correct->maximum[0] = (hat_x < 0) ? 1 : absinfo_x.maximum;
|
||||
correct->minimum[1] = (hat_y < 0) ? -1 : absinfo_y.minimum;
|
||||
correct->maximum[1] = (hat_y < 0) ? 1 : absinfo_y.maximum;
|
||||
++joystick->nhats;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ABS_MAX; ++i) {
|
||||
/* Skip hats */
|
||||
if (i == ABS_HAT0X) {
|
||||
i = ABS_HAT3Y;
|
||||
/* Skip digital hats */
|
||||
if (joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) {
|
||||
continue;
|
||||
}
|
||||
if (test_bit(i, absbit)) {
|
||||
|
|
@ -973,9 +1049,9 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
|||
}
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
SDL_Log("Joystick has absolute axis: 0x%.2x\n", i);
|
||||
SDL_Log("Values = { %d, %d, %d, %d, %d }\n",
|
||||
SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
|
||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||
absinfo.fuzz, absinfo.flat);
|
||||
absinfo.fuzz, absinfo.flat, absinfo.resolution);
|
||||
#endif /* DEBUG_INPUT_EVENTS */
|
||||
joystick->hwdata->abs_map[i] = joystick->naxes;
|
||||
joystick->hwdata->has_abs[i] = SDL_TRUE;
|
||||
|
|
@ -1003,24 +1079,6 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
|||
++joystick->naxes;
|
||||
}
|
||||
}
|
||||
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
|
||||
if (test_bit(i, absbit) || test_bit(i + 1, absbit)) {
|
||||
struct input_absinfo absinfo;
|
||||
int hat_index = (i - ABS_HAT0X) / 2;
|
||||
|
||||
if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
SDL_Log("Joystick has hat %d\n", hat_index);
|
||||
SDL_Log("Values = { %d, %d, %d, %d, %d }\n",
|
||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||
absinfo.fuzz, absinfo.flat);
|
||||
#endif /* DEBUG_INPUT_EVENTS */
|
||||
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
|
||||
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
|
||||
++joystick->nballs;
|
||||
}
|
||||
|
|
@ -1066,14 +1124,19 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
|||
for (i = 0; i < abs_pam_size; ++i) {
|
||||
Uint8 code = joystick->hwdata->abs_pam[i];
|
||||
|
||||
// TODO: is there any way to detect analog hats in advance via this API?
|
||||
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);
|
||||
SDL_Log("Joystick has digital hat: #%d\n", hat_index);
|
||||
#endif
|
||||
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
|
||||
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
||||
joystick->hwdata->hat_correct[hat_index].minimum[0] = -1;
|
||||
joystick->hwdata->hat_correct[hat_index].maximum[0] = 1;
|
||||
joystick->hwdata->hat_correct[hat_index].minimum[1] = -1;
|
||||
joystick->hwdata->hat_correct[hat_index].maximum[1] = 1;
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
|
|
@ -1272,26 +1335,48 @@ LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
|||
}
|
||||
|
||||
static void
|
||||
HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
||||
HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
|
||||
{
|
||||
const int hatnum = stick->hwdata->hats_indices[hatidx];
|
||||
struct hwdata_hat *the_hat;
|
||||
struct hat_axis_correct *correct;
|
||||
const Uint8 position_map[3][3] = {
|
||||
{SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP},
|
||||
{SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT},
|
||||
{SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN}
|
||||
};
|
||||
|
||||
the_hat = &stick->hwdata->hats[hat];
|
||||
the_hat = &stick->hwdata->hats[hatnum];
|
||||
correct = &stick->hwdata->hat_correct[hatidx];
|
||||
/* Hopefully we detected any analog axes and left them as is rather than trying
|
||||
* to use them as digital hats, but just in case, the deadzones here will
|
||||
* prevent the slightest of twitches on an analog axis from registering as a hat
|
||||
* movement. If the axes really are digital, this won't hurt since they should
|
||||
* only ever be sending min, 0, or max anyway. */
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
} else if (value == 0) {
|
||||
value = 1;
|
||||
if (value <= correct->minimum[axis]) {
|
||||
correct->minimum[axis] = value;
|
||||
value = 0;
|
||||
} else if (!correct->use_deadzones || value < correct->minimum[axis] / 3) {
|
||||
value = 0;
|
||||
} else {
|
||||
value = 1;
|
||||
}
|
||||
} else if (value > 0) {
|
||||
value = 2;
|
||||
if (value >= correct->maximum[axis]) {
|
||||
correct->maximum[axis] = value;
|
||||
value = 2;
|
||||
} else if (!correct->use_deadzones || value > correct->maximum[axis] / 3) {
|
||||
value = 2;
|
||||
} else {
|
||||
value = 1;
|
||||
}
|
||||
} else { // value == 0
|
||||
value = 1;
|
||||
}
|
||||
if (value != the_hat->axis[axis]) {
|
||||
the_hat->axis[axis] = value;
|
||||
SDL_PrivateJoystickHat(stick, hat,
|
||||
SDL_PrivateJoystickHat(stick, hatnum,
|
||||
position_map[the_hat->axis[1]][the_hat->axis[0]]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1346,10 +1431,7 @@ PollAllValues(SDL_Joystick *joystick)
|
|||
|
||||
/* Poll all axis */
|
||||
for (i = ABS_X; i < ABS_MAX; i++) {
|
||||
if (i == ABS_HAT0X) { /* we handle hats in the next loop, skip them for now. */
|
||||
i = ABS_HAT3Y;
|
||||
continue;
|
||||
}
|
||||
/* We don't need to test for digital hats here, they won't have has_abs[] set */
|
||||
if (joystick->hwdata->has_abs[i]) {
|
||||
if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
|
||||
absinfo.value = AxisCorrect(joystick, i, absinfo.value);
|
||||
|
|
@ -1365,15 +1447,16 @@ PollAllValues(SDL_Joystick *joystick)
|
|||
}
|
||||
}
|
||||
|
||||
/* Poll all hats */
|
||||
/* Poll all digital hats */
|
||||
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) {
|
||||
const int baseaxis = i - ABS_HAT0X;
|
||||
const int hatidx = baseaxis / 2;
|
||||
SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat));
|
||||
/* We don't need to test for analog axes here, they won't have has_hat[] set */
|
||||
if (joystick->hwdata->has_hat[hatidx]) {
|
||||
if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
|
||||
const int hataxis = baseaxis % 2;
|
||||
HandleHat(joystick, joystick->hwdata->hats_indices[hatidx], hataxis, absinfo.value);
|
||||
HandleHat(joystick, hatidx, hataxis, absinfo.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1401,7 +1484,7 @@ static void
|
|||
HandleInputEvents(SDL_Joystick *joystick)
|
||||
{
|
||||
struct input_event events[32];
|
||||
int i, len, code;
|
||||
int i, len, code, hat_index;
|
||||
|
||||
if (joystick->hwdata->fresh) {
|
||||
PollAllValues(joystick);
|
||||
|
|
@ -1436,9 +1519,11 @@ HandleInputEvents(SDL_Joystick *joystick)
|
|||
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;
|
||||
hat_index = (code - ABS_HAT0X) / 2;
|
||||
if (joystick->hwdata->has_hat[hat_index]) {
|
||||
HandleHat(joystick, hat_index, code % 2, events[i].value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
events[i].value = AxisCorrect(joystick, code, events[i].value);
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
|
|
@ -1491,7 +1576,7 @@ static void
|
|||
HandleClassicEvents(SDL_Joystick *joystick)
|
||||
{
|
||||
struct js_event events[32];
|
||||
int i, len, code;
|
||||
int i, len, code, hat_index;
|
||||
|
||||
joystick->hwdata->fresh = SDL_FALSE;
|
||||
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
||||
|
|
@ -1515,9 +1600,11 @@ HandleClassicEvents(SDL_Joystick *joystick)
|
|||
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;
|
||||
hat_index = (code - ABS_HAT0X) / 2;
|
||||
if (joystick->hwdata->has_hat[hat_index]) {
|
||||
HandleHat(joystick, hat_index, code % 2, events[i].value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
joystick->hwdata->abs_map[code],
|
||||
|
|
@ -1623,10 +1710,14 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
{
|
||||
SDL_Joystick *joystick;
|
||||
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
||||
unsigned int mapped;
|
||||
|
||||
if (item->checked_mapping) {
|
||||
if (item->mapping) {
|
||||
SDL_memcpy(out, item->mapping, sizeof(*out));
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Prior mapping for device %d", device_index);
|
||||
#endif
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
|
|
@ -1674,11 +1765,17 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
if (joystick->hwdata->has_key[BTN_A]) {
|
||||
out->a.kind = EMappingKind_Button;
|
||||
out->a.target = joystick->hwdata->key_map[BTN_A];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped A to button %d (BTN_A)", out->a.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_B]) {
|
||||
out->b.kind = EMappingKind_Button;
|
||||
out->b.target = joystick->hwdata->key_map[BTN_B];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped B to button %d (BTN_B)", out->b.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */
|
||||
|
|
@ -1686,47 +1783,74 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
if (joystick->hwdata->has_key[BTN_WEST]) {
|
||||
out->x.kind = EMappingKind_Button;
|
||||
out->x.target = joystick->hwdata->key_map[BTN_WEST];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped X to button %d (BTN_WEST)", out->x.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_NORTH]) {
|
||||
out->y.kind = EMappingKind_Button;
|
||||
out->y.target = joystick->hwdata->key_map[BTN_NORTH];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped Y to button %d (BTN_NORTH)", out->y.target);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (joystick->hwdata->has_key[BTN_X]) {
|
||||
out->x.kind = EMappingKind_Button;
|
||||
out->x.target = joystick->hwdata->key_map[BTN_X];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped X to button %d (BTN_X)", out->x.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_Y]) {
|
||||
out->y.kind = EMappingKind_Button;
|
||||
out->y.target = joystick->hwdata->key_map[BTN_Y];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped Y to button %d (BTN_Y)", out->y.target);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_SELECT]) {
|
||||
out->back.kind = EMappingKind_Button;
|
||||
out->back.target = joystick->hwdata->key_map[BTN_SELECT];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped BACK to button %d (BTN_SELECT)", out->back.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_START]) {
|
||||
out->start.kind = EMappingKind_Button;
|
||||
out->start.target = joystick->hwdata->key_map[BTN_START];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped START to button %d (BTN_START)", out->start.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_THUMBL]) {
|
||||
out->leftstick.kind = EMappingKind_Button;
|
||||
out->leftstick.target = joystick->hwdata->key_map[BTN_THUMBL];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTSTICK to button %d (BTN_THUMBL)", out->leftstick.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_THUMBR]) {
|
||||
out->rightstick.kind = EMappingKind_Button;
|
||||
out->rightstick.target = joystick->hwdata->key_map[BTN_THUMBR];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTSTICK to button %d (BTN_THUMBR)", out->rightstick.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_MODE]) {
|
||||
out->guide.kind = EMappingKind_Button;
|
||||
out->guide.target = joystick->hwdata->key_map[BTN_MODE];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped GUIDE to button %d (BTN_MODE)", out->guide.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1734,84 +1858,191 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
can be digital, or analog, or both at the same time.
|
||||
*/
|
||||
|
||||
/* Prefer digital shoulder buttons, but settle for analog if missing. */
|
||||
/* Prefer digital shoulder buttons, but settle for digital or analog hat. */
|
||||
mapped = 0;
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_TL]) {
|
||||
out->leftshoulder.kind = EMappingKind_Button;
|
||||
out->leftshoulder.target = joystick->hwdata->key_map[BTN_TL];
|
||||
mapped |= 0x1;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTSHOULDER to button %d (BTN_TL)", out->leftshoulder.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_TR]) {
|
||||
out->rightshoulder.kind = EMappingKind_Button;
|
||||
out->rightshoulder.target = joystick->hwdata->key_map[BTN_TR];
|
||||
mapped |= 0x2;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTSHOULDER to button %d (BTN_TR)", out->rightshoulder.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_hat[1] && /* Check if ABS_HAT1{X, Y} is available. */
|
||||
(!joystick->hwdata->has_key[BTN_TL] || !joystick->hwdata->has_key[BTN_TR])) {
|
||||
if (mapped != 0x3 && joystick->hwdata->has_hat[1]) {
|
||||
int hat = joystick->hwdata->hats_indices[1] << 4;
|
||||
out->leftshoulder.kind = EMappingKind_Hat;
|
||||
out->rightshoulder.kind = EMappingKind_Hat;
|
||||
out->leftshoulder.target = hat | 0x4;
|
||||
out->rightshoulder.target = hat | 0x2;
|
||||
mapped |= 0x3;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFT+RIGHTSHOULDER to hat 1 (ABS_HAT1X, ABS_HAT1Y)");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prefer analog triggers, but settle for digital if missing. */
|
||||
if (joystick->hwdata->has_hat[2]) { /* Check if ABS_HAT2{X,Y} is available. */
|
||||
if (!(mapped & 0x1) && joystick->hwdata->has_abs[ABS_HAT1Y]) {
|
||||
out->leftshoulder.kind = EMappingKind_Axis;
|
||||
out->leftshoulder.target = joystick->hwdata->abs_map[ABS_HAT1Y];
|
||||
mapped |= 0x1;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTSHOULDER to axis %d (ABS_HAT1Y)", out->leftshoulder.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!(mapped & 0x2) && joystick->hwdata->has_abs[ABS_HAT1X]) {
|
||||
out->rightshoulder.kind = EMappingKind_Axis;
|
||||
out->rightshoulder.target = joystick->hwdata->abs_map[ABS_HAT1X];
|
||||
mapped |= 0x2;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTSHOULDER to axis %d (ABS_HAT1X)", out->rightshoulder.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prefer analog triggers, but settle for digital hat or buttons. */
|
||||
mapped = 0;
|
||||
|
||||
if (joystick->hwdata->has_abs[ABS_HAT2Y]) {
|
||||
out->lefttrigger.kind = EMappingKind_Axis;
|
||||
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_HAT2Y];
|
||||
mapped |= 0x1;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_HAT2Y)", out->lefttrigger.target);
|
||||
#endif
|
||||
} else if (joystick->hwdata->has_abs[ABS_Z]) {
|
||||
out->lefttrigger.kind = EMappingKind_Axis;
|
||||
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
|
||||
mapped |= 0x1;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_Z)", out->lefttrigger.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_abs[ABS_HAT2X]) {
|
||||
out->righttrigger.kind = EMappingKind_Axis;
|
||||
out->righttrigger.target = joystick->hwdata->abs_map[ABS_HAT2X];
|
||||
mapped |= 0x2;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_HAT2X)", out->righttrigger.target);
|
||||
#endif
|
||||
} else if (joystick->hwdata->has_abs[ABS_RZ]) {
|
||||
out->righttrigger.kind = EMappingKind_Axis;
|
||||
out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
|
||||
mapped |= 0x2;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_RZ)", out->righttrigger.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mapped != 0x3 && joystick->hwdata->has_hat[2]) {
|
||||
int hat = joystick->hwdata->hats_indices[2] << 4;
|
||||
out->lefttrigger.kind = EMappingKind_Hat;
|
||||
out->righttrigger.kind = EMappingKind_Hat;
|
||||
out->lefttrigger.target = hat | 0x4;
|
||||
out->righttrigger.target = hat | 0x2;
|
||||
} else {
|
||||
if (joystick->hwdata->has_abs[ABS_Z]) {
|
||||
out->lefttrigger.kind = EMappingKind_Axis;
|
||||
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_abs[ABS_RZ]) {
|
||||
out->righttrigger.kind = EMappingKind_Axis;
|
||||
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];
|
||||
}
|
||||
mapped |= 0x3;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFT+RIGHTTRIGGER to hat 2 (ABS_HAT2X, ABS_HAT2Y)");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prefer digital D-Pad, but settle for analog if missing. */
|
||||
if (!(mapped & 0x1) && joystick->hwdata->has_key[BTN_TL2]) {
|
||||
out->lefttrigger.kind = EMappingKind_Button;
|
||||
out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
|
||||
mapped |= 0x1;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTTRIGGER to button %d (BTN_TL2)", out->lefttrigger.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!(mapped & 0x2) && joystick->hwdata->has_key[BTN_TR2]) {
|
||||
out->righttrigger.kind = EMappingKind_Button;
|
||||
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
|
||||
mapped |= 0x2;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTTRIGGER to button %d (BTN_TR2)", out->righttrigger.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prefer digital D-Pad buttons, but settle for digital or analog hat. */
|
||||
mapped = 0;
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_DPAD_UP]) {
|
||||
out->dpup.kind = EMappingKind_Button;
|
||||
out->dpup.target = joystick->hwdata->key_map[BTN_DPAD_UP];
|
||||
mapped |= 0x1;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped DPUP to button %d (BTN_DPAD_UP)", out->dpup.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_DPAD_DOWN]) {
|
||||
out->dpdown.kind = EMappingKind_Button;
|
||||
out->dpdown.target = joystick->hwdata->key_map[BTN_DPAD_DOWN];
|
||||
mapped |= 0x2;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped DPDOWN to button %d (BTN_DPAD_DOWN)", out->dpdown.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_DPAD_LEFT]) {
|
||||
out->dpleft.kind = EMappingKind_Button;
|
||||
out->dpleft.target = joystick->hwdata->key_map[BTN_DPAD_LEFT];
|
||||
mapped |= 0x4;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped DPLEFT to button %d (BTN_DPAD_LEFT)", out->dpleft.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_DPAD_RIGHT]) {
|
||||
out->dpright.kind = EMappingKind_Button;
|
||||
out->dpright.target = joystick->hwdata->key_map[BTN_DPAD_RIGHT];
|
||||
mapped |= 0x8;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped DPRIGHT to button %d (BTN_DPAD_RIGHT)", out->dpright.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_hat[0] && /* Check if ABS_HAT0{X,Y} is available. */
|
||||
(!joystick->hwdata->has_key[BTN_DPAD_LEFT] || !joystick->hwdata->has_key[BTN_DPAD_RIGHT] ||
|
||||
!joystick->hwdata->has_key[BTN_DPAD_UP] || !joystick->hwdata->has_key[BTN_DPAD_DOWN])) {
|
||||
int hat = joystick->hwdata->hats_indices[0] << 4;
|
||||
out->dpleft.kind = EMappingKind_Hat;
|
||||
out->dpright.kind = EMappingKind_Hat;
|
||||
out->dpup.kind = EMappingKind_Hat;
|
||||
out->dpdown.kind = EMappingKind_Hat;
|
||||
out->dpleft.target = hat | 0x8;
|
||||
out->dpright.target = hat | 0x2;
|
||||
out->dpup.target = hat | 0x1;
|
||||
out->dpdown.target = hat | 0x4;
|
||||
if (mapped != 0xF) {
|
||||
if (joystick->hwdata->has_hat[0]) {
|
||||
int hat = joystick->hwdata->hats_indices[0] << 4;
|
||||
out->dpleft.kind = EMappingKind_Hat;
|
||||
out->dpright.kind = EMappingKind_Hat;
|
||||
out->dpup.kind = EMappingKind_Hat;
|
||||
out->dpdown.kind = EMappingKind_Hat;
|
||||
out->dpleft.target = hat | 0x8;
|
||||
out->dpright.target = hat | 0x2;
|
||||
out->dpup.target = hat | 0x1;
|
||||
out->dpdown.target = hat | 0x4;
|
||||
mapped |= 0xF;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped DPUP+DOWN+LEFT+RIGHT to hat 0 (ABS_HAT0X, ABS_HAT0Y)");
|
||||
#endif
|
||||
} else if (joystick->hwdata->has_abs[ABS_HAT0X] && joystick->hwdata->has_abs[ABS_HAT0Y]) {
|
||||
out->dpleft.kind = EMappingKind_Axis;
|
||||
out->dpright.kind = EMappingKind_Axis;
|
||||
out->dpup.kind = EMappingKind_Axis;
|
||||
out->dpdown.kind = EMappingKind_Axis;
|
||||
out->dpleft.target = joystick->hwdata->abs_map[ABS_HAT0X];
|
||||
out->dpright.target = joystick->hwdata->abs_map[ABS_HAT0X];
|
||||
out->dpup.target = joystick->hwdata->abs_map[ABS_HAT0Y];
|
||||
out->dpdown.target = joystick->hwdata->abs_map[ABS_HAT0Y];
|
||||
mapped |= 0xF;
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped DPUP+DOWN to axis %d (ABS_HAT0Y)", out->dpup.target);
|
||||
SDL_Log("Mapped DPLEFT+RIGHT to axis %d (ABS_HAT0X)", out->dpleft.target);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_abs[ABS_X] && joystick->hwdata->has_abs[ABS_Y]) {
|
||||
|
|
@ -1819,6 +2050,10 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
out->lefty.kind = EMappingKind_Axis;
|
||||
out->leftx.target = joystick->hwdata->abs_map[ABS_X];
|
||||
out->lefty.target = joystick->hwdata->abs_map[ABS_Y];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped LEFTX to axis %d (ABS_X)", out->leftx.target);
|
||||
SDL_Log("Mapped LEFTY to axis %d (ABS_Y)", out->lefty.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_abs[ABS_RX] && joystick->hwdata->has_abs[ABS_RY]) {
|
||||
|
|
@ -1826,6 +2061,10 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
out->righty.kind = EMappingKind_Axis;
|
||||
out->rightx.target = joystick->hwdata->abs_map[ABS_RX];
|
||||
out->righty.target = joystick->hwdata->abs_map[ABS_RY];
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Mapped RIGHTX to axis %d (ABS_RX)", out->rightx.target);
|
||||
SDL_Log("Mapped RIGHTY to axis %d (ABS_RY)", out->righty.target);
|
||||
#endif
|
||||
}
|
||||
|
||||
LINUX_JoystickClose(joystick);
|
||||
|
|
@ -1836,6 +2075,9 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
if (item->mapping) {
|
||||
SDL_memcpy(item->mapping, out, sizeof(*out));
|
||||
}
|
||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||
SDL_Log("Generated mapping for device %d", device_index);
|
||||
#endif
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
|
@ -1846,6 +2088,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
|
|||
LINUX_JoystickGetCount,
|
||||
LINUX_JoystickDetect,
|
||||
LINUX_JoystickGetDeviceName,
|
||||
LINUX_JoystickGetDevicePath,
|
||||
LINUX_JoystickGetDevicePlayerIndex,
|
||||
LINUX_JoystickSetDevicePlayerIndex,
|
||||
LINUX_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -83,6 +83,12 @@ struct joystick_hwdata
|
|||
/* 4 = (ABS_HAT3X-ABS_HAT0X)/2 (see input-event-codes.h in kernel) */
|
||||
int hats_indices[4];
|
||||
SDL_bool has_hat[4];
|
||||
struct hat_axis_correct
|
||||
{
|
||||
SDL_bool use_deadzones;
|
||||
int minimum[2];
|
||||
int maximum[2];
|
||||
} hat_correct[4];
|
||||
|
||||
/* Set when gamepad is pending removal due to ENODEV read error */
|
||||
SDL_bool gone;
|
||||
|
|
|
|||
|
|
@ -377,15 +377,17 @@ static void OS2_JoystickDetect(void)
|
|||
{
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
/***********************************************************/
|
||||
static const char *OS2_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
/* No need to verify if device exists, already done in upper layer */
|
||||
return SYS_JoyData[device_index].szDeviceName;
|
||||
}
|
||||
|
||||
static const char *OS2_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int OS2_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
|
|
@ -779,6 +781,7 @@ SDL_JoystickDriver SDL_OS2_JoystickDriver =
|
|||
OS2_NumJoysticks,
|
||||
OS2_JoystickDetect,
|
||||
OS2_JoystickGetDeviceName,
|
||||
OS2_JoystickGetDevicePath,
|
||||
OS2_JoystickGetDevicePlayerIndex,
|
||||
OS2_JoystickSetDevicePlayerIndex,
|
||||
OS2_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ static void PSP_JoystickDetect(void)
|
|||
}
|
||||
|
||||
#if 0
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *PSP_JoystickName(int idx)
|
||||
{
|
||||
if (idx == 0) return "PSP controller";
|
||||
|
|
@ -151,12 +150,16 @@ static const char *PSP_JoystickName(int idx)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *PSP_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
return "PSP builtin joypad";
|
||||
}
|
||||
|
||||
static const char *PSP_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int PSP_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
|
|
@ -304,6 +307,7 @@ SDL_JoystickDriver SDL_PSP_JoystickDriver =
|
|||
PSP_NumJoysticks,
|
||||
PSP_JoystickDetect,
|
||||
PSP_JoystickGetDeviceName,
|
||||
PSP_JoystickGetDevicePath,
|
||||
PSP_JoystickGetDevicePlayerIndex,
|
||||
PSP_JoystickSetDevicePlayerIndex,
|
||||
PSP_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
/* This is the virtual implementation of the SDL joystick API */
|
||||
|
||||
#include "SDL_endian.h"
|
||||
#include "SDL_virtualjoystick_c.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver;
|
||||
|
||||
static joystick_hwdata * g_VJoys = NULL;
|
||||
|
||||
|
|
@ -56,18 +56,6 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
|||
if (!hwdata) {
|
||||
return;
|
||||
}
|
||||
if (hwdata->axes) {
|
||||
SDL_free((void *)hwdata->axes);
|
||||
hwdata->axes = NULL;
|
||||
}
|
||||
if (hwdata->buttons) {
|
||||
SDL_free((void *)hwdata->buttons);
|
||||
hwdata->buttons = NULL;
|
||||
}
|
||||
if (hwdata->hats) {
|
||||
SDL_free(hwdata->hats);
|
||||
hwdata->hats = NULL;
|
||||
}
|
||||
|
||||
/* Remove hwdata from SDL-global list */
|
||||
while (cur) {
|
||||
|
|
@ -83,51 +71,170 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
|||
cur = cur->next;
|
||||
}
|
||||
|
||||
if (hwdata->joystick) {
|
||||
hwdata->joystick->hwdata = NULL;
|
||||
hwdata->joystick = NULL;
|
||||
}
|
||||
if (hwdata->name) {
|
||||
SDL_free(hwdata->name);
|
||||
hwdata->name = NULL;
|
||||
}
|
||||
if (hwdata->axes) {
|
||||
SDL_free((void *)hwdata->axes);
|
||||
hwdata->axes = NULL;
|
||||
}
|
||||
if (hwdata->buttons) {
|
||||
SDL_free((void *)hwdata->buttons);
|
||||
hwdata->buttons = NULL;
|
||||
}
|
||||
if (hwdata->hats) {
|
||||
SDL_free(hwdata->hats);
|
||||
hwdata->hats = NULL;
|
||||
}
|
||||
SDL_free(hwdata);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_JoystickAttachVirtualInner(SDL_JoystickType type,
|
||||
int naxes,
|
||||
int nbuttons,
|
||||
int nhats)
|
||||
SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
|
||||
{
|
||||
joystick_hwdata *hwdata = NULL;
|
||||
int device_index = -1;
|
||||
const char *name = NULL;
|
||||
Uint16 *guid16;
|
||||
int axis_triggerleft = -1;
|
||||
int axis_triggerright = -1;
|
||||
|
||||
if (!desc) {
|
||||
return SDL_InvalidParamError("desc");
|
||||
}
|
||||
if (desc->version != SDL_VIRTUAL_JOYSTICK_DESC_VERSION) {
|
||||
/* Is this an old version that we can support? */
|
||||
return SDL_SetError("Unsupported virtual joystick description version %d", desc->version);
|
||||
}
|
||||
|
||||
hwdata = SDL_calloc(1, sizeof(joystick_hwdata));
|
||||
if (!hwdata) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memcpy(&hwdata->desc, desc, sizeof(*desc));
|
||||
|
||||
hwdata->naxes = naxes;
|
||||
hwdata->nbuttons = nbuttons;
|
||||
hwdata->nhats = nhats;
|
||||
hwdata->name = "Virtual Joystick";
|
||||
if (hwdata->desc.name) {
|
||||
name = hwdata->desc.name;
|
||||
} else {
|
||||
switch (hwdata->desc.type) {
|
||||
case SDL_JOYSTICK_TYPE_GAMECONTROLLER:
|
||||
name = "Virtual Controller";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_WHEEL:
|
||||
name = "Virtual Wheel";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_ARCADE_STICK:
|
||||
name = "Virtual Arcade Stick";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_FLIGHT_STICK:
|
||||
name = "Virtual Flight Stick";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_DANCE_PAD:
|
||||
name = "Virtual Dance Pad";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_GUITAR:
|
||||
name = "Virtual Guitar";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_DRUM_KIT:
|
||||
name = "Virtual Drum Kit";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_ARCADE_PAD:
|
||||
name = "Virtual Arcade Pad";
|
||||
break;
|
||||
case SDL_JOYSTICK_TYPE_THROTTLE:
|
||||
name = "Virtual Throttle";
|
||||
break;
|
||||
default:
|
||||
name = "Virtual Joystick";
|
||||
break;
|
||||
}
|
||||
}
|
||||
hwdata->name = SDL_strdup(name);
|
||||
|
||||
if (hwdata->desc.type == SDL_JOYSTICK_TYPE_GAMECONTROLLER) {
|
||||
int i, axis;
|
||||
|
||||
if (hwdata->desc.button_mask == 0) {
|
||||
for (i = 0; i < hwdata->desc.nbuttons && i < sizeof(hwdata->desc.button_mask)*8; ++i) {
|
||||
hwdata->desc.button_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (hwdata->desc.axis_mask == 0) {
|
||||
if (hwdata->desc.naxes >= 2) {
|
||||
hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_LEFTX) | (1 << SDL_CONTROLLER_AXIS_LEFTY));
|
||||
}
|
||||
if (hwdata->desc.naxes >= 4) {
|
||||
hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_RIGHTX) | (1 << SDL_CONTROLLER_AXIS_RIGHTY));
|
||||
}
|
||||
if (hwdata->desc.naxes >= 6) {
|
||||
hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT) | (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the trigger axes */
|
||||
axis = 0;
|
||||
for (i = 0; axis < hwdata->desc.naxes && i < SDL_CONTROLLER_AXIS_MAX; ++i) {
|
||||
if (hwdata->desc.axis_mask & (1 << i)) {
|
||||
if (i == SDL_CONTROLLER_AXIS_TRIGGERLEFT) {
|
||||
axis_triggerleft = axis;
|
||||
}
|
||||
if (i == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {
|
||||
axis_triggerright = axis;
|
||||
}
|
||||
++axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 = (Uint16 *)hwdata->guid.data;
|
||||
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_VIRTUAL);
|
||||
*guid16++ = 0;
|
||||
*guid16++ = SDL_SwapLE16(hwdata->desc.vendor_id);
|
||||
*guid16++ = 0;
|
||||
*guid16++ = SDL_SwapLE16(hwdata->desc.product_id);
|
||||
*guid16++ = 0;
|
||||
*guid16++ = 0;
|
||||
*guid16++ = 0; /* This will be overwritten below with the virtual controller signature */
|
||||
|
||||
/* Note that this is a Virtual device and what subtype it is */
|
||||
hwdata->guid.data[14] = 'v';
|
||||
hwdata->guid.data[15] = (Uint8)type;
|
||||
hwdata->guid.data[15] = (Uint8)hwdata->desc.type;
|
||||
|
||||
/* Allocate fields for different control-types */
|
||||
if (naxes > 0) {
|
||||
hwdata->axes = SDL_calloc(naxes, sizeof(Sint16));
|
||||
if (hwdata->desc.naxes > 0) {
|
||||
hwdata->axes = SDL_calloc(hwdata->desc.naxes, sizeof(Sint16));
|
||||
if (!hwdata->axes) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Trigger axes are at minimum value at rest */
|
||||
if (axis_triggerleft >= 0) {
|
||||
hwdata->axes[axis_triggerleft] = SDL_JOYSTICK_AXIS_MIN;
|
||||
}
|
||||
if (axis_triggerright >= 0) {
|
||||
hwdata->axes[axis_triggerright] = SDL_JOYSTICK_AXIS_MIN;
|
||||
}
|
||||
}
|
||||
if (nbuttons > 0) {
|
||||
hwdata->buttons = SDL_calloc(nbuttons, sizeof(Uint8));
|
||||
if (hwdata->desc.nbuttons > 0) {
|
||||
hwdata->buttons = SDL_calloc(hwdata->desc.nbuttons, sizeof(Uint8));
|
||||
if (!hwdata->buttons) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
}
|
||||
if (nhats > 0) {
|
||||
hwdata->hats = SDL_calloc(nhats, sizeof(Uint8));
|
||||
if (hwdata->desc.nhats > 0) {
|
||||
hwdata->hats = SDL_calloc(hwdata->desc.nhats, sizeof(Uint8));
|
||||
if (!hwdata->hats) {
|
||||
VIRTUAL_FreeHWData(hwdata);
|
||||
return SDL_OutOfMemory();
|
||||
|
|
@ -138,8 +245,16 @@ SDL_JoystickAttachVirtualInner(SDL_JoystickType type,
|
|||
hwdata->instance_id = SDL_GetNextJoystickInstanceID();
|
||||
|
||||
/* Add virtual joystick to SDL-global lists */
|
||||
hwdata->next = g_VJoys;
|
||||
g_VJoys = hwdata;
|
||||
if (g_VJoys) {
|
||||
joystick_hwdata *last;
|
||||
|
||||
for (last = g_VJoys; last->next; last = last->next) {
|
||||
continue;
|
||||
}
|
||||
last->next = hwdata;
|
||||
} else {
|
||||
g_VJoys = hwdata;
|
||||
}
|
||||
SDL_PrivateJoystickAdded(hwdata->instance_id);
|
||||
|
||||
/* Return the new virtual-device's index */
|
||||
|
|
@ -176,7 +291,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value)
|
|||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (axis < 0 || axis >= hwdata->naxes) {
|
||||
if (axis < 0 || axis >= hwdata->desc.naxes) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid axis index");
|
||||
}
|
||||
|
|
@ -201,7 +316,7 @@ SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 valu
|
|||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (button < 0 || button >= hwdata->nbuttons) {
|
||||
if (button < 0 || button >= hwdata->desc.nbuttons) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid button index");
|
||||
}
|
||||
|
|
@ -226,7 +341,7 @@ SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value)
|
|||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
if (hat < 0 || hat >= hwdata->nhats) {
|
||||
if (hat < 0 || hat >= hwdata->desc.nhats) {
|
||||
SDL_UnlockJoysticks();
|
||||
return SDL_SetError("Invalid hat index");
|
||||
}
|
||||
|
|
@ -271,7 +386,14 @@ VIRTUAL_JoystickGetDeviceName(int device_index)
|
|||
if (!hwdata) {
|
||||
return NULL;
|
||||
}
|
||||
return hwdata->name ? hwdata->name : "";
|
||||
return hwdata->name;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
VIRTUAL_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -285,6 +407,11 @@ VIRTUAL_JoystickGetDevicePlayerIndex(int device_index)
|
|||
static void
|
||||
VIRTUAL_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
{
|
||||
joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
|
||||
|
||||
if (hwdata && hwdata->desc.SetPlayerIndex) {
|
||||
hwdata->desc.SetPlayerIndex(hwdata->desc.userdata, player_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -319,15 +446,12 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
if (!hwdata) {
|
||||
return SDL_SetError("No such device");
|
||||
}
|
||||
if (hwdata->opened) {
|
||||
return SDL_SetError("Joystick already opened");
|
||||
}
|
||||
joystick->instance_id = hwdata->instance_id;
|
||||
joystick->hwdata = hwdata;
|
||||
joystick->naxes = hwdata->naxes;
|
||||
joystick->nbuttons = hwdata->nbuttons;
|
||||
joystick->nhats = hwdata->nhats;
|
||||
hwdata->opened = SDL_TRUE;
|
||||
joystick->naxes = hwdata->desc.naxes;
|
||||
joystick->nbuttons = hwdata->desc.nbuttons;
|
||||
joystick->nhats = hwdata->desc.nhats;
|
||||
hwdata->joystick = joystick;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -335,33 +459,99 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
static int
|
||||
VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
int result;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
if (hwdata->desc.Rumble) {
|
||||
result = hwdata->desc.Rumble(hwdata->desc.userdata, low_frequency_rumble, high_frequency_rumble);
|
||||
} else {
|
||||
result = SDL_Unsupported();
|
||||
}
|
||||
} else {
|
||||
result = SDL_SetError("Rumble failed, device disconnected");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
int result;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
if (hwdata->desc.RumbleTriggers) {
|
||||
result = hwdata->desc.RumbleTriggers(hwdata->desc.userdata, left_rumble, right_rumble);
|
||||
} else {
|
||||
result = SDL_Unsupported();
|
||||
}
|
||||
} else {
|
||||
result = SDL_SetError("Rumble failed, device disconnected");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static Uint32
|
||||
VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
Uint32 caps = 0;
|
||||
|
||||
if (hwdata) {
|
||||
if (hwdata->desc.Rumble) {
|
||||
caps |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
if (hwdata->desc.RumbleTriggers) {
|
||||
caps |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
if (hwdata->desc.SetLED) {
|
||||
caps |= SDL_JOYCAP_LED;
|
||||
}
|
||||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
int result;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
if (hwdata->desc.SetLED) {
|
||||
result = hwdata->desc.SetLED(hwdata->desc.userdata, red, green, blue);
|
||||
} else {
|
||||
result = SDL_Unsupported();
|
||||
}
|
||||
} else {
|
||||
result = SDL_SetError("SetLED failed, device disconnected");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
int result;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
if (hwdata->desc.SendEffect) {
|
||||
result = hwdata->desc.SendEffect(hwdata->desc.userdata, data, size);
|
||||
} else {
|
||||
result = SDL_Unsupported();
|
||||
}
|
||||
} else {
|
||||
result = SDL_SetError("SendEffect failed, device disconnected");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -386,13 +576,17 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
|||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
|
||||
for (i = 0; i < hwdata->naxes; ++i) {
|
||||
if (hwdata->desc.Update) {
|
||||
hwdata->desc.Update(hwdata->desc.userdata);
|
||||
}
|
||||
|
||||
for (i = 0; i < hwdata->desc.naxes; ++i) {
|
||||
SDL_PrivateJoystickAxis(joystick, i, hwdata->axes[i]);
|
||||
}
|
||||
for (i = 0; i < hwdata->nbuttons; ++i) {
|
||||
for (i = 0; i < hwdata->desc.nbuttons; ++i) {
|
||||
SDL_PrivateJoystickButton(joystick, i, hwdata->buttons[i]);
|
||||
}
|
||||
for (i = 0; i < hwdata->nhats; ++i) {
|
||||
for (i = 0; i < hwdata->desc.nhats; ++i) {
|
||||
SDL_PrivateJoystickHat(joystick, i, hwdata->hats[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -401,17 +595,11 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
|||
static void
|
||||
VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
joystick_hwdata *hwdata;
|
||||
|
||||
if (!joystick) {
|
||||
return;
|
||||
if (joystick->hwdata) {
|
||||
joystick_hwdata *hwdata = joystick->hwdata;
|
||||
hwdata->joystick = NULL;
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
if (!joystick->hwdata) {
|
||||
return;
|
||||
}
|
||||
|
||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
||||
hwdata->opened = SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -426,7 +614,145 @@ VIRTUAL_JoystickQuit(void)
|
|||
static SDL_bool
|
||||
VIRTUAL_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
|
||||
int current_button = 0;
|
||||
int current_axis = 0;
|
||||
|
||||
if (hwdata->desc.type != SDL_JOYSTICK_TYPE_GAMECONTROLLER) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_A))) {
|
||||
out->a.kind = EMappingKind_Button;
|
||||
out->a.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_B))) {
|
||||
out->b.kind = EMappingKind_Button;
|
||||
out->b.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_X))) {
|
||||
out->x.kind = EMappingKind_Button;
|
||||
out->x.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_Y))) {
|
||||
out->y.kind = EMappingKind_Button;
|
||||
out->y.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK))) {
|
||||
out->back.kind = EMappingKind_Button;
|
||||
out->back.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE))) {
|
||||
out->guide.kind = EMappingKind_Button;
|
||||
out->guide.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_START))) {
|
||||
out->start.kind = EMappingKind_Button;
|
||||
out->start.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK))) {
|
||||
out->leftstick.kind = EMappingKind_Button;
|
||||
out->leftstick.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK))) {
|
||||
out->rightstick.kind = EMappingKind_Button;
|
||||
out->rightstick.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER))) {
|
||||
out->leftshoulder.kind = EMappingKind_Button;
|
||||
out->leftshoulder.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))) {
|
||||
out->rightshoulder.kind = EMappingKind_Button;
|
||||
out->rightshoulder.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP))) {
|
||||
out->dpup.kind = EMappingKind_Button;
|
||||
out->dpup.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN))) {
|
||||
out->dpdown.kind = EMappingKind_Button;
|
||||
out->dpdown.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT))) {
|
||||
out->dpleft.kind = EMappingKind_Button;
|
||||
out->dpleft.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT))) {
|
||||
out->dpright.kind = EMappingKind_Button;
|
||||
out->dpright.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1))) {
|
||||
out->misc1.kind = EMappingKind_Button;
|
||||
out->misc1.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE1))) {
|
||||
out->paddle1.kind = EMappingKind_Button;
|
||||
out->paddle1.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE2))) {
|
||||
out->paddle2.kind = EMappingKind_Button;
|
||||
out->paddle2.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE3))) {
|
||||
out->paddle3.kind = EMappingKind_Button;
|
||||
out->paddle3.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE4))) {
|
||||
out->paddle4.kind = EMappingKind_Button;
|
||||
out->paddle4.target = current_button++;
|
||||
}
|
||||
|
||||
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX))) {
|
||||
out->leftx.kind = EMappingKind_Axis;
|
||||
out->leftx.target = current_axis++;
|
||||
}
|
||||
|
||||
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY))) {
|
||||
out->lefty.kind = EMappingKind_Axis;
|
||||
out->lefty.target = current_axis++;
|
||||
}
|
||||
|
||||
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX))) {
|
||||
out->rightx.kind = EMappingKind_Axis;
|
||||
out->rightx.target = current_axis++;
|
||||
}
|
||||
|
||||
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY))) {
|
||||
out->righty.kind = EMappingKind_Axis;
|
||||
out->righty.target = current_axis++;
|
||||
}
|
||||
|
||||
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT))) {
|
||||
out->lefttrigger.kind = EMappingKind_Axis;
|
||||
out->lefttrigger.target = current_axis++;
|
||||
}
|
||||
|
||||
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT))) {
|
||||
out->righttrigger.kind = EMappingKind_Axis;
|
||||
out->righttrigger.target = current_axis++;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
|
||||
|
|
@ -435,6 +761,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
|
|||
VIRTUAL_JoystickGetCount,
|
||||
VIRTUAL_JoystickDetect,
|
||||
VIRTUAL_JoystickGetDeviceName,
|
||||
VIRTUAL_JoystickGetDevicePath,
|
||||
VIRTUAL_JoystickGetDevicePlayerIndex,
|
||||
VIRTUAL_JoystickSetDevicePlayerIndex,
|
||||
VIRTUAL_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -34,24 +34,19 @@ typedef struct joystick_hwdata
|
|||
{
|
||||
SDL_JoystickType type;
|
||||
SDL_bool attached;
|
||||
const char *name;
|
||||
char *name;
|
||||
SDL_JoystickGUID guid;
|
||||
int naxes;
|
||||
SDL_VirtualJoystickDesc desc;
|
||||
Sint16 *axes;
|
||||
int nbuttons;
|
||||
Uint8 *buttons;
|
||||
int nhats;
|
||||
Uint8 *hats;
|
||||
SDL_JoystickID instance_id;
|
||||
SDL_bool opened;
|
||||
SDL_Joystick *joystick;
|
||||
|
||||
struct joystick_hwdata *next;
|
||||
} joystick_hwdata;
|
||||
|
||||
int SDL_JoystickAttachVirtualInner(SDL_JoystickType type,
|
||||
int naxes,
|
||||
int nbuttons,
|
||||
int nhats);
|
||||
|
||||
int SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc);
|
||||
int SDL_JoystickDetachVirtualInner(int device_index);
|
||||
|
||||
int SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value);
|
||||
|
|
@ -59,4 +54,7 @@ int SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8
|
|||
int SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value);
|
||||
|
||||
#endif /* SDL_JOYSTICK_VIRTUAL */
|
||||
|
||||
#endif /* SDL_VIRTUALJOYSTICK_C_H */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -179,7 +179,6 @@ SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index)
|
|||
return device_index;
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *VITA_JoystickGetDeviceName(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
|
|
@ -195,7 +194,12 @@ const char *VITA_JoystickGetDeviceName(int index)
|
|||
return "PSVita Controller";
|
||||
|
||||
SDL_SetError("No joystick available with that index");
|
||||
return(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *VITA_JoystickGetDevicePath(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -400,6 +404,7 @@ SDL_JoystickDriver SDL_VITA_JoystickDriver =
|
|||
VITA_JoystickGetCount,
|
||||
VITA_JoystickDetect,
|
||||
VITA_JoystickGetDeviceName,
|
||||
VITA_JoystickGetDevicePath,
|
||||
VITA_JoystickGetDevicePlayerIndex,
|
||||
VITA_JoystickSetDevicePlayerIndex,
|
||||
VITA_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
|
|||
pNewJoystick = *(JoyStick_DeviceData**)pContext;
|
||||
while (pNewJoystick) {
|
||||
/* update GUIDs of joysticks with matching paths, in case they're not open yet */
|
||||
if (SDL_strcmp(pNewJoystick->hidPath, hidPath) == 0) {
|
||||
if (SDL_strcmp(pNewJoystick->path, hidPath) == 0) {
|
||||
/* if we are replacing the front of the list then update it */
|
||||
if (pNewJoystick == *(JoyStick_DeviceData**)pContext) {
|
||||
*(JoyStick_DeviceData**)pContext = pNewJoystick->pNext;
|
||||
|
|
@ -483,7 +483,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
|
|||
CHECK(pNewJoystick);
|
||||
|
||||
SDL_zerop(pNewJoystick);
|
||||
SDL_strlcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath));
|
||||
SDL_strlcpy(pNewJoystick->path, hidPath, SDL_arraysize(pNewJoystick->path));
|
||||
SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE));
|
||||
SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
|
||||
|
||||
|
|
@ -683,7 +683,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE pDeviceObject, LPVOID pContext)
|
|||
/* Sort using the data offset into the DInput struct.
|
||||
* This gives a reasonable ordering for the inputs.
|
||||
*/
|
||||
static int
|
||||
static int SDLCALL
|
||||
SortDevFunc(const void *a, const void *b)
|
||||
{
|
||||
const input_t *inputA = (const input_t*)a;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ typedef struct _SDL_RAWINPUT_Device
|
|||
{
|
||||
SDL_atomic_t refcount;
|
||||
char *name;
|
||||
char *path;
|
||||
Uint16 vendor_id;
|
||||
Uint16 product_id;
|
||||
Uint16 version;
|
||||
|
|
@ -689,10 +690,9 @@ RAWINPUT_ReleaseDevice(SDL_RAWINPUT_Device *device)
|
|||
#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */
|
||||
|
||||
if (SDL_AtomicDecRef(&device->refcount)) {
|
||||
if (device->preparsed_data) {
|
||||
SDL_HidD_FreePreparsedData(device->preparsed_data);
|
||||
}
|
||||
SDL_free(device->preparsed_data);
|
||||
SDL_free(device->name);
|
||||
SDL_free(device->path);
|
||||
SDL_free(device);
|
||||
}
|
||||
}
|
||||
|
|
@ -716,9 +716,8 @@ RAWINPUT_AddDevice(HANDLE hDevice)
|
|||
SDL_RAWINPUT_Device *device = NULL;
|
||||
SDL_RAWINPUT_Device *curr, *last;
|
||||
RID_DEVICE_INFO rdi;
|
||||
UINT rdi_size = sizeof(rdi);
|
||||
UINT size;
|
||||
char dev_name[MAX_PATH];
|
||||
UINT name_size = SDL_arraysize(dev_name);
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
|
||||
/* Make sure we're not trying to add the same device twice */
|
||||
|
|
@ -727,11 +726,13 @@ RAWINPUT_AddDevice(HANDLE hDevice)
|
|||
}
|
||||
|
||||
/* Figure out what kind of device it is */
|
||||
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &rdi_size) != (UINT)-1);
|
||||
size = sizeof(rdi);
|
||||
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &size) != (UINT)-1);
|
||||
CHECK(rdi.dwType == RIM_TYPEHID);
|
||||
|
||||
/* Get the device "name" (HID Path) */
|
||||
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &name_size) != (UINT)-1);
|
||||
size = SDL_arraysize(dev_name);
|
||||
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1);
|
||||
/* Only take XInput-capable devices */
|
||||
CHECK(SDL_strstr(dev_name, "IG_") != NULL);
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
|
@ -747,6 +748,12 @@ RAWINPUT_AddDevice(HANDLE hDevice)
|
|||
device->is_xinput = SDL_TRUE;
|
||||
device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController;
|
||||
|
||||
/* Get HID Top-Level Collection Preparsed Data */
|
||||
size = 0;
|
||||
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, NULL, &size) != (UINT)-1);
|
||||
CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE)));
|
||||
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1);
|
||||
|
||||
{
|
||||
const Uint16 vendor = device->vendor_id;
|
||||
const Uint16 product = device->product_id;
|
||||
|
|
@ -791,8 +798,7 @@ RAWINPUT_AddDevice(HANDLE hDevice)
|
|||
SDL_free(product_string);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(SDL_HidD_GetPreparsedData(hFile, &device->preparsed_data));
|
||||
device->path = SDL_strdup(dev_name);
|
||||
|
||||
CloseHandle(hFile);
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
|
|
@ -825,8 +831,12 @@ err:
|
|||
CloseHandle(hFile);
|
||||
}
|
||||
if (device) {
|
||||
if (device->name)
|
||||
if (device->name) {
|
||||
SDL_free(device->name);
|
||||
}
|
||||
if (device->path) {
|
||||
SDL_free(device->path);
|
||||
}
|
||||
SDL_free(device);
|
||||
}
|
||||
#undef CHECK
|
||||
|
|
@ -1029,6 +1039,12 @@ RAWINPUT_JoystickGetDeviceName(int device_index)
|
|||
return RAWINPUT_GetDeviceByIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
RAWINPUT_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return RAWINPUT_GetDeviceByIndex(device_index)->path;
|
||||
}
|
||||
|
||||
static int
|
||||
RAWINPUT_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -1053,7 +1069,7 @@ RAWINPUT_JoystickGetDeviceInstanceID(int device_index)
|
|||
return RAWINPUT_GetDeviceByIndex(device_index)->joystick_id;
|
||||
}
|
||||
|
||||
static int
|
||||
static int SDLCALL
|
||||
RAWINPUT_SortValueCaps(const void *A, const void *B)
|
||||
{
|
||||
HIDP_VALUE_CAPS *capsA = (HIDP_VALUE_CAPS *)A;
|
||||
|
|
@ -1253,7 +1269,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
}
|
||||
}
|
||||
|
||||
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_UNKNOWN);
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1263,8 +1279,8 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin
|
|||
{
|
||||
#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT)
|
||||
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
|
||||
SDL_bool rumbled = SDL_FALSE;
|
||||
#endif
|
||||
SDL_bool rumbled = SDL_FALSE;
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
|
||||
if (!rumbled && ctx->wgi_correlated) {
|
||||
|
|
@ -1312,7 +1328,7 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
|
|||
{
|
||||
#if defined(SDL_JOYSTICK_RAWINPUT_WGI)
|
||||
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
|
||||
|
||||
|
||||
if (ctx->wgi_correlated) {
|
||||
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
|
||||
HRESULT hr;
|
||||
|
|
@ -1570,17 +1586,25 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
|
|||
int guide_button = joystick->nbuttons - 1;
|
||||
int left_trigger = joystick->naxes - 2;
|
||||
int right_trigger = joystick->naxes - 1;
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
|
||||
SDL_bool xinput_correlated;
|
||||
#endif
|
||||
|
||||
RAWINPUT_FillMatchState(&match_state_xinput, ctx->match_state);
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
|
||||
xinput_correlated = ctx->xinput_correlated;
|
||||
#else
|
||||
xinput_correlated = SDL_FALSE;
|
||||
#endif
|
||||
/* Parallel logic to WINDOWS_XINPUT below */
|
||||
RAWINPUT_UpdateWindowsGamingInput();
|
||||
if (ctx->wgi_correlated &&
|
||||
!joystick->low_frequency_rumble && !joystick->high_frequency_rumble &&
|
||||
!joystick->left_trigger_rumble && !joystick->right_trigger_rumble) {
|
||||
/* We have been previously correlated, ensure we are still matching, see comments in XINPUT section */
|
||||
if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, ctx->xinput_correlated)) {
|
||||
if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, xinput_correlated)) {
|
||||
ctx->wgi_uncorrelate_count = 0;
|
||||
} else {
|
||||
++ctx->wgi_uncorrelate_count;
|
||||
|
|
@ -1609,7 +1633,7 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
|
|||
if (RAWINPUT_MissingWindowsGamingInputSlot()) {
|
||||
Uint8 correlation_id;
|
||||
WindowsGamingInputGamepadState *slot_idx = NULL;
|
||||
if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, ctx->xinput_correlated)) {
|
||||
if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, xinput_correlated)) {
|
||||
/* we match exactly one WindowsGamingInput device */
|
||||
/* Probably can do without wgi_correlation_count, just check and clear wgi_slot to NULL, unless we need
|
||||
even more frames to be sure. */
|
||||
|
|
@ -1911,7 +1935,7 @@ RAWINPUT_UnregisterNotifications()
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LRESULT CALLBACK
|
||||
RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
|
@ -2006,6 +2030,7 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver =
|
|||
RAWINPUT_JoystickGetCount,
|
||||
RAWINPUT_JoystickDetect,
|
||||
RAWINPUT_JoystickGetDeviceName,
|
||||
RAWINPUT_JoystickGetDevicePath,
|
||||
RAWINPUT_JoystickGetDevicePlayerIndex,
|
||||
RAWINPUT_JoystickSetDevicePlayerIndex,
|
||||
RAWINPUT_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -586,6 +586,12 @@ WGI_JoystickGetDeviceName(int device_index)
|
|||
return wgi.controllers[device_index].name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
WGI_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
WGI_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -893,6 +899,7 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver =
|
|||
WGI_JoystickGetCount,
|
||||
WGI_JoystickDetect,
|
||||
WGI_JoystickGetDeviceName,
|
||||
WGI_JoystickGetDevicePath,
|
||||
WGI_JoystickGetDevicePlayerIndex,
|
||||
WGI_JoystickSetDevicePlayerIndex,
|
||||
WGI_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
|
|||
static SDL_DeviceNotificationData s_notification_data;
|
||||
|
||||
/* Function/thread to scan the system for joysticks. */
|
||||
static int
|
||||
static int SDLCALL
|
||||
SDL_JoystickThread(void *_data)
|
||||
{
|
||||
#if SDL_JOYSTICK_XINPUT
|
||||
|
|
@ -555,7 +555,6 @@ WINDOWS_JoystickDetect(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *
|
||||
WINDOWS_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
|
|
@ -568,6 +567,18 @@ WINDOWS_JoystickGetDeviceName(int device_index)
|
|||
return device->joystickname;
|
||||
}
|
||||
|
||||
static const char *
|
||||
WINDOWS_JoystickGetDevicePath(int device_index)
|
||||
{
|
||||
JoyStick_DeviceData *device = SYS_Joystick;
|
||||
int index;
|
||||
|
||||
for (index = device_index; index > 0; index--)
|
||||
device = device->pNext;
|
||||
|
||||
return device->path;
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
|
|
@ -755,6 +766,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
|||
WINDOWS_JoystickGetCount,
|
||||
WINDOWS_JoystickDetect,
|
||||
WINDOWS_JoystickGetDeviceName,
|
||||
WINDOWS_JoystickGetDevicePath,
|
||||
WINDOWS_JoystickGetDevicePlayerIndex,
|
||||
WINDOWS_JoystickSetDevicePlayerIndex,
|
||||
WINDOWS_JoystickGetDeviceGUID,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ typedef struct JoyStick_DeviceData
|
|||
BYTE SubType;
|
||||
Uint8 XInputUserId;
|
||||
DIDEVICEINSTANCE dxdevice;
|
||||
char hidPath[MAX_PATH];
|
||||
char path[MAX_PATH];
|
||||
struct JoyStick_DeviceData *pNext;
|
||||
} JoyStick_DeviceData;
|
||||
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
|
|||
SDL_free(pNewJoystick);
|
||||
return; /* better luck next time? */
|
||||
}
|
||||
SDL_snprintf(pNewJoystick->path, sizeof(pNewJoystick->path), "XInput#%d", userid);
|
||||
|
||||
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
|
||||
SDL_free(pNewJoystick);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue