SDL-1.2: atari:video:xbios: fix XBIOS_allocVbuffers()

From f6b16fe80d917a4cb7d831480c43f800b2bdf20a Mon Sep 17 00:00:00 2001
From: Miro Kropacek <[EMAIL REDACTED]>
Date: Tue, 12 Dec 2023 18:53:47 +0100
Subject: [PATCH] atari:video:xbios: fix XBIOS_allocVbuffers()

- Some XBIOS_allocVbuffers() overloads relied on XBIOS_current which was set only after calling the function

- CTPCI/Milan passed "XBIOS_current" instead of "XBIOS_current->number" to VsetScreen() leading to corrupted allocation requests

- pushed XBIOS_fbnum and XBIOS_current setting to the bottom of XBIOS_SetVideoMode() to make it explicit that those are not to be used during init

- added a few consts to make it explicit that those are not for writing
---
 src/video/xbios/SDL_xbios.c            | 14 +++++++-------
 src/video/xbios/SDL_xbios.h            |  8 ++++----
 src/video/xbios/SDL_xbios_centscreen.c |  4 ++--
 src/video/xbios/SDL_xbios_ctpci.c      | 14 +++++++-------
 src/video/xbios/SDL_xbios_f30.c        |  8 ++++----
 src/video/xbios/SDL_xbios_milan.c      | 14 +++++++-------
 src/video/xbios/SDL_xbios_nova.c       | 12 ++++++------
 src/video/xbios/SDL_xbios_sb3.c        |  4 ++--
 src/video/xbios/SDL_xbios_st.c         | 16 ++++++++--------
 src/video/xbios/SDL_xbios_tt.c         |  4 ++--
 10 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/video/xbios/SDL_xbios.c b/src/video/xbios/SDL_xbios.c
index 9bd3eff15..cad044df9 100644
--- a/src/video/xbios/SDL_xbios.c
+++ b/src/video/xbios/SDL_xbios.c
@@ -475,7 +475,7 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
 	}
 
 	/* Allocate buffers */
-	if (!(*XBIOS_allocVbuffers)(this, num_buffers, new_screen_size)) {
+	if (!(*XBIOS_allocVbuffers)(this, new_video_mode, num_buffers, new_screen_size)) {
 		XBIOS_FreeBuffers(this);
 		return (NULL);
 	}
@@ -489,21 +489,18 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
 		return(NULL);
 	}
 
-	XBIOS_current = new_video_mode;
+	/* this is for C2P conversion */
+	XBIOS_pitch = (*XBIOS_getLineWidth)(this, new_video_mode, new_video_mode->width, new_video_mode->depth);
+
 	current->w = width;
 	current->h = height;
 	current->pitch = lineWidth;
 
-	/* this is for C2P conversion */
-	XBIOS_pitch = (*XBIOS_getLineWidth)(this, new_video_mode, new_video_mode->width, new_video_mode->depth);
-
 	if (XBIOS_shadowscreen)
 		current->pixels = XBIOS_shadowscreen;
 	else
 		current->pixels = XBIOS_screens[0];
 
