diff --git a/Directory.Packages.props b/Directory.Packages.props index c2ac358ed..f1d7cac61 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -42,7 +42,7 @@ - + diff --git a/src/Ryujinx.Common/Utilities/Rainbow.cs b/src/Ryujinx.Common/Utilities/Rainbow.cs index 2c2ea7bfd..3b49872c2 100644 --- a/src/Ryujinx.Common/Utilities/Rainbow.cs +++ b/src/Ryujinx.Common/Utilities/Rainbow.cs @@ -1,40 +1,62 @@ -using System; +using Gommon; +using System; using System.Drawing; +using System.Threading.Tasks; namespace Ryujinx.Common.Utilities { - public class Rainbow + public static class Rainbow { + public static bool CyclingEnabled { get; set; } + + public static void Enable() + { + if (!CyclingEnabled) + { + CyclingEnabled = true; + Executor.ExecuteBackgroundAsync(async () => + { + while (CyclingEnabled) + { + await Task.Delay(15); + Tick(); + } + }); + } + } + + public static void Disable() + { + CyclingEnabled = false; + } + + public static float Speed { get; set; } = 1; public static Color Color { get; private set; } = Color.Blue; - private static float _lastHue; - public static void Tick() { - float currentHue = Color.GetHue(); - float nextHue = currentHue; - - if (currentHue >= 360) - nextHue = 0; - else - nextHue += Speed; + Color = HsbToRgb((Color.GetHue() + Speed) / 360); - Color = HsbToRgb( - nextHue / 360, - 1, - 1 - ); - - _lastHue = currentHue; - - RainbowColorUpdated?.Invoke(Color.ToArgb()); + UpdatedHandler.Call(Color.ToArgb()); } - public static event Action RainbowColorUpdated; + public static void Reset() + { + Color = Color.Blue; + UpdatedHandler.Clear(); + } - private static Color HsbToRgb(float hue, float saturation, float brightness) + public static event Action Updated + { + add => UpdatedHandler.Add(value); + remove => UpdatedHandler.Remove(value); + } + + internal static Event UpdatedHandler = new(); + + private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1) { int r = 0, g = 0, b = 0; if (saturation == 0) diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index a73d7c730..3ed2880ce 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -148,6 +148,8 @@ namespace Ryujinx.Input.SDL2 { if (disposing && _gamepadHandle != nint.Zero) { + Rainbow.Updated -= RainbowColorChanged; + SDL_GameControllerClose(_gamepadHandle); _gamepadHandle = nint.Zero; @@ -232,6 +234,8 @@ namespace Ryujinx.Input.SDL2 SetLed((uint)packedRgb); } + + private bool _rainbowColorEnabled; public void SetConfiguration(InputConfig configuration) { @@ -243,13 +247,20 @@ namespace Ryujinx.Input.SDL2 { if (_configuration.Led.TurnOffLed) (this as IGamepad).ClearLed(); - else if (_configuration.Led.UseRainbow) - Rainbow.RainbowColorUpdated += RainbowColorChanged; - else - SetLed(_configuration.Led.LedColor); + else switch (_configuration.Led.UseRainbow) + { + case true when !_rainbowColorEnabled: + Rainbow.Updated += RainbowColorChanged; + _rainbowColorEnabled = true; + break; + case false when _rainbowColorEnabled: + Rainbow.Updated -= RainbowColorChanged; + _rainbowColorEnabled = false; + break; + } - if (!_configuration.Led.UseRainbow) - Rainbow.RainbowColorUpdated -= RainbowColorChanged; + if (!_configuration.Led.TurnOffLed && !_rainbowColorEnabled) + SetLed(_configuration.Led.LedColor); } _buttonsUserMapping.Clear(); diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 47c5e60c5..047ccbebf 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -168,8 +168,6 @@ namespace Ryujinx.SDL2.Common HandleSDLEvent(ref evnt); } }); - - Rainbow.Tick(); waitHandle.Wait(WaitTimeMs); } diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index 31f27a965..65c279fc4 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -501,6 +501,8 @@ namespace Ryujinx.Ava _renderingThread.Start(); _viewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value; + + Rainbow.Enable(); MainLoop(); @@ -590,7 +592,11 @@ namespace Ryujinx.Ava foreach (IGamepad gamepad in RyujinxApp.MainWindow.InputManager.GamepadDriver.GetGamepads()) { gamepad?.ClearLed(); + gamepad?.Dispose(); } + + Rainbow.Disable(); + Rainbow.Reset(); _isStopped = true; Stop();