shithub: choc

Download patch

ref: dd9fa2865d5362abf1e0fa8dd15658f91164e26a
parent: 5d838b88a73c3299fc3472c202718e868fc3c9bd
author: Simon Howard <fraggle@soulsphere.org>
date: Sat Feb 27 17:38:55 EST 2016

video: Add support for OS X high-DPI rendering.

This gives extra resolution when using a Mac with a retina display, and
can actually make a significant difference in terms of quality,
especially when using small window sizes.

--- a/src/i_video.c
+++ b/src/i_video.c
@@ -436,14 +436,23 @@
 
 }
 
-static void CreateUpscaledTexture(int w, int h)
+static void CreateUpscaledTexture(void)
 {
     const int actualheight = aspect_ratio_correct ?
                              SCREENHEIGHT_4_3 :
                              SCREENHEIGHT;
+    int w, h;
     int h_upscale, w_upscale;
     static int h_upscale_old, w_upscale_old;
 
+    // Get the size of the renderer output. The units this gives us will be
+    // real world pixels, which are not necessarily equivalent to the screen's
+    // window size (because of highdpi).
+    if (SDL_GetRendererOutputSize(renderer, &w, &h) != 0)
+    {
+        I_Error("Failed to get renderer output size: %s", SDL_GetError());
+    }
+
     // When the screen or window dimensions do not match the aspect ratio
     // of the texture, the rendered area is scaled down to fit. Calculate
     // the actual dimensions of the rendered area.
@@ -461,35 +470,36 @@
         w = h * SCREENWIDTH / actualheight;
     }
 
+    // Pick texture size the next integer multiple of the screen dimensions.
     // If one screen dimension matches an integer multiple of the original
     // resolution, there is no need to overscale in this direction.
 
-    h_upscale = h / SCREENHEIGHT;
+    w_upscale = (w + SCREENWIDTH - 1) / SCREENWIDTH;
+    h_upscale = (h + SCREENHEIGHT - 1) / SCREENHEIGHT;
 
-    if (!h || h % SCREENHEIGHT)
+    // Minimum texture dimensions of 320x200.
+
+    if (w_upscale < 1)
     {
-        h_upscale++;
+        w_upscale = 1;
     }
-
-    w_upscale = w / SCREENWIDTH;
-
-    if (!w || w % SCREENWIDTH)
+    if (h_upscale < 1)
     {
-        w_upscale++;
+        h_upscale = 1;
     }
 
     // Limit maximum texture dimensions to 1600x1200.
+    // It's really diminishing returns at this point.
 
+    if (w_upscale > 5)
+    {
+        w_upscale = 5;
+    }
     if (h_upscale > 6)
     {
         h_upscale = 6;
     }
 
-    if (w_upscale > 5)
-    {
-        w_upscale = 5;
-    }
-
     // Create a new texture only if the upscale factors have actually changed.
 
     if (h_upscale == h_upscale_old && w_upscale == w_upscale_old)
@@ -535,7 +545,7 @@
 
     if (need_resize && SDL_GetTicks() > last_resize_time + 1000/TICRATE)
     {
-        CreateUpscaledTexture(resize_w, resize_h);
+        CreateUpscaledTexture();
         screen_width = resize_w;
         screen_height = resize_h;
         need_resize = false;
@@ -977,6 +987,10 @@
         flags |= SDL_WINDOW_RESIZABLE;
     }
 
+    // Set the highdpi flag - this makes a big difference on Macs with
+    // retina displays, especially when using small window sizes.
+    flags |= SDL_WINDOW_ALLOW_HIGHDPI;
+
     // Create window and renderer contexts. We set the window title
     // later anyway and leave the window position "undefined". If "flags"
     // contains the fullscreen flag (see above), then w and h are ignored.
@@ -1065,7 +1079,7 @@
 
     // Initially create the upscaled texture for rendering to screen
 
-    CreateUpscaledTexture(w, h);
+    CreateUpscaledTexture();
 }
 
 void I_InitGraphics(void)