mirror of https://github.com/encounter/SDL.git
joystick: Add capability flags for rumble and trigger rumble
When API limitations force us to guess, we favor a false positive (reporting support when it doesn't exist) compared to a false negative.
This commit is contained in:
parent
1ccfbf963e
commit
afccabb881
|
@ -123,6 +123,8 @@ struct _SDL_Joystick
|
|||
|
||||
/* Joystick capability flags for GetCapabilities() */
|
||||
#define SDL_JOYCAP_LED 0x01
|
||||
#define SDL_JOYCAP_RUMBLE 0x02
|
||||
#define SDL_JOYCAP_RUMBLE_TRIGGERS 0x04
|
||||
|
||||
/* Macro to combine a USB vendor ID and product ID into a single Uint32 value */
|
||||
#define MAKE_VIDPID(VID, PID) (((Uint32)(VID))<<16|(PID))
|
||||
|
|
|
@ -942,7 +942,18 @@ DARWIN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
|||
static Uint32
|
||||
DARWIN_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
recDevice *device = joystick->hwdata;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (device->ffservice) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -467,7 +467,23 @@ HIDAPI_DriverGameCube_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys
|
|||
static Uint32
|
||||
HIDAPI_DriverGameCube_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!ctx->pc_mode) {
|
||||
Uint8 i;
|
||||
|
||||
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
|
||||
if (joystick->instance_id == ctx->joysticks[i]) {
|
||||
if (!ctx->wireless[i] && ctx->rumbleAllowed[i]) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -135,7 +135,13 @@ HIDAPI_DriverLuna_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
|||
static Uint32
|
||||
HIDAPI_DriverLuna_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -601,7 +601,14 @@ HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
|||
static Uint32
|
||||
HIDAPI_DriverPS4_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_JOYCAP_LED;
|
||||
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (ctx->enhanced_mode && ctx->effects_supported) {
|
||||
result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -666,7 +666,14 @@ HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
|||
static Uint32
|
||||
HIDAPI_DriverPS5_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_JOYCAP_LED;
|
||||
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (ctx->enhanced_mode) {
|
||||
result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -129,7 +129,7 @@ HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti
|
|||
static Uint32
|
||||
HIDAPI_DriverStadia_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -1109,8 +1109,15 @@ HIDAPI_DriverSwitch_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti
|
|||
static Uint32
|
||||
HIDAPI_DriverSwitch_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return 0;
|
||||
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!ctx->m_bInputOnly) {
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -207,7 +207,7 @@ static Uint32
|
|||
HIDAPI_DriverXbox360_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return 0;
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -177,7 +177,7 @@ static Uint32
|
|||
HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return 0;
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -428,6 +428,11 @@ HIDAPI_DriverXboxOne_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joys
|
|||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
if (ctx->has_trigger_rumble) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
|
||||
if (ctx->has_color_led) {
|
||||
result |= SDL_JOYCAP_LED;
|
||||
}
|
||||
|
|
|
@ -1331,7 +1331,6 @@ IOS_JoystickGetCapabilities(SDL_Joystick *joystick)
|
|||
{
|
||||
Uint32 result = 0;
|
||||
|
||||
#ifdef ENABLE_MFI_LIGHT
|
||||
@autoreleasepool {
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
|
@ -1341,13 +1340,25 @@ IOS_JoystickGetCapabilities(SDL_Joystick *joystick)
|
|||
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = device->controller;
|
||||
GCDeviceLight *light = controller.light;
|
||||
if (light) {
|
||||
#ifdef ENABLE_MFI_LIGHT
|
||||
if (controller.light) {
|
||||
result |= SDL_JOYCAP_LED;
|
||||
}
|
||||
#endif /* ENABLE_MFI_LIGHT */
|
||||
|
||||
#ifdef ENABLE_MFI_RUMBLE
|
||||
if (controller.haptics) {
|
||||
for (GCHapticsLocality locality in controller.haptics.supportedLocalities) {
|
||||
if ([locality isEqualToString:GCHapticsLocalityHandles]) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
} else if ([locality isEqualToString:GCHapticsLocalityTriggers]) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MFI_RUMBLE */
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MFI_LIGHT */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1193,7 +1193,13 @@ LINUX_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
|||
static Uint32
|
||||
LINUX_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -368,8 +368,8 @@ VITA_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right)
|
|||
static Uint32
|
||||
VITA_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
// always return LED supported for now
|
||||
return SDL_JOYCAP_LED;
|
||||
// always return LED and rumble supported for now
|
||||
return SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -927,7 +927,13 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
|
|||
Uint32
|
||||
SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick)
|
||||
{
|
||||
return 0;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Uint8
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "SDL_timer.h"
|
||||
#include "../usb_ids.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../controller_type.h"
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_hid.h"
|
||||
#include "../hidapi/SDL_hidapijoystick_c.h"
|
||||
|
@ -102,6 +103,7 @@ typedef struct _SDL_RAWINPUT_Device
|
|||
Uint16 version;
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_bool is_xinput;
|
||||
SDL_bool is_xboxone;
|
||||
PHIDP_PREPARSED_DATA preparsed_data;
|
||||
|
||||
HANDLE hDevice;
|
||||
|
@ -114,6 +116,7 @@ typedef struct _SDL_RAWINPUT_Device
|
|||
struct joystick_hwdata
|
||||
{
|
||||
SDL_bool is_xinput;
|
||||
SDL_bool is_xboxone;
|
||||
PHIDP_PREPARSED_DATA preparsed_data;
|
||||
ULONG max_data_length;
|
||||
HIDP_DATA *data;
|
||||
|
@ -705,6 +708,7 @@ RAWINPUT_AddDevice(HANDLE hDevice)
|
|||
device->product_id = (Uint16)rdi.hid.dwProductId;
|
||||
device->version = (Uint16)rdi.hid.dwVersionNumber;
|
||||
device->is_xinput = SDL_TRUE;
|
||||
device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController;
|
||||
|
||||
{
|
||||
const Uint16 vendor = device->vendor_id;
|
||||
|
@ -1054,6 +1058,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
}
|
||||
|
||||
ctx->is_xinput = device->is_xinput;
|
||||
ctx->is_xboxone = device->is_xboxone;
|
||||
ctx->preparsed_data = device->preparsed_data;
|
||||
ctx->max_data_length = SDL_HidP_MaxDataListLength(HidP_Input, ctx->preparsed_data);
|
||||
ctx->data = (HIDP_DATA *)SDL_malloc(ctx->max_data_length * sizeof(*ctx->data));
|
||||
|
@ -1280,6 +1285,25 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
|
|||
static Uint32
|
||||
RAWINPUT_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
|
||||
Uint32 result = 0;
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
|
||||
if (ctx->is_xinput) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
|
||||
if (ctx->is_xinput) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
|
||||
if (ctx->is_xboxone) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -668,7 +668,14 @@ WGI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
|||
static Uint32
|
||||
WGI_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return 0;
|
||||
struct joystick_hwdata *hwdata = joystick->hwdata;
|
||||
|
||||
if (hwdata->gamepad) {
|
||||
/* FIXME: Can WGI even tell us if trigger rumble is supported? */
|
||||
return SDL_JOYCAP_RUMBLE | SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -506,7 +506,7 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
|
|||
Uint32
|
||||
SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick)
|
||||
{
|
||||
return 0;
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue