Fix some issues with stick magnitude.

This commit is contained in:
MutantAura 2024-05-30 19:41:47 +01:00 committed by Evan Husted
parent ffe366d953
commit e1f5c501b0

View File

@ -7,6 +7,7 @@ using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input; using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Input; using Ryujinx.Input;
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -16,13 +17,15 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
[ObservableProperty] private GamepadInputConfig _config; [ObservableProperty] private GamepadInputConfig _config;
private const int StickUiPollMs = 50; // Milliseconds per poll. private const int DrawStickPollRate = 50; // Milliseconds per poll.
private const int StickCircumference = 5; private const int DrawStickCircumference = 5;
private const float DrawStickScaleFactor = DrawStickCanvasCenter;
private const int CanvasSize = 100; private const int DrawStickCanvasSize = 100;
private const int StickBorderSize = CanvasSize + 5; private const int DrawStickBorderSize = DrawStickCanvasSize + 5;
private const float CanvasCenterOffset = (CanvasSize - StickCircumference) / 2; private const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
private const int StickScaleFactor = 45;
private const float MaxVectorLength = DrawStickCanvasSize / 2;
private IGamepad _selectedGamepad; private IGamepad _selectedGamepad;
@ -30,6 +33,9 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private (float, float) _uiStickLeft; private (float, float) _uiStickLeft;
private (float, float) _uiStickRight; private (float, float) _uiStickRight;
private float _vectorLength;
private float _vectorMultiplier;
internal CancellationTokenSource _pollTokenSource = new(); internal CancellationTokenSource _pollTokenSource = new();
private readonly CancellationToken _pollToken; private readonly CancellationToken _pollToken;
@ -65,7 +71,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public (float, float) UiStickLeft public (float, float) UiStickLeft
{ {
get => (_uiStickLeft.Item1 * StickScaleFactor, _uiStickLeft.Item2 * StickScaleFactor); get => (_uiStickLeft.Item1 * DrawStickScaleFactor, _uiStickLeft.Item2 * DrawStickScaleFactor);
set set
{ {
_uiStickLeft = value; _uiStickLeft = value;
@ -79,7 +85,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public (float, float) UiStickRight public (float, float) UiStickRight
{ {
get => (_uiStickRight.Item1 * StickScaleFactor, _uiStickRight.Item2 * StickScaleFactor); get => (_uiStickRight.Item1 * DrawStickScaleFactor, _uiStickRight.Item2 * DrawStickScaleFactor);
set set
{ {
_uiStickRight = value; _uiStickRight = value;
@ -91,17 +97,76 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
} }
public int UiStickCircumference => StickCircumference; public int UiStickCircumference => DrawStickCircumference;
public int UiCanvasSize => CanvasSize; public int UiCanvasSize => DrawStickCanvasSize;
public int UiStickBorderSize => StickBorderSize; public int UiStickBorderSize => DrawStickBorderSize;
public float UiStickLeftX => UiStickLeft.Item1 + CanvasCenterOffset; public float UiStickLeftX
public float UiStickLeftY => UiStickLeft.Item2 + CanvasCenterOffset; {
public float UiStickRightX => UiStickRight.Item1 + CanvasCenterOffset; get
public float UiStickRightY => UiStickRight.Item2 + CanvasCenterOffset; {
_vectorMultiplier = 1;
_vectorLength = GetVectorLength(UiStickLeft);
public float UiDeadzoneLeft => Config.DeadzoneLeft * (CanvasSize - StickCircumference); if (_vectorLength > MaxVectorLength)
public float UiDeadzoneRight => Config.DeadzoneRight * (CanvasSize - StickCircumference); {
_vectorMultiplier = MaxVectorLength / _vectorLength;
}
return (UiStickLeft.Item1 * _vectorMultiplier) + DrawStickCanvasCenter;
}
}
public float UiStickLeftY
{
get
{
_vectorMultiplier = 1;
_vectorLength = GetVectorLength(UiStickLeft);
if (_vectorLength > MaxVectorLength)
{
_vectorMultiplier = MaxVectorLength / _vectorLength;
}
return (UiStickLeft.Item2 * _vectorMultiplier) + DrawStickCanvasCenter;
}
}
public float UiStickRightX
{
get
{
_vectorMultiplier = 1;
_vectorLength = GetVectorLength(UiStickRight);
if (_vectorLength > MaxVectorLength)
{
_vectorMultiplier = MaxVectorLength / _vectorLength;
}
return (UiStickRight.Item1 * _vectorMultiplier) + DrawStickCanvasCenter;
}
}
public float UiStickRightY
{
get
{
_vectorMultiplier = 1;
_vectorLength = GetVectorLength(UiStickRight);
if (_vectorLength > MaxVectorLength)
{
_vectorMultiplier = MaxVectorLength / _vectorLength;
}
return (UiStickRight.Item2 * _vectorMultiplier) + DrawStickCanvasCenter;
}
}
public float UiDeadzoneLeft => Config.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
public float UiDeadzoneRight => Config.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config) public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
{ {
@ -148,12 +213,17 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
UiStickRight = _selectedGamepad.GetStick(StickInputId.Right); UiStickRight = _selectedGamepad.GetStick(StickInputId.Right);
} }
await Task.Delay(StickUiPollMs, token); await Task.Delay(DrawStickPollRate, token);
} }
_pollTokenSource.Dispose(); _pollTokenSource.Dispose();
} }
private float GetVectorLength((float, float) raw)
{
return (float)Math.Sqrt((raw.Item1 * raw.Item1) + (raw.Item2 * raw.Item2));
}
public void OnParentModelChanged() public void OnParentModelChanged()
{ {
IsLeft = ParentModel.IsLeft; IsLeft = ParentModel.IsLeft;