diff --git a/src/Ryujinx.Input/HLE/NpadManager.cs b/src/Ryujinx.Input/HLE/NpadManager.cs index d5b3dec94..198989444 100644 --- a/src/Ryujinx.Input/HLE/NpadManager.cs +++ b/src/Ryujinx.Input/HLE/NpadManager.cs @@ -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; 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(); - _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 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 - { - 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 - { - Joystick = ConfigStickInputId.Left, - StickButton = ConfigGamepadInputId.LeftStick, - InvertStickX = false, - InvertStickY = false, - Rotate90CW = (controllerType == ControllerType.JoyconLeft), - }, - RightJoycon = new RightJoyconCommonConfig - { - 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 - { - 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) diff --git a/src/Ryujinx/AutoAssignController.cs b/src/Ryujinx/AutoAssignController.cs index 76d7b2b01..8e0a1a411 100644 --- a/src/Ryujinx/AutoAssignController.cs +++ b/src/Ryujinx/AutoAssignController.cs @@ -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 = null) @@ -34,32 +38,47 @@ namespace Ryujinx.Ava if (!_configurationState.Hid.EnableAutoAssign) return; List 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 newConfig = new(); - List 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 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(); } diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index c177d8bba..d00712d81 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -810,7 +810,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input { IsModified = false; - List newConfig = new(); + List 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); } diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index f7543d2bb..1d1d2731a 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -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; diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index fe8f3a554..507f6324b 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -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;