From 70f79e689bc947313aab11c41e59928ce43be517 Mon Sep 17 00:00:00 2001 From: mpnico Date: Thu, 5 Aug 2021 00:39:40 +0200 Subject: Implement vibrations (#2468) * First working vibration implementation * Fix Infinite Rumble in SDL2Mouse * Stop ignoring one vibValues every 2 * Remove RumbleInfinity as suggested * Reworked all the vibration handle / calculation * Revert HidVibrationDevicePosition changes * Add UI to enable and tune rumble * Remove some stub logs * Add PlayerIndex in rumble debug log * Fix all requested changes * Implements hid::GetVibrationDeviceInfo * Better implements HidVibrationValue.Equals/GetHashCode * Added requested changes from code review * Last fixes from review * Update configuration file version for rebase --- Ryujinx.Input/HLE/NpadController.cs | 27 +++++++++++++++++++++++++++ Ryujinx.Input/HLE/NpadManager.cs | 9 ++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'Ryujinx.Input/HLE') diff --git a/Ryujinx.Input/HLE/NpadController.cs b/Ryujinx.Input/HLE/NpadController.cs index 3559b015..79c18ecf 100644 --- a/Ryujinx.Input/HLE/NpadController.cs +++ b/Ryujinx.Input/HLE/NpadController.cs @@ -2,8 +2,11 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller.Motion; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Hid; using System; +using System.Collections.Generic; +using System.Collections.Concurrent; using System.Numerics; using System.Runtime.CompilerServices; @@ -534,5 +537,29 @@ namespace Ryujinx.Input.HLE { Dispose(true); } + + public void UpdateRumble(ConcurrentQueue<(HidVibrationValue, HidVibrationValue)> queue) + { + if (queue.TryDequeue(out (HidVibrationValue, HidVibrationValue) dualVibrationValue)) + { + if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Rumble.EnableRumble) + { + HidVibrationValue leftVibrationValue = dualVibrationValue.Item1; + HidVibrationValue rightVibrationValue = dualVibrationValue.Item2; + + 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)); + + _gamepad.Rumble(low, high, uint.MaxValue); + + Logger.Debug?.Print(LogClass.Hid, $"Effect for {controllerConfig.PlayerIndex} " + + $"L.low.amp={leftVibrationValue.AmplitudeLow}, " + + $"L.high.amp={leftVibrationValue.AmplitudeHigh}, " + + $"R.low.amp={rightVibrationValue.AmplitudeLow}, " + + $"R.high.amp={rightVibrationValue.AmplitudeHigh} " + + $"--> ({low}, {high})"); + } + } + } } } diff --git a/Ryujinx.Input/HLE/NpadManager.cs b/Ryujinx.Input/HLE/NpadManager.cs index 03bde64b..a0d2e513 100644 --- a/Ryujinx.Input/HLE/NpadManager.cs +++ b/Ryujinx.Input/HLE/NpadManager.cs @@ -4,6 +4,7 @@ using Ryujinx.Common.Configuration.Hid.Controller.Motion; using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.HLE.HOS.Services.Hid; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -167,6 +168,7 @@ namespace Ryujinx.Input.HLE (SixAxisInput, SixAxisInput) motionState = default; NpadController controller = _controllers[(int)inputConfig.PlayerIndex]; + Ryujinx.HLE.HOS.Services.Hid.PlayerIndex playerIndex = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; bool isJoyconPair = false; @@ -177,6 +179,7 @@ namespace Ryujinx.Input.HLE controller.UpdateUserConfiguration(inputConfig); controller.Update(); + controller.UpdateRumble(_device.Hid.Npads.GetRumbleQueue(playerIndex)); inputState = controller.GetHLEInputState(); @@ -199,15 +202,15 @@ namespace Ryujinx.Input.HLE motionState.Item1.Orientation = new float[9]; } - inputState.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; - motionState.Item1.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; + inputState.PlayerId = playerIndex; + motionState.Item1.PlayerId = playerIndex; hleInputStates.Add(inputState); hleMotionStates.Add(motionState.Item1); if (isJoyconPair && !motionState.Item2.Equals(default)) { - motionState.Item2.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; + motionState.Item2.PlayerId = playerIndex; hleMotionStates.Add(motionState.Item2); } -- cgit v1.2.3