Skip to content

Commit

Permalink
UI: Add the ability to change a DualSense/DualShock 4's LED color.
Browse files Browse the repository at this point in the history
Not functional yet. This is the UI & persistence side of #572.
  • Loading branch information
GreemDev committed Jan 23, 2025
1 parent 069f630 commit c03cd50
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,10 @@ public float TriggerThreshold
/// Controller Rumble Settings
/// </summary>
public RumbleConfigController Rumble { get; set; }

/// <summary>
/// Controller LED Settings
/// </summary>
public LedConfigController Led { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Ryujinx.Common.Configuration.Hid.Controller
{
public class LedConfigController
{
/// <summary>
/// Packed RGB int of the color
/// </summary>
public uint LedColor { get; set; }

/// <summary>
/// Enable LED color changing by the emulator
/// </summary>
public bool EnableLed { get; set; }
}
}
6 changes: 6 additions & 0 deletions src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Logging;
using SDL2;
using System;
using System.Collections.Generic;
using System.Numerics;
Expand Down Expand Up @@ -118,6 +119,11 @@ private GamepadFeaturesFlag GetFeaturesFlag()
result |= GamepadFeaturesFlag.Rumble;
}

if (SDL_GameControllerHasLED(_gamepadHandle) == SDL_bool.SDL_TRUE)
{
result |= GamepadFeaturesFlag.Led;
}

return result;
}

Expand Down
5 changes: 5 additions & 0 deletions src/Ryujinx.Input/GamepadFeaturesFlag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@ public enum GamepadFeaturesFlag
/// <remarks>Also named sixaxis</remarks>
/// </summary>
Motion,

/// <summary>
/// The LED on the back of modern PlayStation controllers (DualSense &amp; DualShock 4).
/// </summary>
Led,
}
}
43 changes: 42 additions & 1 deletion src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Avalonia.Media;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
Expand Down Expand Up @@ -387,6 +388,30 @@ public float TriggerThreshold
}
}

private bool _enableLedChanging;

public bool EnableLedChanging
{
get => _enableLedChanging;
set
{
_enableLedChanging = value;
OnPropertyChanged();
}
}

private Color _ledColor;

public Color LedColor
{
get => _ledColor;
set
{
_ledColor = value;
OnPropertyChanged();
}
}

private bool _enableMotion;
public bool EnableMotion
{
Expand Down Expand Up @@ -483,12 +508,23 @@ public GamepadInputConfig(InputConfig config)
WeakRumble = controllerInput.Rumble.WeakRumble;
StrongRumble = controllerInput.Rumble.StrongRumble;
}

if (controllerInput.Led != null)
{
EnableLedChanging = controllerInput.Led.EnableLed;
uint rawColor = controllerInput.Led.LedColor;
byte alpha = (byte)(rawColor >> 24);
byte red = (byte)(rawColor >> 16);
byte green = (byte)(rawColor >> 8);
byte blue = (byte)(rawColor % 256);
LedColor = new Color(alpha, red, green, blue);
}
}
}

public InputConfig GetConfig()
{
var config = new StandardControllerInputConfig
StandardControllerInputConfig config = new()
{
Id = Id,
Backend = InputBackendType.GamepadSDL2,
Expand Down Expand Up @@ -540,6 +576,11 @@ public InputConfig GetConfig()
WeakRumble = WeakRumble,
StrongRumble = StrongRumble,
},
Led = new LedConfigController
{
EnableLed = EnableLedChanging,
LedColor = LedColor.ToUInt32()
},
Version = InputConfig.CurrentVersion,
DeadzoneLeft = DeadzoneLeft,
DeadzoneRight = DeadzoneRight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public bool IsRight

[ObservableProperty] private SvgImage _image;

public readonly InputViewModel ParentModel;
public InputViewModel ParentModel { get; }

public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public partial class InputViewModel : BaseModel, IDisposable
public bool IsKeyboard => !IsController;
public bool IsRight { get; set; }
public bool IsLeft { get; set; }

public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);

public bool IsModified { get; set; }
public event Action NotifyChangesEvent;
Expand Down
32 changes: 32 additions & 0 deletions src/Ryujinx/UI/Views/Input/ControllerInputView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
Expand Down Expand Up @@ -486,6 +487,37 @@
</Button>
</Grid>
</Border>
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
HorizontalAlignment="Stretch"
Margin="0,-1,0,0">
<Grid IsVisible="{Binding ParentModel.HasLed}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Margin="10"
MinWidth="0"
Grid.Column="0"
IsChecked="{Binding Config.EnableLedChanging, Mode=TwoWay}">
<TextBlock Text="Custom LED color" />
</CheckBox>
<ui:ColorPickerButton
Grid.Column="1"
Margin="10"
IsMoreButtonVisible="False"
UseColorPalette="False"
UseColorTriangle="False"
UseColorWheel="False"
ShowAcceptDismissButtons="False"
IsAlphaEnabled="False"
Color="{Binding Config.LedColor, Mode=TwoWay}">
</ui:ColorPickerButton>
</Grid>
</Border>
</StackPanel>
</StackPanel>
<!-- Right Controls -->
Expand Down
3 changes: 0 additions & 3 deletions src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using DiscordRPC;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Logging;
using Ryujinx.Input;
using Ryujinx.Input.Assigner;
using System;
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;

namespace Ryujinx.Ava.UI.Views.Input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ConfigurationFileFormat
/// <summary>
/// The current version of the file format
/// </summary>
public const int CurrentVersion = 60;
public const int CurrentVersion = 61;

/// <summary>
/// Version of the configuration file format
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,15 +263,12 @@ in _migrations.OrderBy(x => x.Key))
}),
(30, static cff =>
{
foreach (InputConfig config in cff.InputConfig)
foreach (StandardControllerInputConfig config in cff.InputConfig.OfType<StandardControllerInputConfig>())
{
if (config is StandardControllerInputConfig controllerConfig)
config.Rumble = new RumbleConfigController
{
controllerConfig.Rumble = new RumbleConfigController
{
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
};
}
EnableRumble = false, StrongRumble = 1f, WeakRumble = 1f,
};
}
}),
(31, static cff => cff.BackendThreading = BackendThreading.Auto),
Expand Down Expand Up @@ -416,7 +413,18 @@ in _migrations.OrderBy(x => x.Key))
// so as a compromise users who want to use it will simply need to re-enable it once after updating.
cff.IgnoreApplet = false;
}),
(60, static cff => cff.StartNoUI = false)
(60, static cff => cff.StartNoUI = false),
(61, static cff =>
{
foreach (StandardControllerInputConfig config in cff.InputConfig.OfType<StandardControllerInputConfig>())
{
config.Led = new LedConfigController
{
EnableLed = false,
LedColor = 328189
};
}
})
);
}
}

0 comments on commit c03cd50

Please sign in to comment.