From 6fc827fe67efcbc6f0a4dead1c08e8b4beaa4dc8 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:15:24 -0600 Subject: [PATCH 01/11] headless: collapse headless window definition into a "Windows" folder, change GetWindowFlags to an abstract property. --- src/Ryujinx/Headless/{Metal => Windows}/MetalWindow.cs | 2 +- src/Ryujinx/Headless/{OpenGL => Windows}/OpenGLWindow.cs | 2 +- src/Ryujinx/Headless/{Vulkan => Windows}/VulkanWindow.cs | 2 +- src/Ryujinx/Headless/{ => Windows}/WindowBase.cs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/Ryujinx/Headless/{Metal => Windows}/MetalWindow.cs (93%) rename src/Ryujinx/Headless/{OpenGL => Windows}/OpenGLWindow.cs (98%) rename src/Ryujinx/Headless/{Vulkan => Windows}/VulkanWindow.cs (97%) rename src/Ryujinx/Headless/{ => Windows}/WindowBase.cs (99%) diff --git a/src/Ryujinx/Headless/Metal/MetalWindow.cs b/src/Ryujinx/Headless/Windows/MetalWindow.cs similarity index 93% rename from src/Ryujinx/Headless/Metal/MetalWindow.cs rename to src/Ryujinx/Headless/Windows/MetalWindow.cs index a2693c69d..d79bd7938 100644 --- a/src/Ryujinx/Headless/Metal/MetalWindow.cs +++ b/src/Ryujinx/Headless/Windows/MetalWindow.cs @@ -26,7 +26,7 @@ namespace Ryujinx.Headless bool ignoreControllerApplet) : base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { } - public override SDL_WindowFlags GetWindowFlags() => SDL_WindowFlags.SDL_WINDOW_METAL; + public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_METAL; protected override void InitializeWindowRenderer() { diff --git a/src/Ryujinx/Headless/OpenGL/OpenGLWindow.cs b/src/Ryujinx/Headless/Windows/OpenGLWindow.cs similarity index 98% rename from src/Ryujinx/Headless/OpenGL/OpenGLWindow.cs rename to src/Ryujinx/Headless/Windows/OpenGLWindow.cs index c00a0648f..23c64ad4f 100644 --- a/src/Ryujinx/Headless/OpenGL/OpenGLWindow.cs +++ b/src/Ryujinx/Headless/Windows/OpenGLWindow.cs @@ -124,7 +124,7 @@ namespace Ryujinx.Headless _glLogLevel = glLogLevel; } - public override SDL_WindowFlags GetWindowFlags() => SDL_WindowFlags.SDL_WINDOW_OPENGL; + public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_OPENGL; protected override void InitializeWindowRenderer() { diff --git a/src/Ryujinx/Headless/Vulkan/VulkanWindow.cs b/src/Ryujinx/Headless/Windows/VulkanWindow.cs similarity index 97% rename from src/Ryujinx/Headless/Vulkan/VulkanWindow.cs rename to src/Ryujinx/Headless/Windows/VulkanWindow.cs index 92caad34e..5f6de94a5 100644 --- a/src/Ryujinx/Headless/Vulkan/VulkanWindow.cs +++ b/src/Ryujinx/Headless/Windows/VulkanWindow.cs @@ -24,7 +24,7 @@ namespace Ryujinx.Headless _glLogLevel = glLogLevel; } - public override SDL_WindowFlags GetWindowFlags() => SDL_WindowFlags.SDL_WINDOW_VULKAN; + public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_VULKAN; protected override void InitializeWindowRenderer() { } diff --git a/src/Ryujinx/Headless/WindowBase.cs b/src/Ryujinx/Headless/Windows/WindowBase.cs similarity index 99% rename from src/Ryujinx/Headless/WindowBase.cs rename to src/Ryujinx/Headless/Windows/WindowBase.cs index d89638cc1..b2d18fac1 100644 --- a/src/Ryujinx/Headless/WindowBase.cs +++ b/src/Ryujinx/Headless/Windows/WindowBase.cs @@ -191,7 +191,7 @@ namespace Ryujinx.Headless FullscreenFlag = SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP; } - WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), Width, Height, DefaultFlags | FullscreenFlag | GetWindowFlags()); + WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), Width, Height, DefaultFlags | FullscreenFlag | WindowFlags); if (WindowHandle == nint.Zero) { @@ -246,7 +246,7 @@ namespace Ryujinx.Headless protected abstract void SwapBuffers(); - public abstract SDL_WindowFlags GetWindowFlags(); + public abstract SDL_WindowFlags WindowFlags { get; } private string GetGpuDriverName() { From 6a291d41167d89d79c9df5ffda6fd7aa951c90a1 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:26:12 -0600 Subject: [PATCH 02/11] Headless: Use main UI logo for window icon instead of separate bmp --- src/Ryujinx/Assets/locales.json | 8 +++++--- src/Ryujinx/Headless/Ryujinx.bmp | Bin 3978 -> 0 bytes src/Ryujinx/Headless/Windows/WindowBase.cs | 3 ++- src/Ryujinx/Ryujinx.csproj | 1 - 4 files changed, 7 insertions(+), 5 deletions(-) delete mode 100644 src/Ryujinx/Headless/Ryujinx.bmp diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 1a42051b8..d320c935e 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -3946,7 +3946,8 @@ "zh_CN": "繁体中文(推荐)", "zh_TW": "正體中文 (建議)" } - }, { + }, + { "ID": "SettingsTabSystemSystemLanguageSwedish", "Translations": { "ar_SA": "", @@ -3970,7 +3971,8 @@ "zh_CN": "", "zh_TW": "" } - }, { + }, + { "ID": "SettingsTabSystemSystemLanguageNorwegian", "Translations": { "ar_SA": "", @@ -22896,4 +22898,4 @@ } } ] -} +} \ No newline at end of file diff --git a/src/Ryujinx/Headless/Ryujinx.bmp b/src/Ryujinx/Headless/Ryujinx.bmp deleted file mode 100644 index 36bf2f8ac129d43565ea345df7bb33b3b86e251b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3978 zcmb`}dr(x@836E)i8v*#uV|(=srEUUO#X6Nz+k7flXlualy=f2{i8{cec#6}%kHv@ zCb*+1J`pCdF)>d5$%B}X1vMce0Txtr#z!QXaS{^{d?1<&q8Jr*&-wbDyL(|5xauFd zeE3^!&)jHelc0Wcjb^G@1S$}-+>jxfxp*nl){{u`({pClTM-V|BLGa#0 zi#*IVX^3GmxO|mqN*{Y)X=iz%BX_{l%ziXE;c`%K@@#pSjk#AC$`|4&9g3se%(|3T z_RsJ!Djq$3M}GkYu|068>PcvNJqNmK7Q?v@7sFYK^ROv>I9L1E%rkZQ`90CR(CNCI%AWe1s@^(l)rn93ytbyb z@X?Q2UxfEM{&Ro%USpb>soPOD(6=Wa&erA6?XAoE-|0H*V0SbdyP_8CrZ}-HAGgMq z4F!*cvsWAq!J1h4JzeiDo~`uL`li&@$Wx4-8iqxs9DAaR9_p>ntx0&o%+}4$`h2Wv zDMH`jkXCXuY$-V&hDa=8?)FeGf6Kx59l3|dO|Ivt*-YjKWCjom?TEegc`L}gZMY)O z&iX~V>Fo$&@!_BrxF5Hb_E9_8ZM2VC$W5-LK8`aB9f-7+Cxw{^s;zF?P?)}sK$^Sy z;07q9rd~qvkMF;S=X!ggdSnDdPeo$n9^l~J&(mFDirOag6sCyosP(p}?P;-|6DHSdYnWm*)^jp5;RdMAK}$(zIVjgyCdFK7 zFrGp0q^ZhHHrI~v3sCe?)cOpR98$)9z;4eV6h0u0K!@O>X**tw(SFDb05aEy@k5?;ZN? z8+;W-PUs@d5Aiihj6WgAILK{eQuq#Vi&Vq3qQJ!3iavG*E@7am3D?D3$=r+_#pp-h zv302Qb)h_r8ohHZ$}pRyUgN)2eqdqs67wscv0srHp>WGB{C70Yv&}(}Hgc=Yj|0L; zT~9H0mXKM!55sRnNBcIlwjxiJOlb(oWx`#c{=oCSH+iW#z$(=vY@gc3!xUS|YgF5L z8TD~t@r^r~b{FO@bK>9xQ{2A`zFlMH@#bhc?JWFb1Gsvo-Jag%tG?V6A zq*}h9@Hw1Dwas*R(p^#8;5c*4o!lICN0`O)I-f#@jl9*AXOv+I#ROfDH@m`FB(uO~yzMW3?U&vhRJ;kTn{rGR23;#>r zY`2VA_GG?yGlQFUpzrwRwDmMRNu1f|1KKV5jwUhx!Lodr0JGL}2|kRD6C^E?%G>;>KMlF(ysvpnf;eyzL2B zyn`JT9Gn|iro+$6D7W7fIWUXzT|@DxTHXVJ4V~7~*Y*vBw?#*-G4lYH~A%NPw) zoMm*jT&6veM|j44o;_&_P1RRm&*l|CzO?y(Y{BRH*cQansOrpddDv%`;_OM zL~T>gY{MR8S{p!L*J&+Md|Bi482O7rzK`+l>}{||ti B6odc( diff --git a/src/Ryujinx/Headless/Windows/WindowBase.cs b/src/Ryujinx/Headless/Windows/WindowBase.cs index b2d18fac1..51bfcb214 100644 --- a/src/Ryujinx/Headless/Windows/WindowBase.cs +++ b/src/Ryujinx/Headless/Windows/WindowBase.cs @@ -1,6 +1,7 @@ using Humanizer; using LibHac.Tools.Fs; using Ryujinx.Ava; +using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Logging; @@ -137,7 +138,7 @@ namespace Ryujinx.Headless private void SetWindowIcon() { - Stream iconStream = typeof(Program).Assembly.GetManifestResourceStream("HeadlessLogo"); + Stream iconStream = EmbeddedResources.GetStream("Ryujinx/Assets/UIImages/Logo_Ryujinx.png"); byte[] iconBytes = new byte[iconStream!.Length]; if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length) diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index ab9a3696d..8929ba3eb 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -166,7 +166,6 @@ - From b08e5db6d871da8bb8ee593ba9058443c91fe0c7 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:30:19 -0600 Subject: [PATCH 03/11] Headless: Dispose of inputmanager in a catch-all try --- src/Ryujinx/Headless/HeadlessRyujinx.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.cs b/src/Ryujinx/Headless/HeadlessRyujinx.cs index 5730254f7..d5d6eb44d 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.cs @@ -301,7 +301,10 @@ namespace Ryujinx.Headless _userChannelPersistence.ShouldRestart = false; } - _inputManager.Dispose(); + try + { + _inputManager.Dispose(); + } catch {} return; From 80f44d95473271269d01422517c0e8d530c8709c Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:33:57 -0600 Subject: [PATCH 04/11] misc: chore: small cleanup --- src/Ryujinx/Headless/HeadlessRyujinx.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.cs b/src/Ryujinx/Headless/HeadlessRyujinx.cs index d5d6eb44d..787aaca62 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.cs @@ -228,8 +228,6 @@ namespace Ryujinx.Headless _inputConfiguration ??= []; _enableKeyboard = option.EnableKeyboard; _enableMouse = option.EnableMouse; - - LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1); LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); @@ -341,12 +339,12 @@ namespace Ryujinx.Headless { string label = state switch { - LoadState => $"PTC : {current}/{total}", - ShaderCacheState => $"Shaders : {current}/{total}", - _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"), + LoadState => "PTC", + ShaderCacheState => "Shaders", + _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}") }; - Logger.Info?.Print(LogClass.Application, label); + Logger.Info?.Print(LogClass.Application, $"{label} : {current}/{total}"); } private static WindowBase CreateWindow(Options options) From 2f93a0f706701e6b4c392ff1c1e64f20957402bb Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:38:29 -0600 Subject: [PATCH 05/11] infra: Conditionally compile Metal & OpenGL depending on if the target RuntimeIdentifier is mac --- src/Ryujinx/Ryujinx.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 8929ba3eb..682a08475 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -72,8 +72,8 @@ - - + + From beda3206e0a17ff8807fff1bbe014b24c2683e3d Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:52:32 -0600 Subject: [PATCH 06/11] Only selectively compile Metal & fix some compilation issues --- src/Ryujinx/AppHost.cs | 2 +- src/Ryujinx/Headless/HeadlessRyujinx.Init.cs | 6 ++---- src/Ryujinx/Ryujinx.csproj | 2 +- src/Ryujinx/UI/Renderer/EmbeddedWindow.cs | 3 +-- src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs | 2 ++ 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index a35a79e86..e3a35376c 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -897,7 +897,7 @@ namespace Ryujinx.Ava { #pragma warning disable CA1416 // This call site is reachable on all platforms // SelectGraphicsBackend does a check for Mac, on top of checking if it's an ARM Mac. This isn't a problem. - GraphicsBackend.Metal => new MetalRenderer((RendererHost.EmbeddedWindow as EmbeddedWindowMetal)!.CreateSurface), + GraphicsBackend.Metal => new MetalRenderer(() => new SharpMetal.QuartzCore.CAMetalLayer(((EmbeddedWindowMetal)RendererHost.EmbeddedWindow).MetalLayer)), #pragma warning restore CA1416 GraphicsBackend.Vulkan => VulkanRenderer.Create( ConfigurationState.Instance.Graphics.PreferredGpu, diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs index 7d75ac7c1..e92a56833 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs @@ -12,8 +12,6 @@ using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; -using Ryujinx.Graphics.Metal; -using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; using Ryujinx.Input; @@ -312,10 +310,10 @@ namespace Ryujinx.Headless if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS()) { - return new MetalRenderer(metalWindow.GetLayer); + return new Graphics.Metal.MetalRenderer(metalWindow.GetLayer); } - return new OpenGLRenderer(); + return new Graphics.OpenGL.OpenGLRenderer(); } private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 682a08475..c7cdef14c 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -72,7 +72,7 @@ - + diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs index eea9be283..87b66e4f3 100644 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs +++ b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs @@ -1,6 +1,5 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.Input; using Avalonia.Platform; using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common.Configuration; @@ -28,7 +27,7 @@ namespace Ryujinx.Ava.UI.Renderer protected nint WindowHandle { get; set; } protected nint X11Display { get; set; } protected nint NsView { get; set; } - protected nint MetalLayer { get; set; } + public nint MetalLayer { get; protected set; } public delegate void UpdateBoundsCallbackDelegate(Rect rect); private UpdateBoundsCallbackDelegate _updateBoundsCallback; diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs index eaf6f7bdf..7a2932075 100644 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs +++ b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs @@ -1,8 +1,10 @@ using SharpMetal.QuartzCore; using System; +using System.Runtime.Versioning; namespace Ryujinx.Ava.UI.Renderer { + [SupportedOSPlatform("macos")] public class EmbeddedWindowMetal : EmbeddedWindow { public CAMetalLayer CreateSurface() From e6bad52945e7e35e9aee7bd5b49a0918dd28a0e0 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:56:58 -0600 Subject: [PATCH 07/11] Revert "Only selectively compile Metal & fix some compilation issues" This reverts commit beda3206e0a17ff8807fff1bbe014b24c2683e3d. --- src/Ryujinx/AppHost.cs | 2 +- src/Ryujinx/Headless/HeadlessRyujinx.Init.cs | 6 ++++-- src/Ryujinx/Ryujinx.csproj | 2 +- src/Ryujinx/UI/Renderer/EmbeddedWindow.cs | 3 ++- src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs | 2 -- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index e3a35376c..a35a79e86 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -897,7 +897,7 @@ namespace Ryujinx.Ava { #pragma warning disable CA1416 // This call site is reachable on all platforms // SelectGraphicsBackend does a check for Mac, on top of checking if it's an ARM Mac. This isn't a problem. - GraphicsBackend.Metal => new MetalRenderer(() => new SharpMetal.QuartzCore.CAMetalLayer(((EmbeddedWindowMetal)RendererHost.EmbeddedWindow).MetalLayer)), + GraphicsBackend.Metal => new MetalRenderer((RendererHost.EmbeddedWindow as EmbeddedWindowMetal)!.CreateSurface), #pragma warning restore CA1416 GraphicsBackend.Vulkan => VulkanRenderer.Create( ConfigurationState.Instance.Graphics.PreferredGpu, diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs index e92a56833..7d75ac7c1 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs @@ -12,6 +12,8 @@ using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; +using Ryujinx.Graphics.Metal; +using Ryujinx.Graphics.OpenGL; using Ryujinx.Graphics.Vulkan; using Ryujinx.HLE; using Ryujinx.Input; @@ -310,10 +312,10 @@ namespace Ryujinx.Headless if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS()) { - return new Graphics.Metal.MetalRenderer(metalWindow.GetLayer); + return new MetalRenderer(metalWindow.GetLayer); } - return new Graphics.OpenGL.OpenGLRenderer(); + return new OpenGLRenderer(); } private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index c7cdef14c..682a08475 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -72,7 +72,7 @@ - + diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs index 87b66e4f3..eea9be283 100644 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs +++ b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Input; using Avalonia.Platform; using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common.Configuration; @@ -27,7 +28,7 @@ namespace Ryujinx.Ava.UI.Renderer protected nint WindowHandle { get; set; } protected nint X11Display { get; set; } protected nint NsView { get; set; } - public nint MetalLayer { get; protected set; } + protected nint MetalLayer { get; set; } public delegate void UpdateBoundsCallbackDelegate(Rect rect); private UpdateBoundsCallbackDelegate _updateBoundsCallback; diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs index 7a2932075..eaf6f7bdf 100644 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs +++ b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs @@ -1,10 +1,8 @@ using SharpMetal.QuartzCore; using System; -using System.Runtime.Versioning; namespace Ryujinx.Ava.UI.Renderer { - [SupportedOSPlatform("macos")] public class EmbeddedWindowMetal : EmbeddedWindow { public CAMetalLayer CreateSurface() From 580b150c9a1da8403f7e903caf47d7b775f9ff8e Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 10:57:02 -0600 Subject: [PATCH 08/11] Revert "infra: Conditionally compile Metal & OpenGL depending on if the target RuntimeIdentifier is mac" This reverts commit 2f93a0f706701e6b4c392ff1c1e64f20957402bb. --- src/Ryujinx/Ryujinx.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 682a08475..8929ba3eb 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -72,8 +72,8 @@ - - + + From ade2f256e0abd0064410e01c35b29b6f662c70b5 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 11:19:38 -0600 Subject: [PATCH 09/11] misc: chore: remove duplicate graphics debug levels in headless windows --- src/Ryujinx/Headless/Windows/OpenGLWindow.cs | 6 ++---- src/Ryujinx/Headless/Windows/VulkanWindow.cs | 3 --- src/Ryujinx/Headless/Windows/WindowBase.cs | 6 +++--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Ryujinx/Headless/Windows/OpenGLWindow.cs b/src/Ryujinx/Headless/Windows/OpenGLWindow.cs index 23c64ad4f..117fe5780 100644 --- a/src/Ryujinx/Headless/Windows/OpenGLWindow.cs +++ b/src/Ryujinx/Headless/Windows/OpenGLWindow.cs @@ -108,8 +108,7 @@ namespace Ryujinx.Headless } } } - - private readonly GraphicsDebugLevel _glLogLevel; + private SDL2OpenGLContext _openGLContext; public OpenGLWindow( @@ -121,7 +120,6 @@ namespace Ryujinx.Headless bool ignoreControllerApplet) : base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { - _glLogLevel = glLogLevel; } public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_OPENGL; @@ -129,7 +127,7 @@ namespace Ryujinx.Headless protected override void InitializeWindowRenderer() { // Ensure to not share this context with other contexts before this point. - SetupOpenGLAttributes(false, _glLogLevel); + SetupOpenGLAttributes(false, GlLogLevel); nint context = SDL_GL_CreateContext(WindowHandle); CheckResult(SDL_GL_SetSwapInterval(1)); diff --git a/src/Ryujinx/Headless/Windows/VulkanWindow.cs b/src/Ryujinx/Headless/Windows/VulkanWindow.cs index 5f6de94a5..2abbbd1e9 100644 --- a/src/Ryujinx/Headless/Windows/VulkanWindow.cs +++ b/src/Ryujinx/Headless/Windows/VulkanWindow.cs @@ -10,8 +10,6 @@ namespace Ryujinx.Headless { class VulkanWindow : WindowBase { - private readonly GraphicsDebugLevel _glLogLevel; - public VulkanWindow( InputManager inputManager, GraphicsDebugLevel glLogLevel, @@ -21,7 +19,6 @@ namespace Ryujinx.Headless bool ignoreControllerApplet) : base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { - _glLogLevel = glLogLevel; } public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_VULKAN; diff --git a/src/Ryujinx/Headless/Windows/WindowBase.cs b/src/Ryujinx/Headless/Windows/WindowBase.cs index 51bfcb214..eea01763a 100644 --- a/src/Ryujinx/Headless/Windows/WindowBase.cs +++ b/src/Ryujinx/Headless/Windows/WindowBase.cs @@ -73,7 +73,7 @@ namespace Ryujinx.Headless protected SDL2MouseDriver MouseDriver; private readonly InputManager _inputManager; private readonly IKeyboard _keyboardInterface; - private readonly GraphicsDebugLevel _glLogLevel; + protected readonly GraphicsDebugLevel GlLogLevel; private readonly Stopwatch _chrono; private readonly long _ticksPerFrame; private readonly CancellationTokenSource _gpuCancellationTokenSource; @@ -105,7 +105,7 @@ namespace Ryujinx.Headless NpadManager = _inputManager.CreateNpadManager(); TouchScreenManager = _inputManager.CreateTouchScreenManager(); _keyboardInterface = (IKeyboard)_inputManager.KeyboardDriver.GetGamepad("0"); - _glLogLevel = glLogLevel; + GlLogLevel = glLogLevel; _chrono = new Stopwatch(); _ticksPerFrame = Stopwatch.Frequency / TargetFps; _gpuCancellationTokenSource = new CancellationTokenSource(); @@ -269,7 +269,7 @@ namespace Ryujinx.Headless { InitializeWindowRenderer(); - Device.Gpu.Renderer.Initialize(_glLogLevel); + Device.Gpu.Renderer.Initialize(GlLogLevel); InitializeRenderer(); From 6fca4492d04827df53a70984c43a1f29f8774423 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 15:15:08 -0600 Subject: [PATCH 10/11] misc: chore: Remove status update event stuff in Headless --- .../Headless/StatusUpdatedEventArgs.cs | 21 ------------------ src/Ryujinx/Headless/Windows/WindowBase.cs | 22 +++---------------- .../UI/Models/StatusUpdatedEventArgs.cs | 17 ++++++++++++++ 3 files changed, 20 insertions(+), 40 deletions(-) delete mode 100644 src/Ryujinx/Headless/StatusUpdatedEventArgs.cs diff --git a/src/Ryujinx/Headless/StatusUpdatedEventArgs.cs b/src/Ryujinx/Headless/StatusUpdatedEventArgs.cs deleted file mode 100644 index 6c76a43a1..000000000 --- a/src/Ryujinx/Headless/StatusUpdatedEventArgs.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Ryujinx.Headless -{ - class StatusUpdatedEventArgs( - string vSyncMode, - string dockedMode, - string aspectRatio, - string gameStatus, - string fifoStatus, - string gpuName) - : EventArgs - { - public string VSyncMode = vSyncMode; - public string DockedMode = dockedMode; - public string AspectRatio = aspectRatio; - public string GameStatus = gameStatus; - public string FifoStatus = fifoStatus; - public string GpuName = gpuName; - } -} diff --git a/src/Ryujinx/Headless/Windows/WindowBase.cs b/src/Ryujinx/Headless/Windows/WindowBase.cs index eea01763a..2ce8ad82b 100644 --- a/src/Ryujinx/Headless/Windows/WindowBase.cs +++ b/src/Ryujinx/Headless/Windows/WindowBase.cs @@ -1,13 +1,12 @@ using Humanizer; -using LibHac.Tools.Fs; using Ryujinx.Ava; +using Ryujinx.Ava.UI.Models; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; -using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.OpenGL; using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types; @@ -54,8 +53,6 @@ namespace Ryujinx.Headless public Switch Device { get; private set; } public IRenderer Renderer { get; private set; } - public event EventHandler StatusUpdatedEvent; - protected nint WindowHandle { get; set; } public IHostUITheme HostUITheme { get; } @@ -164,6 +161,8 @@ namespace Ryujinx.Headless } } + private StatusUpdatedEventArgs _lastStatus; + private void InitializeWindow() { var activeProcess = Device.Processes.ActiveApplication; @@ -309,21 +308,6 @@ namespace Ryujinx.Headless if (_ticks >= _ticksPerFrame) { - string dockedMode = Device.System.State.DockedMode ? "Docked" : "Handheld"; - float scale = GraphicsConfig.ResScale; - if (scale != 1) - { - dockedMode += $" ({scale}x)"; - } - - StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs( - Device.VSyncMode.ToString(), - dockedMode, - Device.Configuration.AspectRatio.ToText(), - $"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", - $"FIFO: {Device.Statistics.GetFifoPercent():0.00} %", - $"GPU: {_gpuDriverName}")); - _ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame); } } diff --git a/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs index 6f0f5ab5d..9755aad46 100644 --- a/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs +++ b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs @@ -22,5 +22,22 @@ namespace Ryujinx.Ava.UI.Models FifoStatus = fifoStatus; ShaderCount = shaderCount; } + + + public override bool Equals(object obj) + { + if (obj is not StatusUpdatedEventArgs suea) return false; + return + VSyncMode == suea.VSyncMode && + VolumeStatus == suea.VolumeStatus && + DockedMode == suea.DockedMode && + AspectRatio == suea.AspectRatio && + GameStatus == suea.GameStatus && + FifoStatus == suea.FifoStatus && + ShaderCount == suea.ShaderCount; + } + + public override int GetHashCode() + => HashCode.Combine(VSyncMode, VolumeStatus, AspectRatio, DockedMode, FifoStatus, GameStatus, ShaderCount); } } From 4868fface808dfc3a71d032712d782cc3c7c6507 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 18 Jan 2025 15:33:05 -0600 Subject: [PATCH 11/11] UI: Intel Mac warning Upon launch, shows a warning about using an Intel Mac. This will only show once every boot. You can only turn it off by getting a better system. --- src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index 2aaac4098..5a5fb502e 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Linq; +using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -136,6 +137,8 @@ namespace Ryujinx.Ava.UI.Windows base.OnApplyTemplate(e); NotificationHelper.SetNotificationManager(this); + + ShowIntelMacWarningAsync(); } private void OnScalingChanged(object sender, EventArgs e) @@ -731,5 +734,22 @@ namespace Ryujinx.Ava.UI.Windows (int)Symbol.Checkmark); }); } + + private static bool _intelMacWarningShown; + + public static async Task ShowIntelMacWarningAsync() + { + if (!_intelMacWarningShown && + (OperatingSystem.IsMacOS() && + (RuntimeInformation.OSArchitecture == Architecture.X64 || + RuntimeInformation.OSArchitecture == Architecture.X86))) + { + _intelMacWarningShown = true; + + await Dispatcher.UIThread.InvokeAsync(async () => await ContentDialogHelper.CreateWarningDialog( + "Intel Mac Warning", + "Intel Macs are not supported and will not work properly.\nIf you continue, do not come to our Discord asking for support.")); + } + } } }