Added effects support for virtual controllers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h
index 277e29a..9825b5b 100644
--- a/include/SDL_joystick.h
+++ b/include/SDL_joystick.h
@@ -352,6 +352,7 @@ extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type,
* The structure that defines an extended virtual joystick description
*
* The caller must zero the structure and then initialize the version with `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` before passing it to SDL_JoystickAttachVirtualEx()
+ * All other elements of this structure are optional and can be left 0.
*
* \sa SDL_JoystickAttachVirtualEx
*/
@@ -373,6 +374,11 @@ typedef struct SDL_VirtualJoystickDesc
void *userdata; /**< User data pointer passed to callbacks */
void (*Update)(void *userdata); /**< Called when the joystick state should be updated */
+ void (*SetPlayerIndex)(void *userdata, int player_index); /**< Called when the player index is set */
+ int (*Rumble)(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); /**< Implements SDL_JoystickRumble() */
+ int (*RumbleTriggers)(void *userdata, Uint16 left_rumble, Uint16 right_rumble); /**< Implements SDL_JoystickRumbleTriggers() */
+ int (*SetLED)(void *userdata, Uint8 red, Uint8 green, Uint8 blue); /**< Implements SDL_JoystickSetLED() */
+ int (*SendEffect)(void *userdata, const void *data, int size); /**< Implements SDL_JoystickSendEffect() */
} SDL_VirtualJoystickDesc;
diff --git a/src/joystick/virtual/SDL_virtualjoystick.c b/src/joystick/virtual/SDL_virtualjoystick.c
index 6e80d38..4449d0a 100644
--- a/src/joystick/virtual/SDL_virtualjoystick.c
+++ b/src/joystick/virtual/SDL_virtualjoystick.c
@@ -395,6 +395,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);
+ }
}
@@ -446,12 +451,22 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
static int
VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
+ joystick_hwdata *hwdata = joystick->hwdata;
+
+ if (hwdata && hwdata->desc.Rumble) {
+ return hwdata->desc.Rumble(hwdata->desc.userdata, low_frequency_rumble, high_frequency_rumble);
+ }
return SDL_Unsupported();
}
static int
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
+ joystick_hwdata *hwdata = joystick->hwdata;
+
+ if (hwdata && hwdata->desc.RumbleTriggers) {
+ return hwdata->desc.RumbleTriggers(hwdata->desc.userdata, left_rumble, right_rumble);
+ }
return SDL_Unsupported();
}
@@ -459,19 +474,43 @@ VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint1
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)
{
+ joystick_hwdata *hwdata = joystick->hwdata;
+
+ if (hwdata && hwdata->desc.SetLED) {
+ return hwdata->desc.SetLED(hwdata->desc.userdata, red, green, blue);
+ }
return SDL_Unsupported();
}
static int
VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
+ joystick_hwdata *hwdata = joystick->hwdata;
+
+ if (hwdata && hwdata->desc.SendEffect) {
+ return hwdata->desc.SendEffect(hwdata->desc.userdata, data, size);
+ }
return SDL_Unsupported();
}
diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c
index 086a340..b245815 100644
--- a/test/testgamecontroller.c
+++ b/test/testgamecontroller.c
@@ -312,6 +312,29 @@ static SDL_bool ShowingFront()
return showing_front;
}
+static void VirtualControllerSetPlayerIndex(void *userdata, int player_index)
+{
+ SDL_Log("Virtual Controller: player index set to %d\n", player_index);
+}
+
+static int VirtualControllerRumble(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
+{
+ SDL_Log("Virtual Controller: rumble set to %d/%d\n", low_frequency_rumble, high_frequency_rumble);
+ return 0;
+}
+
+static int VirtualControllerRumbleTriggers(void *userdata, Uint16 left_rumble, Uint16 right_rumble)
+{
+ SDL_Log("Virtual Controller: trigger rumble set to %d/%d\n", left_rumble, right_rumble);
+ return 0;
+}
+
+static int VirtualControllerSetLED(void *userdata, Uint8 red, Uint8 green, Uint8 blue)
+{
+ SDL_Log("Virtual Controller: LED set to RGB %d,%d,%d\n", red, green, blue);
+ return 0;
+}
+
static int OpenVirtualController()
{
SDL_VirtualJoystickDesc desc;
@@ -321,6 +344,10 @@ static int OpenVirtualController()
desc.type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
desc.naxes = SDL_CONTROLLER_AXIS_MAX;
desc.nbuttons = SDL_CONTROLLER_BUTTON_MAX;
+ desc.SetPlayerIndex = VirtualControllerSetPlayerIndex;
+ desc.Rumble = VirtualControllerRumble;
+ desc.RumbleTriggers = VirtualControllerRumbleTriggers;
+ desc.SetLED = VirtualControllerSetLED;
return SDL_JoystickAttachVirtualEx(&desc);
}