Dynamically create list of video modes, easier to add new ones
authorPatrice Mandin <patmandin@gmail.com>
Mon, 07 Mar 2005 10:00:58 +0000
changeset 1042 0e7218843cfb
parent 1041 af92ee34b3e2
child 1043 21d1d05aad39
Dynamically create list of video modes, easier to add new ones
README.MiNT
src/video/xbios/SDL_xbios.c
src/video/xbios/SDL_xbios.h
src/video/xbios/SDL_xbios_blowup.c
src/video/xbios/SDL_xbios_sb3.c
--- a/README.MiNT	Wed Mar 02 17:17:26 2005 +0000
+++ b/README.MiNT	Mon Mar 07 10:00:58 2005 +0000
@@ -156,6 +156,7 @@
 		320x480x8 and 320x240x8 (software double-lined mode).
 	Falcon:
 		All modes supported by the current monitor (RVB or VGA).
+		BlowUp extended modes, ScreenBlaster 3 current mode.
 	Clones and any machine with monochrome monitor:
 		Not supported.
 
--- a/src/video/xbios/SDL_xbios.c	Wed Mar 02 17:17:26 2005 +0000
+++ b/src/video/xbios/SDL_xbios.c	Mon Mar 07 10:00:58 2005 +0000
@@ -60,7 +60,17 @@
 
 #define XBIOS_VID_DRIVER_NAME "xbios"
 
+/* Debug print info */
+#if 1
+#define DEBUG_PRINT(what) \
+	{ \
+		printf what; \
+	}
 /*#define DEBUG_VIDEO_XBIOS 1*/
+#else
+#define DEBUG_PRINT(what)
+#undef DEBUG_VIDEO_XBIOS
+#endif
 
 /* Initialization/Query functions */
 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
@@ -82,55 +92,6 @@
 static void XBIOS_GL_SwapBuffers(_THIS);
 #endif
 
-/* List of video modes */
-
-/* ST modes */
-static int xbiosnummodes_st=1;
-static xbiosmode_t xbiosmodelist_st[]={
-	{ST_LOW>>8,320,200,4,SDL_FALSE}
-};
-
-/* TT modes */
-static int xbiosnummodes_tt=2;
-static xbiosmode_t xbiosmodelist_tt[]={
-	{TT_LOW,320,480,8,SDL_FALSE},
-	{TT_LOW,320,240,8,SDL_TRUE}	/* Software double-lined mode */
-};
-
-/* Falcon RVB modes */
-static int xbiosnummodes_f30rvb=16;
-static xbiosmode_t xbiosmodelist_f30rvb[]={
-	{BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE},
-	{BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE},
-	{BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE},
-	{BPS16|COL80,640,200,16,SDL_FALSE},
-	{BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE},
-	{BPS16|OVERSCAN,384,240,16,SDL_FALSE},
-	{BPS16|VERTFLAG,320,400,16,SDL_FALSE},
-	{BPS16,320,200,16,SDL_FALSE},
-
-	{BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE},
-	{BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE},
-	{BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE},
-	{BPS8|COL80,640,200,8,SDL_FALSE},
-	{BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE},
-	{BPS8|OVERSCAN,384,240,8,SDL_FALSE},
-	{BPS8|VERTFLAG,320,400,8,SDL_FALSE},
-	{BPS8,320,200,8,SDL_FALSE}
-};
-
-/* Falcon VGA modes */
-static int xbiosnummodes_f30vga=6;
-static xbiosmode_t xbiosmodelist_f30vga[]={
-	{BPS16,320,480,16,SDL_FALSE},
-	{BPS16|VERTFLAG,320,240,16,SDL_FALSE},
-
-	{BPS8|COL80,640,480,8,SDL_FALSE},	
-	{BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE},
-	{BPS8,320,480,8,SDL_FALSE},
-	{BPS8|VERTFLAG,320,240,8,SDL_FALSE}
-};
-
 /* To setup palette */
 
 static unsigned short	TT_palette[256];
@@ -245,6 +206,57 @@
 	XBIOS_Available, XBIOS_CreateDevice
 };
 
