We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4915

Summary: [patch] Joystick not shutdown for HIDAPI device with multiple joysticks
Product: SDL Reporter: Zack Middleton (zturtleman) <zack>
Component: joystickAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: HG 2.0   
Hardware: x86_64   
OS: Linux   
Attachments: Patch to disconnect all HIDAPI device joysticks

Description Zack Middleton (zturtleman) 2019-12-22 20:49:45 UTC
Created attachment 4137 [details]
Patch to disconnect all HIDAPI device joysticks

Using Wii U GameCube USB adapter with multiple controllers attached and restarting SDL input in a game results in extra joysticks with NULL name (SDL_JoystickNameForIndex()).

0. Nintendo GameCube Controller
1. Nintendo GameCube Controller
2. Nintendo GameCube Controller
3. Nintendo GameCube Controller
4. NULL
5. NULL

There are more NULL name joysticks added each time input is restarted.

SDL doesn't shutdown all joysticks, the SDL_assert(SDL_HIDAPI_numjoysticks == 0) fails in SDL_hidapijoystick.c.

HIDAPI_CleanupDeviceDriver() shuts down joysticks by iterating through device->num_joysticks but each HIDAPI_JoystickDisconnected() decreases device->num_joysticks and shifts joysticks array down. Resulting in only half of controllers being disconnected. It works with only 1 controller attached though.

HIDAPI_CleanupDeviceDriver():
    for i: 0 < num_joysticks: 4; i++

    HIDAPI_JoystickDisconnected(device, device->joysticks[i: 0]);
    --num_joysticks;

    for i: 1 < num_joysticks: 3; i++
    HIDAPI_JoystickDisconnected(device, device->joysticks[i: 1]);
    --num_joysticks;

    for i: 2 < num_joysticks: 2; i++

    end loop

There are still two others joysticks moved down into device->joysticks[0 and 1] though.

Patch attached to disconnect HIDAPI device joystick 0 until there are no joysticks left (with other joysticks moved down to index 0 each time). Alternatively running the HIDAPI_CleanupDeviceDriver() "for loop" in reverse also solves the issue "for (i = device->num_joysticks - 1; i >= 0; --i)".
Comment 1 Sam Lantinga 2019-12-22 21:17:01 UTC
Patch added, thanks!
https://hg.libsdl.org/SDL/rev/4ba8f4018ea1