-	XBIOS_fbnum = 0;
-
 #if SDL_VIDEO_OPENGL
 	if (flags & SDL_OPENGL) {
 		if (!SDL_AtariGL_Init(this, current)) {
@@ -525,6 +522,9 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
 	(*XBIOS_vsync)(this);
 #endif
 
+	XBIOS_fbnum = 0;
+	XBIOS_current = new_video_mode;
+
 	this->UpdateRects = XBIOS_updRects;
 
 	return (current);
diff --git a/src/video/xbios/SDL_xbios.h b/src/video/xbios/SDL_xbios.h
index 5d8ab9b7b..a74ab11d7 100644
--- a/src/video/xbios/SDL_xbios.h
+++ b/src/video/xbios/SDL_xbios.h
@@ -57,7 +57,7 @@ struct SDL_PrivateVideoData {
 	int frame_number;		/* Number of frame for double buffer */
 	int pitch;				/* Destination line width for C2P */
 
-	xbiosmode_t *current;	/* Current set mode */
+	const xbiosmode_t *current;	/* Current set mode */
 	int SDL_nummodes[NUM_MODELISTS];
 	SDL_Rect **SDL_modelist[NUM_MODELISTS];
 	xbiosmode_t **SDL_xbiosmode[NUM_MODELISTS];
@@ -69,13 +69,13 @@ struct SDL_PrivateVideoData {
 
 	void (*listModes)(_THIS, int actually_add);	/* List video modes */
 	void (*saveMode)(_THIS, SDL_PixelFormat *vformat);	/* Save mode,palette,vbase change format if needed */
-	void (*setMode)(_THIS, xbiosmode_t *new_video_mode);	/* Set mode */
+	void (*setMode)(_THIS, const xbiosmode_t *new_video_mode);	/* Set mode */
 	void (*restoreMode)(_THIS);	/* Restore system mode */
 	void (*vsync)(_THIS);
 	void (*getScreenFormat)(_THIS, int bpp, Uint32 *rmask, Uint32 *gmask, Uint32 *bmask, Uint32 *amask);	/* Get TrueColor screen format */
-	int (*getLineWidth)(_THIS, xbiosmode_t *new_video_mode, int width, int bpp);	/* Return video mode pitch */
+	int (*getLineWidth)(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp);	/* Return video mode pitch */
 	void (*swapVbuffers)(_THIS);	/* Swap video buffers */
-	int (*allocVbuffers)(_THIS, int num_buffers, int bufsize);	/* Allocate video buffers */
+	int (*allocVbuffers)(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize);	/* Allocate video buffers */
 	void (*freeVbuffers)(_THIS);	/* Free video buffers */
 
 	void (*updRects)(_THIS, int numrects, SDL_Rect *rects);	/* updateRects to use when video ready */
diff --git a/src/video/xbios/SDL_xbios_centscreen.c b/src/video/xbios/SDL_xbios_centscreen.c
index 20d9abc4e..6ba67b40d 100644
--- a/src/video/xbios/SDL_xbios_centscreen.c
+++ b/src/video/xbios/SDL_xbios_centscreen.c
@@ -35,7 +35,7 @@
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 
 void SDL_XBIOS_VideoInit_Centscreen(_THIS)
@@ -98,7 +98,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	}
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	centscreen_mode_t newmode, curmode;
 
diff --git a/src/video/xbios/SDL_xbios_ctpci.c b/src/video/xbios/SDL_xbios_ctpci.c
index 4f4ad567e..d82eafbb0 100644
--- a/src/video/xbios/SDL_xbios_ctpci.c
+++ b/src/video/xbios/SDL_xbios_ctpci.c
@@ -71,10 +71,10 @@ static SDL_VideoDevice *enum_this;
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp);
-static int allocVbuffers(_THIS, int num_buffers, int bufsize);
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp);
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize);
 static void freeVbuffers(_THIS);
 static void updateRects(_THIS, int numrects, SDL_Rect *rects);
 static int flipHWSurface(_THIS, SDL_Surface *surface);
@@ -172,7 +172,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	}
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	VsetScreen(-1, XBIOS_screens[0], VN_MAGIC, CMD_SETADR);
 
@@ -194,7 +194,7 @@ static void restoreMode(_THIS)
 	}
 }
 
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp)
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp)
 {
 	SCREENINFO si;
 	int retvalue = width * (((bpp==15) ? 16 : bpp)>>3);
@@ -211,7 +211,7 @@ static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp)
 	return (retvalue);
 }
 
-static int allocVbuffers(_THIS, int num_buffers, int bufsize)
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize)
 {
 	int i;
 
@@ -220,7 +220,7 @@ static int allocVbuffers(_THIS, int num_buffers, int bufsize)
 			/* Buffer 0 is current screen */
 			XBIOS_screensmem[i] = XBIOS_oldvbase;
 		} else {
-			VsetScreen(&XBIOS_screensmem[i], XBIOS_current, VN_MAGIC, CMD_ALLOCPAGE);
+			VsetScreen(&XBIOS_screensmem[i], new_video_mode->number, VN_MAGIC, CMD_ALLOCPAGE);
 		}
 
 		if (!XBIOS_screensmem[i]) {
diff --git a/src/video/xbios/SDL_xbios_f30.c b/src/video/xbios/SDL_xbios_f30.c
index d713b7315..d69e7a4b3 100644
--- a/src/video/xbios/SDL_xbios_f30.c
+++ b/src/video/xbios/SDL_xbios_f30.c
@@ -122,11 +122,11 @@ static int has_supervidel;
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 
-static int allocVbuffers_SV(_THIS, int num_buffers, int bufsize);
+static int allocVbuffers_SV(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize);
 #ifdef ENABLE_SV_SHADOWBUF
 static void updateRects_SV(_THIS, int numrects, SDL_Rect *rects);
 static int flipHWSurface_SV(_THIS, SDL_Surface *surface);
@@ -223,7 +223,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	}
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	Setscreen(-1,XBIOS_screens[0],-1);
 
