Răsfoiți Sursa

Headless: Add support for fullscreen option (#5339)

* Headless: Added support for fullscreen option

* Headless: cleanup of fullscreen support

* Headless: fullscreen support : implemented proposed changes

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: fix for OpenGL scaling

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: add. macOS fullscreen fix

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup

* Headless: fullscreen support: cleanup
Theun de Bruijn 2 ani în urmă
părinte
comite
c19c8bbade

+ 16 - 2
src/Ryujinx.Headless.SDL2/OpenGL/OpenGLWindow.cs

@@ -151,8 +151,22 @@ namespace Ryujinx.Headless.SDL2.OpenGL
             GL.Clear(ClearBufferMask.ColorBufferBit);
             SwapBuffers();
 
-            Renderer?.Window.SetSize(DefaultWidth, DefaultHeight);
-            MouseDriver.SetClientSize(DefaultWidth, DefaultHeight);
+            if (IsFullscreen)
+            {
+                // NOTE: grabbing the main display's dimensions directly as OpenGL doesn't scale along like the VulkanWindow.
+                // we might have to amend this if people run this on a non-primary display set to a different resolution.
+                SDL_Rect displayBounds;
+                SDL_GetDisplayBounds(0, out displayBounds);
+
+                Renderer?.Window.SetSize(displayBounds.w, displayBounds.h);
+                MouseDriver.SetClientSize(displayBounds.w, displayBounds.h);
+            }
+
+            else
+            {
+                Renderer?.Window.SetSize(DefaultWidth, DefaultHeight);
+                MouseDriver.SetClientSize(DefaultWidth, DefaultHeight);
+            }
         }
 
         protected override void InitializeRenderer() { }

+ 3 - 0
src/Ryujinx.Headless.SDL2/Options.cs

@@ -14,6 +14,9 @@ namespace Ryujinx.Headless.SDL2
         [Option("profile", Required = false, HelpText = "Set the user profile to launch the game with.")]
         public string UserProfile { get; set; }
 
+        [Option("fullscreen", Required = false, HelpText = "Launch the game in fullscreen mode.")]
+        public bool IsFullscreen { get; set; }
+
         // Input
 
         [Option("input-profile-1", Required = false, HelpText = "Set the input profile in use for Player 1.")]

+ 5 - 0
src/Ryujinx.Headless.SDL2/Program.cs

@@ -64,6 +64,9 @@ namespace Ryujinx.Headless.SDL2
         {
             Version = ReleaseInformation.GetVersion();
 
+            // Make process DPI aware for proper window sizing on high-res screens.
+            ForceDpiAware.Windows();
+
             Console.Title = $"Ryujinx Console {Version} (Headless SDL2)";
 
             if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
@@ -592,6 +595,8 @@ namespace Ryujinx.Headless.SDL2
 
             _window = window;
 
+            _window.IsFullscreen = options.IsFullscreen;
+
             _emulationContext = InitializeEmulationContext(window, renderer, options);
 
             SystemVersion firmwareVersion = _contentManager.GetCurrentFirmwareVersion();

+ 14 - 5
src/Ryujinx.Headless.SDL2/WindowBase.cs

@@ -55,6 +55,7 @@ namespace Ryujinx.Headless.SDL2
         public IHostUiTheme HostUiTheme { get; }
         public int Width { get; private set; }
         public int Height { get; private set; }
+        public bool IsFullscreen { get; set; }
 
         protected SDL2MouseDriver MouseDriver;
         private readonly InputManager _inputManager;
@@ -158,7 +159,9 @@ namespace Ryujinx.Headless.SDL2
             string titleIdSection = string.IsNullOrWhiteSpace(activeProcess.ProgramIdText) ? string.Empty : $" ({activeProcess.ProgramIdText.ToUpper()})";
             string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)";
 
-            WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, DefaultFlags | GetWindowFlags());
+            SDL_WindowFlags fullscreenFlag = IsFullscreen ? SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
+
+            WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DefaultWidth, DefaultHeight, DefaultFlags | fullscreenFlag | GetWindowFlags());
 
             if (WindowHandle == IntPtr.Zero)
             {
@@ -185,10 +188,16 @@ namespace Ryujinx.Headless.SDL2
                 switch (evnt.window.windowEvent)
                 {
                     case SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
-                        Width = evnt.window.data1;
-                        Height = evnt.window.data2;
-                        Renderer?.Window.SetSize(Width, Height);
-                        MouseDriver.SetClientSize(Width, Height);
+                        // Unlike on Windows, this event fires on macOS when triggering fullscreen mode.
+                        // And promptly crashes the process because `Renderer?.window.SetSize` is undefined.
+                        // As we don't need this to fire in either case we can test for isFullscreen.
+                        if (!IsFullscreen)
+                        {
+                            Width = evnt.window.data1;
+                            Height = evnt.window.data2;
+                            Renderer?.Window.SetSize(Width, Height);
+                            MouseDriver.SetClientSize(Width, Height);
+                        }
                         break;
 
                     case SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE: