aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs')
-rw-r--r--src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs74
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)