Display position to help set the deadzone.
This commit is contained in:
parent
536f792558
commit
de9e93606a
@ -7,6 +7,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
public class ControllerInputViewModel : BaseModel
|
public class ControllerInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private GamepadInputConfig _config;
|
private GamepadInputConfig _config;
|
||||||
|
|
||||||
public GamepadInputConfig Config
|
public GamepadInputConfig Config
|
||||||
{
|
{
|
||||||
get => _config;
|
get => _config;
|
||||||
@ -18,6 +19,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool _isLeft;
|
private bool _isLeft;
|
||||||
|
|
||||||
public bool IsLeft
|
public bool IsLeft
|
||||||
{
|
{
|
||||||
get => _isLeft;
|
get => _isLeft;
|
||||||
@ -30,6 +32,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool _isRight;
|
private bool _isRight;
|
||||||
|
|
||||||
public bool IsRight
|
public bool IsRight
|
||||||
{
|
{
|
||||||
get => _isRight;
|
get => _isRight;
|
||||||
@ -44,6 +47,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
public bool HasSides => IsLeft ^ IsRight;
|
public bool HasSides => IsLeft ^ IsRight;
|
||||||
|
|
||||||
private SvgImage _image;
|
private SvgImage _image;
|
||||||
|
|
||||||
public SvgImage Image
|
public SvgImage Image
|
||||||
{
|
{
|
||||||
get => _image;
|
get => _image;
|
||||||
@ -56,6 +60,30 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
|
private string _leftStickPosition;
|
||||||
|
|
||||||
|
public string LeftStickPosition
|
||||||
|
{
|
||||||
|
get => _leftStickPosition;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_leftStickPosition = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _rightStickPosition;
|
||||||
|
|
||||||
|
public string RightStickPosition
|
||||||
|
{
|
||||||
|
get => _rightStickPosition;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_rightStickPosition = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
||||||
{
|
{
|
||||||
ParentModel = model;
|
ParentModel = model;
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
x:DataType="viewModels:ControllerInputViewModel"
|
x:DataType="viewModels:ControllerInputViewModel"
|
||||||
x:CompileBindings="True"
|
x:CompileBindings="True"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Focusable="True">
|
Focusable="True"
|
||||||
|
Unloaded="Control_OnUnloaded"
|
||||||
|
>
|
||||||
<Design.DataContext>
|
<Design.DataContext>
|
||||||
<viewModels:ControllerInputViewModel />
|
<viewModels:ControllerInputViewModel />
|
||||||
</Design.DataContext>
|
</Design.DataContext>
|
||||||
@ -183,6 +185,9 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Text="{ext:Locale ControllerSettingsStickDeadzone}" />
|
Text="{ext:Locale ControllerSettingsStickDeadzone}" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="{Binding LeftStickPosition }" />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@ -716,6 +721,9 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Text="{ext:Locale ControllerSettingsStickDeadzone}" />
|
Text="{ext:Locale ControllerSettingsStickDeadzone}" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="{Binding RightStickPosition }" />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
@ -4,14 +4,14 @@ using Avalonia.Controls.Primitives;
|
|||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.LogicalTree;
|
using Avalonia.LogicalTree;
|
||||||
using DiscordRPC;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Input
|
namespace Ryujinx.Ava.UI.Views.Input
|
||||||
@ -19,6 +19,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||||||
public partial class ControllerInputView : UserControl
|
public partial class ControllerInputView : UserControl
|
||||||
{
|
{
|
||||||
private ButtonKeyAssigner _currentAssigner;
|
private ButtonKeyAssigner _currentAssigner;
|
||||||
|
private volatile bool _isRunning = true;
|
||||||
|
|
||||||
public ControllerInputView()
|
public ControllerInputView()
|
||||||
{
|
{
|
||||||
@ -39,6 +40,8 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StartUpdatingData();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
||||||
@ -106,7 +109,9 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||||||
|
|
||||||
var viewModel = (DataContext as ControllerInputViewModel);
|
var viewModel = (DataContext as ControllerInputViewModel);
|
||||||
|
|
||||||
IKeyboard keyboard = (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
IKeyboard keyboard =
|
||||||
|
(IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver
|
||||||
|
.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
||||||
IButtonAssigner assigner = CreateButtonAssigner(isStick);
|
IButtonAssigner assigner = CreateButtonAssigner(isStick);
|
||||||
|
|
||||||
_currentAssigner.ButtonAssigned += (sender, e) =>
|
_currentAssigner.ButtonAssigned += (sender, e) =>
|
||||||
@ -237,5 +242,81 @@ namespace Ryujinx.Ava.UI.Views.Input
|
|||||||
_currentAssigner?.Cancel();
|
_currentAssigner?.Cancel();
|
||||||
_currentAssigner = null;
|
_currentAssigner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Control_OnUnloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async void StartUpdatingData()
|
||||||
|
{
|
||||||
|
while (_isRunning)
|
||||||
|
{
|
||||||
|
var viewModel = (DataContext as ControllerInputViewModel);
|
||||||
|
if (viewModel != null)
|
||||||
|
{
|
||||||
|
IGamepad gamepad = viewModel.ParentModel.SelectedGamepad;
|
||||||
|
var config = viewModel.Config;
|
||||||
|
|
||||||
|
if (config.LeftJoystick != StickInputId.Unbound)
|
||||||
|
{
|
||||||
|
var stickInputId = (Ryujinx.Input.StickInputId)(int)config.LeftJoystick;
|
||||||
|
(float leftAxisX, float leftAxisY) =
|
||||||
|
gamepad.GetStick(stickInputId);
|
||||||
|
viewModel.LeftStickPosition =
|
||||||
|
ClampToCircle(ApplyDeadzone(leftAxisX, leftAxisY, config.DeadzoneLeft), config.RangeLeft)
|
||||||
|
.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.RightJoystick != StickInputId.Unbound)
|
||||||
|
{
|
||||||
|
var stickInputId = (Ryujinx.Input.StickInputId)(int)config.RightJoystick;
|
||||||
|
(float rightAxisX, float rightAxisY) = gamepad.GetStick(stickInputId);
|
||||||
|
viewModel.RightStickPosition =
|
||||||
|
ClampToCircle(ApplyDeadzone(rightAxisX, rightAxisY, config.DeadzoneRight),
|
||||||
|
config.RangeRight).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (int x, int y) ClampToCircle((int x, int y) postion, float range)
|
||||||
|
{
|
||||||
|
Vector2 point = new Vector2(postion.x, postion.y) * range;
|
||||||
|
|
||||||
|
if (point.Length() > short.MaxValue)
|
||||||
|
{
|
||||||
|
point = point / point.Length() * short.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((int)point.X, (int)point.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (short x, short y) ApplyDeadzone(float x, float y, float deadzone)
|
||||||
|
{
|
||||||
|
float magnitudeClamped = Math.Min(MathF.Sqrt(x * x + y * y), 1f);
|
||||||
|
|
||||||
|
if (magnitudeClamped <= deadzone)
|
||||||
|
{
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ClampAxis((x / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))),
|
||||||
|
ClampAxis((y / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static short ClampAxis(float value)
|
||||||
|
{
|
||||||
|
if (Math.Sign(value) < 0)
|
||||||
|
{
|
||||||
|
return (short)Math.Max(value * -short.MinValue, short.MinValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (short)Math.Min(value * short.MaxValue, short.MaxValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user