Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cc315700e4 | |||
| 24e88e2485 | |||
| 3b447b764e | |||
| 849fd0199e | |||
| 57e26114e8 | |||
| 6a283190b3 | |||
| 85547874c8 | |||
| 16ca8e5005 | |||
| cfa5ad0757 | |||
| 43ece083b2 | |||
| e1f5c501b0 | |||
| ffe366d953 | |||
| 75c7a29278 | |||
| 3a0d9c1435 | |||
| 93d1476a2a | |||
| ce13830063 | |||
| aa3f2824e0 | |||
| d2bb580aea |
@@ -1,58 +0,0 @@
|
|||||||
using Gommon;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
|
||||||
{
|
|
||||||
public class RefEvent<T>
|
|
||||||
{
|
|
||||||
public delegate void Handler(ref T arg);
|
|
||||||
|
|
||||||
private readonly Lock _subLock = new();
|
|
||||||
private readonly List<Handler> _subscriptions = [];
|
|
||||||
|
|
||||||
public bool HasSubscribers
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_subLock)
|
|
||||||
return _subscriptions.Count != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IReadOnlyList<Handler> Subscriptions
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_subLock)
|
|
||||||
return _subscriptions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(Handler subscriber)
|
|
||||||
{
|
|
||||||
Guard.Require(subscriber, nameof(subscriber));
|
|
||||||
lock (_subLock)
|
|
||||||
_subscriptions.Add(subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(Handler subscriber)
|
|
||||||
{
|
|
||||||
Guard.Require(subscriber, nameof(subscriber));
|
|
||||||
lock (_subLock)
|
|
||||||
_subscriptions.Remove(subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
lock (_subLock)
|
|
||||||
_subscriptions.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Call(ref T arg)
|
|
||||||
{
|
|
||||||
foreach (Handler subscription in Subscriptions)
|
|
||||||
subscription(ref arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Common.Helper;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -56,7 +55,7 @@ namespace Ryujinx.Common.Utilities
|
|||||||
{
|
{
|
||||||
_color = HsbToRgb((_color.GetHue() + Speed) / 360);
|
_color = HsbToRgb((_color.GetHue() + Speed) / 360);
|
||||||
|
|
||||||
_updatedHandler.Call(ref _color);
|
_updatedHandler.Call(_color.ToArgb());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,13 +67,13 @@ namespace Ryujinx.Common.Utilities
|
|||||||
_color = Color.Blue;
|
_color = Color.Blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static event RefEvent<Color>.Handler Updated
|
public static event Action<int> Updated
|
||||||
{
|
{
|
||||||
add => _updatedHandler.Add(value);
|
add => _updatedHandler.Add(value);
|
||||||
remove => _updatedHandler.Remove(value);
|
remove => _updatedHandler.Remove(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly RefEvent<Color> _updatedHandler = new();
|
private static readonly Event<int> _updatedHandler = new();
|
||||||
|
|
||||||
private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1)
|
private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ namespace Ryujinx.Input.SDL2
|
|||||||
byte blue = packedRgb > 0 ? (byte)(packedRgb % 256) : (byte)0;
|
byte blue = packedRgb > 0 ? (byte)(packedRgb % 256) : (byte)0;
|
||||||
|
|
||||||
if (SDL_GameControllerSetLED(_gamepadHandle, red, green, blue) != 0)
|
if (SDL_GameControllerSetLED(_gamepadHandle, red, green, blue) != 0)
|
||||||
Logger.Error?.Print(LogClass.Hid, "LED setting failed; probably in the middle of disconnecting.");
|
Logger.Error?.Print(LogClass.Hid, "LED is not supported on this game controller.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private GamepadFeaturesFlag GetFeaturesFlag()
|
private GamepadFeaturesFlag GetFeaturesFlag()
|
||||||
|
|||||||
@@ -112,11 +112,7 @@ namespace Ryujinx.Ava
|
|||||||
// Hook unhandled exception and process exit events.
|
// Hook unhandled exception and process exit events.
|
||||||
AppDomain.CurrentDomain.UnhandledException += (sender, e)
|
AppDomain.CurrentDomain.UnhandledException += (sender, e)
|
||||||
=> ProcessUnhandledException(sender, e.ExceptionObject as Exception, e.IsTerminating);
|
=> ProcessUnhandledException(sender, e.ExceptionObject as Exception, e.IsTerminating);
|
||||||
TaskScheduler.UnobservedTaskException += (sender, e)
|
|
||||||
=> ProcessUnhandledException(sender, e.Exception, false);
|
|
||||||
AppDomain.CurrentDomain.ProcessExit += (_, _) => Exit();
|
AppDomain.CurrentDomain.ProcessExit += (_, _) => Exit();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Setup base data directory.
|
// Setup base data directory.
|
||||||
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
|
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
|
||||||
@@ -286,7 +282,9 @@ namespace Ryujinx.Ava
|
|||||||
log.PrintMsg(LogClass.Application, message);
|
log.PrintMsg(LogClass.Application, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isTerminating)
|
if (isTerminating)
|
||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,260 @@
|
|||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
|
using Ryujinx.Input;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Models.Input
|
||||||
|
{
|
||||||
|
public class StickVisualizer : BaseModel, IDisposable
|
||||||
|
{
|
||||||
|
public const int DrawStickPollRate = 50; // Milliseconds per poll.
|
||||||
|
public const int DrawStickCircumference = 5;
|
||||||
|
public const float DrawStickScaleFactor = DrawStickCanvasCenter;
|
||||||
|
public const int DrawStickCanvasSize = 100;
|
||||||
|
public const int DrawStickBorderSize = DrawStickCanvasSize + 5;
|
||||||
|
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
|
||||||
|
public const float MaxVectorLength = DrawStickCanvasSize / 2;
|
||||||
|
|
||||||
|
public CancellationTokenSource PollTokenSource;
|
||||||
|
public CancellationToken PollToken;
|
||||||
|
|
||||||
|
private static float _vectorLength;
|
||||||
|
private static float _vectorMultiplier;
|
||||||
|
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
private DeviceType _type;
|
||||||
|
public DeviceType Type
|
||||||
|
{
|
||||||
|
get => _type;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GamepadInputConfig _gamepadConfig;
|
||||||
|
public GamepadInputConfig GamepadConfig
|
||||||
|
{
|
||||||
|
get => _gamepadConfig;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_gamepadConfig = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyboardInputConfig _keyboardConfig;
|
||||||
|
public KeyboardInputConfig KeyboardConfig
|
||||||
|
{
|
||||||
|
get => _keyboardConfig;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_keyboardConfig = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 float UiStickLeftX => ClampVector(UiStickLeft).Item1;
|
||||||
|
public float UiStickLeftY => ClampVector(UiStickLeft).Item2;
|
||||||
|
public float UiStickRightX => ClampVector(UiStickRight).Item1;
|
||||||
|
public float UiStickRightY => ClampVector(UiStickRight).Item2;
|
||||||
|
|
||||||
|
public int UiStickCircumference => DrawStickCircumference;
|
||||||
|
public int UiCanvasSize => DrawStickCanvasSize;
|
||||||
|
public int UiStickBorderSize => DrawStickBorderSize;
|
||||||
|
|
||||||
|
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
|
||||||
|
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
|
||||||
|
|
||||||
|
private InputViewModel Parent;
|
||||||
|
|
||||||
|
public StickVisualizer(InputViewModel parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
|
||||||
|
PollTokenSource = new CancellationTokenSource();
|
||||||
|
PollToken = PollTokenSource.Token;
|
||||||
|
|
||||||
|
Task.Run(Initialize, PollToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateConfig(object config)
|
||||||
|
{
|
||||||
|
if (config is ControllerInputViewModel padConfig)
|
||||||
|
{
|
||||||
|
GamepadConfig = padConfig.Config;
|
||||||
|
Type = DeviceType.Controller;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (config is KeyboardInputViewModel keyConfig)
|
||||||
|
{
|
||||||
|
KeyboardConfig = keyConfig.Config;
|
||||||
|
Type = DeviceType.Keyboard;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type = DeviceType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Initialize()
|
||||||
|
{
|
||||||
|
(float, float) leftBuffer;
|
||||||
|
(float, float) rightBuffer;
|
||||||
|
|
||||||
|
while (!PollToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
leftBuffer = (0f, 0f);
|
||||||
|
rightBuffer = (0f, 0f);
|
||||||
|
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case DeviceType.Keyboard:
|
||||||
|
IKeyboard keyboard = (IKeyboard)Parent.AvaloniaKeyboardDriver.GetGamepad("0");
|
||||||
|
|
||||||
|
if (keyboard != null)
|
||||||
|
{
|
||||||
|
KeyboardStateSnapshot snapshot = keyboard.GetKeyboardStateSnapshot();
|
||||||
|
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickRight))
|
||||||
|
{
|
||||||
|
leftBuffer.Item1 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickLeft))
|
||||||
|
{
|
||||||
|
leftBuffer.Item1 -= 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickUp))
|
||||||
|
{
|
||||||
|
leftBuffer.Item2 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickDown))
|
||||||
|
{
|
||||||
|
leftBuffer.Item2 -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickRight))
|
||||||
|
{
|
||||||
|
rightBuffer.Item1 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickLeft))
|
||||||
|
{
|
||||||
|
rightBuffer.Item1 -= 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickUp))
|
||||||
|
{
|
||||||
|
rightBuffer.Item2 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickDown))
|
||||||
|
{
|
||||||
|
rightBuffer.Item2 -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiStickLeft = leftBuffer;
|
||||||
|
UiStickRight = rightBuffer;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType.Controller:
|
||||||
|
IGamepad controller = Parent.SelectedGamepad;
|
||||||
|
|
||||||
|
if (controller != null)
|
||||||
|
{
|
||||||
|
leftBuffer = controller.GetStick((StickInputId)GamepadConfig.LeftJoystick);
|
||||||
|
rightBuffer = controller.GetStick((StickInputId)GamepadConfig.RightJoystick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType.None:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unable to poll device type \"{Type}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
UiStickLeft = leftBuffer;
|
||||||
|
UiStickRight = rightBuffer;
|
||||||
|
|
||||||
|
await Task.Delay(DrawStickPollRate, PollToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
PollTokenSource.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
PollTokenSource.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardConfig = null;
|
||||||
|
GamepadConfig = null;
|
||||||
|
Parent = null;
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,42 @@
|
|||||||
using Avalonia.Svg.Skia;
|
using Avalonia.Svg.Skia;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
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.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.UI.Views.Input;
|
using Ryujinx.UI.Views.Input;
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public partial class ControllerInputViewModel : BaseModel
|
public partial class ControllerInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
[ObservableProperty] private GamepadInputConfig _config;
|
private GamepadInputConfig _config;
|
||||||
|
public GamepadInputConfig Config
|
||||||
|
{
|
||||||
|
get => _config;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_config = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StickVisualizer _visualizer;
|
||||||
|
public StickVisualizer Visualizer
|
||||||
|
{
|
||||||
|
get => _visualizer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_visualizer = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool _isLeft;
|
private bool _isLeft;
|
||||||
public bool IsLeft
|
public bool IsLeft
|
||||||
{
|
{
|
||||||
@@ -37,14 +62,15 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool HasSides => IsLeft ^ IsRight;
|
public bool HasSides => IsLeft ^ IsRight;
|
||||||
|
|
||||||
[ObservableProperty] private SvgImage _image;
|
[ObservableProperty] private SvgImage _image;
|
||||||
|
|
||||||
public InputViewModel ParentModel { get; }
|
public InputViewModel ParentModel { get; }
|
||||||
|
|
||||||
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
|
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
|
||||||
{
|
{
|
||||||
ParentModel = model;
|
ParentModel = model;
|
||||||
|
Visualizer = visualizer;
|
||||||
model.NotifyChangesEvent += OnParentModelChanged;
|
model.NotifyChangesEvent += OnParentModelChanged;
|
||||||
OnParentModelChanged();
|
OnParentModelChanged();
|
||||||
config.PropertyChanged += (_, args) =>
|
config.PropertyChanged += (_, args) =>
|
||||||
@@ -52,7 +78,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
if (args.PropertyName is nameof(Config.UseRainbowLed))
|
if (args.PropertyName is nameof(Config.UseRainbowLed))
|
||||||
{
|
{
|
||||||
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
|
if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true })
|
||||||
Rainbow.Updated += (ref Color color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb());
|
Rainbow.Updated += color => ParentModel.SelectedGamepad.SetLed((uint)color);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Rainbow.Reset();
|
Rainbow.Reset();
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
|
using Ryujinx.Input.SDL2;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
private int _controller;
|
private int _controller;
|
||||||
private string _controllerImage;
|
private string _controllerImage;
|
||||||
private int _device;
|
private int _device;
|
||||||
[ObservableProperty] private object _configViewModel;
|
private object _configViewModel;
|
||||||
[ObservableProperty] private string _profileName;
|
[ObservableProperty] private string _profileName;
|
||||||
private bool _isLoaded;
|
private bool _isLoaded;
|
||||||
|
|
||||||
@@ -69,11 +69,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
_selectedGamepad = value;
|
_selectedGamepad = value;
|
||||||
|
|
||||||
if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
|
if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true })
|
||||||
Rainbow.Updated += (ref Color color) => _selectedGamepad.SetLed((uint)color.ToArgb());
|
Rainbow.Updated += color => _selectedGamepad.SetLed((uint)color);
|
||||||
|
|
||||||
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
|
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public StickVisualizer VisualStick { get; private set; }
|
||||||
|
|
||||||
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
|
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
|
||||||
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
|
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
|
||||||
@@ -94,6 +95,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
public event Action NotifyChangesEvent;
|
public event Action NotifyChangesEvent;
|
||||||
|
|
||||||
|
public object ConfigViewModel
|
||||||
|
{
|
||||||
|
get => _configViewModel;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_configViewModel = value;
|
||||||
|
|
||||||
|
VisualStick.UpdateConfig(value);
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PlayerIndex PlayerIdChoose
|
public PlayerIndex PlayerIdChoose
|
||||||
{
|
{
|
||||||
get => _playerIdChoose;
|
get => _playerIdChoose;
|
||||||
@@ -269,6 +283,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
Devices = [];
|
Devices = [];
|
||||||
ProfilesList = [];
|
ProfilesList = [];
|
||||||
DeviceList = [];
|
DeviceList = [];
|
||||||
|
VisualStick = new StickVisualizer(this);
|
||||||
|
|
||||||
ControllerImage = ProControllerResource;
|
ControllerImage = ProControllerResource;
|
||||||
|
|
||||||
@@ -289,12 +304,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
|
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)
|
if (Config is StandardControllerInputConfig controllerInputConfig)
|
||||||
{
|
{
|
||||||
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
|
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -893,6 +908,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
|
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
|
||||||
|
|
||||||
|
VisualStick.Dispose();
|
||||||
|
|
||||||
SelectedGamepad?.Dispose();
|
SelectedGamepad?.Dispose();
|
||||||
|
|
||||||
AvaloniaKeyboardDriver.Dispose();
|
AvaloniaKeyboardDriver.Dispose();
|
||||||
|
|||||||
@@ -6,7 +6,29 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
{
|
{
|
||||||
public partial class KeyboardInputViewModel : BaseModel
|
public partial class KeyboardInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
[ObservableProperty] private KeyboardInputConfig _config;
|
private KeyboardInputConfig _config;
|
||||||
|
public KeyboardInputConfig Config
|
||||||
|
{
|
||||||
|
get => _config;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_config = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StickVisualizer _visualizer;
|
||||||
|
public StickVisualizer Visualizer
|
||||||
|
{
|
||||||
|
get => _visualizer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_visualizer = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool _isLeft;
|
private bool _isLeft;
|
||||||
public bool IsLeft
|
public bool IsLeft
|
||||||
@@ -38,9 +60,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config)
|
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config, StickVisualizer visualizer)
|
||||||
{
|
{
|
||||||
ParentModel = model;
|
ParentModel = model;
|
||||||
|
Visualizer = visualizer;
|
||||||
model.NotifyChangesEvent += OnParentModelChanged;
|
model.NotifyChangesEvent += OnParentModelChanged;
|
||||||
OnParentModelChanged();
|
OnParentModelChanged();
|
||||||
Config = config;
|
Config = config;
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using Gommon;
|
|
||||||
using Humanizer;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
|
||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
@@ -27,19 +21,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
[ObservableProperty] private bool _enableLedChanging;
|
[ObservableProperty] private bool _enableLedChanging;
|
||||||
[ObservableProperty] private Color _ledColor;
|
[ObservableProperty] private Color _ledColor;
|
||||||
|
|
||||||
public string RainbowSpeedText => RainbowSpeed.ToString(CultureInfo.CurrentCulture);
|
|
||||||
|
|
||||||
public float RainbowSpeed
|
|
||||||
{
|
|
||||||
get => ConfigurationState.Instance.Hid.RainbowSpeed;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ConfigurationState.Instance.Hid.RainbowSpeed.Value = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
OnPropertyChanged(nameof(RainbowSpeedText));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed;
|
public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed;
|
||||||
|
|
||||||
|
|||||||
@@ -316,17 +316,103 @@
|
|||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch">
|
VerticalAlignment="Stretch">
|
||||||
<!-- Controller Picture -->
|
<!-- Controller Picture -->
|
||||||
<Image
|
|
||||||
Margin="0,10"
|
|
||||||
MaxHeight="300"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Source="{Binding Image}" />
|
|
||||||
<Border
|
<Border
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
|
Margin="0,10"
|
||||||
MinHeight="90">
|
MinHeight="90">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<Image
|
||||||
|
Margin="5,10"
|
||||||
|
MaxHeight="300"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Source="{Binding Image}" />
|
||||||
|
<StackPanel
|
||||||
|
Margin="10"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Spacing="20"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
IsVisible="{Binding IsLeft}">
|
||||||
|
<Canvas
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
|
<Grid
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
|
<Ellipse
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Stroke="Black"
|
||||||
|
StrokeThickness="1"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}" />
|
||||||
|
<Ellipse
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Fill="Gray"
|
||||||
|
Opacity="100"
|
||||||
|
Height="{Binding Visualizer.UiDeadzoneLeft}"
|
||||||
|
Width="{Binding Visualizer.UiDeadzoneLeft}" />
|
||||||
|
</Grid>
|
||||||
|
<Ellipse
|
||||||
|
Fill="Red"
|
||||||
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
|
||||||
|
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
|
||||||
|
</Canvas>
|
||||||
|
</Border>
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
IsVisible="{Binding IsRight}">
|
||||||
|
<Canvas
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
|
<Grid
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
|
<Ellipse
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Stroke="Black"
|
||||||
|
StrokeThickness="1"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}" />
|
||||||
|
<Ellipse
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Fill="Gray"
|
||||||
|
Opacity="100"
|
||||||
|
Height="{Binding Visualizer.UiDeadzoneRight}"
|
||||||
|
Width="{Binding Visualizer.UiDeadzoneRight}" />
|
||||||
|
</Grid>
|
||||||
|
<Ellipse
|
||||||
|
Fill="Red"
|
||||||
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
|
||||||
|
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
|
||||||
|
</Canvas>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5">
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="8"
|
Margin="8"
|
||||||
Orientation="Vertical">
|
Orientation="Vertical">
|
||||||
@@ -345,8 +431,8 @@
|
|||||||
Minimum="0"
|
Minimum="0"
|
||||||
Value="{Binding Config.TriggerThreshold, Mode=TwoWay}" />
|
Value="{Binding Config.TriggerThreshold, Mode=TwoWay}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Width="25"
|
Width="25"
|
||||||
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
|
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
|
|||||||
@@ -309,12 +309,79 @@
|
|||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch">
|
VerticalAlignment="Stretch">
|
||||||
<!-- Controller Picture -->
|
<!-- Controller Picture -->
|
||||||
<Image
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
Margin="0,10"
|
Margin="0,10"
|
||||||
MaxHeight="300"
|
MinHeight="90">
|
||||||
HorizontalAlignment="Stretch"
|
<StackPanel
|
||||||
VerticalAlignment="Stretch"
|
Margin="10"
|
||||||
Source="{Binding Image}" />
|
Orientation="Horizontal"
|
||||||
|
Spacing="20"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
IsVisible="{Binding IsLeft}">
|
||||||
|
<Canvas
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
|
<Grid
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
|
<Ellipse
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Stroke="Black"
|
||||||
|
StrokeThickness="1"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||||
|
</Grid>
|
||||||
|
<Ellipse
|
||||||
|
Fill="Red"
|
||||||
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
|
||||||
|
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
|
||||||
|
</Canvas>
|
||||||
|
</Border>
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
Height="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
Width="{Binding Visualizer.UiStickBorderSize}"
|
||||||
|
IsVisible="{Binding IsRight}">
|
||||||
|
<Canvas
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}">
|
||||||
|
<Grid
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Background="{DynamicResource ThemeBackgroundColor}">
|
||||||
|
<Ellipse
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Stroke="Black"
|
||||||
|
StrokeThickness="1"
|
||||||
|
Width="{Binding Visualizer.UiCanvasSize}"
|
||||||
|
Height="{Binding Visualizer.UiCanvasSize}"/>
|
||||||
|
</Grid>
|
||||||
|
<Ellipse
|
||||||
|
Fill="Red"
|
||||||
|
Width="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Height="{Binding Visualizer.UiStickCircumference}"
|
||||||
|
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
|
||||||
|
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
|
||||||
|
</Canvas>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
<Border
|
<Border
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
x:Class="Ryujinx.UI.Views.Input.LedInputView">
|
x:Class="Ryujinx.UI.Views.Input.LedInputView">
|
||||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
|
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
|
||||||
<StackPanel Orientation="Horizontal" IsVisible="{Binding ParentModel.CanClearLed}">
|
<StackPanel Orientation="Horizontal" IsVisible="{Binding ParentModel.CanClearLed}">
|
||||||
<TextBlock MinWidth="75" MaxWidth="200" Text="{ext:Locale ControllerSettingsLedColorDisable}" />
|
<TextBlock MinWidth="75" MaxWidth="150" Text="{ext:Locale ControllerSettingsLedColorDisable}" />
|
||||||
<CheckBox
|
<CheckBox
|
||||||
Margin="5"
|
Margin="5"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
@@ -20,32 +20,15 @@
|
|||||||
</CheckBox>
|
</CheckBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal" IsEnabled="{Binding !TurnOffLed}">
|
<StackPanel Orientation="Horizontal" IsEnabled="{Binding !TurnOffLed}">
|
||||||
<TextBlock MinWidth="75" MaxWidth="200" Text="{ext:Locale ControllerSettingsLedColorRainbow}" />
|
<TextBlock MinWidth="75" MaxWidth="150" Text="{ext:Locale ControllerSettingsLedColorRainbow}" />
|
||||||
<CheckBox
|
<CheckBox
|
||||||
Margin="5"
|
Margin="5"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
IsChecked="{Binding UseRainbowLed, Mode=TwoWay}">
|
IsChecked="{Binding UseRainbowLed, Mode=TwoWay}">
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Orientation="Horizontal" IsEnabled="{Binding !TurnOffLed}">
|
|
||||||
<TextBlock MinWidth="75" MaxWidth="200" Text="Rainbow Speed" />
|
|
||||||
<Slider HorizontalAlignment="Center"
|
|
||||||
Value="{Binding RainbowSpeed}"
|
|
||||||
Width="175"
|
|
||||||
Margin="0,-3,0,0"
|
|
||||||
Height="32"
|
|
||||||
Padding="0,-5"
|
|
||||||
TickFrequency="0.25"
|
|
||||||
IsSnapToTickEnabled="True"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Minimum="1"
|
|
||||||
Maximum="10" />
|
|
||||||
<TextBlock Margin="5,0"
|
|
||||||
MinWidth="75"
|
|
||||||
Text="{Binding RainbowSpeed}"/>
|
|
||||||
</StackPanel>
|
|
||||||
<StackPanel Orientation="Horizontal" IsEnabled="{Binding ShowLedColorPicker}">
|
<StackPanel Orientation="Horizontal" IsEnabled="{Binding ShowLedColorPicker}">
|
||||||
<TextBlock MinWidth="75" MaxWidth="200" Text="{ext:Locale ControllerSettingsLedColor}" />
|
<TextBlock MinWidth="75" MaxWidth="150" Text="{ext:Locale ControllerSettingsLedColor}" />
|
||||||
<ui:ColorPickerButton
|
<ui:ColorPickerButton
|
||||||
Margin="5"
|
Margin="5"
|
||||||
IsMoreButtonVisible="False"
|
IsMoreButtonVisible="False"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
xmlns:settings="clr-namespace:Ryujinx.Ava.UI.Views.Settings"
|
xmlns:settings="clr-namespace:Ryujinx.Ava.UI.Views.Settings"
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
Width="1100"
|
Width="1100"
|
||||||
Height="768"
|
Height="850"
|
||||||
MinWidth="800"
|
MinWidth="800"
|
||||||
MinHeight="480"
|
MinHeight="480"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsWindow()
|
public SettingsWindow()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Utilities.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
using Ryujinx.Ava.Utilities.Configuration.UI;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
@@ -7,6 +8,7 @@ using Ryujinx.Common.Logging;
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
{
|
{
|
||||||
@@ -15,7 +17,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 62;
|
public const int CurrentVersion = 61;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
@@ -374,15 +376,24 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public KeyboardHotkeys Hotkeys { get; set; }
|
public KeyboardHotkeys Hotkeys { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Legacy keyboard control bindings
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks>
|
||||||
|
/// TODO: Remove this when those older versions aren't in use anymore.
|
||||||
|
public List<JsonObject> KeyboardConfig { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Legacy controller control bindings
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks>
|
||||||
|
/// TODO: Remove this when those older versions aren't in use anymore.
|
||||||
|
public List<JsonObject> ControllerConfig { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Input configurations
|
/// Input configurations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<InputConfig> InputConfig { get; set; }
|
public List<InputConfig> InputConfig { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The speed of spectrum cycling for the Rainbow LED feature.
|
|
||||||
/// </summary>
|
|
||||||
public float RainbowSpeed { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Graphics backend
|
/// Graphics backend
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
Hid.EnableMouse.Value = cff.EnableMouse;
|
Hid.EnableMouse.Value = cff.EnableMouse;
|
||||||
Hid.Hotkeys.Value = cff.Hotkeys;
|
Hid.Hotkeys.Value = cff.Hotkeys;
|
||||||
Hid.InputConfig.Value = cff.InputConfig ?? [];
|
Hid.InputConfig.Value = cff.InputConfig ?? [];
|
||||||
Hid.RainbowSpeed.Value = cff.RainbowSpeed;
|
|
||||||
|
|
||||||
Multiplayer.LanInterfaceId.Value = cff.MultiplayerLanInterfaceId;
|
Multiplayer.LanInterfaceId.Value = cff.MultiplayerLanInterfaceId;
|
||||||
Multiplayer.Mode.Value = cff.MultiplayerMode;
|
Multiplayer.Mode.Value = cff.MultiplayerMode;
|
||||||
@@ -428,8 +427,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
LedColor = new Color(255, 5, 1, 253).ToUInt32()
|
LedColor = new Color(255, 5, 1, 253).ToUInt32()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
(62, static cff => cff.RainbowSpeed = 1f)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Ryujinx.Common.Configuration.Hid;
|
|||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -445,11 +444,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// TODO: Implement a ReactiveList class.
|
/// TODO: Implement a ReactiveList class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<List<InputConfig>> InputConfig { get; private set; }
|
public ReactiveObject<List<InputConfig>> InputConfig { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The speed of spectrum cycling for the Rainbow LED feature.
|
|
||||||
/// </summary>
|
|
||||||
public ReactiveObject<float> RainbowSpeed { get; }
|
|
||||||
|
|
||||||
public HidSection()
|
public HidSection()
|
||||||
{
|
{
|
||||||
@@ -457,8 +451,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
EnableMouse = new ReactiveObject<bool>();
|
EnableMouse = new ReactiveObject<bool>();
|
||||||
Hotkeys = new ReactiveObject<KeyboardHotkeys>();
|
Hotkeys = new ReactiveObject<KeyboardHotkeys>();
|
||||||
InputConfig = new ReactiveObject<List<InputConfig>>();
|
InputConfig = new ReactiveObject<List<InputConfig>>();
|
||||||
RainbowSpeed = new ReactiveObject<float>();
|
|
||||||
RainbowSpeed.Event += (_, args) => Rainbow.Speed = args.NewValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,8 +130,9 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
EnableKeyboard = Hid.EnableKeyboard,
|
EnableKeyboard = Hid.EnableKeyboard,
|
||||||
EnableMouse = Hid.EnableMouse,
|
EnableMouse = Hid.EnableMouse,
|
||||||
Hotkeys = Hid.Hotkeys,
|
Hotkeys = Hid.Hotkeys,
|
||||||
|
KeyboardConfig = [],
|
||||||
|
ControllerConfig = [],
|
||||||
InputConfig = Hid.InputConfig,
|
InputConfig = Hid.InputConfig,
|
||||||
RainbowSpeed = Hid.RainbowSpeed,
|
|
||||||
GraphicsBackend = Graphics.GraphicsBackend,
|
GraphicsBackend = Graphics.GraphicsBackend,
|
||||||
PreferredGpu = Graphics.PreferredGpu,
|
PreferredGpu = Graphics.PreferredGpu,
|
||||||
MultiplayerLanInterfaceId = Multiplayer.LanInterfaceId,
|
MultiplayerLanInterfaceId = Multiplayer.LanInterfaceId,
|
||||||
@@ -254,7 +255,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
VolumeUp = Key.Unbound,
|
VolumeUp = Key.Unbound,
|
||||||
VolumeDown = Key.Unbound,
|
VolumeDown = Key.Unbound,
|
||||||
};
|
};
|
||||||
Hid.RainbowSpeed.Value = 1f;
|
|
||||||
Hid.InputConfig.Value =
|
Hid.InputConfig.Value =
|
||||||
[
|
[
|
||||||
new StandardKeyboardInputConfig
|
new StandardKeyboardInputConfig
|
||||||
|
|||||||
Reference in New Issue
Block a user