Compare commits

...

6 Commits

Author SHA1 Message Date
Evan Husted
76b8c79a4c Merge branch 'master' into Change-Controller-LED-Color 2025-01-24 13:42:44 -06:00
Evan Husted
5e8ba2c245 cleanup testing changes 2025-01-24 13:12:55 -06:00
Evan Husted
8b76295ee0 forgot to use the new locale key 2025-01-24 13:10:39 -06:00
Evan Husted
e8025e175d Rainbow LED 2025-01-24 13:03:10 -06:00
Evan Husted
c06f16c5e6 infra: chore: Raise minimum required Windows 10 version
Inspired by the breakages covered in #409
2025-01-23 17:39:34 -06:00
Evan Husted
7829fd8ee7 misc: chore: OS + CPU arch helpers 2025-01-23 16:58:48 -06:00
12 changed files with 210 additions and 47 deletions

View File

@@ -12,6 +12,11 @@
/// </summary>
public bool TurnOffLed { get; set; }
/// <summary>
/// Ignores the color and uses the rainbow color functionality for the LED.
/// </summary>
public bool UseRainbow { get; set; }
/// <summary>
/// Packed RGB int of the color
/// </summary>

View File

@@ -0,0 +1,23 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace Ryujinx.Common.Helper
{
public static class RunningPlatform
{
public static bool IsMacOS => OperatingSystem.IsMacOS();
public static bool IsWindows => OperatingSystem.IsWindows();
public static bool IsLinux => OperatingSystem.IsLinux();
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
}
}

View File

@@ -1,5 +1,6 @@
using Gommon;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper;
using System;
using System.Linq;
using System.Runtime.InteropServices;
@@ -21,7 +22,7 @@ namespace Ryujinx.Common
return currentBackend;
}
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
if (!RunningPlatform.IsArmMac)
return GraphicsBackend.Vulkan;
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;

View File

@@ -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<int> 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));
}
}
}

View File

@@ -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 @@ namespace Ryujinx.Input.SDL2
{
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();

View File

@@ -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 @@ namespace Ryujinx.SDL2.Common
HandleSDLEvent(ref evnt);
}
});
Rainbow.Tick();
waitHandle.Wait(WaitTimeMs);
}

View File

@@ -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": {

View File

@@ -47,9 +47,9 @@ namespace Ryujinx.Ava
{
Version = ReleaseInformation.Version;
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))
{
_ = MessageBoxA(nint.Zero, "You are running an outdated version of Windows.\n\nRyujinx supports Windows 10 version 1803 and newer.\n", $"Ryujinx {Version}", MbIconwarning);
_ = MessageBoxA(nint.Zero, "You are running an outdated version of Windows.\n\nRyujinx supports Windows 10 version 20H1 and newer.\n", $"Ryujinx {Version}", MbIconwarning);
}
PreviewerDetached = true;

View File

@@ -388,42 +388,6 @@ namespace Ryujinx.Ava.UI.Models.Input
}
}
private bool _enableLedChanging;
public bool EnableLedChanging
{
get => _enableLedChanging;
set
{
_enableLedChanging = value;
OnPropertyChanged();
}
}
private bool _turnOffLed;
public bool TurnOffLed
{
get => _turnOffLed;
set
{
_turnOffLed = value;
OnPropertyChanged();
}
}
private Color _ledColor;
public Color LedColor
{
get => _ledColor;
set
{
_ledColor = value;
OnPropertyChanged();
}
}
private bool _enableMotion;
public bool EnableMotion
{
@@ -445,6 +409,58 @@ namespace Ryujinx.Ava.UI.Models.Input
OnPropertyChanged();
}
}
private bool _enableLedChanging;
public bool EnableLedChanging
{
get => _enableLedChanging;
set
{
_enableLedChanging = value;
OnPropertyChanged();
}
}
public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed;
private bool _turnOffLed;
public bool TurnOffLed
{
get => _turnOffLed;
set
{
_turnOffLed = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowLedColorPicker));
}
}
private bool _useRainbowLed;
public bool UseRainbowLed
{
get => _useRainbowLed;
set
{
_useRainbowLed = value;
OnPropertyChanged();
OnPropertyChanged(nameof(ShowLedColorPicker));
}
}
private Color _ledColor;
public Color LedColor
{
get => _ledColor;
set
{
_ledColor = value;
OnPropertyChanged();
}
}
public GamepadInputConfig(InputConfig config)
{
@@ -525,6 +541,7 @@ namespace Ryujinx.Ava.UI.Models.Input
{
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 @@ namespace Ryujinx.Ava.UI.Models.Input
{
EnableLed = EnableLedChanging,
TurnOffLed = this.TurnOffLed,
UseRainbow = UseRainbowLed,
LedColor = LedColor.ToUInt32()
},
Version = InputConfig.CurrentVersion,

View File

@@ -495,19 +495,20 @@
Margin="0,-1,0,0">
<Grid IsVisible="{Binding ParentModel.HasLed}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Margin="10"
Margin="10, 10, 5, 10"
MinWidth="0"
Grid.Column="0"
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}">
<TextBlock Text="{ext:Locale ControllerSettingsLedColor}" />
</CheckBox>
<CheckBox
Margin="10"
Margin="5, 10, 5, 10"
MinWidth="0"
Grid.Column="1"
IsVisible="{Binding ParentModel.CanClearLed}"
@@ -515,10 +516,18 @@
Command="{Binding LedDisabledChanged}">
<TextBlock Text="{ext:Locale ControllerSettingsLedColorDisable}" />
</CheckBox>
<ui:ColorPickerButton
<CheckBox
Margin="5, 10 5,10"
MinWidth="0"
Grid.Column="2"
IsEnabled="{Binding !Config.TurnOffLed}"
Margin="10"
IsChecked="{Binding Config.UseRainbowLed, Mode=TwoWay}">
<TextBlock Text="{ext:Locale ControllerSettingsLedColorRainbow}" />
</CheckBox>
<ui:ColorPickerButton
Grid.Column="3"
IsEnabled="{Binding Config.ShowLedColorPicker}"
Margin="5, 10, 10, 10"
IsMoreButtonVisible="False"
UseColorPalette="False"
UseColorTriangle="False"

View File

@@ -736,9 +736,7 @@ namespace Ryujinx.Ava.UI.Windows
});
}
private static bool _intelMacWarningShown = !(OperatingSystem.IsMacOS() &&
(RuntimeInformation.OSArchitecture == Architecture.X64 ||
RuntimeInformation.OSArchitecture == Architecture.X86));
private static bool _intelMacWarningShown = !RunningPlatform.IsIntelMac;
public static async Task ShowIntelMacWarningAsync()
{

View File

@@ -423,6 +423,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
{
EnableLed = false,
TurnOffLed = false,
UseRainbow = false,
LedColor = new Color(255, 5, 1, 253).ToUInt32()
};
}