mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-27 22:06:24 +02:00
Overlays: Move the structure to Ryujinx/UI/Overlay (also no longer need to cross-pass locales)
This commit is contained in:
parent
076dd9a56a
commit
d6232008d5
15 changed files with 138 additions and 66 deletions
|
@ -40,6 +40,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||
/// GPU synchronization manager.
|
||||
/// </summary>
|
||||
public SynchronizationManager Synchronization { get; }
|
||||
public IOverlayManager OverlayManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Presentation window.
|
||||
|
@ -121,14 +122,18 @@ namespace Ryujinx.Graphics.Gpu
|
|||
/// Creates a new instance of the GPU emulation context.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
public GpuContext(IRenderer renderer, DirtyHacks hacks)
|
||||
/// <param name="hacks">Enabled dirty hacks</param>
|
||||
/// <param name="overlayManager">Overlay manager for rendering overlays</param>
|
||||
public GpuContext(IRenderer renderer, DirtyHacks hacks, IOverlayManager overlayManager)
|
||||
{
|
||||
Renderer = renderer;
|
||||
|
||||
GPFifo = new GPFifoDevice(this);
|
||||
|
||||
Synchronization = new SynchronizationManager();
|
||||
|
||||
|
||||
OverlayManager = overlayManager;
|
||||
|
||||
Window = new Window(this);
|
||||
|
||||
HostInitalized = new ManualResetEvent(false);
|
||||
|
@ -462,6 +467,8 @@ namespace Ryujinx.Graphics.Gpu
|
|||
RunDeferredActions();
|
||||
|
||||
Renderer.Dispose();
|
||||
|
||||
OverlayManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
54
src/Ryujinx.Graphics.Gpu/IOverlay.cs
Normal file
54
src/Ryujinx.Graphics.Gpu/IOverlay.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for overlay functionality
|
||||
/// </summary>
|
||||
public interface IOverlay : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the overlay
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the overlay is visible
|
||||
/// </summary>
|
||||
bool IsVisible { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Opacity of the overlay (0.0 to 1.0)
|
||||
/// </summary>
|
||||
float Opacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X position of the overlay
|
||||
/// </summary>
|
||||
float X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Y position of the overlay
|
||||
/// </summary>
|
||||
float Y { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Z-index for overlay ordering
|
||||
/// </summary>
|
||||
int ZIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Update overlay (for animations)
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">Time elapsed since last update</param>
|
||||
/// <param name="screenSize">Current screen size</param>
|
||||
void Update(float deltaTime, SKSize screenSize = default);
|
||||
|
||||
/// <summary>
|
||||
/// Render this overlay
|
||||
/// </summary>
|
||||
/// <param name="canvas">The canvas to render to</param>
|
||||
void Render(SKCanvas canvas);
|
||||
}
|
||||
}
|
30
src/Ryujinx.Graphics.Gpu/IOverlayManager.cs
Normal file
30
src/Ryujinx.Graphics.Gpu/IOverlayManager.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for overlay management functionality
|
||||
/// </summary>
|
||||
public interface IOverlayManager : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Add an overlay to the manager
|
||||
/// </summary>
|
||||
/// <param name="overlay">The overlay to add</param>
|
||||
void AddOverlay(IOverlay overlay);
|
||||
|
||||
/// <summary>
|
||||
/// Update all overlays (for animations)
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">Time elapsed since last update</param>
|
||||
/// <param name="screenSize">Current screen size</param>
|
||||
void Update(float deltaTime, SKSize screenSize = default);
|
||||
|
||||
/// <summary>
|
||||
/// Render all visible overlays
|
||||
/// </summary>
|
||||
/// <param name="canvas">The canvas to render to</param>
|
||||
void Render(SKCanvas canvas);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ using Ryujinx.Common.Memory;
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
using Ryujinx.Graphics.Gpu.Overlay;
|
||||
using Ryujinx.Graphics.Texture;
|
||||
using Ryujinx.Memory.Range;
|
||||
using SkiaSharp;
|
||||
|
@ -20,7 +19,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||
public class Window
|
||||
{
|
||||
private readonly GpuContext _context;
|
||||
private readonly OverlayManager _overlayManager;
|
||||
private DateTime? _lastUpdateTime = null;
|
||||
|
||||
/// <summary>
|
||||
|
@ -105,7 +103,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||
public Window(GpuContext context)
|
||||
{
|
||||
_context = context;
|
||||
_overlayManager = new OverlayManager();
|
||||
|
||||
_frameQueue = new ConcurrentQueue<PresentationTexture>();
|
||||
}
|
||||
|
@ -258,9 +255,9 @@ namespace Ryujinx.Graphics.Gpu
|
|||
/// <summary>
|
||||
/// Add overlay to the overlay manager
|
||||
/// </summary>
|
||||
public void AddOverlay(Overlay.Overlay overlay)
|
||||
public void AddOverlay(IOverlay overlay)
|
||||
{
|
||||
_overlayManager.AddOverlay(overlay);
|
||||
_context.OverlayManager.AddOverlay(overlay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -276,7 +273,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||
{
|
||||
// Calculate delta time for lifespan updates
|
||||
float deltaTime = (float)(currentTime - _lastUpdateTime.Value).TotalSeconds;
|
||||
_overlayManager.Update(deltaTime, new SKSize(texture.Info.Width, texture.Info.Height));
|
||||
_context.OverlayManager.Update(deltaTime, new SKSize(texture.Info.Width, texture.Info.Height));
|
||||
}
|
||||
|
||||
// Update overlay animations
|
||||
|
@ -326,7 +323,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||
}
|
||||
|
||||
// Render all overlays
|
||||
_overlayManager.Render(canvas);
|
||||
_context.OverlayManager.Render(canvas);
|
||||
|
||||
// Copy modified bitmap data back to texture data array
|
||||
var pixels = bitmap.Bytes;
|
||||
|
@ -370,13 +367,5 @@ namespace Ryujinx.Graphics.Gpu
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_overlayManager?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using Ryujinx.Audio.Integration;
|
|||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Configuration.Multiplayer;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
|
@ -65,6 +66,12 @@ namespace Ryujinx.HLE
|
|||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal IHostUIHandler HostUIHandler { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The overlay manager to use for all overlay operations.
|
||||
/// </summary>
|
||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||
internal IOverlayManager OverlayManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Control the memory configuration used by the emulation context.
|
||||
/// </summary>
|
||||
|
@ -262,7 +269,8 @@ namespace Ryujinx.HLE
|
|||
UserChannelPersistence userChannelPersistence,
|
||||
IRenderer gpuRenderer,
|
||||
IHardwareDeviceDriver audioDeviceDriver,
|
||||
IHostUIHandler hostUIHandler
|
||||
IHostUIHandler hostUIHandler,
|
||||
IOverlayManager overlayManager
|
||||
)
|
||||
{
|
||||
VirtualFileSystem = virtualFileSystem;
|
||||
|
@ -273,6 +281,7 @@ namespace Ryujinx.HLE
|
|||
GpuRenderer = gpuRenderer;
|
||||
AudioDeviceDriver = audioDeviceDriver;
|
||||
HostUIHandler = hostUIHandler;
|
||||
OverlayManager = overlayManager;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Ryujinx.HLE
|
|||
DirtyHacks = new DirtyHacks(Configuration.Hacks);
|
||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
||||
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
||||
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
|
||||
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks, Configuration.OverlayManager);
|
||||
System = new HOS.Horizon(this);
|
||||
Statistics = new PerformanceStatistics(this);
|
||||
Hid = new Hid(this, System.HidStorage);
|
||||
|
|
|
@ -17,6 +17,7 @@ using Ryujinx.Graphics.OpenGL;
|
|||
using Ryujinx.Graphics.Vulkan;
|
||||
using Ryujinx.HLE;
|
||||
using Ryujinx.Input;
|
||||
using Ryujinx.UI.Overlay;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
@ -348,7 +349,8 @@ namespace Ryujinx.Headless
|
|||
_userChannelPersistence,
|
||||
renderer.TryMakeThreaded(options.BackendThreading),
|
||||
new SDL2HardwareDeviceDriver(),
|
||||
window
|
||||
window,
|
||||
new OverlayManager()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ using Ryujinx.Common.Utilities;
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.GAL.Multithreading;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.Graphics.Gpu.Overlay;
|
||||
using Ryujinx.UI.Overlay;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.Vulkan;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
|
@ -931,20 +931,12 @@ namespace Ryujinx.Ava.Systems
|
|||
_userChannelPersistence,
|
||||
renderer.TryMakeThreaded(ConfigurationState.Instance.Graphics.BackendThreading),
|
||||
InitializeAudio(),
|
||||
_viewModel.UiHandler
|
||||
_viewModel.UiHandler,
|
||||
new OverlayManager()
|
||||
)
|
||||
);
|
||||
|
||||
// Initialize controller overlay with localization
|
||||
var localization = new ControllerOverlayLocalization
|
||||
{
|
||||
TitleText = LocaleManager.Instance[LocaleKeys.ControllerOverlayTitle],
|
||||
NoControllerText = LocaleManager.Instance[LocaleKeys.ControllerOverlayNoController],
|
||||
KeyboardText = LocaleManager.Instance[LocaleKeys.ControllerOverlayKeyboard],
|
||||
ControllerText = LocaleManager.Instance[LocaleKeys.ControllerOverlayController],
|
||||
UnknownText = LocaleManager.Instance[LocaleKeys.ControllerOverlayUnknown]
|
||||
};
|
||||
_controllerOverlay = new ControllerOverlay(localization);
|
||||
_controllerOverlay = new ControllerOverlay();
|
||||
Device.Gpu.Window.AddOverlay(_controllerOverlay);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,21 +5,10 @@ using System.Linq;
|
|||
using OriginalInputConfig = Ryujinx.Common.Configuration.Hid.InputConfig;
|
||||
using OriginalPlayerIndex = Ryujinx.Common.Configuration.Hid.PlayerIndex;
|
||||
using OriginalInputBackendType = Ryujinx.Common.Configuration.Hid.InputBackendType;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.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>
|
||||
|
@ -35,11 +24,9 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
private const float PlayerTextSize = 22;
|
||||
|
||||
private float _lifespan = 0f;
|
||||
private ControllerOverlayLocalization _localization;
|
||||
|
||||
public ControllerOverlay(ControllerOverlayLocalization localization) : base("ControllerOverlay")
|
||||
public ControllerOverlay() : base("ControllerOverlay")
|
||||
{
|
||||
_localization = localization;
|
||||
CreateBaseElements();
|
||||
}
|
||||
|
||||
|
@ -57,7 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
AddElement(background);
|
||||
|
||||
// Title text (will be updated with localized text)
|
||||
var titleText = new TextElement(Padding + 30, Padding, _localization.TitleText, TitleTextSize, SKColors.White)
|
||||
var titleText = new TextElement(Padding + 30, Padding, LocaleManager.Instance[LocaleKeys.ControllerOverlayTitle], TitleTextSize, SKColors.White)
|
||||
{
|
||||
Name = "TitleText",
|
||||
FontStyle = SKFontStyle.Bold
|
||||
|
@ -74,7 +61,7 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
var titleElement = FindElement<TextElement>("TitleText");
|
||||
if (titleElement != null)
|
||||
{
|
||||
titleElement.Text = _localization.TitleText;
|
||||
titleElement.Text = LocaleManager.Instance[LocaleKeys.ControllerOverlayTitle];
|
||||
}
|
||||
|
||||
// Reset lifespan and opacity
|
||||
|
@ -144,7 +131,7 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
}
|
||||
else
|
||||
{
|
||||
var noControllerTextElement = new TextElement(Padding + 56, rowY + 2, _localization.NoControllerText, PlayerTextSize, new SKColor(128, 128, 128)) // Gray
|
||||
var noControllerTextElement = new TextElement(Padding + 56, rowY + 2, LocaleManager.Instance[LocaleKeys.ControllerOverlayNoController], PlayerTextSize, new SKColor(128, 128, 128)) // Gray
|
||||
{
|
||||
Name = $"NoControllerText_{i}",
|
||||
FontStyle = SKFontStyle.Italic
|
||||
|
@ -188,9 +175,9 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
{
|
||||
return config.Backend switch
|
||||
{
|
||||
OriginalInputBackendType.WindowKeyboard => _localization.KeyboardText,
|
||||
OriginalInputBackendType.GamepadSDL2 => _localization.ControllerText,
|
||||
_ => _localization.UnknownText
|
||||
OriginalInputBackendType.WindowKeyboard => LocaleManager.Instance[LocaleKeys.ControllerOverlayKeyboard],
|
||||
OriginalInputBackendType.GamepadSDL2 => LocaleManager.Instance[LocaleKeys.ControllerOverlayController],
|
||||
_ => LocaleManager.Instance[LocaleKeys.ControllerOverlayUnknown]
|
||||
};
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
|
|||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.Overlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Image overlay element
|
|
@ -2,13 +2,14 @@ using SkiaSharp;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.Overlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Base overlay class containing multiple elements
|
||||
/// </summary>
|
||||
public abstract class Overlay : IDisposable
|
||||
public abstract class Overlay : IOverlay
|
||||
{
|
||||
private readonly List<OverlayElement> _elements = new();
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.Overlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all overlay elements
|
|
@ -3,21 +3,22 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ryujinx.Graphics.Gpu.Image;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.Overlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages multiple overlays and handles rendering
|
||||
/// </summary>
|
||||
public class OverlayManager : IDisposable
|
||||
public class OverlayManager : IOverlayManager
|
||||
{
|
||||
private readonly List<Overlay> _overlays = new();
|
||||
private readonly List<IOverlay> _overlays = new();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Add an overlay to the manager
|
||||
/// </summary>
|
||||
public void AddOverlay(Overlay overlay)
|
||||
public void AddOverlay(IOverlay overlay)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
@ -56,7 +57,7 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
/// <summary>
|
||||
/// Find overlay by name
|
||||
/// </summary>
|
||||
public Overlay FindOverlay(string name)
|
||||
public IOverlay FindOverlay(string name)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
@ -67,7 +68,7 @@ namespace Ryujinx.Graphics.Gpu.Overlay
|
|||
/// <summary>
|
||||
/// Get all overlays
|
||||
/// </summary>
|
||||
public IReadOnlyList<Overlay> GetOverlays()
|
||||
public IReadOnlyList<IOverlay> GetOverlays()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
using SkiaSharp;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.Overlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Rectangle overlay element
|
|
@ -1,6 +1,6 @@
|
|||
using SkiaSharp;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Overlay
|
||||
namespace Ryujinx.UI.Overlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Text overlay element
|
Loading…
Add table
Add a link
Reference in a new issue