diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index ed22c3661..4f2160cf2 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; @@ -86,7 +87,7 @@ namespace Ryujinx.Input.SDL2 Id = driverId; Features = GetFeaturesFlag(); _triggerThreshold = 0.0f; - + // Enable motion tracking if (Features.HasFlag(GamepadFeaturesFlag.Motion)) { @@ -102,6 +103,17 @@ namespace Ryujinx.Input.SDL2 } } + 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); + + SDL_GameControllerSetLED(_gamepadHandle, red, green, blue); + } + private GamepadFeaturesFlag GetFeaturesFlag() { GamepadFeaturesFlag result = GamepadFeaturesFlag.None; @@ -220,6 +232,9 @@ namespace Ryujinx.Input.SDL2 { _configuration = (StandardControllerInputConfig)configuration; + if (Features.HasFlag(GamepadFeaturesFlag.Led) && _configuration.Led.EnableLed) + SetLed(_configuration.Led.LedColor); + _buttonsUserMapping.Clear(); // First update sticks diff --git a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs index 8d6a30d11..270af5114 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; @@ -385,6 +386,11 @@ namespace Ryujinx.Input.SDL2 } } + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an SDL2Keyboard"); + } + public void SetTriggerThreshold(float triggerThreshold) { // No operations diff --git a/src/Ryujinx.Input.SDL2/SDL2Mouse.cs b/src/Ryujinx.Input.SDL2/SDL2Mouse.cs index 37b356b76..eb86fa799 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; @@ -76,6 +77,11 @@ namespace Ryujinx.Input.SDL2 throw new NotImplementedException(); } + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an SDL2Mouse"); + } + public void SetTriggerThreshold(float triggerThreshold) { throw new NotImplementedException(); diff --git a/src/Ryujinx.Input/IGamepad.cs b/src/Ryujinx.Input/IGamepad.cs index 3853f2819..6781c0faa 100644 --- a/src/Ryujinx.Input/IGamepad.cs +++ b/src/Ryujinx.Input/IGamepad.cs @@ -65,6 +65,13 @@ namespace Ryujinx.Input /// 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 0b63af2d9..031d8b033 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; @@ -143,6 +144,11 @@ namespace Ryujinx.Ava.Input } } + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an AvaloniaKeyboard"); + } + public void SetTriggerThreshold(float triggerThreshold) { } public void Rumble(float lowFrequency, float highFrequency, uint durationMs) { } diff --git a/src/Ryujinx/Input/AvaloniaMouse.cs b/src/Ryujinx/Input/AvaloniaMouse.cs index 1aa2d586a..52a341a01 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; @@ -74,6 +75,11 @@ namespace Ryujinx.Ava.Input throw new NotImplementedException(); } + public void SetLed(uint packedRgb) + { + Logger.Info?.Print(LogClass.UI, "SetLed called on an AvaloniaMouse"); + } + public void SetTriggerThreshold(float triggerThreshold) { throw new NotImplementedException(); diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index 0380ef598..107b543ca 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/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 3d1bd5f4a..720a43614 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -69,8 +69,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input 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; diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml index db7040f4b..3592df7cd 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 52a6d51b9..4e469da81 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.Controls.Primitives; 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 @@ namespace Ryujinx.Ava.UI.Views.Input _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()); + } } }