ensure gamepads connect automatically to firs player without controller

This commit is contained in:
Jean-Philippe HAUTIN 2024-12-19 21:07:36 +01:00
parent 8db5a7e98b
commit 6d38a5bfc1
4 changed files with 103 additions and 5 deletions

View file

@ -426,6 +426,8 @@ namespace Ryujinx.Headless.SDL2
return;
}
_inputManager.AddUpdaterForConfiguration(_inputConfiguration);
// Setup logging level
Logger.SetEnable(LogLevel.Debug, option.LoggingEnableDebug);
Logger.SetEnable(LogLevel.Stub, !option.LoggingDisableStub);
@ -482,7 +484,7 @@ namespace Ryujinx.Headless.SDL2
}
_inputManager.Dispose();
}
}
private static void SetupProgressHandler()
{

View file

@ -1,4 +1,9 @@
using LibHac.Common;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Input.HLE
{
@ -41,6 +46,76 @@ namespace Ryujinx.Input.HLE
}
}
private void removeSDPWhenExternalPadsConnected(List<Tuple<string,string>> availableDevices) {
//remove all steam virtual gamepads
availableDevices.RemoveAll(a => a.Item2 == "Steam Virtual Gamepad");
//remove Steam Deck Controller if external controllers are connected (docked game mode)
if (availableDevices.Count > 1) {
var steamDeckPad = availableDevices.FindFirst( a => a.Item2 == "Steam Deck Controller");
if (steamDeckPad.HasValue) {
availableDevices.Remove(steamDeckPad.Value);
}
}
}
private List<Tuple<string,string>> getGamepadsDescriptions() {
var result = new List<Tuple<string,string>> ();
foreach (string id in GamepadDriver.GamepadsIds) {
result.Add(Tuple.Create(id,GamepadDriver.GetGamepad(id).Name));
}
return result;
}
private void LinkDevicesToPlayers(List<InputConfig> _inputConfig) {
var _availableDevices = getGamepadsDescriptions();
removeSDPWhenExternalPadsConnected(_availableDevices);
var _playersWithNoDevices = new List<PlayerIndex>();
//Remove all used Devices in current Config and at the same time list player with missing Devices
foreach(PlayerIndex _playerId in Enum.GetValues(typeof(PlayerIndex)))
{
var _config = _inputConfig.Find(inputConfig => inputConfig.PlayerIndex == _playerId);
if (_config != null && _config.Backend != InputBackendType.WindowKeyboard)
{
//check device id of the player is in the existing/connected devices
var _connectedDevice = _availableDevices.FindFirst(d => d.Item1 == _config.Id);
if (_connectedDevice.HasValue)
{
_availableDevices.Remove(_connectedDevice.Value);
}
else
{
_playersWithNoDevices.Add(_playerId);
}
}
}
var hasChanges = _playersWithNoDevices.Count() > 0 && _availableDevices.Count() > 0;
if (hasChanges)
{
Logger.Info?.Print(LogClass.Configuration, $"Controllers configuration changed. Updating players configuration...");
for (int i = 0; i < _playersWithNoDevices.Count; i++)
{
var _playerId = _playersWithNoDevices[i];
var _config = _inputConfig.Find(inputConfig => inputConfig.PlayerIndex == _playerId);
if (_config != null && _availableDevices.Count > 0)
{
var _device = _availableDevices.First();
var deviceId = _device.Item1;
var deviceName = _device.Item2;
_config.Id = _device.Item1;
Logger.Info?.Print(LogClass.Configuration, $"Link Player {_playerId} to Device {deviceName}");
_availableDevices.Remove(_device);
}
}
Logger.Info?.Print(LogClass.Configuration, $"Updated players configuration to sync with Controllers configuration changes.");
}
}
public void AddUpdaterForConfiguration(List<InputConfig> _inputConfig) {
GamepadDriver.OnGamepadConnected += id => LinkDevicesToPlayers(_inputConfig);
GamepadDriver.OnGamepadDisconnected += id => LinkDevicesToPlayers(_inputConfig);
}
public void Dispose()
{
GC.SuppressFinalize(this);

View file

@ -97,7 +97,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
if (IsModified)
{
_playerIdChoose = value;
return;
}
@ -367,12 +367,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private void HandleOnGamepadDisconnected(string id)
{
Dispatcher.UIThread.Post(LoadDevices);
Dispatcher.UIThread.Post(RefreshDevicesAndCurrentPlayerConfiguration);
}
private void HandleOnGamepadConnected(string id)
{
Dispatcher.UIThread.Post(LoadDevices);
Dispatcher.UIThread.Post(RefreshDevicesAndCurrentPlayerConfiguration);
}
private string GetCurrentGamepadId()
@ -441,6 +441,21 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
return str[(str.IndexOf(Hyphen) + Offset)..];
}
public void RefreshDevicesAndCurrentPlayerConfiguration()
{
LoadDevices();
//update Device for current user based on new configuration.
var config = ConfigurationState.Instance.Hid.InputConfig.Value.Find(inputConfig => inputConfig.PlayerIndex == PlayerId);
var device = Devices.FindFirst(d => d.Id==config.Id);
if (device.HasValue) {
Device=Devices.IndexOf(device);
} else {
//0 is the None Device
Device = 0;
}
}
public void LoadDevices()
{
string GetGamepadName(IGamepad gamepad, int controllerNumber)
@ -464,17 +479,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
DeviceList.Clear();
Devices.Add((DeviceType.None, Disabled, LocaleManager.Instance[LocaleKeys.ControllerSettingsDeviceDisabled]));
int controllerNumber = 0;
int controllerNumber = 1;
foreach (string id in _mainWindow.InputManager.KeyboardDriver.GamepadsIds)
{
using IGamepad gamepad = _mainWindow.InputManager.KeyboardDriver.GetGamepad(id);
if (gamepad != null)
{
controllerNumber++;
Devices.Add((DeviceType.Keyboard, id, $"{GetShortGamepadName(gamepad.Name)}"));
}
}
controllerNumber = 1;
foreach (string id in _mainWindow.InputManager.GamepadDriver.GamepadsIds)
{
using IGamepad gamepad = _mainWindow.InputManager.GamepadDriver.GetGamepad(id);
@ -482,6 +499,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (gamepad != null)
{
string name = GetUniqueGamepadName(gamepad, ref controllerNumber);
controllerNumber++;
Devices.Add((DeviceType.Controller, id, name));
}
}

View file

@ -16,6 +16,7 @@ using Ryujinx.Ava.UI.Applet;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.FileSystem;
@ -103,6 +104,8 @@ namespace Ryujinx.Ava.UI.Windows
if (Program.PreviewerDetached)
{
InputManager = new InputManager(new AvaloniaKeyboardDriver(this), new SDL2GamepadDriver());
InputManager.AddUpdaterForConfiguration(ConfigurationState.Instance.Hid.InputConfig);
_ = this.GetObservable(IsActiveProperty).Subscribe(it => ViewModel.IsActive = it);
this.ScalingChanged += OnScalingChanged;