+void SDL_XBIOS_AddMode(_THIS, Uint16 modecode, Uint16 width, Uint16 height,
+	Uint16 depth, SDL_bool flags)
+{
+	int i, curpos;
+	xbiosmode_t *current_mode;
+
+	/* Check if mode already exists */
+	if (XBIOS_modelist) {
+		current_mode = XBIOS_modelist;
+		for (i=0;i<XBIOS_nummodes; i++, current_mode++) {
+			if (current_mode->width != width)
+				continue;
+			if (current_mode->height != height)
+				continue;
+			if (current_mode->depth != depth)
+				continue;
+			return;
+		}
+	}
+
+	++XBIOS_nummodes;
+	XBIOS_modelist = (xbiosmode_t *) realloc(XBIOS_modelist, XBIOS_nummodes * sizeof(xbiosmode_t));
+
+	/* Keep the list sorted: bpp, width, height */
+	curpos=0;
+
+	for(i=0; i<XBIOS_nummodes-1; i++) {
+		if (XBIOS_modelist[i].depth <= depth) {
+			if (XBIOS_modelist[i].width < width) {
+				break;
+			} else if (XBIOS_modelist[i].width == width) {
+				if (XBIOS_modelist[i].height <= height) {
+					break;
+				}
+			}
+		}
+		curpos++;
+	}
+
+	/* Push remaining modes further */
+	for(i=XBIOS_nummodes-1; i>curpos; i--) {
+		memcpy(&XBIOS_modelist[i], &XBIOS_modelist[i-1], sizeof(xbiosmode_t));
+	}
+
+	XBIOS_modelist[curpos].number = modecode;
+	XBIOS_modelist[curpos].width = width;
+	XBIOS_modelist[curpos].height = height;
+	XBIOS_modelist[curpos].depth = depth;
+	XBIOS_modelist[curpos].doubleline = flags;
+}
+
 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
 {
 	int i,j8,j16;
@@ -268,6 +280,8 @@
 
 	/* Initialize video mode list */
 	/* and save current screen status (palette, screen address, video mode) */
+	XBIOS_nummodes = 0;
+	XBIOS_modelist = NULL;
 
 	switch (XBIOS_cvdo >>16) {
 		case VDO_ST:
@@ -275,8 +289,7 @@
 			{
 				short *oldpalette;
 
-				XBIOS_nummodes=xbiosnummodes_st;
-				XBIOS_modelist=xbiosmodelist_st;
+				SDL_XBIOS_AddMode(this, ST_LOW>>8,320,200,4,SDL_FALSE);
 			
 				XBIOS_oldvbase=Physbase();
 				XBIOS_oldvmode=Getrez();
@@ -304,8 +317,10 @@
 			}
 			break;
 		case VDO_TT:
-			XBIOS_nummodes=xbiosnummodes_tt;
-			XBIOS_modelist=xbiosmodelist_tt;
+
+			SDL_XBIOS_AddMode(this, TT_LOW,320,480,8,SDL_FALSE);
+			/* Software double-lined mode */
+			SDL_XBIOS_AddMode(this, TT_LOW,320,240,8,SDL_TRUE);
 
 			XBIOS_oldvbase=Logbase();
 			XBIOS_oldvmode=EgetShift();
@@ -343,12 +358,30 @@
 					break;
 				case MONITOR_RGB:
 				case MONITOR_TV:
-					XBIOS_nummodes = xbiosnummodes_f30rvb;
-					XBIOS_modelist = xbiosmodelist_f30rvb;
+					SDL_XBIOS_AddMode(this, BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|COL80,640,200,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|OVERSCAN,384,240,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|VERTFLAG,320,400,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16,320,200,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|COL80,640,200,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|OVERSCAN,384,240,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|VERTFLAG,320,400,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8,320,200,8,SDL_FALSE);
 					break;
 				case MONITOR_VGA:
-					XBIOS_nummodes = xbiosnummodes_f30vga;
-					XBIOS_modelist = xbiosmodelist_f30vga;
+					SDL_XBIOS_AddMode(this, BPS16,320,480,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS16|VERTFLAG,320,240,16,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|COL80,640,480,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8,320,480,8,SDL_FALSE);
+					SDL_XBIOS_AddMode(this, BPS8|VERTFLAG,320,240,8,SDL_FALSE);
 					break;
 			}
 			XBIOS_oldvbase=Logbase();
@@ -386,10 +419,10 @@
 
 			break;
 	}
-	
+
 	current_mode = XBIOS_modelist;
 	j8 = j16 = 0;
-	for (i=0;i<XBIOS_nummodes;i++) {
+	for (i=0; i<XBIOS_nummodes; i++, current_mode++) {
 		switch (current_mode->depth) {
 			case 4:
 			case 8:
@@ -398,7 +431,6 @@
 				SDL_modelist[0][j8]->w = current_mode->width;
 				SDL_modelist[0][j8]->h = current_mode->height;
 				XBIOS_videomodes[0][j8]=current_mode;
-				current_mode++;
 				j8++;
 				break;
 			case 16:
@@ -407,7 +439,6 @@
 				SDL_modelist[1][j16]->w = current_mode->width;
 				SDL_modelist[1][j16]->h = current_mode->height;
 				XBIOS_videomodes[1][j16]=current_mode;
-				current_mode++;
 				j16++;
 				break;
 		}		
@@ -891,6 +922,12 @@
 		}
 	}
 
+	if (XBIOS_modelist) {
+		free(XBIOS_modelist);
+		XBIOS_nummodes=0;
+		XBIOS_modelist=NULL;
+	}
+
 	this->screen->pixels = NULL;	
 }
 
--- a/src/video/xbios/SDL_xbios.h	Wed Mar 02 17:17:26 2005 +0000
+++ b/src/video/xbios/SDL_xbios.h	Mon Mar 07 10:00:58 2005 +0000
@@ -124,4 +124,9 @@
 #define XBIOS_width			(this->hidden->width)
 #define XBIOS_height		(this->hidden->height)
 
