Fixed crash if a virtual joystick was disconnected
parent
2317a96c8e
commit
3c3ccb1d48
|
@ -71,6 +71,10 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hwdata->joystick) {
|
||||||
|
hwdata->joystick->hwdata = NULL;
|
||||||
|
hwdata->joystick = NULL;
|
||||||
|
}
|
||||||
if (hwdata->name) {
|
if (hwdata->name) {
|
||||||
SDL_free(hwdata->name);
|
SDL_free(hwdata->name);
|
||||||
hwdata->name = NULL;
|
hwdata->name = NULL;
|
||||||
|
@ -434,16 +438,12 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||||
if (!hwdata) {
|
if (!hwdata) {
|
||||||
return SDL_SetError("No such device");
|
return SDL_SetError("No such device");
|
||||||
}
|
}
|
||||||
if (hwdata->opened) {
|
|
||||||
/* This should never happen, it's handled by the higher joystick code */
|
|
||||||
return SDL_SetError("Joystick already opened");
|
|
||||||
}
|
|
||||||
joystick->instance_id = hwdata->instance_id;
|
joystick->instance_id = hwdata->instance_id;
|
||||||
joystick->hwdata = hwdata;
|
joystick->hwdata = hwdata;
|
||||||
joystick->naxes = hwdata->desc.naxes;
|
joystick->naxes = hwdata->desc.naxes;
|
||||||
joystick->nbuttons = hwdata->desc.nbuttons;
|
joystick->nbuttons = hwdata->desc.nbuttons;
|
||||||
joystick->nhats = hwdata->desc.nhats;
|
joystick->nhats = hwdata->desc.nhats;
|
||||||
hwdata->opened = SDL_TRUE;
|
hwdata->joystick = joystick;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,23 +451,39 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||||
static int
|
static int
|
||||||
VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
int result;
|
||||||
|
|
||||||
if (hwdata && hwdata->desc.Rumble) {
|
if (joystick->hwdata) {
|
||||||
return hwdata->desc.Rumble(hwdata->desc.userdata, low_frequency_rumble, high_frequency_rumble);
|
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 SDL_Unsupported();
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
int result;
|
||||||
|
|
||||||
if (hwdata && hwdata->desc.RumbleTriggers) {
|
if (joystick->hwdata) {
|
||||||
return hwdata->desc.RumbleTriggers(hwdata->desc.userdata, left_rumble, right_rumble);
|
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 SDL_Unsupported();
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -495,23 +511,39 @@ VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||||
static int
|
static int
|
||||||
VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
int result;
|
||||||
|
|
||||||
if (hwdata && hwdata->desc.SetLED) {
|
if (joystick->hwdata) {
|
||||||
return hwdata->desc.SetLED(hwdata->desc.userdata, red, green, blue);
|
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 SDL_Unsupported();
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
|
VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
int result;
|
||||||
|
|
||||||
if (hwdata && hwdata->desc.SendEffect) {
|
if (joystick->hwdata) {
|
||||||
return hwdata->desc.SendEffect(hwdata->desc.userdata, data, size);
|
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 SDL_Unsupported();
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -555,17 +587,11 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
static void
|
static void
|
||||||
VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata;
|
if (joystick->hwdata) {
|
||||||
|
joystick_hwdata *hwdata = joystick->hwdata;
|
||||||
if (!joystick) {
|
hwdata->joystick = NULL;
|
||||||
return;
|
joystick->hwdata = NULL;
|
||||||
}
|
}
|
||||||
if (!joystick->hwdata) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hwdata = (joystick_hwdata *)joystick->hwdata;
|
|
||||||
hwdata->opened = SDL_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@ typedef struct joystick_hwdata
|
||||||
Uint8 *buttons;
|
Uint8 *buttons;
|
||||||
Uint8 *hats;
|
Uint8 *hats;
|
||||||
SDL_JoystickID instance_id;
|
SDL_JoystickID instance_id;
|
||||||
SDL_bool opened;
|
SDL_Joystick *joystick;
|
||||||
|
|
||||||
struct joystick_hwdata *next;
|
struct joystick_hwdata *next;
|
||||||
} joystick_hwdata;
|
} joystick_hwdata;
|
||||||
|
|
||||||
|
|
|
@ -335,9 +335,10 @@ static int VirtualControllerSetLED(void *userdata, Uint8 red, Uint8 green, Uint8
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OpenVirtualController()
|
static void OpenVirtualController()
|
||||||
{
|
{
|
||||||
SDL_VirtualJoystickDesc desc;
|
SDL_VirtualJoystickDesc desc;
|
||||||
|
int virtual_index;
|
||||||
|
|
||||||
SDL_zero(desc);
|
SDL_zero(desc);
|
||||||
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
|
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
|
||||||
|
@ -348,7 +349,32 @@ static int OpenVirtualController()
|
||||||
desc.Rumble = VirtualControllerRumble;
|
desc.Rumble = VirtualControllerRumble;
|
||||||
desc.RumbleTriggers = VirtualControllerRumbleTriggers;
|
desc.RumbleTriggers = VirtualControllerRumbleTriggers;
|
||||||
desc.SetLED = VirtualControllerSetLED;
|
desc.SetLED = VirtualControllerSetLED;
|
||||||
return SDL_JoystickAttachVirtualEx(&desc);
|
|
||||||
|
virtual_index = SDL_JoystickAttachVirtualEx(&desc);
|
||||||
|
if (virtual_index < 0) {
|
||||||
|
SDL_Log("Couldn't open virtual device: %s\n", SDL_GetError());
|
||||||
|
} else {
|
||||||
|
virtual_joystick = SDL_JoystickOpen(virtual_index);
|
||||||
|
if (!virtual_joystick) {
|
||||||
|
SDL_Log("Couldn't open virtual device: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CloseVirtualController()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < SDL_NumJoysticks(); ++i) {
|
||||||
|
if (SDL_JoystickIsVirtual(i)) {
|
||||||
|
SDL_JoystickDetachVirtual(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virtual_joystick) {
|
||||||
|
SDL_JoystickClose(virtual_joystick);
|
||||||
|
virtual_joystick = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_GameControllerButton FindButtonAtPosition(int x, int y)
|
static SDL_GameControllerButton FindButtonAtPosition(int x, int y)
|
||||||
|
@ -580,6 +606,14 @@ loop(void *arg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (event.key.keysym.sym == SDLK_a) {
|
||||||
|
OpenVirtualController();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (event.key.keysym.sym == SDLK_d) {
|
||||||
|
CloseVirtualController();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (event.key.keysym.sym != SDLK_ESCAPE) {
|
if (event.key.keysym.sym != SDLK_ESCAPE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -836,15 +870,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
for (i = 1; i < argc; ++i) {
|
for (i = 1; i < argc; ++i) {
|
||||||
if (SDL_strcmp(argv[i], "--virtual") == 0) {
|
if (SDL_strcmp(argv[i], "--virtual") == 0) {
|
||||||
int virtual_index = OpenVirtualController();
|
OpenVirtualController();
|
||||||
if (virtual_index < 0) {
|
|
||||||
SDL_Log("Couldn't open virtual device: %s\n", SDL_GetError());
|
|
||||||
} else {
|
|
||||||
virtual_joystick = SDL_JoystickOpen(virtual_index);
|
|
||||||
if (!virtual_joystick) {
|
|
||||||
SDL_Log("Couldn't open virtual device: %s\n", SDL_GetError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (argv[i] && *argv[i] != '-') {
|
if (argv[i] && *argv[i] != '-') {
|
||||||
controller_index = SDL_atoi(argv[i]);
|
controller_index = SDL_atoi(argv[i]);
|
||||||
|
@ -873,6 +899,7 @@ main(int argc, char *argv[])
|
||||||
CyclePS5TriggerEffect();
|
CyclePS5TriggerEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseVirtualController();
|
||||||
SDL_DestroyRenderer(screen);
|
SDL_DestroyRenderer(screen);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
||||||
|
|
Loading…
Reference in New Issue