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/HeadlessRyujinx.cs b/src/Ryujinx/Headless/HeadlessRyujinx.cs index 5730254f7..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); @@ -301,7 +299,10 @@ namespace Ryujinx.Headless _userChannelPersistence.ShouldRestart = false; } - _inputManager.Dispose(); + try + { + _inputManager.Dispose(); + } catch {} return; @@ -338,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) diff --git a/src/Ryujinx/Headless/Ryujinx.bmp b/src/Ryujinx/Headless/Ryujinx.bmp deleted file mode 100644 index 36bf2f8ac..000000000 Binary files a/src/Ryujinx/Headless/Ryujinx.bmp and /dev/null differ 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/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 96% rename from src/Ryujinx/Headless/OpenGL/OpenGLWindow.cs rename to src/Ryujinx/Headless/Windows/OpenGLWindow.cs index c00a0648f..117fe5780 100644 --- a/src/Ryujinx/Headless/OpenGL/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,15 +120,14 @@ namespace Ryujinx.Headless bool ignoreControllerApplet) : base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { - _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() { // 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/Vulkan/VulkanWindow.cs b/src/Ryujinx/Headless/Windows/VulkanWindow.cs similarity index 94% rename from src/Ryujinx/Headless/Vulkan/VulkanWindow.cs rename to src/Ryujinx/Headless/Windows/VulkanWindow.cs index 92caad34e..2abbbd1e9 100644 --- a/src/Ryujinx/Headless/Vulkan/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,10 +19,9 @@ namespace Ryujinx.Headless bool ignoreControllerApplet) : base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { - _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 93% rename from src/Ryujinx/Headless/WindowBase.cs rename to src/Ryujinx/Headless/Windows/WindowBase.cs index 4e6848449..c28ae33ce 100644 --- a/src/Ryujinx/Headless/WindowBase.cs +++ b/src/Ryujinx/Headless/Windows/WindowBase.cs @@ -1,12 +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.Account.Acc; @@ -54,8 +54,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; } @@ -73,7 +71,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 +103,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(); @@ -138,7 +136,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) @@ -164,6 +162,8 @@ namespace Ryujinx.Headless } } + private StatusUpdatedEventArgs _lastStatus; + private void InitializeWindow() { var activeProcess = Device.Processes.ActiveApplication; @@ -192,7 +192,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) { @@ -247,7 +247,7 @@ namespace Ryujinx.Headless protected abstract void SwapBuffers(); - public abstract SDL_WindowFlags GetWindowFlags(); + public abstract SDL_WindowFlags WindowFlags { get; } private string GetGpuDriverName() { @@ -269,7 +269,7 @@ namespace Ryujinx.Headless { InitializeWindowRenderer(); - Device.Gpu.Renderer.Initialize(_glLogLevel); + Device.Gpu.Renderer.Initialize(GlLogLevel); InitializeRenderer(); @@ -309,21 +309,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/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index 0a284e58b..8c72d5a3c 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -166,7 +166,6 @@ - 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); } } 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.")); + } + } } }