+/*--- Functions prototypes ---*/
+
+void SDL_XBIOS_AddMode(_THIS, Uint16 modecode, Uint16 width, Uint16 height,
+	Uint16 depth, SDL_bool flags);
+
 #endif /* _SDL_xbios_h */
--- a/src/video/xbios/SDL_xbios_blowup.c	Wed Mar 02 17:17:26 2005 +0000
+++ b/src/video/xbios/SDL_xbios_blowup.c	Mon Mar 07 10:00:58 2005 +0000
@@ -26,68 +26,44 @@
 	Patrice Mandin
 */
 
+#include <mint/falcon.h>
+
 #include "SDL_xbios.h"
 #include "SDL_xbios_blowup.h"
 
 void SDL_XBIOS_BlowupInit(_THIS, blow_cookie_t *cookie_blow)
 {
-	int i, num_mode, bank, keep_old;
-	xbiosmode_t *current_mode;
+	int i, num_mode, bank;
 	blow_mode_t *blow_mode;
 
-	current_mode = XBIOS_modelist;
+	/* Add bit 15 for old modes */
 	for (i=0;i<XBIOS_nummodes;i++) {
-		keep_old=1;	/* use default mode */
-		blow_mode = NULL;
-		switch (current_mode->depth) {
-			case 1:
-				num_mode=0;
-				break;
-			case 2:
-				num_mode=1;
-				break;
-			case 4:
-				num_mode=2;
-				break;
-			case 8:
-				num_mode=3;
-				break;
-			case 16:
-				num_mode=4;
-				break;
-			default:
-				num_mode=-1;
-				break;
-		}
+		XBIOS_modelist[i].number |= 1<<15;
+	}
+
+	/* Add Blowup modes for 8 and 16 bpp */
+	for (num_mode=3; num_mode<5; num_mode++) {
+		bank = cookie_blow->num_mode[num_mode];
+		blow_mode = &(cookie_blow->blowup_modes[num_mode+(bank*5)]);
 
-		/* Check which bank of modes to use */
-		if (num_mode>=0) {
-			bank = cookie_blow->num_mode[num_mode];
-			blow_mode = &(cookie_blow->blowup_modes[num_mode+(bank*5)]);
-	
-			/* Check extended mode enabled */
-			if (blow_mode->enabled == 0) {
-				/* Check monitor needed for this mode */
-				if ((blow_mode->monitor == cookie_blow->montype)
-					|| ((blow_mode->monitor == MONITOR_TV)
-						&& (cookie_blow->montype == MONITOR_RGB))
-					|| ((blow_mode->monitor == MONITOR_RGB)
-						&& (cookie_blow->montype == MONITOR_TV)))
-				{
-					keep_old = 0; /* we can use this extended mode */
-				}
+		/* Check extended mode enabled */
+		if (blow_mode->enabled == 0) {
+			/* Check monitor needed for this mode */
+			if ((blow_mode->monitor == cookie_blow->montype)
+				|| ((blow_mode->monitor == MONITOR_TV)
+					&& (cookie_blow->montype == MONITOR_RGB))
+				|| ((blow_mode->monitor == MONITOR_RGB)
+					&& (cookie_blow->montype == MONITOR_TV)))
+			{
+				/* we can use this extended mode */
+				SDL_XBIOS_AddMode(this,
+					num_mode == 3 ? BPS8 : BPS16,
+					blow_mode->width + 1,
+					blow_mode->height + 1,
+					num_mode == 3 ? 8 : 16,
+					SDL_FALSE
+				);
 			}
 		}
-
-		if (keep_old) {
-			/* disable blowup for this mode */
-			current_mode->number |= (1<<15);	
-		} else {
-			/* Update mode size */
-			current_mode->width = blow_mode->width +1;
-			current_mode->height = blow_mode->height +1;
-		}
-
-		current_mode++;
 	}
 }
--- a/src/video/xbios/SDL_xbios_sb3.c	Wed Mar 02 17:17:26 2005 +0000
+++ b/src/video/xbios/SDL_xbios_sb3.c	Mon Mar 07 10:00:58 2005 +0000
@@ -67,14 +67,19 @@
 	scpn_screeninfo_t *scrinfo;
 
 	/* SB3 prevent changing video modes, we can only use current one */
-
-	XBIOS_nummodes = 1;
-	current_mode = XBIOS_modelist;	
-	current_mode->number = -1;
+	if (XBIOS_modelist) {
+		free(XBIOS_modelist);
+		XBIOS_nummodes = 0;
+		XBIOS_modelist = NULL;
+	}
 
 	scrinfo = cookie_scpn->screen_info;
-	current_mode->width = scrinfo->virtual_width;
-	current_mode->height = scrinfo->virtual_height;
-	current_mode->depth = 1<<(SDL_XBIOS_scpn_planes_device[scrinfo->device]);
 	scrinfo->h_pos = scrinfo->v_pos = 0;
+
+	SDL_XBIOS_AddMode(this,
+		-1,
+		scrinfo->virtual_width, scrinfo->virtual_height,
+		1<<(SDL_XBIOS_scpn_planes_device[scrinfo->device]),
+		SDL_FALSE
+	);
 }