From 89043976855e2578f1099d79e569359e8f3e75f1 Mon Sep 17 00:00:00 2001 From: Otozinclus <58051309+Otozinclus@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:55:53 +0100 Subject: [PATCH 01/30] Change controller LED color This changes the controller LED color. Now I need to add the option to change it in the settings --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 12bfab4bb4..2736a3a262 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -86,6 +86,11 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; + //if (SDL_GameControllerHasLED(_gamepadHandle)) + { + _setControllerLedColor("000000"); + } + // Enable motion tracking if (Features.HasFlag(GamepadFeaturesFlag.Motion)) { @@ -101,6 +106,16 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) } } + private void _setControllerLedColor(string hex) + { + ulong LEDcolor = Convert.ToUInt64(hex, 16); + byte red = (byte)((LEDcolor >> 16) % 256); + byte green = (byte)((LEDcolor >> 8) % 256); + byte blue = (byte)(LEDcolor % 256); + + SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); + } + private GamepadFeaturesFlag GetFeaturesFlag() { GamepadFeaturesFlag result = GamepadFeaturesFlag.None; From e861204078e85a36c6e59b7cc6e3cc266faf560a Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 22 Jan 2025 16:04:57 -0600 Subject: [PATCH 02/30] fix formatting & styling --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 2736a3a262..0c95d0b7c7 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -88,7 +88,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) //if (SDL_GameControllerHasLED(_gamepadHandle)) { - _setControllerLedColor("000000"); + SetLedColor("000000"); } // Enable motion tracking @@ -106,7 +106,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) } } - private void _setControllerLedColor(string hex) + public void SetLedColor(string hex) { ulong LEDcolor = Convert.ToUInt64(hex, 16); byte red = (byte)((LEDcolor >> 16) % 256); From 6c0526c59fbcab0de6ac21ec5f974d2fecf18f6b Mon Sep 17 00:00:00 2001 From: Otozinclus <58051309+Otozinclus@users.noreply.github.com> Date: Wed, 22 Jan 2025 23:18:41 +0100 Subject: [PATCH 03/30] Check if controller has a controllable LED --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 0c95d0b7c7..d3c8e8fda0 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -86,7 +86,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; - //if (SDL_GameControllerHasLED(_gamepadHandle)) + if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) { SetLedColor("000000"); } From 861531f431d0c233ab6c303f298107b60343941b Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 00:06:24 +0100 Subject: [PATCH 04/30] just testing if git is working --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index d3c8e8fda0..cd887a5f38 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -88,7 +88,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) { - SetLedColor("000000"); + SetLedColor("FFE4B5"); } // Enable motion tracking From c21aa86a7ba1a553de330d7b3681a33cd746e6cf Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 00:09:07 +0100 Subject: [PATCH 05/30] just testing if git works --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index cd887a5f38..1c634229c6 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -88,7 +88,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) { - SetLedColor("FFE4B5"); + SetLedColor("FFE3B5"); } // Enable motion tracking From eff11f52a8f0864fe9eca6a54f74c4eadcfa3973 Mon Sep 17 00:00:00 2001 From: Otozinclus <58051309+Otozinclus@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:55:53 +0100 Subject: [PATCH 06/30] Change controller LED color This changes the controller LED color. Now I need to add the option to change it in the settings --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index ed22c3661a..16d1e070fe 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -87,6 +87,11 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; + //if (SDL_GameControllerHasLED(_gamepadHandle)) + { + _setControllerLedColor("000000"); + } + // Enable motion tracking if (Features.HasFlag(GamepadFeaturesFlag.Motion)) { @@ -102,6 +107,16 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) } } + private void _setControllerLedColor(string hex) + { + ulong LEDcolor = Convert.ToUInt64(hex, 16); + byte red = (byte)((LEDcolor >> 16) % 256); + byte green = (byte)((LEDcolor >> 8) % 256); + byte blue = (byte)(LEDcolor % 256); + + SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); + } + private GamepadFeaturesFlag GetFeaturesFlag() { GamepadFeaturesFlag result = GamepadFeaturesFlag.None; From f4c3a2e4873e7c44234be418fd2b745edee1e8e1 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 22 Jan 2025 16:04:57 -0600 Subject: [PATCH 07/30] fix formatting & styling --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 16d1e070fe..45f6265437 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -89,7 +89,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) //if (SDL_GameControllerHasLED(_gamepadHandle)) { - _setControllerLedColor("000000"); + SetLedColor("000000"); } // Enable motion tracking @@ -107,7 +107,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) } } - private void _setControllerLedColor(string hex) + public void SetLedColor(string hex) { ulong LEDcolor = Convert.ToUInt64(hex, 16); byte red = (byte)((LEDcolor >> 16) % 256); From 488b09f97452d1acd9bb95bb65b549760037c0fc Mon Sep 17 00:00:00 2001 From: Otozinclus <58051309+Otozinclus@users.noreply.github.com> Date: Wed, 22 Jan 2025 23:18:41 +0100 Subject: [PATCH 08/30] Check if controller has a controllable LED --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 45f6265437..a5b427f594 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -87,7 +87,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; - //if (SDL_GameControllerHasLED(_gamepadHandle)) + if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) { SetLedColor("000000"); } From bdaaddb591219fe6dc622a6a0992e0ab40672742 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 00:06:24 +0100 Subject: [PATCH 09/30] just testing if git is working --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index a5b427f594..427c859c12 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -89,7 +89,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) { - SetLedColor("000000"); + SetLedColor("FFE4B5"); } // Enable motion tracking From e9455652597e7974ed736c052e27ed2542a52b38 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 00:09:07 +0100 Subject: [PATCH 10/30] just testing if git works --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 427c859c12..3e712a3899 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -89,7 +89,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) { - SetLedColor("FFE4B5"); + SetLedColor("FFE3B5"); } // Enable motion tracking From 2c4236f7332b0469c34704136c111457e4a28106 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 03:39:33 +0100 Subject: [PATCH 11/30] test --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 3e712a3899..039567228a 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -87,9 +87,9 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; - if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE) + if (Features.HasFlag(GamepadFeaturesFlag.Led)) { - SetLedColor("FFE3B5"); + SetLedColor(); } // Enable motion tracking @@ -107,12 +107,13 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) } } - public void SetLedColor(string hex) + public void SetLedColor() { - ulong LEDcolor = Convert.ToUInt64(hex, 16); - byte red = (byte)((LEDcolor >> 16) % 256); - byte green = (byte)((LEDcolor >> 8) % 256); - byte blue = (byte)(LEDcolor % 256); + //IAMTOOTIREDWILLCONTINUETOMORROWSORRY + uint rawColor = 100; + byte red = (byte)(rawColor >> 16); + byte green = (byte)(rawColor >> 8); + byte blue = (byte)(rawColor % 256); SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); } From 740e35872db4abc398640272041e1827a6a24000 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 03:40:45 +0100 Subject: [PATCH 12/30] test --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 039567228a..7cd3d4b4b9 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -110,7 +110,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLedColor() { //IAMTOOTIREDWILLCONTINUETOMORROWSORRY - uint rawColor = 100; + uint rawColor = 111; byte red = (byte)(rawColor >> 16); byte green = (byte)(rawColor >> 8); byte blue = (byte)(rawColor % 256); From 9aa834c268d67075cb41479441dbccc38e58a542 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 05:02:11 +0100 Subject: [PATCH 13/30] maybe this works --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index e9f23d80ad..82004729f2 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -1,6 +1,7 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Hid; using SDL2; using System; using System.Collections.Generic; @@ -87,7 +88,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; - if (Features.HasFlag(GamepadFeaturesFlag.Led)) + //if (Features.HasFlag(GamepadFeaturesFlag.Led)) { SetLedColor(); } @@ -110,7 +111,8 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLedColor() { //IAMTOOTIREDWILLCONTINUETOMORROWSORRY - uint rawColor = 110; + //uint rawColor = 0; + uint rawColor = _configuration.Led.LedColor; byte red = (byte)(rawColor >> 16); byte green = (byte)(rawColor >> 8); byte blue = (byte)(rawColor % 256); From 96e9e3611d9ef25dc6cad2f4202163ec69b36b87 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 23 Jan 2025 05:29:18 +0100 Subject: [PATCH 14/30] move logic around --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 82004729f2..641ccebe98 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -78,6 +78,8 @@ private readonly record struct ButtonMappingEntry(GamepadButtonInputId To, Gamep private float _triggerThreshold; + private uint _rawColor; + public SDL2Gamepad(nint gamepadHandle, string driverId) { _gamepadHandle = gamepadHandle; @@ -110,12 +112,11 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLedColor() { - //IAMTOOTIREDWILLCONTINUETOMORROWSORRY //uint rawColor = 0; - uint rawColor = _configuration.Led.LedColor; - byte red = (byte)(rawColor >> 16); - byte green = (byte)(rawColor >> 8); - byte blue = (byte)(rawColor % 256); + //_rawColor = _configuration.Led.LedColor; + byte red = (byte)(_rawColor >> 16); + byte green = (byte)(_rawColor >> 8); + byte blue = (byte)(_rawColor % 256); SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); } @@ -238,6 +239,9 @@ public void SetConfiguration(InputConfig configuration) { _configuration = (StandardControllerInputConfig)configuration; + _rawColor = _configuration.Led.LedColor; + SetLedColor(); + _buttonsUserMapping.Clear(); // First update sticks From 898153ae13770c0513cf1c4273389673c5481113 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 22 Jan 2025 22:35:09 -0600 Subject: [PATCH 15/30] Update SDL2Gamepad.cs --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 641ccebe98..8f208481b8 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -78,8 +78,6 @@ private readonly record struct ButtonMappingEntry(GamepadButtonInputId To, Gamep private float _triggerThreshold; - private uint _rawColor; - public SDL2Gamepad(nint gamepadHandle, string driverId) { _gamepadHandle = gamepadHandle; @@ -89,11 +87,6 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) Id = driverId; Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; - - //if (Features.HasFlag(GamepadFeaturesFlag.Led)) - { - SetLedColor(); - } // Enable motion tracking if (Features.HasFlag(GamepadFeaturesFlag.Motion)) @@ -112,8 +105,9 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLedColor() { - //uint rawColor = 0; - //_rawColor = _configuration.Led.LedColor; + if (!HasConfiguration) return; + + uint _rawColor = _configuration.Led.LedColor; byte red = (byte)(_rawColor >> 16); byte green = (byte)(_rawColor >> 8); byte blue = (byte)(_rawColor % 256); @@ -239,8 +233,8 @@ public void SetConfiguration(InputConfig configuration) { _configuration = (StandardControllerInputConfig)configuration; - _rawColor = _configuration.Led.LedColor; - SetLedColor(); + if (Features.HasFlag(GamepadFeaturesFlag.Led)) + SetLedColor(); _buttonsUserMapping.Clear(); From 5276991517a5ab3863db7285488ee92afc369414 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 22 Jan 2025 22:37:03 -0600 Subject: [PATCH 16/30] Update SDL2Gamepad.cs --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 8f208481b8..48636b99bb 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -106,6 +106,7 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLedColor() { if (!HasConfiguration) return; + if (!_configuration.Led.EnableLed) return; uint _rawColor = _configuration.Led.LedColor; byte red = (byte)(_rawColor >> 16); From 5712e83a11037b30be26eec1cfd66c1b6aada028 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 17:22:25 -0600 Subject: [PATCH 17/30] UI: enable LED changing --- src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 3d1bd5f4a8..720a43614c 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -69,8 +69,7 @@ public partial class InputViewModel : BaseModel, IDisposable public bool IsRight { get; set; } public bool IsLeft { get; set; } - public bool HasLed => false; //temporary - //SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led); + public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led); public bool IsModified { get; set; } public event Action NotifyChangesEvent; From cfe42563f298ea3e577fa652c2aa9f541f201a5b Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 18:33:52 -0600 Subject: [PATCH 18/30] Add the LED functionality to the base IGamepad interface --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 14 +++++++------- src/Ryujinx.Input.SDL2/SDL2Keyboard.cs | 2 ++ src/Ryujinx.Input.SDL2/SDL2Mouse.cs | 2 ++ src/Ryujinx.Input/IGamepad.cs | 7 +++++++ src/Ryujinx/Input/AvaloniaKeyboard.cs | 2 ++ src/Ryujinx/Input/AvaloniaMouse.cs | 2 ++ 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 48636b99bb..9037f7ef7a 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -103,16 +103,16 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) } } - public void SetLedColor() + public void SetLed(uint packedRgb) { + if (!Features.HasFlag(GamepadFeaturesFlag.Led)) return; if (!HasConfiguration) return; if (!_configuration.Led.EnableLed) return; - uint _rawColor = _configuration.Led.LedColor; - byte red = (byte)(_rawColor >> 16); - byte green = (byte)(_rawColor >> 8); - byte blue = (byte)(_rawColor % 256); - + byte red = (byte)(packedRgb >> 16); + byte green = (byte)(packedRgb >> 8); + byte blue = (byte)(packedRgb % 256); + SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); } @@ -235,7 +235,7 @@ public void SetConfiguration(InputConfig configuration) _configuration = (StandardControllerInputConfig)configuration; if (Features.HasFlag(GamepadFeaturesFlag.Led)) - SetLedColor(); + SetLed(_configuration.Led.LedColor); _buttonsUserMapping.Clear(); diff --git a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs index 8d6a30d11a..4a418230bb 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs @@ -384,6 +384,8 @@ public void SetConfiguration(InputConfig configuration) _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger1, (Key)_configuration.RightJoycon.ButtonSl)); } } + + public void SetLed(uint packedRgb) {} public void SetTriggerThreshold(float triggerThreshold) { diff --git a/src/Ryujinx.Input.SDL2/SDL2Mouse.cs b/src/Ryujinx.Input.SDL2/SDL2Mouse.cs index 37b356b765..57997726f3 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Mouse.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Mouse.cs @@ -75,6 +75,8 @@ public void SetConfiguration(InputConfig configuration) { throw new NotImplementedException(); } + + public void SetLed(uint packedRgb) {} public void SetTriggerThreshold(float triggerThreshold) { diff --git a/src/Ryujinx.Input/IGamepad.cs b/src/Ryujinx.Input/IGamepad.cs index 3853f28196..6781c0faa6 100644 --- a/src/Ryujinx.Input/IGamepad.cs +++ b/src/Ryujinx.Input/IGamepad.cs @@ -65,6 +65,13 @@ public interface IGamepad : IDisposable /// The configuration of the gamepad void SetConfiguration(InputConfig configuration); + /// + /// Set the LED on the gamepad to a given color. + /// + /// Does nothing on a controller without LED functionality. + /// The packed RGB integer. + void SetLed(uint packedRgb); + /// /// Starts a rumble effect on the gamepad. /// diff --git a/src/Ryujinx/Input/AvaloniaKeyboard.cs b/src/Ryujinx/Input/AvaloniaKeyboard.cs index 0b63af2d9b..0b79c76cee 100644 --- a/src/Ryujinx/Input/AvaloniaKeyboard.cs +++ b/src/Ryujinx/Input/AvaloniaKeyboard.cs @@ -142,6 +142,8 @@ public void SetConfiguration(InputConfig configuration) #pragma warning restore IDE0055 } } + + public void SetLed(uint packedRgb) { } public void SetTriggerThreshold(float triggerThreshold) { } diff --git a/src/Ryujinx/Input/AvaloniaMouse.cs b/src/Ryujinx/Input/AvaloniaMouse.cs index 1aa2d586a3..6cc7d14bb2 100644 --- a/src/Ryujinx/Input/AvaloniaMouse.cs +++ b/src/Ryujinx/Input/AvaloniaMouse.cs @@ -73,6 +73,8 @@ public void SetConfiguration(InputConfig configuration) { throw new NotImplementedException(); } + + public void SetLed(uint packedRgb) { } public void SetTriggerThreshold(float triggerThreshold) { From 72d5af8b46ad3a603aec22753504a0d5b1880d48 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 19:02:35 -0600 Subject: [PATCH 19/30] Update LED as its changed in the UI --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 4 +--- src/Ryujinx.Input.SDL2/SDL2Keyboard.cs | 8 ++++++-- src/Ryujinx.Input.SDL2/SDL2Mouse.cs | 8 ++++++-- src/Ryujinx/Input/AvaloniaKeyboard.cs | 8 ++++++-- src/Ryujinx/Input/AvaloniaMouse.cs | 8 ++++++-- .../Input/ControllerInputViewModel.cs | 1 + .../UI/Views/Input/ControllerInputView.axaml | 4 +++- .../Views/Input/ControllerInputView.axaml.cs | 18 ++++++++++++++++++ 8 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 9037f7ef7a..4f2160cf2a 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -106,8 +106,6 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLed(uint packedRgb) { if (!Features.HasFlag(GamepadFeaturesFlag.Led)) return; - if (!HasConfiguration) return; - if (!_configuration.Led.EnableLed) return; byte red = (byte)(packedRgb >> 16); byte green = (byte)(packedRgb >> 8); @@ -234,7 +232,7 @@ public void SetConfiguration(InputConfig configuration) { _configuration = (StandardControllerInputConfig)configuration; - if (Features.HasFlag(GamepadFeaturesFlag.Led)) + if (Features.HasFlag(GamepadFeaturesFlag.Led) && _configuration.Led.EnableLed) SetLed(_configuration.Led.LedColor); _buttonsUserMapping.Clear(); diff --git a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs index 4a418230bb..270af51143 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; +using Ryujinx.Common.Logging; using System; using System.Collections.Generic; using System.Numerics; @@ -384,8 +385,11 @@ public void SetConfiguration(InputConfig configuration) _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger1, (Key)_configuration.RightJoycon.ButtonSl)); } } - - public void SetLed(uint packedRgb) {} + + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an SDL2Keyboard"); + } public void SetTriggerThreshold(float triggerThreshold) { diff --git a/src/Ryujinx.Input.SDL2/SDL2Mouse.cs b/src/Ryujinx.Input.SDL2/SDL2Mouse.cs index 57997726f3..eb86fa7998 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Mouse.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Mouse.cs @@ -1,4 +1,5 @@ using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Logging; using System; using System.Drawing; using System.Numerics; @@ -75,8 +76,11 @@ public void SetConfiguration(InputConfig configuration) { throw new NotImplementedException(); } - - public void SetLed(uint packedRgb) {} + + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an SDL2Mouse"); + } public void SetTriggerThreshold(float triggerThreshold) { diff --git a/src/Ryujinx/Input/AvaloniaKeyboard.cs b/src/Ryujinx/Input/AvaloniaKeyboard.cs index 0b79c76cee..031d8b033e 100644 --- a/src/Ryujinx/Input/AvaloniaKeyboard.cs +++ b/src/Ryujinx/Input/AvaloniaKeyboard.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; +using Ryujinx.Common.Logging; using Ryujinx.Input; using System; using System.Collections.Generic; @@ -142,8 +143,11 @@ public void SetConfiguration(InputConfig configuration) #pragma warning restore IDE0055 } } - - public void SetLed(uint packedRgb) { } + + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an AvaloniaKeyboard"); + } public void SetTriggerThreshold(float triggerThreshold) { } diff --git a/src/Ryujinx/Input/AvaloniaMouse.cs b/src/Ryujinx/Input/AvaloniaMouse.cs index 6cc7d14bb2..52a341a016 100644 --- a/src/Ryujinx/Input/AvaloniaMouse.cs +++ b/src/Ryujinx/Input/AvaloniaMouse.cs @@ -1,4 +1,5 @@ using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Logging; using Ryujinx.Input; using System; using System.Drawing; @@ -73,8 +74,11 @@ public void SetConfiguration(InputConfig configuration) { throw new NotImplementedException(); } - - public void SetLed(uint packedRgb) { } + + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an AvaloniaMouse"); + } public void SetTriggerThreshold(float triggerThreshold) { diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 0380ef5987..107b543cae 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -1,5 +1,6 @@ using Avalonia.Svg.Skia; using CommunityToolkit.Mvvm.ComponentModel; +using FluentAvalonia.UI.Controls; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Views.Input; diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml index db7040f4bc..3592df7cdf 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml @@ -429,7 +429,7 @@ - + diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index 52a6d51b9d..4e469da81b 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -4,6 +4,7 @@ using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.LogicalTree; +using FluentAvalonia.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Common.Configuration.Hid.Controller; @@ -234,5 +235,22 @@ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e _currentAssigner?.Cancel(); _currentAssigner = null; } + + private void ColorPickerButton_OnColorChanged(ColorPickerButton sender, ColorButtonColorChangedEventArgs args) + { + if (!args.NewColor.HasValue) return; + if (DataContext is not ControllerInputViewModel cVm) return; + if (!cVm.Config.EnableLedChanging) return; + + cVm.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32()); + } + + private void ColorPickerButton_OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e) + { + if (DataContext is not ControllerInputViewModel cVm) return; + if (!cVm.Config.EnableLedChanging) return; + + cVm.ParentModel.SelectedGamepad.SetLed(cVm.Config.LedColor.ToUInt32()); + } } } From bf869b0ee195faf1e762dd329ebfeb8a4c404ac3 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 19:18:29 -0600 Subject: [PATCH 20/30] Properly save default --- .../Utilities/Configuration/ConfigurationState.Migration.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs index 1b00a8fa40..025f6bdb8c 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs @@ -1,3 +1,4 @@ +using Avalonia.Media; using Gommon; using Ryujinx.Ava.Utilities.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.UI; @@ -421,7 +422,7 @@ in _migrations.OrderBy(x => x.Key)) config.Led = new LedConfigController { EnableLed = false, - LedColor = 328189 + LedColor = new Color(255, 5, 1, 253).ToUInt32() }; } }) From 033f3058723dc53180a8e09c6ee4b2293f50c661 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 19:18:29 -0600 Subject: [PATCH 21/30] log line to match other optional gamepad features --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 4f2160cf2a..0f66021815 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -111,7 +111,8 @@ public void SetLed(uint packedRgb) byte green = (byte)(packedRgb >> 8); byte blue = (byte)(packedRgb % 256); - SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); + if (SDL_GameControllerSetLED(_gamepadHandle, red, green, blue) != 0) + Logger.Error?.Print(LogClass.Hid, "LED is not supported on this game controller."); } private GamepadFeaturesFlag GetFeaturesFlag() From b442d32b7c672b3fdc07bc81139fef8c6c60119f Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 19:30:11 -0600 Subject: [PATCH 22/30] directly compare result of rumble instead of storing an error int --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 0f66021815..51f739c362 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -125,9 +125,7 @@ private GamepadFeaturesFlag GetFeaturesFlag() result |= GamepadFeaturesFlag.Motion; } - int error = SDL_GameControllerRumble(_gamepadHandle, 0, 0, 100); - - if (error == 0) + if (SDL_GameControllerRumble(_gamepadHandle, 0, 0, 100) == 0) { result |= GamepadFeaturesFlag.Rumble; } From 6619453aed022f1cad178adcbb28be8a70bd73fc Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 19:32:36 -0600 Subject: [PATCH 23/30] Check if controller supports Rumble rather than trying to rumble for 100ms --- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index 51f739c362..ba11fab873 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -125,7 +125,7 @@ private GamepadFeaturesFlag GetFeaturesFlag() result |= GamepadFeaturesFlag.Motion; } - if (SDL_GameControllerRumble(_gamepadHandle, 0, 0, 100) == 0) + if (SDL_GameControllerHasRumble(_gamepadHandle) == SDL_bool.SDL_TRUE) { result |= GamepadFeaturesFlag.Rumble; } From 5f027651305fcce8a4aae1f6305d83df8592c427 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 20:29:59 -0600 Subject: [PATCH 24/30] Allow the ability to turn off the LED entirely Only works for DualSense; in my testing, my DualShock 4 ignored the requests to set the LED to off. --- .../Hid/Controller/LedConfigController.cs | 15 +++++++---- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 15 +++++++---- src/Ryujinx.Input/IGamepad.cs | 2 ++ src/Ryujinx/Assets/locales.json | 25 +++++++++++++++++++ .../UI/Models/Input/GamepadInputConfig.cs | 14 +++++++++++ .../Input/ControllerInputViewModel.cs | 12 +++++++++ .../UI/ViewModels/Input/InputViewModel.cs | 15 ++++++++++- .../UI/Views/Input/ControllerInputView.axaml | 13 +++++++++- .../Views/Input/ControllerInputView.axaml.cs | 12 +++++---- .../ConfigurationState.Migration.cs | 1 + 10 files changed, 107 insertions(+), 17 deletions(-) diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs index 21727d62ea..8ed68cd077 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs @@ -2,14 +2,19 @@ { public class LedConfigController { - /// - /// Packed RGB int of the color - /// - public uint LedColor { get; set; } - /// /// Enable LED color changing by the emulator /// public bool EnableLed { get; set; } + + /// + /// Ignores the color and disables the LED entirely. + /// + public bool TurnOffLed { get; set; } + + /// + /// Packed RGB int of the color + /// + public uint LedColor { get; set; } } } diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index ba11fab873..f64e1c4796 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -106,11 +106,11 @@ public SDL2Gamepad(nint gamepadHandle, string driverId) public void SetLed(uint packedRgb) { if (!Features.HasFlag(GamepadFeaturesFlag.Led)) return; - - byte red = (byte)(packedRgb >> 16); - byte green = (byte)(packedRgb >> 8); - byte blue = (byte)(packedRgb % 256); + byte red = packedRgb > 0 ? (byte)(packedRgb >> 16) : (byte)0; + byte green = packedRgb > 0 ? (byte)(packedRgb >> 8) : (byte)0; + byte blue = packedRgb > 0 ? (byte)(packedRgb % 256) : (byte)0; + if (SDL_GameControllerSetLED(_gamepadHandle, red, green, blue) != 0) Logger.Error?.Print(LogClass.Hid, "LED is not supported on this game controller."); } @@ -232,7 +232,12 @@ public void SetConfiguration(InputConfig configuration) _configuration = (StandardControllerInputConfig)configuration; if (Features.HasFlag(GamepadFeaturesFlag.Led) && _configuration.Led.EnableLed) - SetLed(_configuration.Led.LedColor); + { + if (_configuration.Led.TurnOffLed) + (this as IGamepad).ClearLed(); + else + SetLed(_configuration.Led.LedColor); + } _buttonsUserMapping.Clear(); diff --git a/src/Ryujinx.Input/IGamepad.cs b/src/Ryujinx.Input/IGamepad.cs index 6781c0faa6..8329506600 100644 --- a/src/Ryujinx.Input/IGamepad.cs +++ b/src/Ryujinx.Input/IGamepad.cs @@ -72,6 +72,8 @@ public interface IGamepad : IDisposable /// The packed RGB integer. void SetLed(uint packedRgb); + public void ClearLed() => SetLed(0); + /// /// Starts a rumble effect on the gamepad. /// diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 8ceef5f673..d4a52c003a 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -7647,6 +7647,31 @@ "zh_TW": "" } }, + { + "ID": "ControllerSettingsLedColorDisable", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Disable", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "ControllerSettingsSave", "Translations": { diff --git a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs index ea7dd34c3e..ae36768538 100644 --- a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs +++ b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs @@ -400,6 +400,18 @@ public bool EnableLedChanging } } + private bool _turnOffLed; + + public bool TurnOffLed + { + get => _turnOffLed; + set + { + _turnOffLed = value; + OnPropertyChanged(); + } + } + private Color _ledColor; public Color LedColor @@ -512,6 +524,7 @@ public GamepadInputConfig(InputConfig config) if (controllerInput.Led != null) { EnableLedChanging = controllerInput.Led.EnableLed; + TurnOffLed = controllerInput.Led.TurnOffLed; uint rawColor = controllerInput.Led.LedColor; byte alpha = (byte)(rawColor >> 24); byte red = (byte)(rawColor >> 16); @@ -579,6 +592,7 @@ public InputConfig GetConfig() Led = new LedConfigController { EnableLed = EnableLedChanging, + TurnOffLed = this.TurnOffLed, LedColor = LedColor.ToUInt32() }, Version = InputConfig.CurrentVersion, diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 107b543cae..d291f09a0d 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -1,6 +1,8 @@ using Avalonia.Svg.Skia; using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using FluentAvalonia.UI.Controls; +using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Views.Input; @@ -58,6 +60,16 @@ public async void ShowRumbleConfig() await RumbleInputView.Show(this); } + public RelayCommand LedDisabledChanged => Commands.Create(() => + { + if (!Config.EnableLedChanging) return; + + if (Config.TurnOffLed) + ParentModel.SelectedGamepad.ClearLed(); + else + ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32()); + }); + public void OnParentModelChanged() { IsLeft = ParentModel.IsLeft; diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 720a43614c..c59ec540c6 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -3,6 +3,7 @@ using Avalonia.Svg.Skia; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; +using Gommon; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Input; using Ryujinx.Ava.UI.Helpers; @@ -54,7 +55,18 @@ public partial class InputViewModel : BaseModel, IDisposable private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); public IGamepadDriver AvaloniaKeyboardDriver { get; } - public IGamepad SelectedGamepad { get; private set; } + + private IGamepad _selectedGamepad; + + public IGamepad SelectedGamepad + { + get => _selectedGamepad; + private set + { + _selectedGamepad = value; + OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); + } + } public ObservableCollection PlayerIndexes { get; set; } public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; } @@ -70,6 +82,7 @@ public partial class InputViewModel : BaseModel, IDisposable public bool IsLeft { get; set; } public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led); + public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense"); public bool IsModified { get; set; } public event Action NotifyChangesEvent; diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml index 3592df7cdf..6b8673a9f3 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml @@ -495,6 +495,7 @@ Margin="0,-1,0,0"> + @@ -505,8 +506,18 @@ IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}"> - + + + @@ -235,13 +237,13 @@ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e _currentAssigner?.Cancel(); _currentAssigner = null; } - + private void ColorPickerButton_OnColorChanged(ColorPickerButton sender, ColorButtonColorChangedEventArgs args) { if (!args.NewColor.HasValue) return; if (DataContext is not ControllerInputViewModel cVm) return; if (!cVm.Config.EnableLedChanging) return; - + cVm.ParentModel.SelectedGamepad.SetLed(args.NewColor.Value.ToUInt32()); } @@ -249,7 +251,7 @@ private void ColorPickerButton_OnAttachedToVisualTree(object sender, VisualTreeA { if (DataContext is not ControllerInputViewModel cVm) return; if (!cVm.Config.EnableLedChanging) return; - + cVm.ParentModel.SelectedGamepad.SetLed(cVm.Config.LedColor.ToUInt32()); } } diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs index 025f6bdb8c..78e3dfc0f5 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs @@ -422,6 +422,7 @@ in _migrations.OrderBy(x => x.Key)) config.Led = new LedConfigController { EnableLed = false, + TurnOffLed = false, LedColor = new Color(255, 5, 1, 253).ToUInt32() }; } From a6dfbe9ec238eef48dcff421979ff2386d373665 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 21:39:19 -0600 Subject: [PATCH 25/30] Clear the LED on all controllers when settings window is closed and when input view is removed from the visual tree. --- .../UI/Views/Input/ControllerInputView.axaml.cs | 13 +++++++++++++ src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index ec0ea59e5d..a7c2c2d3cf 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -6,10 +6,12 @@ using Avalonia.LogicalTree; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Input; using Ryujinx.Input.Assigner; +using System.Linq; using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; namespace Ryujinx.Ava.UI.Views.Input @@ -234,6 +236,17 @@ private IButtonAssigner CreateButtonAssigner(bool forStick) protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); + + if (DataContext is ControllerInputViewModel vm) + { + foreach ((_, string id, _) in vm.ParentModel.Devices.Where(x => x.Type == DeviceType.Controller)) + { + IGamepad gamepad = RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepad(id); + + gamepad?.ClearLed(); + } + } + _currentAssigner?.Cancel(); _currentAssigner = null; } diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs index db8e0f6bb0..ab8f468fdc 100644 --- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs @@ -4,9 +4,14 @@ using FluentAvalonia.Core; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.HLE.FileSystem; +using Ryujinx.Input; using System; +using System.Linq; +using Key = Avalonia.Input.Key; namespace Ryujinx.Ava.UI.Windows { @@ -106,6 +111,17 @@ private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionCh protected override void OnClosing(WindowClosingEventArgs e) { HotkeysPage.Dispose(); + + if (InputPage.InputView.DataContext is InputViewModel vm) + { + foreach ((_, string id, _) in vm.Devices.Where(x => x.Type == DeviceType.Controller)) + { + IGamepad gamepad = RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepad(id); + + gamepad?.ClearLed(); + } + } + InputPage.Dispose(); base.OnClosing(e); } From 344c1a5fef97cb43ea1ac11d78e646d3274c2f00 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 21:59:54 -0600 Subject: [PATCH 26/30] Clear LED on game close as well --- src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs | 11 +++++++++++ src/Ryujinx.Input.SDL2/SDL2MouseDriver.cs | 3 +++ src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs | 9 +++++++++ src/Ryujinx.Input/IGamepadDriver.cs | 6 ++++++ src/Ryujinx/AppHost.cs | 5 +++++ src/Ryujinx/Input/AvaloniaKeyboardDriver.cs | 2 ++ src/Ryujinx/Input/AvaloniaMouseDriver.cs | 3 +++ .../UI/Views/Input/ControllerInputView.axaml.cs | 9 ++------- src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs | 9 ++------- 9 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs index c580e4e7d6..251f53cba3 100644 --- a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs +++ b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs @@ -173,5 +173,16 @@ public IGamepad GetGamepad(string id) return new SDL2Gamepad(gamepadHandle, id); } + + public IEnumerable GetGamepads() + { + lock (_gamepadsIds) + { + foreach (string gamepadId in _gamepadsIds) + { + yield return GetGamepad(gamepadId); + } + } + } } } diff --git a/src/Ryujinx.Input.SDL2/SDL2MouseDriver.cs b/src/Ryujinx.Input.SDL2/SDL2MouseDriver.cs index 768ea8c629..7a96799018 100644 --- a/src/Ryujinx.Input.SDL2/SDL2MouseDriver.cs +++ b/src/Ryujinx.Input.SDL2/SDL2MouseDriver.cs @@ -1,6 +1,7 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using System; +using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Numerics; @@ -164,6 +165,8 @@ public IGamepad GetGamepad(string id) return new SDL2Mouse(this); } + public IEnumerable GetGamepads() => [GetGamepad("0")]; + public void Dispose() { if (_isDisposed) diff --git a/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs b/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs index 965f7935aa..69e12bda0a 100644 --- a/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs +++ b/src/Ryujinx.Input.SDL2/SDLKeyboardDriver.cs @@ -1,5 +1,6 @@ using Ryujinx.SDL2.Common; using System; +using System.Collections.Generic; namespace Ryujinx.Input.SDL2 { @@ -51,5 +52,13 @@ public IGamepad GetGamepad(string id) return new SDL2Keyboard(this, _keyboardIdentifers[0], "All keyboards"); } + + public IEnumerable GetGamepads() + { + foreach (var keyboardId in _keyboardIdentifers) + { + yield return GetGamepad(keyboardId); + } + } } } diff --git a/src/Ryujinx.Input/IGamepadDriver.cs b/src/Ryujinx.Input/IGamepadDriver.cs index 625c3e6941..e61013ae11 100644 --- a/src/Ryujinx.Input/IGamepadDriver.cs +++ b/src/Ryujinx.Input/IGamepadDriver.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Ryujinx.Input { @@ -33,6 +34,11 @@ public interface IGamepadDriver : IDisposable /// The unique id of the gamepad /// An instance of associated to the gamepad id given or null if not found IGamepad GetGamepad(string id); + + /// + /// Returns an of the connected gamepads. + /// + IEnumerable GetGamepads(); /// /// Clear the internal state of the driver. diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index 4df3eab0d3..31f27a9652 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -587,6 +587,11 @@ private void Exit() return; } + foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads()) + { + gamepad?.ClearLed(); + } + _isStopped = true; Stop(); } diff --git a/src/Ryujinx/Input/AvaloniaKeyboardDriver.cs b/src/Ryujinx/Input/AvaloniaKeyboardDriver.cs index 9f87e821ad..2146522657 100644 --- a/src/Ryujinx/Input/AvaloniaKeyboardDriver.cs +++ b/src/Ryujinx/Input/AvaloniaKeyboardDriver.cs @@ -59,6 +59,8 @@ public IGamepad GetGamepad(string id) return new AvaloniaKeyboard(this, _keyboardIdentifers[0], LocaleManager.Instance[LocaleKeys.AllKeyboards]); } + public IEnumerable GetGamepads() => [GetGamepad("0")]; + protected virtual void Dispose(bool disposing) { if (disposing) diff --git a/src/Ryujinx/Input/AvaloniaMouseDriver.cs b/src/Ryujinx/Input/AvaloniaMouseDriver.cs index e71bbf64af..be14411013 100644 --- a/src/Ryujinx/Input/AvaloniaMouseDriver.cs +++ b/src/Ryujinx/Input/AvaloniaMouseDriver.cs @@ -3,6 +3,7 @@ using Avalonia.Input; using Ryujinx.Input; using System; +using System.Collections.Generic; using System.Numerics; using MouseButton = Ryujinx.Input.MouseButton; using Size = System.Drawing.Size; @@ -134,6 +135,8 @@ public IGamepad GetGamepad(string id) return new AvaloniaMouse(this); } + public IEnumerable GetGamepads() => [GetGamepad("0")]; + public void Dispose() { if (_isDisposed) diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index a7c2c2d3cf..81483ce0ef 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -237,14 +237,9 @@ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e { base.OnDetachedFromVisualTree(e); - if (DataContext is ControllerInputViewModel vm) + foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads()) { - foreach ((_, string id, _) in vm.ParentModel.Devices.Where(x => x.Type == DeviceType.Controller)) - { - IGamepad gamepad = RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepad(id); - - gamepad?.ClearLed(); - } + gamepad?.ClearLed(); } _currentAssigner?.Cancel(); diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs index ab8f468fdc..67deb97233 100644 --- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs @@ -112,14 +112,9 @@ protected override void OnClosing(WindowClosingEventArgs e) { HotkeysPage.Dispose(); - if (InputPage.InputView.DataContext is InputViewModel vm) + foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads()) { - foreach ((_, string id, _) in vm.Devices.Where(x => x.Type == DeviceType.Controller)) - { - IGamepad gamepad = RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepad(id); - - gamepad?.ClearLed(); - } + gamepad?.ClearLed(); } InputPage.Dispose(); From 8a22d9a942954ba70864bf95ca45693d0ef50675 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Thu, 23 Jan 2025 22:58:08 -0600 Subject: [PATCH 27/30] tab --- src/Ryujinx.Input/IGamepadDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.Input/IGamepadDriver.cs b/src/Ryujinx.Input/IGamepadDriver.cs index e61013ae11..25b2295dbe 100644 --- a/src/Ryujinx.Input/IGamepadDriver.cs +++ b/src/Ryujinx.Input/IGamepadDriver.cs @@ -36,7 +36,7 @@ public interface IGamepadDriver : IDisposable IGamepad GetGamepad(string id); /// - /// Returns an of the connected gamepads. + /// Returns an of the connected gamepads. /// IEnumerable GetGamepads(); From e8025e175dd94e7c9536864cf52ef4db63224dec Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 24 Jan 2025 13:03:10 -0600 Subject: [PATCH 28/30] Rainbow LED --- .../Hid/Controller/LedConfigController.cs | 5 ++ src/Ryujinx.Common/Utilities/Rainbow.cs | 76 +++++++++++++++++++ src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 4 + src/Ryujinx.SDL2.Common/SDL2Driver.cs | 3 + src/Ryujinx/Assets/locales.json | 29 ++++++- .../UI/Models/Input/GamepadInputConfig.cs | 58 +++++++++----- .../UI/Views/Input/ControllerInputView.axaml | 17 ++++- .../ConfigurationState.Migration.cs | 1 + 8 files changed, 167 insertions(+), 26 deletions(-) create mode 100644 src/Ryujinx.Common/Utilities/Rainbow.cs diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs index 8ed68cd077..93b75d32cb 100644 --- a/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs +++ b/src/Ryujinx.Common/Configuration/Hid/Controller/LedConfigController.cs @@ -12,6 +12,11 @@ public class LedConfigController /// public bool TurnOffLed { get; set; } + /// + /// Ignores the color and uses the rainbow color functionality for the LED. + /// + public bool UseRainbow { get; set; } + /// /// Packed RGB int of the color /// diff --git a/src/Ryujinx.Common/Utilities/Rainbow.cs b/src/Ryujinx.Common/Utilities/Rainbow.cs new file mode 100644 index 0000000000..42222f157a --- /dev/null +++ b/src/Ryujinx.Common/Utilities/Rainbow.cs @@ -0,0 +1,76 @@ +using System; +using System.Drawing; + +namespace Ryujinx.Common.Utilities +{ + public class Rainbow + { + public const float Speed = 1; + + public static Color Color { get; private set; } = Color.Blue; + + public static void Tick() + { + Color = HsbToRgb( + (Color.GetHue() + Speed) / 360, + 1, + 1 + ); + + RainbowColorUpdated?.Invoke(Color.ToArgb()); + } + + public static event Action RainbowColorUpdated; + + private static Color HsbToRgb(float hue, float saturation, float brightness) + { + int r = 0, g = 0, b = 0; + if (saturation == 0) + { + r = g = b = (int)(brightness * 255.0f + 0.5f); + } + else + { + float h = (hue - (float)Math.Floor(hue)) * 6.0f; + float f = h - (float)Math.Floor(h); + float p = brightness * (1.0f - saturation); + float q = brightness * (1.0f - saturation * f); + float t = brightness * (1.0f - (saturation * (1.0f - f))); + switch ((int)h) + { + case 0: + r = (int)(brightness * 255.0f + 0.5f); + g = (int)(t * 255.0f + 0.5f); + b = (int)(p * 255.0f + 0.5f); + break; + case 1: + r = (int)(q * 255.0f + 0.5f); + g = (int)(brightness * 255.0f + 0.5f); + b = (int)(p * 255.0f + 0.5f); + break; + case 2: + r = (int)(p * 255.0f + 0.5f); + g = (int)(brightness * 255.0f + 0.5f); + b = (int)(t * 255.0f + 0.5f); + break; + case 3: + r = (int)(p * 255.0f + 0.5f); + g = (int)(q * 255.0f + 0.5f); + b = (int)(brightness * 255.0f + 0.5f); + break; + case 4: + r = (int)(t * 255.0f + 0.5f); + g = (int)(p * 255.0f + 0.5f); + b = (int)(brightness * 255.0f + 0.5f); + break; + case 5: + r = (int)(brightness * 255.0f + 0.5f); + g = (int)(p * 255.0f + 0.5f); + b = (int)(q * 255.0f + 0.5f); + break; + } + } + return Color.FromArgb(Convert.ToByte(255), Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)); + } + } +} diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index f64e1c4796..00d079a2b5 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -1,6 +1,7 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; using Ryujinx.HLE.HOS.Services.Hid; using SDL2; using System; @@ -235,8 +236,11 @@ public void SetConfiguration(InputConfig configuration) { if (_configuration.Led.TurnOffLed) (this as IGamepad).ClearLed(); + else if (_configuration.Led.UseRainbow) + Rainbow.RainbowColorUpdated += clr => SetLed((uint)clr); else SetLed(_configuration.Led.LedColor); + } _buttonsUserMapping.Clear(); diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 851c07867e..47c5e60c53 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -167,6 +168,8 @@ private void EventWorker() HandleSDLEvent(ref evnt); } }); + + Rainbow.Tick(); waitHandle.Wait(WaitTimeMs); } diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index d4a52c003a..4946a24f55 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -7628,7 +7628,7 @@ "ar_SA": "", "de_DE": "", "el_GR": "", - "en_US": "Custom LED", + "en_US": "LED", "es_ES": "", "fr_FR": "", "he_IL": "", @@ -7672,6 +7672,31 @@ "zh_TW": "" } }, + { + "ID": "ControllerSettingsLedColorRainbow", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Rainbow", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "ControllerSettingsSave", "Translations": { @@ -23023,4 +23048,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs index ae36768538..6f0f7f47ff 100644 --- a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs +++ b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs @@ -388,6 +388,28 @@ public float TriggerThreshold } } + private bool _enableMotion; + public bool EnableMotion + { + get => _enableMotion; + set + { + _enableMotion = value; + OnPropertyChanged(); + } + } + + private bool _enableRumble; + public bool EnableRumble + { + get => _enableRumble; + set + { + _enableRumble = value; + OnPropertyChanged(); + } + } + private bool _enableLedChanging; public bool EnableLedChanging @@ -400,6 +422,8 @@ public bool EnableLedChanging } } + public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed; + private bool _turnOffLed; public bool TurnOffLed @@ -409,39 +433,31 @@ public bool TurnOffLed { _turnOffLed = value; OnPropertyChanged(); + OnPropertyChanged(nameof(ShowLedColorPicker)); } } - private Color _ledColor; - - public Color LedColor - { - get => _ledColor; - set - { - _ledColor = value; - OnPropertyChanged(); - } - } - - private bool _enableMotion; - public bool EnableMotion + private bool _useRainbowLed; + + public bool UseRainbowLed { - get => _enableMotion; + get => _useRainbowLed; set { - _enableMotion = value; + _useRainbowLed = value; OnPropertyChanged(); + OnPropertyChanged(nameof(ShowLedColorPicker)); } } + + private Color _ledColor; - private bool _enableRumble; - public bool EnableRumble + public Color LedColor { - get => _enableRumble; + get => _ledColor; set { - _enableRumble = value; + _ledColor = value; OnPropertyChanged(); } } @@ -525,6 +541,7 @@ public GamepadInputConfig(InputConfig config) { EnableLedChanging = controllerInput.Led.EnableLed; TurnOffLed = controllerInput.Led.TurnOffLed; + UseRainbowLed = controllerInput.Led.UseRainbow; uint rawColor = controllerInput.Led.LedColor; byte alpha = (byte)(rawColor >> 24); byte red = (byte)(rawColor >> 16); @@ -593,6 +610,7 @@ public InputConfig GetConfig() { EnableLed = EnableLedChanging, TurnOffLed = this.TurnOffLed, + UseRainbow = UseRainbowLed, LedColor = LedColor.ToUInt32() }, Version = InputConfig.CurrentVersion, diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml index 6b8673a9f3..a4218c61ed 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml @@ -495,19 +495,20 @@ Margin="0,-1,0,0"> + - + + + x.Key)) { EnableLed = false, TurnOffLed = false, + UseRainbow = false, LedColor = new Color(255, 5, 1, 253).ToUInt32() }; } From 8b76295ee0f8f7ee69fba2dd70f42deab5169b6a Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 24 Jan 2025 13:10:39 -0600 Subject: [PATCH 29/30] forgot to use the new locale key --- src/Ryujinx/Assets/locales.json | 2 +- src/Ryujinx/UI/Views/Input/ControllerInputView.axaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 4946a24f55..698af9d177 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -23048,4 +23048,4 @@ } } ] -} +} \ No newline at end of file diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml index a4218c61ed..28c62dcf2b 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml @@ -522,7 +522,7 @@ Grid.Column="2" IsEnabled="{Binding !Config.TurnOffLed}" IsChecked="{Binding Config.UseRainbowLed, Mode=TwoWay}"> - + Date: Fri, 24 Jan 2025 13:12:55 -0600 Subject: [PATCH 30/30] cleanup testing changes --- src/Ryujinx/UI/Views/Input/ControllerInputView.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml index 28c62dcf2b..1662f4a3dc 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml @@ -531,7 +531,7 @@ IsMoreButtonVisible="False" UseColorPalette="False" UseColorTriangle="False" - UseColorWheel="True" + UseColorWheel="False" ShowAcceptDismissButtons="False" IsAlphaEnabled="False" AttachedToVisualTree="ColorPickerButton_OnAttachedToVisualTree"