@@ -263,7 +263,7 @@ static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
 	return 1;
 }
 
-static int allocVbuffers_SV(_THIS, int num_buffers, int bufsize)
+static int allocVbuffers_SV(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize)
 {
 	int i;
 	Uint32 tmp;
diff --git a/src/video/xbios/SDL_xbios_milan.c b/src/video/xbios/SDL_xbios_milan.c
index a05d3624f..dbf17e4bc 100644
--- a/src/video/xbios/SDL_xbios_milan.c
+++ b/src/video/xbios/SDL_xbios_milan.c
@@ -62,11 +62,11 @@ static SDL_VideoDevice *enum_this;
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp);
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp);
 static void swapVbuffers(_THIS);
-static int allocVbuffers(_THIS, int num_buffers, int bufsize);
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize);
 static void freeVbuffers(_THIS);
 static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 
@@ -157,7 +157,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	}
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	VsetScreen(-1, XBIOS_screens[0], MI_MAGIC, CMD_SETADR);
 
@@ -185,7 +185,7 @@ static void swapVbuffers(_THIS)
 	VsetScreen(-1, -1, MI_MAGIC, CMD_FLIPPAGE);
 }
 
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp)
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp)
 {
 	SCREENINFO si;
 	int retvalue = width * (((bpp==15) ? 16 : bpp)>>3);
@@ -202,7 +202,7 @@ static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp)
 	return (retvalue);
 }
 
-static int allocVbuffers(_THIS, int num_buffers, int bufsize)
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize)
 {
 	int i;
 
@@ -211,7 +211,7 @@ static int allocVbuffers(_THIS, int num_buffers, int bufsize)
 			/* Buffer 0 is current screen */
 			XBIOS_screensmem[i] = XBIOS_oldvbase;
 		} else {
-			VsetScreen(&XBIOS_screensmem[i], XBIOS_current, MI_MAGIC, CMD_ALLOCPAGE);
+			VsetScreen(&XBIOS_screensmem[i], new_video_mode->number, MI_MAGIC, CMD_ALLOCPAGE);
 		}
 
 		if (!XBIOS_screensmem[i]) {
diff --git a/src/video/xbios/SDL_xbios_nova.c b/src/video/xbios/SDL_xbios_nova.c
index a3a5eaf31..7d04737e0 100644
--- a/src/video/xbios/SDL_xbios_nova.c
+++ b/src/video/xbios/SDL_xbios_nova.c
@@ -58,13 +58,13 @@ static void XBIOS_DeleteDevice_NOVA(_THIS);
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 static void vsync_NOVA(_THIS);
 static void getScreenFormat(_THIS, int bpp, Uint32 *rmask, Uint32 *gmask, Uint32 *bmask, Uint32 *amask);
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp);
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp);
 static void swapVbuffers(_THIS);
-static int allocVbuffers(_THIS, int num_buffers, int bufsize);
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize);
 static void freeVbuffers(_THIS);
 static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 
@@ -170,7 +170,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	NOVA_xcb->blnk_time = 0;
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	NOVA_SetMode(this, new_video_mode->number);
 }
@@ -234,7 +234,7 @@ static void getScreenFormat(_THIS, int bpp, Uint32 *rmask, Uint32 *gmask, Uint32
 	}
 }
 
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp)
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp)
 {
 	return (NOVA_modes[new_video_mode->number].pitch);
 }
@@ -244,7 +244,7 @@ static void swapVbuffers(_THIS)
 	NOVA_SetScreen(this, XBIOS_screens[XBIOS_fbnum]);
 }
 
