Move most logic into new StickVisualizer class and add keyboard support.
This commit is contained in:
@@ -7,7 +7,6 @@ using Ryujinx.Ava.Input;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.Views.Input;
|
||||
using Ryujinx.Input;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -15,8 +14,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
public partial class ControllerInputViewModel : BaseModel
|
||||
{
|
||||
[ObservableProperty] private GamepadInputConfig _config;
|
||||
|
||||
private const int DrawStickPollRate = 50; // Milliseconds per poll.
|
||||
private const int DrawStickCircumference = 5;
|
||||
private const float DrawStickScaleFactor = DrawStickCanvasCenter;
|
||||
@@ -26,15 +23,34 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
private const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
|
||||
|
||||
private const float MaxVectorLength = DrawStickCanvasSize / 2;
|
||||
|
||||
|
||||
private IGamepad _selectedGamepad;
|
||||
|
||||
private float _vectorLength;
|
||||
private float _vectorMultiplier;
|
||||
private StickVisualizer _stickVisualizer;
|
||||
public StickVisualizer StickVisualizer
|
||||
{
|
||||
get => _stickVisualizer;
|
||||
set
|
||||
{
|
||||
_stickVisualizer = value;
|
||||
|
||||
internal CancellationTokenSource _pollTokenSource = new();
|
||||
private readonly CancellationToken _pollToken;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private GamepadInputConfig _config;
|
||||
public GamepadInputConfig Config
|
||||
{
|
||||
get => _config;
|
||||
set
|
||||
{
|
||||
_config = value;
|
||||
StickVisualizer.UpdateConfig(Config);
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isLeft;
|
||||
public bool IsLeft
|
||||
{
|
||||
@@ -64,7 +80,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
[ObservableProperty] private SvgImage _image;
|
||||
|
||||
public InputViewModel ParentModel { get; }
|
||||
|
||||
|
||||
private (float, float) _uiStickLeft;
|
||||
|
||||
public (float, float) UiStickLeft
|
||||
@@ -113,12 +129,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
ParentModel = model;
|
||||
model.NotifyChangesEvent += OnParentModelChanged;
|
||||
OnParentModelChanged();
|
||||
_stickVisualizer = new();
|
||||
Config = config;
|
||||
|
||||
_pollTokenSource = new();
|
||||
_pollToken = _pollTokenSource.Token;
|
||||
StickVisualizer.PollToken = StickVisualizer.PollTokenSource.Token;
|
||||
|
||||
Task.Run(() => PollSticks(_pollToken));
|
||||
Task.Run(() => PollSticks(StickVisualizer.PollToken));
|
||||
}
|
||||
|
||||
public async void ShowMotionConfig()
|
||||
@@ -149,30 +165,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
if (_selectedGamepad != null && _selectedGamepad is not AvaloniaKeyboard)
|
||||
{
|
||||
UiStickLeft = _selectedGamepad.GetStick(StickInputId.Left);
|
||||
UiStickRight = _selectedGamepad.GetStick(StickInputId.Right);
|
||||
StickVisualizer.UiStickLeft = _selectedGamepad.GetStick(StickInputId.Left);
|
||||
StickVisualizer.UiStickRight = _selectedGamepad.GetStick(StickInputId.Right);
|
||||
}
|
||||
|
||||
await Task.Delay(DrawStickPollRate, token);
|
||||
await Task.Delay(StickVisualizer.DrawStickPollRate, token);
|
||||
}
|
||||
|
||||
_pollTokenSource.Dispose();
|
||||
}
|
||||
|
||||
private (float, float) ClampVector((float, float) vect)
|
||||
{
|
||||
_vectorMultiplier = 1;
|
||||
_vectorLength = MathF.Sqrt((vect.Item1 * vect.Item1) + (vect.Item2 * vect.Item2));
|
||||
|
||||
if (_vectorLength > MaxVectorLength)
|
||||
{
|
||||
_vectorMultiplier = MaxVectorLength / _vectorLength;
|
||||
}
|
||||
|
||||
vect.Item1 = vect.Item1 * _vectorMultiplier + DrawStickCanvasCenter;
|
||||
vect.Item2 = vect.Item2 * _vectorMultiplier + DrawStickCanvasCenter;
|
||||
|
||||
return vect;
|
||||
StickVisualizer.PollTokenSource.Dispose();
|
||||
}
|
||||
|
||||
public void OnParentModelChanged()
|
||||
|
||||
@@ -884,7 +884,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
|
||||
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
|
||||
|
||||
(ConfigViewModel as ControllerInputViewModel)?._pollTokenSource.Cancel();
|
||||
(ConfigViewModel as ControllerInputViewModel)?.StickVisualizer.PollTokenSource.Cancel();
|
||||
|
||||
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
|
||||
|
||||
|
||||
@@ -1,12 +1,40 @@
|
||||
using Avalonia.Svg.Skia;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Input;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
public partial class KeyboardInputViewModel : BaseModel
|
||||
{
|
||||
[ObservableProperty] private KeyboardInputConfig _config;
|
||||
private (float, float) _leftBuffer = (0, 0);
|
||||
private (float, float) _rightBuffer = (0, 0);
|
||||
private StickVisualizer _stickVisualizer;
|
||||
public StickVisualizer StickVisualizer
|
||||
{
|
||||
get => _stickVisualizer;
|
||||
set
|
||||
{
|
||||
_stickVisualizer = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private KeyboardInputConfig _config;
|
||||
public KeyboardInputConfig Config
|
||||
{
|
||||
get => _config;
|
||||
set
|
||||
{
|
||||
_config = value;
|
||||
StickVisualizer.UpdateConfig(_config);
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isLeft;
|
||||
public bool IsLeft
|
||||
@@ -43,7 +71,65 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
ParentModel = model;
|
||||
model.NotifyChangesEvent += OnParentModelChanged;
|
||||
OnParentModelChanged();
|
||||
_stickVisualizer = new();
|
||||
Config = config;
|
||||
|
||||
StickVisualizer.PollToken = StickVisualizer.PollTokenSource.Token;
|
||||
|
||||
Task.Run(() => PollKeyboard(StickVisualizer.PollToken));
|
||||
}
|
||||
|
||||
private async Task PollKeyboard(CancellationToken token)
|
||||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
if (ParentModel.IsKeyboard)
|
||||
{
|
||||
IKeyboard keyboard = (IKeyboard)ParentModel.AvaloniaKeyboardDriver.GetGamepad("0");
|
||||
var snap = keyboard.GetKeyboardStateSnapshot();
|
||||
|
||||
if (snap.IsPressed((Key)Config.LeftStickRight))
|
||||
{
|
||||
_leftBuffer.Item1 += 1;
|
||||
}
|
||||
if (snap.IsPressed((Key)Config.LeftStickLeft))
|
||||
{
|
||||
_leftBuffer.Item1 -= 1;
|
||||
}
|
||||
if (snap.IsPressed((Key)Config.LeftStickUp))
|
||||
{
|
||||
_leftBuffer.Item2 += 1;
|
||||
}
|
||||
if (snap.IsPressed((Key)Config.LeftStickDown))
|
||||
{
|
||||
_leftBuffer.Item2 -= 1;
|
||||
}
|
||||
|
||||
if (snap.IsPressed((Key)Config.RightStickRight))
|
||||
{
|
||||
_rightBuffer.Item1 += 1;
|
||||
}
|
||||
if (snap.IsPressed((Key)Config.RightStickLeft))
|
||||
{
|
||||
_rightBuffer.Item1 -= 1;
|
||||
}
|
||||
if (snap.IsPressed((Key)Config.RightStickUp))
|
||||
{
|
||||
_rightBuffer.Item2 += 1;
|
||||
}
|
||||
if (snap.IsPressed((Key)Config.RightStickDown))
|
||||
{
|
||||
_rightBuffer.Item2 -= 1;
|
||||
}
|
||||
|
||||
StickVisualizer.UiStickLeft = _leftBuffer;
|
||||
StickVisualizer.UiStickRight = _rightBuffer;
|
||||
}
|
||||
|
||||
await Task.Delay(StickVisualizer.DrawStickPollRate, token);
|
||||
}
|
||||
|
||||
StickVisualizer.PollTokenSource.Dispose();
|
||||
}
|
||||
|
||||
public void OnParentModelChanged()
|
||||
|
||||
Reference in New Issue
Block a user