From 9b7dc6f4ee11885c52db0f40c0ebf6c3ef3b738e Mon Sep 17 00:00:00 2001 From: uncavo-hdmi Date: Sun, 2 Feb 2025 22:40:47 +0100 Subject: [PATCH] simplify RefreshControllers logic and introduce GetOrderedConfig for better controller management --- src/Ryujinx/AutoAssignController.cs | 76 ++++++++++++++++++----------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/src/Ryujinx/AutoAssignController.cs b/src/Ryujinx/AutoAssignController.cs index 8e0a1a411..df16ac75b 100644 --- a/src/Ryujinx/AutoAssignController.cs +++ b/src/Ryujinx/AutoAssignController.cs @@ -16,6 +16,8 @@ namespace Ryujinx.Ava { public class AutoAssignController { + private const int MaxControllers = 9; + private readonly InputManager _inputManager; private readonly MainWindowViewModel _viewModel; private readonly ConfigurationState _configurationState; @@ -33,46 +35,21 @@ namespace Ryujinx.Ava RefreshControllers(); } - public void RefreshControllers(List inputConfig = null) + public void RefreshControllers() { if (!_configurationState.Hid.EnableAutoAssign) return; - - List controllers = _inputManager.GamepadDriver.GetGamepads().ToList(); //if (controllers.Count == 0) return; // Get every controller config and update the configuration state - List newConfig = new(); - - Logger.Warning?.Print(LogClass.Application, $"inputConfig: {inputConfig != null}"); - if (inputConfig != null) - { - newConfig = inputConfig; - } - 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++; - } - } + List controllers = _inputManager.GamepadDriver.GetGamepads().ToList(); + List oldConfig = _configurationState.Hid.InputConfig.Value.Where(x => x != null).ToList(); + List newConfig = GetOrderedConfig(controllers, oldConfig); _viewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, _configurationState.Hid.EnableKeyboard, _configurationState.Hid.EnableMouse); - Logger.Warning?.Print(LogClass.Application, $"(AAC) NpadManager: {_viewModel.AppHost?.NpadManager.GetHashCode()}"); - _configurationState.Hid.InputConfig.Value = newConfig; - Logger.Warning?.Print(LogClass.Application, $"inputConfig: {newConfig.Count}"); - ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); } @@ -87,6 +64,47 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Application, $"Gamepad disconnected: {id}"); RefreshControllers(); } + + private List GetOrderedConfig(List controllers, List oldConfig) + { + // Dictionary to store assigned PlayerIndexes + Dictionary playerIndexMap = new(); + + // Convert oldConfig into a dictionary for quick lookup by controller Id + Dictionary oldConfigMap = oldConfig.ToDictionary(x => x.Id, x => x); + + foreach (var controller in controllers) + { + if (controller == null) continue; + + // If the controller already has a config in oldConfig, use it + if (oldConfigMap.TryGetValue(controller.Id, out InputConfig existingConfig)) + { + // Use the existing PlayerIndex from oldConfig and add it to the map + playerIndexMap[(int)existingConfig.PlayerIndex] = existingConfig; + } + else + { + // Find the first available PlayerIndex (0 to MaxControllers) + for (int i = 0; i < MaxControllers-1; i++) + { + if (!playerIndexMap.ContainsKey(i)) // Check if the PlayerIndex is available + { + // Create a new InputConfig and assign PlayerIndex + InputConfig newConfig = CreateConfigFromController(controller); + newConfig.PlayerIndex = (PlayerIndex)i; + + // Add the new config to the map with the available PlayerIndex + playerIndexMap[i] = newConfig; + break; + } + } + } + } + + // Return the sorted list of InputConfigs, ordered by PlayerIndex + return playerIndexMap.OrderBy(x => x.Key).Select(x => x.Value).ToList(); + } private InputConfig CreateConfigFromController(IGamepad controller) {