diff --git a/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs b/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs index 7e624152..aae01a0c 100644 --- a/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs +++ b/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs @@ -12,8 +12,8 @@ namespace Ryujinx.Headless.SDL2 private bool _canProcessInput; public event DynamicTextChangedHandler TextChangedEvent; - public event KeyPressedHandler KeyPressedEvent { add { } remove { } } - public event KeyReleasedHandler KeyReleasedEvent { add { } remove { } } + public event KeyPressedHandler KeyPressedEvent { add { } remove { } } + public event KeyReleasedHandler KeyReleasedEvent { add { } remove { } } public bool TextProcessingEnabled { @@ -48,4 +48,4 @@ namespace Ryujinx.Headless.SDL2 public void Dispose() { } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs b/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs index 4ef00b3c..361ef090 100644 --- a/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs +++ b/src/Ryujinx.Headless.SDL2/HeadlessHostUiTheme.cs @@ -6,12 +6,10 @@ namespace Ryujinx.Headless.SDL2 { public string FontFamily => "sans-serif"; - public ThemeColor DefaultBackgroundColor => new ThemeColor(1, 0, 0, 0); - public ThemeColor DefaultForegroundColor => new ThemeColor(1, 1, 1, 1); - public ThemeColor DefaultBorderColor => new ThemeColor(1, 1, 1, 1); - public ThemeColor SelectionBackgroundColor => new ThemeColor(1, 1, 1, 1); - public ThemeColor SelectionForegroundColor => new ThemeColor(1, 0, 0, 0); - - public HeadlessHostUiTheme() { } + public ThemeColor DefaultBackgroundColor => new(1, 0, 0, 0); + public ThemeColor DefaultForegroundColor => new(1, 1, 1, 1); + public ThemeColor DefaultBorderColor => new(1, 1, 1, 1); + public ThemeColor SelectionBackgroundColor => new(1, 1, 1, 1); + public ThemeColor SelectionForegroundColor => new(1, 0, 0, 0); } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs b/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs index dc7d811b..199f723e 100644 --- a/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs +++ b/src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs @@ -11,23 +11,31 @@ namespace Ryujinx.Headless.SDL2.OpenGL { class OpenGLWindow : WindowBase { + private static void CheckResult(int result) + { + if (result < 0) + { + throw new InvalidOperationException($"SDL_GL function returned an error: {SDL_GetError()}"); + } + } + private static void SetupOpenGLAttributes(bool sharedContext, GraphicsDebugLevel debugLevel) { - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_FLAGS, debugLevel != GraphicsDebugLevel.None ? (int)SDL_GLcontext.SDL_GL_CONTEXT_DEBUG_FLAG : 0); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, sharedContext ? 1 : 0); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 3)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_FLAGS, debugLevel != GraphicsDebugLevel.None ? (int)SDL_GLcontext.SDL_GL_CONTEXT_DEBUG_FLAG : 0)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, sharedContext ? 1 : 0)); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_ACCELERATED_VISUAL, 1); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_ALPHA_SIZE, 8); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_STENCIL_SIZE, 0); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_STEREO, 0); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_ACCELERATED_VISUAL, 1)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_RED_SIZE, 8)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_GREEN_SIZE, 8)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_BLUE_SIZE, 8)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_ALPHA_SIZE, 8)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_DEPTH_SIZE, 16)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_STENCIL_SIZE, 0)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1)); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_STEREO, 0)); } private class OpenToolkitBindingsContext : IBindingsContext @@ -40,9 +48,9 @@ namespace Ryujinx.Headless.SDL2.OpenGL private class SDL2OpenGLContext : IOpenGLContext { - private IntPtr _context; - private IntPtr _window; - private bool _shouldDisposeWindow; + private readonly IntPtr _context; + private readonly IntPtr _window; + private readonly bool _shouldDisposeWindow; public SDL2OpenGLContext(IntPtr context, IntPtr window, bool shouldDisposeWindow = true) { @@ -62,9 +70,9 @@ namespace Ryujinx.Headless.SDL2.OpenGL GL.LoadBindings(new OpenToolkitBindingsContext()); - SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 0); + CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 0)); - SDL_GL_MakeCurrent(windowHandle, IntPtr.Zero); + CheckResult(SDL_GL_MakeCurrent(windowHandle, IntPtr.Zero)); return new SDL2OpenGLContext(context, windowHandle); } @@ -99,7 +107,7 @@ namespace Ryujinx.Headless.SDL2.OpenGL } } - private GraphicsDebugLevel _glLogLevel; + private readonly GraphicsDebugLevel _glLogLevel; private SDL2OpenGLContext _openGLContext; public OpenGLWindow( @@ -120,7 +128,7 @@ namespace Ryujinx.Headless.SDL2.OpenGL // Ensure to not share this context with other contexts before this point. SetupOpenGLAttributes(false, _glLogLevel); IntPtr context = SDL_GL_CreateContext(WindowHandle); - SDL_GL_SetSwapInterval(1); + CheckResult(SDL_GL_SetSwapInterval(1)); if (context == IntPtr.Zero) { @@ -157,7 +165,7 @@ namespace Ryujinx.Headless.SDL2.OpenGL Device.DisposeGpu(); // Unbind context and destroy everything - SDL_GL_MakeCurrent(WindowHandle, IntPtr.Zero); + CheckResult(SDL_GL_MakeCurrent(WindowHandle, IntPtr.Zero)); _openGLContext.Dispose(); } @@ -166,4 +174,4 @@ namespace Ryujinx.Headless.SDL2.OpenGL SDL_GL_SwapWindow(WindowHandle); } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/Options.cs b/src/Ryujinx.Headless.SDL2/Options.cs index d7ad8cf7..86a6c63c 100644 --- a/src/Ryujinx.Headless.SDL2/Options.cs +++ b/src/Ryujinx.Headless.SDL2/Options.cs @@ -88,7 +88,7 @@ namespace Ryujinx.Headless.SDL2 // System [Option("disable-ptc", Required = false, HelpText = "Disables profiled persistent translation cache.")] - public bool DisablePtc { get; set; } + public bool DisablePTC { get; set; } [Option("enable-internet-connection", Required = false, Default = false, HelpText = "Enables guest Internet connection.")] public bool EnableInternetAccess { get; set; } @@ -100,7 +100,7 @@ namespace Ryujinx.Headless.SDL2 public int FsGlobalAccessLogMode { get; set; } [Option("disable-vsync", Required = false, HelpText = "Disables Vertical Sync.")] - public bool DisableVsync { get; set; } + public bool DisableVSync { get; set; } [Option("disable-shader-cache", Required = false, HelpText = "Disables Shader cache.")] public bool DisableShaderCache { get; set; } @@ -126,7 +126,7 @@ namespace Ryujinx.Headless.SDL2 [Option("memory-manager-mode", Required = false, Default = MemoryManagerMode.HostMappedUnsafe, HelpText = "The selected memory manager mode.")] public MemoryManagerMode MemoryManagerMode { get; set; } - [Option("audio-volume", Required = false, Default = 1.0f, HelpText ="The audio level (0 to 1).")] + [Option("audio-volume", Required = false, Default = 1.0f, HelpText = "The audio level (0 to 1).")] public float AudioVolume { get; set; } [Option("use-hypervisor", Required = false, Default = true, HelpText = "Uses Hypervisor over JIT if available.")] @@ -181,7 +181,7 @@ namespace Ryujinx.Headless.SDL2 [Option("backend-threading", Required = false, Default = BackendThreading.Auto, HelpText = "Whether or not backend threading is enabled. The \"Auto\" setting will determine whether threading should be enabled at runtime.")] public BackendThreading BackendThreading { get; set; } - [Option("disable-macro-hle", Required= false, HelpText = "Disables high-level emulation of Macro code. Leaving this enabled improves performance but may cause graphical glitches in some games.")] + [Option("disable-macro-hle", Required = false, HelpText = "Disables high-level emulation of Macro code. Leaving this enabled improves performance but may cause graphical glitches in some games.")] public bool DisableMacroHLE { get; set; } [Option("graphics-shaders-dump-path", Required = false, HelpText = "Dumps shaders in this local directory. (Developer only)")] @@ -191,12 +191,12 @@ namespace Ryujinx.Headless.SDL2 public GraphicsBackend GraphicsBackend { get; set; } [Option("preferred-gpu-vendor", Required = false, Default = "", HelpText = "When using the Vulkan backend, prefer using the GPU from the specified vendor.")] - public string PreferredGpuVendor { get; set; } + public string PreferredGPUVendor { get; set; } // Hacks [Option("expand-ram", Required = false, Default = false, HelpText = "Expands the RAM amount on the emulated system from 4GiB to 6GiB.")] - public bool ExpandRam { get; set; } + public bool ExpandRAM { get; set; } [Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")] public bool IgnoreMissingServices { get; set; } @@ -206,4 +206,4 @@ namespace Ryujinx.Headless.SDL2 [Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)] public string InputPath { get; set; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 6e6b4a7f..39eae14a 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -28,6 +28,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.Input; using Ryujinx.Input.HLE; using Ryujinx.Input.SDL2; +using Ryujinx.SDL2.Common; using Silk.NET.Vulkan; using System; using System.Collections.Generic; @@ -57,7 +58,7 @@ namespace Ryujinx.Headless.SDL2 private static bool _enableKeyboard; private static bool _enableMouse; - private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); + private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); static void Main(string[] args) { @@ -67,10 +68,10 @@ namespace Ryujinx.Headless.SDL2 if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) { - AutoResetEvent invoked = new AutoResetEvent(false); + AutoResetEvent invoked = new(false); // MacOS must perform SDL polls from the main thread. - Ryujinx.SDL2.Common.SDL2Driver.MainThreadDispatcher = (Action action) => + SDL2Driver.MainThreadDispatcher = action => { invoked.Reset(); @@ -140,53 +141,53 @@ namespace Ryujinx.Headless.SDL2 { config = new StandardKeyboardInputConfig { - Version = InputConfig.CurrentVersion, - Backend = InputBackendType.WindowKeyboard, - Id = null, - ControllerType = ControllerType.JoyconPair, - LeftJoycon = new LeftJoyconCommonConfig + Version = InputConfig.CurrentVersion, + Backend = InputBackendType.WindowKeyboard, + Id = null, + ControllerType = ControllerType.JoyconPair, + LeftJoycon = new LeftJoyconCommonConfig { - DpadUp = Key.Up, - DpadDown = Key.Down, - DpadLeft = Key.Left, - DpadRight = Key.Right, - ButtonMinus = Key.Minus, - ButtonL = Key.E, - ButtonZl = Key.Q, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound + DpadUp = Key.Up, + DpadDown = Key.Down, + DpadLeft = Key.Left, + DpadRight = Key.Right, + ButtonMinus = Key.Minus, + ButtonL = Key.E, + ButtonZl = Key.Q, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound, }, - LeftJoyconStick = new JoyconConfigKeyboardStick + LeftJoyconStick = new JoyconConfigKeyboardStick { - StickUp = Key.W, - StickDown = Key.S, - StickLeft = Key.A, - StickRight = Key.D, - StickButton = Key.F, + StickUp = Key.W, + StickDown = Key.S, + StickLeft = Key.A, + StickRight = Key.D, + StickButton = Key.F, }, - RightJoycon = new RightJoyconCommonConfig + RightJoycon = new RightJoyconCommonConfig { - ButtonA = Key.Z, - ButtonB = Key.X, - ButtonX = Key.C, - ButtonY = Key.V, - ButtonPlus = Key.Plus, - ButtonR = Key.U, - ButtonZr = Key.O, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound + ButtonA = Key.Z, + ButtonB = Key.X, + ButtonX = Key.C, + ButtonY = Key.V, + ButtonPlus = Key.Plus, + ButtonR = Key.U, + ButtonZr = Key.O, + ButtonSl = Key.Unbound, + ButtonSr = Key.Unbound, }, RightJoyconStick = new JoyconConfigKeyboardStick { - StickUp = Key.I, - StickDown = Key.K, - StickLeft = Key.J, - StickRight = Key.L, - StickButton = Key.H, - } + StickUp = Key.I, + StickDown = Key.K, + StickLeft = Key.J, + StickRight = Key.L, + StickButton = Key.H, + }, }; } else @@ -195,72 +196,72 @@ namespace Ryujinx.Headless.SDL2 config = new StandardControllerInputConfig { - Version = InputConfig.CurrentVersion, - Backend = InputBackendType.GamepadSDL2, - Id = null, - ControllerType = ControllerType.JoyconPair, - DeadzoneLeft = 0.1f, - DeadzoneRight = 0.1f, - RangeLeft = 1.0f, - RangeRight = 1.0f, + Version = InputConfig.CurrentVersion, + Backend = InputBackendType.GamepadSDL2, + Id = null, + ControllerType = ControllerType.JoyconPair, + DeadzoneLeft = 0.1f, + DeadzoneRight = 0.1f, + RangeLeft = 1.0f, + RangeRight = 1.0f, TriggerThreshold = 0.5f, LeftJoycon = new LeftJoyconCommonConfig { - DpadUp = ConfigGamepadInputId.DpadUp, - DpadDown = ConfigGamepadInputId.DpadDown, - DpadLeft = ConfigGamepadInputId.DpadLeft, - DpadRight = ConfigGamepadInputId.DpadRight, - ButtonMinus = ConfigGamepadInputId.Minus, - ButtonL = ConfigGamepadInputId.LeftShoulder, - ButtonZl = ConfigGamepadInputId.LeftTrigger, - ButtonSl = ConfigGamepadInputId.Unbound, - ButtonSr = ConfigGamepadInputId.Unbound, + DpadUp = ConfigGamepadInputId.DpadUp, + DpadDown = ConfigGamepadInputId.DpadDown, + DpadLeft = ConfigGamepadInputId.DpadLeft, + DpadRight = ConfigGamepadInputId.DpadRight, + ButtonMinus = ConfigGamepadInputId.Minus, + ButtonL = ConfigGamepadInputId.LeftShoulder, + ButtonZl = ConfigGamepadInputId.LeftTrigger, + ButtonSl = ConfigGamepadInputId.Unbound, + ButtonSr = ConfigGamepadInputId.Unbound, }, LeftJoyconStick = new JoyconConfigControllerStick { - Joystick = ConfigStickInputId.Left, - StickButton = ConfigGamepadInputId.LeftStick, + Joystick = ConfigStickInputId.Left, + StickButton = ConfigGamepadInputId.LeftStick, InvertStickX = false, InvertStickY = false, - Rotate90CW = false, + Rotate90CW = false, }, RightJoycon = new RightJoyconCommonConfig { - ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, - ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, - ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, - ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, - ButtonPlus = ConfigGamepadInputId.Plus, - ButtonR = ConfigGamepadInputId.RightShoulder, - ButtonZr = ConfigGamepadInputId.RightTrigger, - ButtonSl = ConfigGamepadInputId.Unbound, - ButtonSr = ConfigGamepadInputId.Unbound, + ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, + ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, + ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, + ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, + ButtonPlus = ConfigGamepadInputId.Plus, + ButtonR = ConfigGamepadInputId.RightShoulder, + ButtonZr = ConfigGamepadInputId.RightTrigger, + ButtonSl = ConfigGamepadInputId.Unbound, + ButtonSr = ConfigGamepadInputId.Unbound, }, RightJoyconStick = new JoyconConfigControllerStick { - Joystick = ConfigStickInputId.Right, - StickButton = ConfigGamepadInputId.RightStick, + Joystick = ConfigStickInputId.Right, + StickButton = ConfigGamepadInputId.RightStick, InvertStickX = false, InvertStickY = false, - Rotate90CW = false, + Rotate90CW = false, }, Motion = new StandardMotionConfigController { MotionBackend = MotionInputBackendType.GamepadDriver, EnableMotion = true, - Sensitivity = 100, + Sensitivity = 100, GyroDeadzone = 1, }, Rumble = new RumbleConfigController { StrongRumble = 1f, WeakRumble = 1f, - EnableRumble = false - } + EnableRumble = false, + }, }; } } @@ -288,7 +289,7 @@ namespace Ryujinx.Headless.SDL2 try { - config = JsonHelper.DeserializeFromFile(path, SerializerContext.InputConfig); + config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig); } catch (JsonException) { @@ -310,7 +311,7 @@ namespace Ryujinx.Headless.SDL2 { if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f) { - controllerConfig.RangeLeft = 1.0f; + controllerConfig.RangeLeft = 1.0f; controllerConfig.RangeRight = 1.0f; Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration"); @@ -387,7 +388,7 @@ namespace Ryujinx.Headless.SDL2 _enableKeyboard = option.EnableKeyboard; _enableMouse = option.EnableMouse; - void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) + static void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) { InputConfig inputConfig = HandlePlayerConfiguration(inputProfileName, inputId, index); @@ -468,19 +469,12 @@ namespace Ryujinx.Headless.SDL2 private static void ProgressHandler(T state, int current, int total) where T : Enum { - string label; - - switch (state) + string label = state switch { - case LoadState ptcState: - label = $"PTC : {current}/{total}"; - break; - case ShaderCacheState shaderCacheState: - label = $"Shaders : {current}/{total}"; - break; - default: - throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"); - } + LoadState => $"PTC : {current}/{total}", + ShaderCacheState => $"Shaders : {current}/{total}", + _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"), + }; Logger.Info?.Print(LogClass.Application, label); } @@ -499,9 +493,9 @@ namespace Ryujinx.Headless.SDL2 string preferredGpuId = string.Empty; Vk api = Vk.GetApi(); - if (!string.IsNullOrEmpty(options.PreferredGpuVendor)) + if (!string.IsNullOrEmpty(options.PreferredGPUVendor)) { - string preferredGpuVendor = options.PreferredGpuVendor.ToLowerInvariant(); + string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant(); var devices = VulkanRenderer.GetPhysicalDevices(api); foreach (var device in devices) @@ -520,10 +514,8 @@ namespace Ryujinx.Headless.SDL2 vulkanWindow.GetRequiredInstanceExtensions, preferredGpuId); } - else - { - return new OpenGLRenderer(); - } + + return new OpenGLRenderer(); } private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) @@ -537,31 +529,31 @@ namespace Ryujinx.Headless.SDL2 renderer = new ThreadedRenderer(renderer); } - HLEConfiguration configuration = new HLEConfiguration(_virtualFileSystem, - _libHacHorizonManager, - _contentManager, - _accountManager, - _userChannelPersistence, - renderer, - new SDL2HardwareDeviceDriver(), - options.ExpandRam ? MemoryConfiguration.MemoryConfiguration6GiB : MemoryConfiguration.MemoryConfiguration4GiB, - window, - options.SystemLanguage, - options.SystemRegion, - !options.DisableVsync, - !options.DisableDockedMode, - !options.DisablePtc, - options.EnableInternetAccess, - !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, - options.FsGlobalAccessLogMode, - options.SystemTimeOffset, - options.SystemTimeZone, - options.MemoryManagerMode, - options.IgnoreMissingServices, - options.AspectRatio, - options.AudioVolume, - options.UseHypervisor ?? true, - options.MultiplayerLanInterfaceId); + HLEConfiguration configuration = new(_virtualFileSystem, + _libHacHorizonManager, + _contentManager, + _accountManager, + _userChannelPersistence, + renderer, + new SDL2HardwareDeviceDriver(), + options.ExpandRAM ? MemoryConfiguration.MemoryConfiguration6GiB : MemoryConfiguration.MemoryConfiguration4GiB, + window, + options.SystemLanguage, + options.SystemRegion, + !options.DisableVSync, + !options.DisableDockedMode, + !options.DisablePTC, + options.EnableInternetAccess, + !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, + options.FsGlobalAccessLogMode, + options.SystemTimeOffset, + options.SystemTimeZone, + options.MemoryManagerMode, + options.IgnoreMissingServices, + options.AspectRatio, + options.AudioVolume, + options.UseHypervisor ?? true, + options.MultiplayerLanInterfaceId); return new Switch(configuration); } @@ -713,4 +705,4 @@ namespace Ryujinx.Headless.SDL2 return true; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs b/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs index 4ce8eafd..68443368 100644 --- a/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs +++ b/src/Ryujinx.Headless.SDL2/SDL2Mouse.cs @@ -87,4 +87,4 @@ namespace Ryujinx.Headless.SDL2 _driver = null; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/SDL2MouseDriver.cs b/src/Ryujinx.Headless.SDL2/SDL2MouseDriver.cs index 7b88e265..8983091f 100644 --- a/src/Ryujinx.Headless.SDL2/SDL2MouseDriver.cs +++ b/src/Ryujinx.Headless.SDL2/SDL2MouseDriver.cs @@ -1,4 +1,5 @@ -using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration; +using Ryujinx.Common.Logging; using Ryujinx.Input; using System; using System.Diagnostics; @@ -14,7 +15,7 @@ namespace Ryujinx.Headless.SDL2 private const int CursorHideIdleTime = 5; // seconds private bool _isDisposed; - private HideCursorMode _hideCursorMode; + private readonly HideCursorMode _hideCursorMode; private bool _isHidden; private long _lastCursorMoveTime; @@ -22,7 +23,7 @@ namespace Ryujinx.Headless.SDL2 public Vector2 CurrentPosition { get; private set; } public Vector2 Scroll { get; private set; } - public Size _clientSize; + public Size ClientSize; public SDL2MouseDriver(HideCursorMode hideCursorMode) { @@ -31,7 +32,11 @@ namespace Ryujinx.Headless.SDL2 if (_hideCursorMode == HideCursorMode.Always) { - SDL_ShowCursor(SDL_DISABLE); + if (SDL_ShowCursor(SDL_DISABLE) != SDL_DISABLE) + { + Logger.Error?.PrintMsg(LogClass.Application, "Failed to disable the cursor."); + } + _isHidden = true; } } @@ -46,7 +51,7 @@ namespace Ryujinx.Headless.SDL2 public void UpdatePosition() { - SDL_GetMouseState(out int posX, out int posY); + _ = SDL_GetMouseState(out int posX, out int posY); Vector2 position = new(posX, posY); if (CurrentPosition != position) @@ -71,7 +76,11 @@ namespace Ryujinx.Headless.SDL2 { if (!_isHidden) { - SDL_ShowCursor(SDL_DISABLE); + if (SDL_ShowCursor(SDL_DISABLE) != SDL_DISABLE) + { + Logger.Error?.PrintMsg(LogClass.Application, "Failed to disable the cursor."); + } + _isHidden = true; } } @@ -79,7 +88,11 @@ namespace Ryujinx.Headless.SDL2 { if (_isHidden) { - SDL_ShowCursor(SDL_ENABLE); + if (SDL_ShowCursor(SDL_ENABLE) != SDL_ENABLE) + { + Logger.Error?.PrintMsg(LogClass.Application, "Failed to enable the cursor."); + } + _isHidden = false; } } @@ -118,7 +131,7 @@ namespace Ryujinx.Headless.SDL2 public void SetClientSize(int width, int height) { - _clientSize = new Size(width, height); + ClientSize = new Size(width, height); } public bool IsButtonPressed(MouseButton button) @@ -128,7 +141,7 @@ namespace Ryujinx.Headless.SDL2 public Size GetClientSize() { - return _clientSize; + return ClientSize; } public string DriverName => "SDL2"; @@ -162,4 +175,4 @@ namespace Ryujinx.Headless.SDL2 _isDisposed = true; } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs b/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs index 5d048da1..f2f337a5 100644 --- a/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs +++ b/src/Ryujinx.Headless.SDL2/Vulkan/VulkanWindow.cs @@ -10,7 +10,7 @@ namespace Ryujinx.Headless.SDL2.Vulkan { class VulkanWindow : WindowBase { - private GraphicsDebugLevel _glLogLevel; + private readonly GraphicsDebugLevel _glLogLevel; public VulkanWindow( InputManager inputManager, @@ -33,16 +33,16 @@ namespace Ryujinx.Headless.SDL2.Vulkan MouseDriver.SetClientSize(DefaultWidth, DefaultHeight); } - private void BasicInvoke(Action action) + private static void BasicInvoke(Action action) { action(); } - public unsafe IntPtr CreateWindowSurface(IntPtr instance) + public IntPtr CreateWindowSurface(IntPtr instance) { ulong surfaceHandle = 0; - Action createSurface = () => + void CreateSurface() { if (SDL_Vulkan_CreateSurface(WindowHandle, instance, out surfaceHandle) == SDL_bool.SDL_FALSE) { @@ -52,15 +52,15 @@ namespace Ryujinx.Headless.SDL2.Vulkan throw new Exception(errorMessage); } - }; + } if (SDL2Driver.MainThreadDispatcher != null) { - SDL2Driver.MainThreadDispatcher(createSurface); + SDL2Driver.MainThreadDispatcher(CreateSurface); } else { - createSurface(); + CreateSurface(); } return (IntPtr)surfaceHandle; @@ -101,4 +101,4 @@ namespace Ryujinx.Headless.SDL2.Vulkan protected override void SwapBuffers() { } } -} \ No newline at end of file +} diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs index d163da22..2fcd00f8 100644 --- a/src/Ryujinx.Headless.SDL2/WindowBase.cs +++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs @@ -4,6 +4,8 @@ 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; using Ryujinx.HLE.Ui; @@ -30,7 +32,7 @@ namespace Ryujinx.Headless.SDL2 private const SDL_WindowFlags DefaultFlags = SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI | SDL_WindowFlags.SDL_WINDOW_RESIZABLE | SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS | SDL_WindowFlags.SDL_WINDOW_SHOWN; private const int TargetFps = 60; - private static ConcurrentQueue MainThreadActions = new ConcurrentQueue(); + private static readonly ConcurrentQueue _mainThreadActions = new(); [LibraryImport("SDL2")] // TODO: Remove this as soon as SDL2-CS was updated to expose this method publicly @@ -38,7 +40,7 @@ namespace Ryujinx.Headless.SDL2 public static void QueueMainThreadAction(Action action) { - MainThreadActions.Enqueue(action); + _mainThreadActions.Enqueue(action); } public NpadManager NpadManager { get; } @@ -55,9 +57,9 @@ namespace Ryujinx.Headless.SDL2 public int Height { get; private set; } protected SDL2MouseDriver MouseDriver; - private InputManager _inputManager; - private IKeyboard _keyboardInterface; - private GraphicsDebugLevel _glLogLevel; + private readonly InputManager _inputManager; + private readonly IKeyboard _keyboardInterface; + private readonly GraphicsDebugLevel _glLogLevel; private readonly Stopwatch _chrono; private readonly long _ticksPerFrame; private readonly CancellationTokenSource _gpuCancellationTokenSource; @@ -71,8 +73,8 @@ namespace Ryujinx.Headless.SDL2 private string _gpuVendorName; - private AspectRatio _aspectRatio; - private bool _enableMouse; + private readonly AspectRatio _aspectRatio; + private readonly bool _enableMouse; public WindowBase( InputManager inputManager, @@ -192,9 +194,6 @@ namespace Ryujinx.Headless.SDL2 case SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE: Exit(); break; - - default: - break; } } else @@ -260,7 +259,7 @@ namespace Ryujinx.Headless.SDL2 if (_ticks >= _ticksPerFrame) { string dockedMode = Device.System.State.DockedMode ? "Docked" : "Handheld"; - float scale = Graphics.Gpu.GraphicsConfig.ResScale; + float scale = GraphicsConfig.ResScale; if (scale != 1) { dockedMode += $" ({scale}x)"; @@ -309,9 +308,9 @@ namespace Ryujinx.Headless.SDL2 _exitEvent.Dispose(); } - public void ProcessMainThreadQueue() + public static void ProcessMainThreadQueue() { - while (MainThreadActions.TryDequeue(out Action action)) + while (_mainThreadActions.TryDequeue(out Action action)) { action(); } @@ -334,7 +333,7 @@ namespace Ryujinx.Headless.SDL2 _exitEvent.Set(); } - private void NVStutterWorkaround() + private void NvidiaStutterWorkaround() { while (_isActive) { @@ -348,7 +347,7 @@ namespace Ryujinx.Headless.SDL2 // TODO: This should be removed when the issue with the GateThread is resolved. - ThreadPool.QueueUserWorkItem((state) => { }); + ThreadPool.QueueUserWorkItem(state => { }); Thread.Sleep(300); } } @@ -396,20 +395,20 @@ namespace Ryujinx.Headless.SDL2 InitializeWindow(); - Thread renderLoopThread = new Thread(Render) + Thread renderLoopThread = new(Render) { - Name = "GUI.RenderLoop" + Name = "GUI.RenderLoop", }; renderLoopThread.Start(); - Thread nvStutterWorkaround = null; - if (Renderer is Graphics.OpenGL.OpenGLRenderer) + Thread nvidiaStutterWorkaround = null; + if (Renderer is OpenGLRenderer) { - nvStutterWorkaround = new Thread(NVStutterWorkaround) + nvidiaStutterWorkaround = new Thread(NvidiaStutterWorkaround) { - Name = "GUI.NVStutterWorkaround" + Name = "GUI.NvidiaStutterWorkaround", }; - nvStutterWorkaround.Start(); + nvidiaStutterWorkaround.Start(); } MainLoop(); @@ -418,7 +417,7 @@ namespace Ryujinx.Headless.SDL2 // We only need to wait for all commands submitted during the main gpu loop to be processed. _gpuDoneEvent.WaitOne(); _gpuDoneEvent.Dispose(); - nvStutterWorkaround?.Join(); + nvidiaStutterWorkaround?.Join(); Exit(); } @@ -465,13 +464,13 @@ namespace Ryujinx.Headless.SDL2 public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText) { - SDL_MessageBoxData data = new SDL_MessageBoxData + SDL_MessageBoxData data = new() { title = title, message = message, buttons = new SDL_MessageBoxButtonData[buttonsText.Length], numbuttons = buttonsText.Length, - window = WindowHandle + window = WindowHandle, }; for (int i = 0; i < buttonsText.Length; i++) @@ -479,7 +478,7 @@ namespace Ryujinx.Headless.SDL2 data.buttons[i] = new SDL_MessageBoxButtonData { buttonid = i, - text = buttonsText[i] + text = buttonsText[i], }; } @@ -509,4 +508,4 @@ namespace Ryujinx.Headless.SDL2 } } } -} \ No newline at end of file +}