Consolidate most logic into StickVisualizer.

This commit is contained in:
MutantAura
2024-06-03 23:10:04 +01:00
committed by Evan Husted
parent 16ca8e5005
commit 85547874c8
6 changed files with 244 additions and 248 deletions

View File

@@ -6,38 +6,11 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Input;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.ViewModels.Input
{
public partial class ControllerInputViewModel : BaseModel
{
private const int DrawStickPollRate = 50; // Milliseconds per poll.
private const int DrawStickCircumference = 5;
private const float DrawStickScaleFactor = DrawStickCanvasCenter;
private const int DrawStickCanvasSize = 100;
private const int DrawStickBorderSize = DrawStickCanvasSize + 5;
private const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
private const float MaxVectorLength = DrawStickCanvasSize / 2;
private IGamepad _selectedGamepad;
private StickVisualizer _stickVisualizer;
public StickVisualizer StickVisualizer
{
get => _stickVisualizer;
set
{
_stickVisualizer = value;
OnPropertyChanged();
}
}
private GamepadInputConfig _config;
public GamepadInputConfig Config
{
@@ -45,7 +18,18 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
set
{
_config = value;
StickVisualizer.UpdateConfig(Config);
OnPropertyChanged();
}
}
private StickVisualizer _visualizer;
public StickVisualizer Visualizer
{
get => _visualizer;
set
{
_visualizer = value;
OnPropertyChanged();
}
@@ -81,60 +65,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public InputViewModel ParentModel { get; }
private (float, float) _uiStickLeft;
public (float, float) UiStickLeft
{
get => (_uiStickLeft.Item1 * DrawStickScaleFactor, _uiStickLeft.Item2 * DrawStickScaleFactor);
set
{
_uiStickLeft = value;
OnPropertyChanged();
OnPropertyChanged(nameof(UiStickRightX));
OnPropertyChanged(nameof(UiStickRightY));
OnPropertyChanged(nameof(UiDeadzoneRight));
}
}
private (float, float) _uiStickRight;
public (float, float) UiStickRight
{
get => (_uiStickRight.Item1 * DrawStickScaleFactor, _uiStickRight.Item2 * DrawStickScaleFactor);
set
{
_uiStickRight = value;
OnPropertyChanged();
OnPropertyChanged(nameof(UiStickLeftX));
OnPropertyChanged(nameof(UiStickLeftY));
OnPropertyChanged(nameof(UiDeadzoneLeft));
}
}
public int UiStickCircumference => DrawStickCircumference;
public int UiCanvasSize => DrawStickCanvasSize;
public int UiStickBorderSize => DrawStickBorderSize;
public float UiStickLeftX => ClampVector(UiStickLeft).Item1;
public float UiStickLeftY => ClampVector(UiStickLeft).Item2;
public float UiStickRightX => ClampVector(UiStickRight).Item1;
public float UiStickRightY => ClampVector(UiStickRight).Item2;
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, StickVisualizer visualizer)
{
ParentModel = model;
Visualizer = visualizer;
model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged();
_stickVisualizer = new();
Config = config;
StickVisualizer.PollToken = StickVisualizer.PollTokenSource.Token;
Task.Run(() => PollSticks(StickVisualizer.PollToken));
}
public async void ShowMotionConfig()
@@ -157,24 +94,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32());
});
private async Task PollSticks(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
_selectedGamepad = ParentModel.SelectedGamepad;
if (_selectedGamepad != null && _selectedGamepad is not AvaloniaKeyboard)
{
StickVisualizer.UiStickLeft = _selectedGamepad.GetStick(StickInputId.Left);
StickVisualizer.UiStickRight = _selectedGamepad.GetStick(StickInputId.Right);
}
await Task.Delay(StickVisualizer.DrawStickPollRate, token);
}
StickVisualizer.PollTokenSource.Dispose();
}
public void OnParentModelChanged()
{
IsLeft = ParentModel.IsLeft;

View File

@@ -48,7 +48,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private int _controller;
private string _controllerImage;
private int _device;
[ObservableProperty] private object _configViewModel;
private object _configViewModel;
[ObservableProperty] private string _profileName;
private bool _isLoaded;
@@ -67,6 +67,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
}
}
public StickVisualizer VisualStick { get; private set; }
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
@@ -87,6 +88,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool IsModified { get; set; }
public event Action NotifyChangesEvent;
public object ConfigViewModel
{
get => _configViewModel;
set
{
_configViewModel = value;
VisualStick.UpdateConfig(value);
OnPropertyChanged();
}
}
public PlayerIndex PlayerIdChoose
{
get => _playerIdChoose;
@@ -262,6 +276,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
Devices = new ObservableCollection<(DeviceType Type, string Id, string Name)>();
ProfilesList = new AvaloniaList<string>();
DeviceList = new AvaloniaList<string>();
VisualStick = new StickVisualizer(this);
ControllerImage = ProControllerResource;
@@ -282,12 +297,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
{
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig));
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig), VisualStick);
}
if (Config is StandardControllerInputConfig controllerInputConfig)
{
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
}
}
@@ -884,10 +899,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
(ConfigViewModel as ControllerInputViewModel)?.StickVisualizer.PollTokenSource.Cancel();
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
VisualStick.Dispose();
SelectedGamepad?.Dispose();
AvaloniaKeyboardDriver.Dispose();

View File

@@ -1,28 +1,11 @@
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
{
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
{
@@ -30,7 +13,18 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
set
{
_config = value;
StickVisualizer.UpdateConfig(_config);
OnPropertyChanged();
}
}
private StickVisualizer _visualizer;
public StickVisualizer Visualizer
{
get => _visualizer;
set
{
_visualizer = value;
OnPropertyChanged();
}
@@ -66,70 +60,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public readonly InputViewModel ParentModel;
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config)
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config, StickVisualizer visualizer)
{
ParentModel = model;
Visualizer = visualizer;
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()