Extended hotkeys to player1-8 + h, localized the overlay

This commit is contained in:
Barış Hamil 2025-06-21 01:34:50 +03:00 committed by GreemDev
parent ef0dac5533
commit 3ec079855d
16 changed files with 338 additions and 79 deletions

View file

@ -8,6 +8,18 @@ using OriginalInputBackendType = Ryujinx.Common.Configuration.Hid.InputBackendTy
namespace Ryujinx.Graphics.Gpu.Overlay
{
/// <summary>
/// Localization strings for the controller overlay
/// </summary>
public class ControllerOverlayLocalization
{
public string TitleText { get; set; } = "Controller Bindings";
public string NoControllerText { get; set; } = "No controller assigned";
public string KeyboardText { get; set; } = "Keyboard";
public string ControllerText { get; set; } = "Controller";
public string UnknownText { get; set; } = "Unknown";
}
/// <summary>
/// Controller overlay that shows controller bindings matching the original AXAML design
/// </summary>
@ -23,9 +35,11 @@ namespace Ryujinx.Graphics.Gpu.Overlay
private const float PlayerTextSize = 22;
private float _lifespan = 0f;
private ControllerOverlayLocalization _localization;
public ControllerOverlay() : base("ControllerOverlay")
public ControllerOverlay(ControllerOverlayLocalization localization) : base("ControllerOverlay")
{
_localization = localization;
CreateBaseElements();
}
@ -42,8 +56,8 @@ namespace Ryujinx.Graphics.Gpu.Overlay
};
AddElement(background);
// Title text
var titleText = new TextElement(Padding + 30, Padding, "Controller Bindings", TitleTextSize, SKColors.White)
// Title text (will be updated with localized text)
var titleText = new TextElement(Padding + 30, Padding, _localization.TitleText, TitleTextSize, SKColors.White)
{
Name = "TitleText",
FontStyle = SKFontStyle.Bold
@ -52,21 +66,27 @@ namespace Ryujinx.Graphics.Gpu.Overlay
}
/// <summary>
/// Show controller bindings matching the original AXAML implementation
/// Show controller bindings with localized strings
/// </summary>
public void ShowControllerBindings(List<OriginalInputConfig> inputConfigs, int durationSeconds = 3)
{
// Update title text
var titleElement = FindElement<TextElement>("TitleText");
if (titleElement != null)
{
titleElement.Text = _localization.TitleText;
}
// Reset lifespan and opacity
_lifespan = durationSeconds;
// Clear existing player bindings
ClearPlayerBindings();
// Debug: Log input data
// Group controllers by player index
// Group controllers by player index (support all players + handheld)
var playerBindings = new Dictionary<OriginalPlayerIndex, List<OriginalInputConfig>>();
foreach (var config in inputConfigs.Where(c => c.PlayerIndex <= OriginalPlayerIndex.Player4))
foreach (var config in inputConfigs.Where(c => c.PlayerIndex <= OriginalPlayerIndex.Handheld))
{
if (!playerBindings.ContainsKey(config.PlayerIndex))
{
@ -77,10 +97,17 @@ namespace Ryujinx.Graphics.Gpu.Overlay
float currentY = Padding + 40; // After title
// Add player bindings to UI
for (int i = 0; i < 4; i++)
// Add player bindings to UI (support 8 players + handheld)
var playerIndices = new[]
{
OriginalPlayerIndex.Player1, OriginalPlayerIndex.Player2, OriginalPlayerIndex.Player3, OriginalPlayerIndex.Player4,
OriginalPlayerIndex.Player5, OriginalPlayerIndex.Player6, OriginalPlayerIndex.Player7, OriginalPlayerIndex.Player8,
OriginalPlayerIndex.Handheld
};
for (int i = 0; i < playerIndices.Length; i++)
{
var playerIndex = (OriginalPlayerIndex)i;
var playerIndex = playerIndices[i];
float rowY = currentY + (i * (PlayerRowHeight + PlayerSpacing));
// Player number with colored background (circular badge)
@ -93,13 +120,14 @@ namespace Ryujinx.Graphics.Gpu.Overlay
AddElement(playerBadge);
// Player number text
var playerLabel = new TextElement(Padding + 12, rowY + 2, $"P{i + 1}", PlayerTextSize, SKColors.White)
string playerLabel = playerIndex == OriginalPlayerIndex.Handheld ? "H" : $"P{(int)playerIndex + 1}";
var playerLabelElement = new TextElement(Padding + 12, rowY + 2, playerLabel, PlayerTextSize, SKColors.White)
{
Name = $"PlayerLabel_{i}",
FontStyle = SKFontStyle.Bold,
TextAlign = SKTextAlign.Center
};
AddElement(playerLabel);
AddElement(playerLabelElement);
// Controller info
if (playerBindings.ContainsKey(playerIndex))
@ -107,37 +135,32 @@ namespace Ryujinx.Graphics.Gpu.Overlay
var controllers = playerBindings[playerIndex];
var controllerNames = controllers.Select(c => GetControllerDisplayName(c)).ToList();
var controllerText = new TextElement(Padding + 56, rowY + 2, string.Join(", ", controllerNames), PlayerTextSize, new SKColor(144, 238, 144)) // LightGreen
var controllerTextElement = new TextElement(Padding + 56, rowY + 2, string.Join(", ", controllerNames), PlayerTextSize, new SKColor(144, 238, 144)) // LightGreen
{
Name = $"ControllerText_{i}",
FontStyle = SKFontStyle.Bold
};
AddElement(controllerText);
AddElement(controllerTextElement);
}
else
{
var noControllerText = new TextElement(Padding + 56, rowY + 2, "No controller assigned", PlayerTextSize, new SKColor(128, 128, 128)) // Gray
var noControllerTextElement = new TextElement(Padding + 56, rowY + 2, _localization.NoControllerText, PlayerTextSize, new SKColor(128, 128, 128)) // Gray
{
Name = $"NoControllerText_{i}",
FontStyle = SKFontStyle.Italic
};
AddElement(noControllerText);
AddElement(noControllerTextElement);
}
}
// Calculate total height and update background
float totalHeight = Padding + 40 + (4 * (PlayerRowHeight + PlayerSpacing)) + Padding + 40; // Extra space for duration text
float totalHeight = Padding + 40 + (playerIndices.Length * (PlayerRowHeight + PlayerSpacing)) + Padding + 20;
var background = FindElement<RectangleElement>("Background");
if (background != null)
{
background.Height = totalHeight;
}
// Duration text at bottom
string durationText = durationSeconds == 1
? "This overlay will disappear in 1 second"
: $"This overlay will disappear in {durationSeconds} seconds";
// Show the overlay (position will be set by Window class with actual dimensions)
IsVisible = true;
}
@ -150,19 +173,24 @@ namespace Ryujinx.Graphics.Gpu.Overlay
1 => new SKColor(54, 162, 235), // Blue for Player 2
2 => new SKColor(255, 206, 84), // Yellow for Player 3
3 => new SKColor(75, 192, 192), // Green for Player 4
4 => new SKColor(153, 102, 255), // Purple for Player 5
5 => new SKColor(255, 159, 64), // Orange for Player 6
6 => new SKColor(199, 199, 199), // Light Gray for Player 7
7 => new SKColor(83, 102, 255), // Indigo for Player 8
8 => new SKColor(255, 99, 132), // Pink for Handheld
_ => new SKColor(128, 128, 128) // Gray fallback
};
}
private static string GetControllerDisplayName(OriginalInputConfig config)
private string GetControllerDisplayName(OriginalInputConfig config)
{
if (string.IsNullOrEmpty(config.Name))
{
return config.Backend switch
{
OriginalInputBackendType.WindowKeyboard => "Keyboard",
OriginalInputBackendType.GamepadSDL2 => "Controller",
_ => "Unknown"
OriginalInputBackendType.WindowKeyboard => _localization.KeyboardText,
OriginalInputBackendType.GamepadSDL2 => _localization.ControllerText,
_ => _localization.UnknownText
};
}