From 1e9282d75dbe40638bd747282244953e99ef2372 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Sat, 26 Oct 2024 17:04:12 -0400
Subject: [PATCH] Fix an off-by-less-than-one issue in
 bitmap_double_mult_inside()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This was sometimes causing an integer scaled mode (ie: 4×) to be
reduced to very slightly less than that (ie: 3.996255×), making the
window one pixel smaller than it was supposed to be due to integer
truncation.

This could result in being unable to increase the window size using
the Alt+Right-Arrow shortcut and could make new windows one full
size smaller than they needed to be (such as C64 windows).

While we're here, fix the SDL and X11 outputs to trust what
bitmap_drv_init_mode() does.  It was fixed when GDI mode was being
written, but the other drivers weren't updated to take advantage of
that.

Should resolve issue 156 reported by DigitalMan
---
 src/conio/bitmap_con.c | 18 ++++++++++++++++--
 src/conio/sdl_con.c    | 15 ++-------------
 src/conio/x_events.c   | 10 ++++++----
 3 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/src/conio/bitmap_con.c b/src/conio/bitmap_con.c
index a1ae858b18..5ff88585df 100644
--- a/src/conio/bitmap_con.c
+++ b/src/conio/bitmap_con.c
@@ -1711,13 +1711,27 @@ bitmap_double_mult_inside(int maxwidth, int maxheight)
 	double mult = 1.0;
 	double wmult = 1.0;
 	double hmult = 1.0;
+	int wmw, wmh;
+	int hmw, hmh;
 	int w, h;
 
 	bitmap_get_scaled_win_size_nomax(1.0, &w, &h);
 	wmult = (double)maxwidth / w;
 	hmult = (double)maxheight / h;
-	if (wmult < hmult)
-		mult = wmult;
+	bitmap_get_scaled_win_size_nomax(wmult, &wmw, &wmh);
+	bitmap_get_scaled_win_size_nomax(hmult, &hmw, &hmh);
+	if (wmult < hmult) {
+		if (hmw <= maxwidth && hmh <= maxheight)
+			mult = hmult;
+		else
+			mult = wmult;
+	}
+	else if(hmult < wmult) {
+		if (wmw <= maxwidth && wmh <= maxheight)
+			mult = wmult;
+		else
+			mult = hmult;
+	}
 	else
 		mult = hmult;
 	// TODO: Allow below 1.0?
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index aedbaa6d4b..d92788fb07 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -372,20 +372,9 @@ static int sdl_init_mode(int mode, bool init)
 	}
 	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height, w, h);
 	if (ciolib_initial_scaling < 1.0) {
-		if (w != 0 && h != 0) {
-			w *= ciolib_initial_scaling;
-			h *= ciolib_initial_scaling;
-			ciolib_initial_scaling = bitmap_double_mult_inside(w, h);
-		}
-		if (ciolib_initial_scaling < 1.0) {
+		ciolib_initial_scaling = vstat.scaling;
+		if (ciolib_initial_scaling < 1.0)
 			ciolib_initial_scaling = 1.0;
-		}
-	}
-	if (init) {
-		internal_scaling = (ciolib_initial_scaling_type == CIOLIB_SCALING_INTERNAL);
-		if (ciolib_initial_scaling) {
-			bitmap_get_scaled_win_size(ciolib_initial_scaling, &vstat.winwidth, &vstat.winheight, 0, 0);
-		}
 	}
 	pthread_mutex_lock(&sdl_mode_mutex);
 	sdl_mode = true;
diff --git a/src/conio/x_events.c b/src/conio/x_events.c
index e526793d00..8cd43e6198 100644
--- a/src/conio/x_events.c
+++ b/src/conio/x_events.c
@@ -1227,17 +1227,19 @@ static void resize_window()
 static void init_mode_internal(int mode)
 {
 	int mw, mh;
-	int ow, oh;
 
 	x11_get_maxsize(&mw, &mh);
 	free_last();
 	pthread_mutex_lock(&vstatlock);
-	ow = vstat.winwidth;
-	oh = vstat.winheight;
+	double os = vstat.scaling;
+	int ow = vstat.winwidth;
+	int oh = vstat.winheight;
 	bitmap_drv_init_mode(mode, NULL, NULL, mw, mh);
+	// TODO: This hacks the right values into the wrong places so resize_window() fixes them.
+	x_cvstat.scaling = vstat.scaling;
+	vstat.scaling = os;
 	vstat.winwidth = ow;
 	vstat.winheight = oh;
-	vstat.scaling = bitmap_double_mult_inside(ow, oh);
 	pthread_mutex_unlock(&vstatlock);
 	resize_window();
 	pthread_mutex_lock(&vstatlock);
-- 
GitLab