-static int allocVbuffers(_THIS, int num_buffers, int bufsize)
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize)
 {
 	XBIOS_screens[0] = NOVA_xcb->base;
 	if (num_buffers>1) {
diff --git a/src/video/xbios/SDL_xbios_sb3.c b/src/video/xbios/SDL_xbios_sb3.c
index f9a91f944..da36a70f4 100644
--- a/src/video/xbios/SDL_xbios_sb3.c
+++ b/src/video/xbios/SDL_xbios_sb3.c
@@ -52,7 +52,7 @@ const int SDL_XBIOS_scpn_planes_device[]={
 /*--- Functions ---*/
 
 static void listModes(_THIS, int actually_add);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 
 int SDL_XBIOS_SB3Usable(scpn_cookie_t *cookie_scpn)
@@ -100,7 +100,7 @@ static void listModes(_THIS, int actually_add)
 	}
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	/* SB3 do not allow changing video mode */
 	Setscreen(-1,XBIOS_screens[0],-1);
diff --git a/src/video/xbios/SDL_xbios_st.c b/src/video/xbios/SDL_xbios_st.c
index e56ed6cca..01e9579d7 100644
--- a/src/video/xbios/SDL_xbios_st.c
+++ b/src/video/xbios/SDL_xbios_st.c
@@ -42,14 +42,14 @@ static const xbiosmode_t stmodes[]={
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode_ST(_THIS, xbiosmode_t *new_video_mode);
-static void setMode_STE(_THIS, xbiosmode_t *new_video_mode);
+static void setMode_ST(_THIS, const xbiosmode_t *new_video_mode);
+static void setMode_STE(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 static void vsync_ST(_THIS);
 static void getScreenFormat(_THIS, int bpp, Uint32 *rmask, Uint32 *gmask, Uint32 *bmask, Uint32 *amask);
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp);
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp);
 static void swapVbuffers(_THIS);
-static int allocVbuffers(_THIS, int num_buffers, int bufsize);
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize);
 static void freeVbuffers(_THIS);
 static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 
@@ -104,7 +104,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	}
 }
 
-static void setMode_ST(_THIS, xbiosmode_t *new_video_mode)
+static void setMode_ST(_THIS, const xbiosmode_t *new_video_mode)
 {
 	int i;
 
@@ -119,7 +119,7 @@ static void setMode_ST(_THIS, xbiosmode_t *new_video_mode)
 	Setpalette(TT_palette);
 }
 
-static void setMode_STE(_THIS, xbiosmode_t *new_video_mode)
+static void setMode_STE(_THIS, const xbiosmode_t *new_video_mode)
 {
 	int i;
 
@@ -156,7 +156,7 @@ static void getScreenFormat(_THIS, int bpp, Uint32 *rmask, Uint32 *gmask, Uint32
 	*rmask = *gmask = *bmask = *amask = 0;
 }
 
-static int getLineWidth(_THIS, xbiosmode_t *new_video_mode, int width, int bpp)
+static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp)
 {
 	if (bpp==4) {
 		return (width >> 1);
@@ -170,7 +170,7 @@ static void swapVbuffers(_THIS)
 	Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
 }
 
-static int allocVbuffers(_THIS, int num_buffers, int bufsize)
+static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffers, int bufsize)
 {
 	int i;
 
diff --git a/src/video/xbios/SDL_xbios_tt.c b/src/video/xbios/SDL_xbios_tt.c
index e78b85cd9..67095b043 100644
--- a/src/video/xbios/SDL_xbios_tt.c
+++ b/src/video/xbios/SDL_xbios_tt.c
@@ -42,7 +42,7 @@ static const xbiosmode_t ttmodes[]={
 
 static void listModes(_THIS, int actually_add);
 static void saveMode(_THIS, SDL_PixelFormat *vformat);
-static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 
@@ -99,7 +99,7 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat)
 	}
 }
 
-static void setMode(_THIS, xbiosmode_t *new_video_mode)
+static void setMode(_THIS, const xbiosmode_t *new_video_mode)
 {
 	Setscreen(-1,XBIOS_screens[0],-1);