From cd22c54ed72c1c7f408c094c64b878380295f7df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Mon, 26 Dec 2022 00:44:11 -0500
Subject: [PATCH] Various SDL fixes:

Pass window size in SDL_USEREVENT_SETVIDMODE
- Fixes race condition where SDL_WINDOWEVENT_RESIZED or
  SDL_WINDOWEVENT_SIZE_CHANGED arraves while
  SDL_USEREVENT_SETVIDMODE is in the queue

Set new scaling based on old scaling multiplier
- Will resize window on mode changes, but tries to keep integer
  multiplier similar.  May break fullscreen modes, dunno.

Have aspect_fix() return higher rather than lower
- This may make it the same as aspect_correct(), but I'm too lazy
  to figure that out.
---
 src/conio/sdl_con.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index 46b575ec62..5a49d674fd 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -254,11 +254,16 @@ static int sdl_user_func_ret(int func, ...)
 	/* Drain the swamp */
 	while(1) {
 		switch(func) {
+			case SDL_USEREVENT_SETVIDMODE:
+				ev.user.data1 = NULL + va_arg(argptr, int);
+				ev.user.data2 = NULL + va_arg(argptr, int);
+				while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)!=1)
+					YIELD();
+				break;
 			case SDL_USEREVENT_GETWINPOS:
 				ev.user.data1 = va_arg(argptr, void *);
 				ev.user.data2 = va_arg(argptr, void *);
 				// Fallthrough
-			case SDL_USEREVENT_SETVIDMODE:
 			case SDL_USEREVENT_INIT:
 			case SDL_USEREVENT_QUIT:
 				while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)!=1)
@@ -356,6 +361,7 @@ internal_scaling_factors(int winwidth, int winheight, int *x, int *y)
 static int sdl_init_mode(int mode)
 {
 	int oldcols;
+	int scaling = 1;
 
 	if (mode != CIOLIB_MODE_CUSTOM) {
 		pthread_mutex_lock(&vstatlock);
@@ -372,9 +378,13 @@ static int sdl_init_mode(int mode)
 	pthread_mutex_lock(&vstatlock);
 	oldcols = cvstat.cols;
 	bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
-	vstat.winwidth = lround((double)cvstat.winwidth / cvstat.scrnwidth * vstat.scrnwidth);
-	vstat.winheight = lround((double)cvstat.winheight / cvstat.scrnheight * vstat.scrnheight);
-	aspect_correct(&vstat.winwidth, &cvstat.winheight, cvstat.aspect_width, cvstat.aspect_height);
+	if (cvstat.scrnwidth > 0) {
+		for (scaling = 1; (scaling + 1) * cvstat.scrnwidth < cvstat.winwidth; scaling++)
+			;
+	}
+	vstat.winwidth = vstat.scrnwidth * scaling;
+	vstat.winheight = vstat.scrnheight * scaling;
+	aspect_fix(&vstat.winwidth, &vstat.winheight, vstat.aspect_width, vstat.aspect_height);
 	if (oldcols != vstat.cols) {
 		if (oldcols == 0) {
 			if (ciolib_initial_window_width > 0)
@@ -403,7 +413,7 @@ static int sdl_init_mode(int mode)
 	pthread_mutex_unlock(&vstatlock);
 	pthread_mutex_unlock(&blinker_lock);
 
-	sdl_user_func_ret(SDL_USEREVENT_SETVIDMODE);
+	sdl_user_func_ret(SDL_USEREVENT_SETVIDMODE, cvstat.winwidth, cvstat.winheight);
 
 	return(0);
 }
@@ -1190,6 +1200,8 @@ void sdl_video_event_thread(void *data)
 						break;
 					case SDL_USEREVENT_SETVIDMODE:
 						pthread_mutex_lock(&vstatlock);
+						cvstat.winwidth = ev.user.data1 - NULL;
+						cvstat.winheight = ev.user.data2 - NULL;
 						setup_surfaces_locked();
 						pthread_mutex_unlock(&vstatlock);
 						sdl_ufunc_retval=0;
-- 
GitLab