From 5f6949d9b0b213e6f8fc75137c54287e088cfb8a Mon Sep 17 00:00:00 2001
From: Thog <me@thog.eu>
Date: Tue, 18 Feb 2020 12:34:57 +0100
Subject: [PATCH] Improve rendering on resolution lower than 1080p (#944)

* Improve rendering on resolution lower than 1080p

* Apply scaling factor to the renderer (This fix 4K displays)
---
 Ryujinx/Ui/GLRenderer.cs    | 70 ++++++++++++++++++++++++++++---------
 Ryujinx/Ui/MainWindow.glade |  2 --
 2 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs
index 591a24dfa6..b8f9377c20 100644
--- a/Ryujinx/Ui/GLRenderer.cs
+++ b/Ryujinx/Ui/GLRenderer.cs
@@ -18,8 +18,8 @@ namespace Ryujinx.Ui
 {
     public class GLRenderer : GLWidget
     {
-        private const int TouchScreenWidth = 1280;
-        private const int TouchScreenHeight = 720;
+        private const int SwitchPanelWidth = 1280;
+        private const int SwitchPanelHeight = 720;
         private const int TargetFps = 60;
 
         public ManualResetEvent WaitEvent { get; set; }
@@ -52,9 +52,9 @@ namespace Ryujinx.Ui
 
         private Input.NpadController _primaryController;
 
-        public GLRenderer(Switch device) 
+        public GLRenderer(Switch device)
             : base (new GraphicsMode(new ColorFormat()),
-            3, 3, 
+            3, 3,
             GraphicsContextFlags.ForwardCompatible)
         {
             WaitEvent = new ManualResetEvent(false);
@@ -73,9 +73,9 @@ namespace Ryujinx.Ui
 
             _primaryController = new Input.NpadController(ConfigurationState.Instance.Hid.JoystickControls);
 
-            AddEvents((int)(Gdk.EventMask.ButtonPressMask 
-                          | Gdk.EventMask.ButtonReleaseMask 
-                          | Gdk.EventMask.PointerMotionMask 
+            AddEvents((int)(Gdk.EventMask.ButtonPressMask
+                          | Gdk.EventMask.ButtonReleaseMask
+                          | Gdk.EventMask.PointerMotionMask
                           | Gdk.EventMask.KeyPressMask
                           | Gdk.EventMask.KeyReleaseMask));
 
@@ -109,9 +109,9 @@ namespace Ryujinx.Ui
 
         public void HandleScreenState(KeyboardState keyboard)
         {
-            bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11) 
-                                || ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft) 
-                                ||   keyboard.IsKeyDown(OpenTK.Input.Key.AltRight)) 
+            bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11)
+                                || ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft)
+                                ||   keyboard.IsKeyDown(OpenTK.Input.Key.AltRight))
                                 &&   keyboard.IsKeyDown(OpenTK.Input.Key.Enter))
                                 || keyboard.IsKeyDown(OpenTK.Input.Key.Escape);
 
@@ -156,7 +156,9 @@ namespace Ryujinx.Ui
         {
             var result = base.OnConfigureEvent(evnt);
 
-            _renderer.Window.SetSize(AllocatedWidth, AllocatedHeight);
+            Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
+
+            _renderer.Window.SetSize(evnt.Width * monitor.ScaleFactor, evnt.Height * monitor.ScaleFactor);
 
             return result;
         }
@@ -226,6 +228,42 @@ namespace Ryujinx.Ui
             return false;
         }
 
+        protected override void OnGetPreferredHeight(out int minimumHeight, out int naturalHeight)
+        {
+            Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
+
+            // If the monitor is at least 1080p, use the Switch panel size as minimal size.
+            if (monitor.Geometry.Height >= 1080)
+            {
+                minimumHeight = SwitchPanelHeight;
+            }
+            // Otherwise, we default minimal size to 480p 16:9.
+            else
+            {
+                minimumHeight = 480;
+            }
+
+            naturalHeight = minimumHeight;
+        }
+
+        protected override void OnGetPreferredWidth(out int minimumWidth, out int naturalWidth)
+        {
+            Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
+
+            // If the monitor is at least 1080p, use the Switch panel size as minimal size.
+            if (monitor.Geometry.Height >= 1080)
+            {
+                minimumWidth = SwitchPanelWidth;
+            }
+            // Otherwise, we default minimal size to 480p 16:9.
+            else
+            {
+                minimumWidth = 854;
+            }
+
+            naturalWidth = minimumWidth;
+        }
+
         public void Exit()
         {
             if (IsStopped)
@@ -421,13 +459,13 @@ namespace Ryujinx.Ui
                 int screenWidth = AllocatedWidth;
                 int screenHeight = AllocatedHeight;
 
-                if (AllocatedWidth > (AllocatedHeight * TouchScreenWidth) / TouchScreenHeight)
+                if (AllocatedWidth > (AllocatedHeight * SwitchPanelWidth) / SwitchPanelHeight)
                 {
-                    screenWidth = (AllocatedHeight * TouchScreenWidth) / TouchScreenHeight;
+                    screenWidth = (AllocatedHeight * SwitchPanelWidth) / SwitchPanelHeight;
                 }
                 else
                 {
-                    screenHeight = (AllocatedWidth * TouchScreenHeight) / TouchScreenWidth;
+                    screenHeight = (AllocatedWidth * SwitchPanelHeight) / SwitchPanelWidth;
                 }
 
                 int startX = (AllocatedWidth - screenWidth) >> 1;
@@ -445,8 +483,8 @@ namespace Ryujinx.Ui
                     int screenMouseX = (int)_mouseX - startX;
                     int screenMouseY = (int)_mouseY - startY;
 
-                    int mX = (screenMouseX * TouchScreenWidth) / screenWidth;
-                    int mY = (screenMouseY * TouchScreenHeight) / screenHeight;
+                    int mX = (screenMouseX * SwitchPanelWidth) / screenWidth;
+                    int mY = (screenMouseY * SwitchPanelHeight) / screenHeight;
 
                     TouchPoint currentPoint = new TouchPoint
                     {
diff --git a/Ryujinx/Ui/MainWindow.glade b/Ryujinx/Ui/MainWindow.glade
index 6eeab7a41e..67bfdf0cde 100644
--- a/Ryujinx/Ui/MainWindow.glade
+++ b/Ryujinx/Ui/MainWindow.glade
@@ -363,8 +363,6 @@
             <property name="orientation">vertical</property>
             <child>
               <object class="GtkBox" id="_viewBox">
-                <property name="width_request">1280</property>
-                <property name="height_request">720</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="orientation">vertical</property>