mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2026-05-12 09:30:37 +00:00
Fix SDL3 gamepad crash, broken motion, and thread safety issues
- Remove SDL_DestroyProperties call on SDL-owned properties in SDL3Gamepad.GetFeaturesFlag(). SDL_GetGamepadProperties returns properties owned internally by SDL, freed when SDL_CloseGamepad is called. Destroying them causes use-after-free, breaking motion sensor data retrieval and crashing on controller reconnect. - Fix GetGamepads() using wrong lock objects (_gamepadsIds, _joyConsIds, _linkedJoyConsIds instead of _lock) and holding locks across yield boundaries, which is incompatible with System.Threading.Lock. Snapshot IDs under _lock and iterate outside it. - Add null-conditional to _gamepad.Rumble() in NpadController.UpdateRumble() to prevent NullReferenceException if gamepad is disconnected mid-update.
This commit is contained in:
parent
69c22a744e
commit
6320ff6d1b
3 changed files with 12 additions and 20 deletions
|
|
@ -151,7 +151,9 @@ namespace Ryujinx.Input.SDL3
|
||||||
result |= GamepadFeaturesFlag.Led;
|
result |= GamepadFeaturesFlag.Led;
|
||||||
}
|
}
|
||||||
SDL_UnlockProperties(propID);
|
SDL_UnlockProperties(propID);
|
||||||
SDL_DestroyProperties(propID);
|
|
||||||
|
// NOTE: Do not call SDL_DestroyProperties here. These properties are owned
|
||||||
|
// internally by SDL and are freed when SDL_CloseGamepad is called (in Dispose).
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -331,28 +331,18 @@ namespace Ryujinx.Input.SDL3
|
||||||
|
|
||||||
public IEnumerable<IGamepad> GetGamepads()
|
public IEnumerable<IGamepad> GetGamepads()
|
||||||
{
|
{
|
||||||
lock (_gamepadsIds)
|
string[] ids;
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
foreach (var gamepad in _gamepadsIds)
|
ids = _gamepadsIds.Values
|
||||||
{
|
.Concat(_joyConsIds.Values)
|
||||||
yield return GetGamepad(gamepad.Value);
|
.Concat(_linkedJoyConsIds.Values)
|
||||||
}
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_joyConsIds)
|
foreach (string id in ids)
|
||||||
{
|
{
|
||||||
foreach (var gamepad in _joyConsIds)
|
yield return GetGamepad(id);
|
||||||
{
|
|
||||||
yield return GetGamepad(gamepad.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_linkedJoyConsIds)
|
|
||||||
{
|
|
||||||
foreach (var gamepad in _linkedJoyConsIds)
|
|
||||||
{
|
|
||||||
yield return GetGamepad(gamepad.Value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -563,7 +563,7 @@ namespace Ryujinx.Input.HLE
|
||||||
float low = Math.Min(1f, (float)((rightVibrationValue.AmplitudeLow * 0.85 + rightVibrationValue.AmplitudeHigh * 0.15) * controllerConfig.Rumble.StrongRumble));
|
float low = Math.Min(1f, (float)((rightVibrationValue.AmplitudeLow * 0.85 + rightVibrationValue.AmplitudeHigh * 0.15) * controllerConfig.Rumble.StrongRumble));
|
||||||
float high = Math.Min(1f, (float)((leftVibrationValue.AmplitudeLow * 0.15 + leftVibrationValue.AmplitudeHigh * 0.85) * controllerConfig.Rumble.WeakRumble));
|
float high = Math.Min(1f, (float)((leftVibrationValue.AmplitudeLow * 0.15 + leftVibrationValue.AmplitudeHigh * 0.85) * controllerConfig.Rumble.WeakRumble));
|
||||||
|
|
||||||
_gamepad.Rumble(low, high, uint.MaxValue);
|
_gamepad?.Rumble(low, high, uint.MaxValue);
|
||||||
|
|
||||||
Logger.Debug?.Print(LogClass.Hid, $"Effect for {controllerConfig.PlayerIndex} " +
|
Logger.Debug?.Print(LogClass.Hid, $"Effect for {controllerConfig.PlayerIndex} " +
|
||||||
$"L.low.amp={leftVibrationValue.AmplitudeLow}, " +
|
$"L.low.amp={leftVibrationValue.AmplitudeLow}, " +
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue