Overcooked! All You Can Eat only adds new controllers if no existing controller has the same serial as it. SDL GUIDs mark the model of controller, but don't differentiate between multiple controllers of the same model. This is especially bad with Steam virtual controllers, which all have the same GUID.
Switch to using SDL_JoystickGetSerial if available, and otherwise combining the GUID with the controller index
-- v3: winebus.sys: Report unique serial numbers for SDL devices.
From: Evan Tang etang@codeweavers.com
--- dlls/winebus.sys/bus_sdl.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 1af029bed65..cd6166a91a8 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -120,6 +120,7 @@ static Uint16 (*pSDL_JoystickGetProduct)(SDL_Joystick * joystick); static Uint16 (*pSDL_JoystickGetProductVersion)(SDL_Joystick * joystick); static Uint16 (*pSDL_JoystickGetVendor)(SDL_Joystick * joystick); static SDL_JoystickType (*pSDL_JoystickGetType)(SDL_Joystick * joystick); +static const char *(*pSDL_JoystickGetSerial)(SDL_Joystick * joystick);
/* internal bits for extended rumble support, SDL_Haptic types are 16-bits */ #define WINE_SDL_JOYSTICK_RUMBLE 0x40000000 /* using SDL_JoystickRumble API */ @@ -936,9 +937,8 @@ static void sdl_add_device(unsigned int index)
SDL_Joystick* joystick; SDL_JoystickID id; - SDL_JoystickGUID guid; SDL_GameController *controller = NULL; - const char *product; + const char *product, *sdl_serial; char guid_str[33], buffer[ARRAY_SIZE(desc.product)]; int axis_count, axis_offset;
@@ -969,9 +969,19 @@ static void sdl_add_device(unsigned int index) desc.version = 0; }
- guid = pSDL_JoystickGetGUID(joystick); - pSDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); - ntdll_umbstowcs(guid_str, strlen(guid_str) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber)); + if (pSDL_JoystickGetSerial && (sdl_serial = pSDL_JoystickGetSerial(joystick))) + { + ntdll_umbstowcs(sdl_serial, strlen(sdl_serial) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber)); + } + else + { + /* Overcooked! All You Can Eat only adds controllers with unique serial numbers + * Prefer keeping serial numbers unique over keeping them consistent across runs */ + pSDL_JoystickGetGUIDString(pSDL_JoystickGetGUID(joystick), guid_str, sizeof(guid_str)); + snprintf(buffer, sizeof(buffer), "%s.%d", guid_str, index); + TRACE("Making up serial number for %s: %s\n", product, buffer); + ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber)); + }
if (controller) { @@ -1126,6 +1136,7 @@ NTSTATUS sdl_bus_init(void *args) pSDL_JoystickGetProductVersion = dlsym(sdl_handle, "SDL_JoystickGetProductVersion"); pSDL_JoystickGetVendor = dlsym(sdl_handle, "SDL_JoystickGetVendor"); pSDL_JoystickGetType = dlsym(sdl_handle, "SDL_JoystickGetType"); + pSDL_JoystickGetSerial = dlsym(sdl_handle, "SDL_JoystickGetSerial");
if (pSDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) {