SDL-1.2: atari:video:xbios: replace custom XBIOS_shadowscreen handling with a flag

From 7b7a50eb9a752ea84fe1437b7d7bb8228fe2e239 Mon Sep 17 00:00:00 2001
From: Miro Kropacek <[EMAIL REDACTED]>
Date: Tue, 12 Dec 2023 21:11:25 +0100
Subject: [PATCH] atari:video:xbios: replace custom XBIOS_shadowscreen handling
 with a flag

This saves a lot of code duplicity and makes Milan/CTPCI XBIOS handling nearly identical.
---
 src/video/xbios/SDL_xbios.c       |  36 +++++++++-
 src/video/xbios/SDL_xbios.h       |   1 +
 src/video/xbios/SDL_xbios_ctpci.c | 112 ++++++------------------------
 src/video/xbios/SDL_xbios_f30.c   |   1 +
 src/video/xbios/SDL_xbios_milan.c |   1 -
 5 files changed, 59 insertions(+), 92 deletions(-)

diff --git a/src/video/xbios/SDL_xbios.c b/src/video/xbios/SDL_xbios.c
index cad044df..8c4a20f8 100644
--- a/src/video/xbios/SDL_xbios.c
+++ b/src/video/xbios/SDL_xbios.c
@@ -444,7 +444,7 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
 	new_screen_size = lineWidth * height;
 	new_screen_size += 256; /* To align on a 256 byte adress */
 
-	if (new_video_mode->flags & XBIOSMODE_C2P) {
+	if (new_video_mode->flags & (XBIOSMODE_C2P | XBIOSMODE_SHADOWCOPY)) {
 		XBIOS_shadowscreen = Atari_SysMalloc(new_screen_size, MX_PREFTTRAM);
 
 		if (XBIOS_shadowscreen == NULL) {
@@ -554,11 +554,11 @@ static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
 {
 	SDL_Surface *surface;
+	int i;
 
 	surface = this->screen;
 
 	if (XBIOS_current->flags & XBIOSMODE_C2P) {
-		int i;
 		int doubleline = (XBIOS_current->flags & XBIOSMODE_DOUBLELINE ? 1 : 0);
 
 		for (i=0;i<numrects;i++) {
@@ -590,6 +590,26 @@ static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
 				XBIOS_pitch
 			);
 		}
+	} else if (XBIOS_current->flags & XBIOSMODE_SHADOWCOPY) {
+		for (i=0;i<numrects;i++) {
+			Uint8 *blockSrcStart, *blockDstStart;
+			int y;
+
+			blockSrcStart = (Uint8 *) surface->pixels;
+			blockSrcStart += surface->pitch*rects[i].y;
+			blockSrcStart += surface->format->BytesPerPixel*rects[i].x;
+
+			blockDstStart = ((Uint8 *) XBIOS_screens[XBIOS_fbnum]) + surface->offset;
+			blockDstStart += XBIOS_pitch*rects[i].y;
+			blockDstStart += surface->format->BytesPerPixel*rects[i].x;
+
+			for(y=0;y<rects[i].h;y++){
+				SDL_memcpy(blockDstStart,blockSrcStart,surface->pitch);
+
+				blockSrcStart += surface->pitch;
+				blockDstStart += XBIOS_pitch;
+			}
+		}
 	}
 
 	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
@@ -629,6 +649,18 @@ static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface)
 			surface->pitch,
 			XBIOS_pitch
 		);
+	} else if (XBIOS_current->flags & XBIOSMODE_SHADOWCOPY) {
+		int i;
+		Uint8 *src, *dst;
+
+		src = surface->pixels;
+		dst = ((Uint8 *) XBIOS_screens[XBIOS_fbnum]) + surface->offset;
+
+		for (i=0; i<surface->h; i++) {
+			SDL_memcpy(dst, src, surface->w * surface->format->BytesPerPixel);
+			src += surface->pitch;
+			dst += XBIOS_pitch;
+		}
 	}
 
 	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
diff --git a/src/video/xbios/SDL_xbios.h b/src/video/xbios/SDL_xbios.h
index a74ab11d..b3faa8bd 100644
--- a/src/video/xbios/SDL_xbios.h
+++ b/src/video/xbios/SDL_xbios.h
@@ -32,6 +32,7 @@
 
 #define XBIOSMODE_DOUBLELINE (1<<0)
 #define XBIOSMODE_C2P (1<<1)
