diff options
Diffstat (limited to 'src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs')
-rw-r--r-- | src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs index 0e3a1301..c741493c 100644 --- a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs +++ b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs @@ -9,8 +9,18 @@ namespace Ryujinx.Input.SDL2 { private readonly Dictionary<int, string> _gamepadsInstanceIdsMapping; private readonly List<string> _gamepadsIds; + private readonly object _lock = new object(); - public ReadOnlySpan<string> GamepadsIds => _gamepadsIds.ToArray(); + public ReadOnlySpan<string> GamepadsIds + { + get + { + lock (_lock) + { + return _gamepadsIds.ToArray(); + } + } + } public string DriverName => "SDL2"; @@ -35,28 +45,39 @@ namespace Ryujinx.Input.SDL2 } } - private static string GenerateGamepadId(int joystickIndex) + private string GenerateGamepadId(int joystickIndex) { Guid guid = SDL_JoystickGetDeviceGUID(joystickIndex); + // Add a unique identifier to the start of the GUID in case of duplicates. + if (guid == Guid.Empty) { return null; } - return joystickIndex + "-" + guid; + string id; + + lock (_lock) + { + int guidIndex = 0; + id = guidIndex + "-" + guid; + + while (_gamepadsIds.Contains(id)) + { + id = (++guidIndex) + "-" + guid; + } + } + + return id; } - private static int GetJoystickIndexByGamepadId(string id) + private int GetJoystickIndexByGamepadId(string id) { - string[] data = id.Split("-"); - - if (data.Length != 6 || !int.TryParse(data[0], out int joystickIndex)) + lock (_lock) { - return -1; + return _gamepadsIds.IndexOf(id); } - - return joystickIndex; } private void HandleJoyStickDisconnected(int joystickInstanceId) @@ -64,7 +85,11 @@ namespace Ryujinx.Input.SDL2 if (_gamepadsInstanceIdsMapping.TryGetValue(joystickInstanceId, out string id)) { _gamepadsInstanceIdsMapping.Remove(joystickInstanceId); - _gamepadsIds.Remove(id); + + lock (_lock) + { + _gamepadsIds.Remove(id); + } OnGamepadDisconnected?.Invoke(id); } @@ -74,23 +99,26 @@ namespace Ryujinx.Input.SDL2 { if (SDL_IsGameController(joystickDeviceId) == SDL_bool.SDL_TRUE) { - string id = GenerateGamepadId(joystickDeviceId); - - if (id == null) + if (_gamepadsInstanceIdsMapping.ContainsKey(joystickInstanceId)) { + // Sometimes a JoyStick connected event fires after the app starts even though it was connected before + // so it is rejected to avoid doubling the entries. return; } - // Sometimes a JoyStick connected event fires after the app starts even though it was connected before - // so it is rejected to avoid doubling the entries. - if (_gamepadsIds.Contains(id)) + string id = GenerateGamepadId(joystickDeviceId); + + if (id == null) { return; } if (_gamepadsInstanceIdsMapping.TryAdd(joystickInstanceId, id)) { - _gamepadsIds.Add(id); + lock (_lock) + { + _gamepadsIds.Add(id); + } OnGamepadConnected?.Invoke(id); } @@ -110,7 +138,10 @@ namespace Ryujinx.Input.SDL2 OnGamepadDisconnected?.Invoke(id); } - _gamepadsIds.Clear(); + lock (_lock) + { + _gamepadsIds.Clear(); + } SDL2Driver.Instance.Dispose(); } @@ -131,11 +162,6 @@ namespace Ryujinx.Input.SDL2 return null; } - if (id != GenerateGamepadId(joystickIndex)) - { - return null; - } - IntPtr gamepadHandle = SDL_GameControllerOpen(joystickIndex); if (gamepadHandle == IntPtr.Zero) |