refactor: enhance AutoAssignController to utilize ViewModel and improve controller refresh logic
This commit is contained in:
parent
ab4bb0a885
commit
3ff9d1e128
@ -4,6 +4,7 @@ using Ryujinx.Common.Configuration.Hid.Controller.Motion;
|
||||
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
||||
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Hid;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -40,7 +41,6 @@ namespace Ryujinx.Input.HLE
|
||||
private List<InputConfig> _inputConfig;
|
||||
private bool _enableKeyboard;
|
||||
private bool _enableMouse;
|
||||
private bool _enableAutoAssign;
|
||||
private Switch _device;
|
||||
|
||||
public NpadManager(IGamepadDriver keyboardDriver, IGamepadDriver gamepadDriver, IGamepadDriver mouseDriver)
|
||||
@ -53,7 +53,7 @@ namespace Ryujinx.Input.HLE
|
||||
_mouseDriver = mouseDriver;
|
||||
_inputConfig = new List<InputConfig>();
|
||||
|
||||
_gamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
|
||||
//_gamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
|
||||
_gamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ namespace Ryujinx.Input.HLE
|
||||
}
|
||||
}
|
||||
|
||||
ReloadConfiguration(_inputConfig, _enableKeyboard, _enableMouse);
|
||||
//ReloadConfiguration(_inputConfig, _enableKeyboard, _enableMouse);
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ namespace Ryujinx.Input.HLE
|
||||
NpadController[] oldControllers = _controllers.ToArray();
|
||||
|
||||
List<InputConfig> validInputs = new();
|
||||
|
||||
|
||||
foreach (InputConfig inputConfigEntry in inputConfig)
|
||||
{
|
||||
NpadController controller;
|
||||
@ -160,129 +160,23 @@ namespace Ryujinx.Input.HLE
|
||||
validInputs.Add(inputConfigEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < oldControllers.Length; i++)
|
||||
{
|
||||
// Disconnect any controllers that weren't reused by the new configuration.
|
||||
|
||||
|
||||
oldControllers[i]?.Dispose();
|
||||
oldControllers[i] = null;
|
||||
}
|
||||
|
||||
|
||||
_inputConfig = inputConfig;
|
||||
_enableKeyboard = enableKeyboard;
|
||||
_enableMouse = enableMouse;
|
||||
|
||||
_device.Hid.RefreshInputConfig(validInputs);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private InputConfig CreateConfigFromController(IGamepad controller)
|
||||
{
|
||||
if (controller == null) return null;
|
||||
|
||||
string id = controller.Id.Split(" ")[0];
|
||||
bool isNintendoStyle = controller.Name.Contains("Nintendo");
|
||||
ControllerType controllerType;
|
||||
|
||||
if (isNintendoStyle && !controller.Name.Contains("(L/R)"))
|
||||
{
|
||||
if (controller.Name.Contains("(L)"))
|
||||
{
|
||||
controllerType = ControllerType.JoyconLeft;
|
||||
}
|
||||
else if (controller.Name.Contains("(R)"))
|
||||
{
|
||||
controllerType = ControllerType.JoyconRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
controllerType = ControllerType.ProController;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it's not a nintendo controller, we assume it's a pro controller or a joycon pair
|
||||
controllerType = ControllerType.ProController;
|
||||
}
|
||||
|
||||
InputConfig config = new StandardControllerInputConfig
|
||||
{
|
||||
Version = InputConfig.CurrentVersion,
|
||||
Backend = InputBackendType.GamepadSDL2,
|
||||
Id = id,
|
||||
ControllerType = controllerType,
|
||||
DeadzoneLeft = 0.1f,
|
||||
DeadzoneRight = 0.1f,
|
||||
RangeLeft = 1.0f,
|
||||
RangeRight = 1.0f,
|
||||
TriggerThreshold = 0.5f,
|
||||
LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
|
||||
{
|
||||
DpadUp = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.Y : ConfigGamepadInputId.DpadUp,
|
||||
DpadDown = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.A : ConfigGamepadInputId.DpadDown,
|
||||
DpadLeft = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.B : ConfigGamepadInputId.DpadLeft,
|
||||
DpadRight = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.X : ConfigGamepadInputId.DpadRight,
|
||||
ButtonMinus = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.Plus : ConfigGamepadInputId.Minus,
|
||||
ButtonL = ConfigGamepadInputId.LeftShoulder,
|
||||
ButtonZl = ConfigGamepadInputId.LeftTrigger,
|
||||
ButtonSl = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.LeftShoulder : ConfigGamepadInputId.Unbound,
|
||||
ButtonSr = (controllerType == ControllerType.JoyconLeft) ? ConfigGamepadInputId.RightShoulder : ConfigGamepadInputId.Unbound,
|
||||
},
|
||||
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||
{
|
||||
Joystick = ConfigStickInputId.Left,
|
||||
StickButton = ConfigGamepadInputId.LeftStick,
|
||||
InvertStickX = false,
|
||||
InvertStickY = false,
|
||||
Rotate90CW = (controllerType == ControllerType.JoyconLeft),
|
||||
},
|
||||
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
|
||||
{
|
||||
ButtonA = ConfigGamepadInputId.B,
|
||||
ButtonB = (controllerType == ControllerType.JoyconRight) ? ConfigGamepadInputId.Y : ConfigGamepadInputId.A,
|
||||
ButtonX = (controllerType == ControllerType.JoyconRight) ? ConfigGamepadInputId.A : ConfigGamepadInputId.Y,
|
||||
ButtonY = ConfigGamepadInputId.X,
|
||||
ButtonPlus = ConfigGamepadInputId.Plus,
|
||||
ButtonR = ConfigGamepadInputId.RightShoulder,
|
||||
ButtonZr = ConfigGamepadInputId.RightTrigger,
|
||||
ButtonSl = (controllerType == ControllerType.JoyconRight) ? ConfigGamepadInputId.LeftShoulder : ConfigGamepadInputId.Unbound,
|
||||
ButtonSr = (controllerType == ControllerType.JoyconRight) ? ConfigGamepadInputId.RightShoulder : ConfigGamepadInputId.Unbound,
|
||||
},
|
||||
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||
{
|
||||
Joystick = (controllerType == ControllerType.JoyconRight) ? ConfigStickInputId.Left : ConfigStickInputId.Right,
|
||||
StickButton = ConfigGamepadInputId.RightStick,
|
||||
InvertStickX = (controllerType == ControllerType.JoyconRight),
|
||||
InvertStickY = (controllerType == ControllerType.JoyconRight),
|
||||
Rotate90CW = (controllerType == ControllerType.JoyconRight),
|
||||
},
|
||||
Motion = new StandardMotionConfigController
|
||||
{
|
||||
MotionBackend = MotionInputBackendType.GamepadDriver,
|
||||
EnableMotion = true,
|
||||
Sensitivity = 100,
|
||||
GyroDeadzone = 1,
|
||||
},
|
||||
Rumble = new RumbleConfigController
|
||||
{
|
||||
StrongRumble = 1f,
|
||||
WeakRumble = 1f,
|
||||
EnableRumble = false,
|
||||
},
|
||||
Led = new LedConfigController
|
||||
{
|
||||
EnableLed = false,
|
||||
TurnOffLed = false,
|
||||
UseRainbow = false,
|
||||
LedColor = 0,
|
||||
},
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
public void UnblockInputUpdates()
|
||||
{
|
||||
lock (_lock)
|
||||
|
@ -17,16 +17,20 @@ namespace Ryujinx.Ava
|
||||
public class AutoAssignController
|
||||
{
|
||||
private readonly InputManager _inputManager;
|
||||
private readonly MainWindowViewModel _viewModel;
|
||||
private readonly ConfigurationState _configurationState;
|
||||
|
||||
private readonly IGamepad[] _controllers;
|
||||
|
||||
public AutoAssignController(InputManager inputManager)
|
||||
public AutoAssignController(InputManager inputManager, MainWindowViewModel mainWindowViewModel)
|
||||
{
|
||||
_configurationState = ConfigurationState.Instance;
|
||||
_inputManager = inputManager;
|
||||
_viewModel = mainWindowViewModel;
|
||||
_configurationState = ConfigurationState.Instance;
|
||||
_inputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
|
||||
_inputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
|
||||
|
||||
RefreshControllers();
|
||||
}
|
||||
|
||||
public void RefreshControllers(List<InputConfig> inputConfig = null)
|
||||
@ -34,32 +38,47 @@ namespace Ryujinx.Ava
|
||||
if (!_configurationState.Hid.EnableAutoAssign) return;
|
||||
|
||||
List<IGamepad> controllers = _inputManager.GamepadDriver.GetGamepads().ToList();
|
||||
|
||||
if (controllers.Count == 0) return;
|
||||
|
||||
MainWindow _mainWindow = RyujinxApp.MainWindow;
|
||||
//if (controllers.Count == 0) return;
|
||||
|
||||
// Get every controller config and update the configuration state
|
||||
List<InputConfig> newConfig = new();
|
||||
List<InputConfig> oldConfigs = (inputConfig != null) ? inputConfig : ConfigurationState.Instance.Hid.InputConfig.Value.Where(x => x != null).ToList();
|
||||
|
||||
Logger.Warning?.Print(LogClass.Application, $"inputConfig: {inputConfig != null}");
|
||||
|
||||
int index = 0;
|
||||
foreach (var controller in controllers)
|
||||
if (inputConfig != null)
|
||||
{
|
||||
InputConfig config = oldConfigs.FirstOrDefault(x => x.Id == controller.Id) ?? CreateConfigFromController(controller);
|
||||
config.PlayerIndex = (PlayerIndex)index;
|
||||
newConfig.Add(config);
|
||||
index++;
|
||||
newConfig = inputConfig;
|
||||
}
|
||||
|
||||
_mainWindow.ViewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
|
||||
else
|
||||
{
|
||||
if (!_configurationState.Hid.EnableAutoAssign) return;
|
||||
List<InputConfig> oldConfig = _configurationState.Hid.InputConfig.Value.Where(x => x != null).ToList();
|
||||
|
||||
int index = 0;
|
||||
foreach (var controller in controllers)
|
||||
{
|
||||
if(controller == null) continue;
|
||||
InputConfig config = oldConfig.FirstOrDefault(x => x.Id == controller.Id) ?? CreateConfigFromController(controller);
|
||||
config.PlayerIndex = (PlayerIndex)index;
|
||||
newConfig.Add(config);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
_viewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, _configurationState.Hid.EnableKeyboard, _configurationState.Hid.EnableMouse);
|
||||
|
||||
Logger.Warning?.Print(LogClass.Application, $"(AAC) NpadManager: {_viewModel.AppHost?.NpadManager.GetHashCode()}");
|
||||
|
||||
ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
|
||||
_configurationState.Hid.InputConfig.Value = newConfig;
|
||||
|
||||
Logger.Warning?.Print(LogClass.Application, $"inputConfig: {newConfig.Count}");
|
||||
|
||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||
}
|
||||
|
||||
private void HandleOnGamepadConnected(string id)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, $"Gamepad disconnected: {id}");
|
||||
Logger.Warning?.Print(LogClass.Application, $"Gamepad connected: {id}");
|
||||
RefreshControllers();
|
||||
}
|
||||
|
||||
|
@ -810,7 +810,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
IsModified = false;
|
||||
|
||||
List<InputConfig> newConfig = new();
|
||||
List<InputConfig> newConfig = [];
|
||||
|
||||
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
|
||||
|
||||
@ -851,12 +851,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
newConfig[i] = config;
|
||||
}
|
||||
}
|
||||
|
||||
//_mainWindow.ViewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
|
||||
|
||||
_mainWindow.ViewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
|
||||
|
||||
// Atomically replace and signal input change.
|
||||
// NOTE: Do not modify InputConfig.Value directly as other code depends on the on-change event.
|
||||
//ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
|
||||
_mainWindow.AutoAssignController.RefreshControllers(newConfig);
|
||||
ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
|
||||
|
||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||
}
|
||||
|
@ -620,6 +620,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.System.EnableDockedMode.Value = EnableDockedMode;
|
||||
config.Hid.EnableKeyboard.Value = EnableKeyboard;
|
||||
config.Hid.EnableMouse.Value = EnableMouse;
|
||||
bool activatingAutoAssign = EnableAutoAssign && !config.Hid.EnableAutoAssign;
|
||||
config.Hid.EnableAutoAssign.Value = EnableAutoAssign;
|
||||
|
||||
// Keyboard Hotkeys
|
||||
@ -715,7 +716,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
MainWindow.UpdateGraphicsConfig();
|
||||
RyujinxApp.MainWindow.ViewModel.VSyncModeSettingChanged();
|
||||
|
||||
SaveSettingsEvent?.Invoke();
|
||||
if(activatingAutoAssign)
|
||||
{
|
||||
RyujinxApp.MainWindow.AutoAssignController.RefreshControllers();
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveSettingsEvent?.Invoke();
|
||||
}
|
||||
|
||||
GameDirectoryChanged = false;
|
||||
AutoloadDirectoryChanged = false;
|
||||
|
@ -110,7 +110,7 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
InputManager = new InputManager(new AvaloniaKeyboardDriver(this), new SDL2GamepadDriver());
|
||||
AutoAssignController = new AutoAssignController(InputManager);
|
||||
AutoAssignController = new AutoAssignController(InputManager, ViewModel);
|
||||
|
||||
_ = this.GetObservable(IsActiveProperty).Subscribe(it => ViewModel.IsActive = it);
|
||||
this.ScalingChanged += OnScalingChanged;
|
||||
|
Loading…
x
Reference in New Issue
Block a user