+#define XBIOSMODE_SHADOWCOPY (1<<2)
 
 typedef struct
 {
diff --git a/src/video/xbios/SDL_xbios_ctpci.c b/src/video/xbios/SDL_xbios_ctpci.c
index 930b7063..ac8baab4 100644
--- a/src/video/xbios/SDL_xbios_ctpci.c
+++ b/src/video/xbios/SDL_xbios_ctpci.c
@@ -29,13 +29,8 @@
 */
 
 #include <mint/cookie.h>
-#include <mint/osbind.h>
 #include <mint/falcon.h>
 
-#include "../SDL_sysvideo.h"
-
-#include "../ataricommon/SDL_atarimxalloc_c.h"
-
 #include "SDL_xbios.h"
 #include "SDL_xbios_milan.h"
 
@@ -45,6 +40,14 @@
  */
 #define CTPCI_USE_TABLE
 
+/*
+ * Blitting directly to screen used to be very slow as TT-RAM->CTPCI
+ * burst mode was (?) not working. However speed tests on CTPCI TOS
+ * 1.01 Beta 10 and CTPCI_1M firmware shows much better framerates
+ * without the shadow buffer.
+ */
+/* #define ENABLE_CTPCI_SHADOWBUF */
+
 typedef struct {
 	Uint16 modecode, width, height;
 } predefined_mode_t;
@@ -76,10 +79,9 @@ static void saveMode(_THIS, SDL_PixelFormat *vformat);
 static void setMode(_THIS, const xbiosmode_t *new_video_mode);
 static void restoreMode(_THIS);
 static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp);
+static void swapVbuffers(_THIS);
 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);
 
 void SDL_XBIOS_VideoInit_Ctpci(_THIS)
 {
@@ -88,11 +90,9 @@ void SDL_XBIOS_VideoInit_Ctpci(_THIS)
 	XBIOS_setMode = setMode;
 	XBIOS_restoreMode = restoreMode;
 	XBIOS_getLineWidth = getLineWidth;
+	XBIOS_swapVbuffers = swapVbuffers;
 	XBIOS_allocVbuffers = allocVbuffers;
 	XBIOS_freeVbuffers = freeVbuffers;
-
-	XBIOS_updRects = updateRects;
-	this->FlipHWSurface = flipHWSurface;
 }
 
 #ifndef CTPCI_USE_TABLE
@@ -104,8 +104,11 @@ static unsigned long /*cdecl*/ enumfunc(SCREENINFO *inf, unsigned long flag)
 	modeinfo.width = inf->scrWidth;
 	modeinfo.height = inf->scrHeight;
 	modeinfo.depth = inf->scrPlanes;
+#ifdef ENABLE_CTPCI_SHADOWBUF
+	modeinfo.flags = XBIOSMODE_SHADOWCOPY;
+#else
 	modeinfo.flags = 0;
-
+#endif
 	SDL_XBIOS_AddMode(enum_this, enum_actually_add, &modeinfo);
 
 	return ENUMMODE_CONT;
@@ -130,8 +133,11 @@ static void listModes(_THIS, int actually_add)
 				modeinfo.width = mode_list[i].width;
 				modeinfo.height = mode_list[i].height;
 				modeinfo.depth = mode_bpp[j-3];
+#ifdef ENABLE_CTPCI_SHADOWBUF
+				modeinfo.flags = XBIOSMODE_SHADOWCOPY;
+#else
 				modeinfo.flags = 0;
-
+#endif
 				SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
 			}
 		}
@@ -196,6 +202,11 @@ static void restoreMode(_THIS)
 	}
 }
 
