sdl12-compat: Use the same logical scaling for OpenGL that SDL2's Render API uses.

From 916210f1bfc781147b3c4ddebc74d0d69d29f438 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Thu, 29 Apr 2021 11:38:18 -0400
Subject: [PATCH] Use the same logical scaling for OpenGL that SDL2's Render
 API uses.

---
 src/SDL12_compat.c | 35 +++++++++++++++++++++++++----------
 src/SDL20_syms.h   |  2 ++
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index 09f9fb2..2562bf9 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -4424,22 +4424,37 @@ SDL_GL_SwapBuffers(void)
         if (OpenGLLogicalScalingFBO != 0) {
             const GLboolean has_scissor = OpenGLFuncs.glIsEnabled(GL_SCISSOR_TEST);
             GLfloat clearcolor[4];
-            int scaledh, scaledw;
-            int centeredx, centeredy;
+            float want_aspect, real_aspect;
             int drawablew, drawableh;
+            SDL_Rect dstrect;
 
             SDL20_GL_GetDrawableSize(VideoWindow20, &drawablew, &drawableh);
             OpenGLFuncs.glGetFloatv(GL_COLOR_CLEAR_VALUE, clearcolor);
 
-            if (drawablew < drawableh) {
-                scaledw = drawablew;
-                scaledh = (int) (((((double)OpenGLLogicalScalingHeight) / ((double)OpenGLLogicalScalingWidth))) * ((double)drawablew));
+            want_aspect = ((float) OpenGLLogicalScalingWidth) / ((float) OpenGLLogicalScalingHeight);
+            real_aspect = ((float) drawablew) / ((float) drawableh);
+
+            if (SDL20_fabsf(want_aspect-real_aspect) < 0.0001f) {
+                /* The aspect ratios are the same, just scale appropriately */
+                dstrect.x = 0;
+                dstrect.y = 0;
+                dstrect.w = drawablew;
+                dstrect.h = drawableh;
+            } else if (want_aspect > real_aspect) {
+                /* We want a wider aspect ratio than is available - letterbox it */
+                const float scale = ((float) drawablew) / OpenGLLogicalScalingWidth;
+                dstrect.x = 0;
+                dstrect.w = drawablew;
+                dstrect.h = (int)SDL20_floorf(OpenGLLogicalScalingHeight * scale);
+                dstrect.y = (drawableh - dstrect.h) / 2;
             } else {
-                scaledh = drawableh;
-                scaledw = (int) (((((double)OpenGLLogicalScalingWidth) / ((double)OpenGLLogicalScalingHeight))) * ((double)drawableh));
+                /* We want a narrower aspect ratio than is available - use side-bars */
+                const float scale = ((float)drawableh) / OpenGLLogicalScalingHeight;
+                dstrect.y = 0;
+                dstrect.h = drawableh;
+                dstrect.w = (int)SDL20_floorf(OpenGLLogicalScalingWidth * scale);
+                dstrect.x = (drawablew - dstrect.w) / 2;
             }
-            centeredx = (drawablew - scaledw) / 2;
-            centeredy = (drawableh - scaledh) / 2;
 
             OpenGLFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
             OpenGLFuncs.glBindFramebuffer(GL_READ_FRAMEBUFFER, OpenGLLogicalScalingFBO);
@@ -4449,7 +4464,7 @@ SDL_GL_SwapBuffers(void)
             OpenGLFuncs.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
             OpenGLFuncs.glClear(GL_COLOR_BUFFER_BIT);
             OpenGLFuncs.glBlitFramebuffer(0, 0, OpenGLLogicalScalingWidth, OpenGLLogicalScalingHeight,
-                                          centeredx, centeredy, centeredx + scaledw, centeredy + scaledh,
+                                          dstrect.x, dstrect.y, dstrect.x + dstrect.w, dstrect.y + dstrect.h,
                                           GL_COLOR_BUFFER_BIT, GL_LINEAR);
             OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, 0);
             SDL20_GL_SwapWindow(VideoWindow20);
diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h
index 5380446..b05ea70 100644
--- a/src/SDL20_syms.h
+++ b/src/SDL20_syms.h
@@ -275,6 +275,8 @@ SDL20_SYM_PASSTHROUGH(size_t,iconv,(SDL_iconv_t a, const char **b, size_t *c, ch
 SDL20_SYM_PASSTHROUGH(char *,iconv_string,(const char *a, const char *b, const char *c, size_t d),(a,b,c,d),return)
 SDL20_SYM(int,setenv,(const char *a, const char *b, int c),(a,b,c),return)
 SDL20_SYM(int,atoi,(const char *a),(a),return)
+SDL20_SYM(float,fabsf,(float a),(a),return)
+SDL20_SYM(float,floorf,(float a),(a),return)
 
 SDL20_SYM(SDL_Renderer *,CreateRenderer,(SDL_Window *a, int b, Uint32 c),(a,b,c),return)
 SDL20_SYM(int,GetRendererInfo,(SDL_Renderer *a, SDL_RendererInfo *b),(a,b),return)