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();