+static void swapVbuffers(_THIS)
+{
+	VsetScreen(-1, -1, VN_MAGIC, CMD_FLIPPAGE);
+}
+
 static int getLineWidth(_THIS, const xbiosmode_t *new_video_mode, int width, int bpp)
 {
 	SCREENINFO si;
@@ -234,23 +245,6 @@ static int allocVbuffers(_THIS, const xbiosmode_t *new_video_mode, int num_buffe
 		XBIOS_screens[i]=XBIOS_screensmem[i];
 	}
 
-	/*--- Always use shadow buffer ---*/
-	if (XBIOS_shadowscreen) {
-		Mfree(XBIOS_shadowscreen);
-		XBIOS_shadowscreen=NULL;
-	}
-
-	/* allocate shadow buffer in TT-RAM, blitting directly to screen is
-	   damn slow, send postcards to R.Czuba for fixing TT-RAM->CTPCI burst
-	   mode */
-	XBIOS_shadowscreen = Atari_SysMalloc(bufsize, MX_PREFTTRAM);
-
-	if (XBIOS_shadowscreen == NULL) {
-		SDL_SetError("Can not allocate %d KB for shadow buffer", bufsize>>10);
-		return (0);
-	}
-	SDL_memset(XBIOS_shadowscreen, 0, bufsize);
-
 	return (1);
 }
 
@@ -269,63 +263,3 @@ static void freeVbuffers(_THIS)
 		}
 	}
 }
-
-static void updateRects(_THIS, int numrects, SDL_Rect *rects)
-{
-	SDL_Surface *surface;
-	int i;
-
-	surface = this->screen;
-
-	for (i=0;i<numrects;i++) {
-		Uint8 *blockSrcStart, *blockDstStart;
-		int y;
-
-		blockSrcStart = (Uint8 *) surface->pixels;
-		blockSrcStart += surface->pitch*rects[i].y;
-		blockSrcStart += surface->format->BytesPerPixel*rects[i].x;
-
-		blockDstStart = ((Uint8 *) XBIOS_screens[XBIOS_fbnum]) + surface->offset;
-		blockDstStart += XBIOS_pitch*rects[i].y;
-		blockDstStart += surface->format->BytesPerPixel*rects[i].x;
-
-		for(y=0;y<rects[i].h;y++){
-			SDL_memcpy(blockDstStart,blockSrcStart,surface->pitch);
-
-			blockSrcStart += surface->pitch;
-			blockDstStart += XBIOS_pitch;
-		}
-	}
-
-	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
-		VsetScreen(-1L, -1L, VN_MAGIC, CMD_FLIPPAGE);
-		(*XBIOS_vsync)(this);
-
-		XBIOS_fbnum ^= 1;
-	}
-}
-
-static int flipHWSurface(_THIS, SDL_Surface *surface)
-{
-	int i;
-	Uint8 *src, *dst;
-
-	src = surface->pixels;
-	dst = ((Uint8 *) XBIOS_screens[XBIOS_fbnum]) + surface->offset;
-
-	for (i=0; i<surface->h; i++) {
-		SDL_memcpy(dst, src, surface->w * surface->format->BytesPerPixel);
-		src += surface->pitch;
-		dst += XBIOS_pitch;
-
-	}
-
-	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
-		VsetScreen(-1L, -1L, VN_MAGIC, CMD_FLIPPAGE);
-		(*XBIOS_vsync)(this);
-
-		XBIOS_fbnum ^= 1;
-	}
-
-	return(0);
-}
diff --git a/src/video/xbios/SDL_xbios_f30.c b/src/video/xbios/SDL_xbios_f30.c
index d69e7a4b..9be194ec 100644
--- a/src/video/xbios/SDL_xbios_f30.c
+++ b/src/video/xbios/SDL_xbios_f30.c
@@ -156,6 +156,7 @@ void SDL_XBIOS_VideoInit_F30(_THIS)
 	/* CTPCI ? */
 	if ((Getcookie(C_CT60, &cookie_dummy) == C_FOUND)
 	    && (Getcookie(C__PCI, &cookie_dummy) == C_FOUND)
+	    /* This check is to differentiate between booting in Videl/Radeon */
 	    && ((unsigned long)Physbase()>=0x01000000UL))
 	{
 		SDL_XBIOS_VideoInit_Ctpci(this);
diff --git a/src/video/xbios/SDL_xbios_milan.c b/src/video/xbios/SDL_xbios_milan.c
index 75977110..85a969c8 100644
--- a/src/video/xbios/SDL_xbios_milan.c
+++ b/src/video/xbios/SDL_xbios_milan.c
@@ -183,7 +183,6 @@ static void restoreMode(_THIS)
 
 static void swapVbuffers(_THIS)
 {
-	/*VsetScreen(-1, XBIOS_screens[XBIOS_fbnum], MI_MAGIC, CMD_SETADR);*/
 	VsetScreen(-1, -1, MI_MAGIC, CMD_FLIPPAGE);
 }