[quake3] [PATCH] set custom resolution from UI

Ludwig Nussel ludwig.nussel at suse.de
Thu Aug 16 11:56:41 EDT 2007


Erik Auerswald wrote:
> the attached patch adds setting the custom resolution (r_mode -1,
> r_customwidth and r_customheight) to the menu.

What about something like the following patch? It stores the list of
available video modes (SDL_ListModes) in a cvar and optionally uses
that in the menu instead of the builtin list.

Index: code/q3_ui/ui_video.c
===================================================================
--- code/q3_ui/ui_video.c	(Revision 1124)
+++ code/q3_ui/ui_video.c	(Arbeitskopie)
@@ -24,6 +24,66 @@
 
 void GraphicsOptions_MenuInit( void );
 
+static const char *builtin_resolutions[] = 
+{
+	"320x240",
+	"400x300",
+	"512x384",
+	"640x480",
+	"800x600",
+	"960x720",
+	"1024x768",
+	"1152x864",
+	"1280x1024",
+	"1600x1200",
+	"2048x1536",
+	"856x480 wide screen",
+	NULL
+};
+
+char resbuf[MAX_STRING_CHARS];
+const char* detected_resolutions[32];
+
+const char** reslist = builtin_resolutions;
+int use_builtin_resolutions = qtrue;
+
+static int det2builtinres(int mode)
+{
+	int i;
+
+	if(use_builtin_resolutions)
+		return mode;
+
+	if(mode < 0)
+		return -1;
+
+	for(i = 0; builtin_resolutions[i]; ++i)
+	{
+		if(!strcmp(builtin_resolutions[i], detected_resolutions[mode]))
+			return i;
+	}
+	return -1;
+}
+
+static int builtin2detres(int mode)
+{
+	int i;
+
+	if(use_builtin_resolutions)
+		return mode;
+
+	if(mode < 0)
+		return -1;
+
+	for(i = 0; detected_resolutions[i]; ++i)
+	{
+		if(!strcmp(builtin_resolutions[mode], detected_resolutions[i]))
+			return i;
+	}
+	return -1;
+}
+
+
 /*
 =======================================================================
 
@@ -359,7 +419,7 @@
 			continue;
 		if ( s_ivo_templates[i].driver != s_graphicsoptions.driver.curvalue )
 			continue;
-		if ( s_ivo_templates[i].mode != s_graphicsoptions.mode.curvalue )
+		if ( s_ivo_templates[i].mode != s_graphicsoptions.mode.curvalue)
 			continue;
 		if ( s_ivo_templates[i].fullscreen != s_graphicsoptions.fs.curvalue )
 			continue;
@@ -419,7 +479,7 @@
 
 	s_graphicsoptions.apply.generic.flags |= QMF_HIDDEN|QMF_INACTIVE;
 
-	if ( s_ivo.mode != s_graphicsoptions.mode.curvalue )
+	if ( s_ivo.mode != s_graphicsoptions.mode.curvalue)
 	{
 		s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE);
 	}
@@ -487,7 +547,28 @@
 	}
 	trap_Cvar_SetValue( "r_picmip", 3 - s_graphicsoptions.tq.curvalue );
 	trap_Cvar_SetValue( "r_allowExtensions", s_graphicsoptions.allow_extensions.curvalue );
-	trap_Cvar_SetValue( "r_mode", s_graphicsoptions.mode.curvalue );
+
+	if(!use_builtin_resolutions)
+	{
+		// search for builtin mode that matches the detected mode
+		int i;
+		int mode = s_graphicsoptions.mode.curvalue;
+		i = det2builtinres(mode);
+		if(i == -1)
+		{
+			char w[16], h[16];
+			Q_strncpyz(w, detected_resolutions[mode], sizeof(w));
+			*strchr(w, 'x') = 0;
+			Q_strncpyz(h, strchr(detected_resolutions[mode], 'x')+1, sizeof(h));
+			trap_Cvar_Set( "r_customwidth", w);
+			trap_Cvar_Set( "r_customheight", h);
+		}
+
+		trap_Cvar_SetValue( "r_mode", i );
+	}
+	else
+		trap_Cvar_SetValue( "r_mode", s_graphicsoptions.mode.curvalue );
+
 	trap_Cvar_SetValue( "r_fullscreen", s_graphicsoptions.fs.curvalue );
 	trap_Cvar_Set( "r_glDriver", ( char * ) s_drivers[s_graphicsoptions.driver.curvalue] );
 	switch ( s_graphicsoptions.colordepth.curvalue )
@@ -637,9 +718,33 @@
 static void GraphicsOptions_SetMenuItems( void )
 {
 	s_graphicsoptions.mode.curvalue = trap_Cvar_VariableValue( "r_mode" );
+	s_graphicsoptions.mode.curvalue = builtin2detres(s_graphicsoptions.mode.curvalue);
 	if ( s_graphicsoptions.mode.curvalue < 0 )
 	{
-		s_graphicsoptions.mode.curvalue = 3;
+		if(use_builtin_resolutions)
+		{
+			s_graphicsoptions.mode.curvalue = 3;
+		}
+		else
+		{
+			int i;
+			char buf[MAX_STRING_CHARS];
+			trap_Cvar_VariableStringBuffer("r_customwidth", buf, sizeof(buf)-2);
+			buf[strlen(buf)+1] = 0;
+			buf[strlen(buf)] = 'x';
+			trap_Cvar_VariableStringBuffer("r_customheight", buf+strlen(buf), sizeof(buf)-strlen(buf));
+
+			for(i = 0; detected_resolutions[i]; ++i)
+			{
+				if(!strcmp(buf, detected_resolutions[i]))
+				{
+					s_graphicsoptions.mode.curvalue = i;
+					break;
+				}
+			}
+			if ( s_graphicsoptions.mode.curvalue < 0 )
+				s_graphicsoptions.mode.curvalue = 0;
+		}
 	}
 	s_graphicsoptions.fs.curvalue = trap_Cvar_VariableValue("r_fullscreen");
 	s_graphicsoptions.allow_extensions.curvalue = trap_Cvar_VariableValue("r_allowExtensions");
@@ -765,22 +870,6 @@
 		NULL
 	};
 
-	static const char *resolutions[] = 
-	{
-		"320x240",
-		"400x300",
-		"512x384",
-		"640x480",
-		"800x600",
-		"960x720",
-		"1024x768",
-		"1152x864",
-		"1280x1024",
-		"1600x1200",
-		"2048x1536",
-		"856x480 wide screen",
-		NULL
-	};
 	static const char *filter_names[] =
 	{
 		"Bilinear",
@@ -806,6 +895,27 @@
 	// zero set all our globals
 	memset( &s_graphicsoptions, 0 ,sizeof(graphicsoptions_t) );
 
+
+	Q_strncpyz(resbuf, UI_Cvar_VariableString("r_availableModes"), sizeof(resbuf));
+	if(*resbuf)
+	{
+		char* e;
+		char* s = resbuf;
+		unsigned i = 0;
+		while( i < sizeof(detected_resolutions)/sizeof(detected_resolutions[0])-1 && ((e = strchr(s, ' ')) != NULL || *s))
+		{
+			if(e) *e = 0;
+			detected_resolutions[i++] = s;
+			s = e+1;
+		}
+		detected_resolutions[i] = NULL;
+		if(i)
+		{
+			reslist = detected_resolutions;
+			use_builtin_resolutions = 0;
+		}
+	}
+
 	GraphicsOptions_Cache();
 
 	s_graphicsoptions.menu.wrapAround = qtrue;
@@ -910,7 +1020,7 @@
 	s_graphicsoptions.mode.generic.flags    = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
 	s_graphicsoptions.mode.generic.x        = 400;
 	s_graphicsoptions.mode.generic.y        = y;
-	s_graphicsoptions.mode.itemnames        = resolutions;
+	s_graphicsoptions.mode.itemnames        = reslist;
 	s_graphicsoptions.mode.generic.callback = GraphicsOptions_Event;
 	s_graphicsoptions.mode.generic.id       = ID_MODE;
 	y += BIGCHAR_HEIGHT+2;
Index: code/unix/sdl_glimp.c
===================================================================
--- code/unix/sdl_glimp.c	(Revision 1124)
+++ code/unix/sdl_glimp.c	(Arbeitskopie)
@@ -612,6 +612,46 @@
   }
 }
 
+static void set_available_modes(void)
+{
+  char buf[MAX_STRING_CHARS];
+  SDL_Rect **modes;
+  size_t len = 0;
+  int i;
+
+  modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
+
+  if (!modes)
+  {
+    ri.Printf( PRINT_WARNING, "Can't get list of available modes\n");
+    return;
+  }
+
+  if (modes == (SDL_Rect **)-1)
+  {
+    ri.Printf( PRINT_ALL, "Display supports any resolution\n");
+    return; // can set any resolution
+  }
+
+  for (i = 0; modes[i]; ++i)
+  {
+    if(snprintf(NULL, 0, "%ux%u ", modes[i]->w, modes[i]->h) < (int)sizeof(buf)-len)
+    {
+      len += sprintf(buf+len, "%ux%u ", modes[i]->w, modes[i]->h);
+    }
+    else
+    {
+      ri.Printf( PRINT_WARNING, "Skipping mode %ux%x, buffer too small\n", modes[i]->w, modes[i]->h);
+    }
+  }
+  if(len) 
+  {
+    buf[strlen(buf)-1] = 0;
+    ri.Printf( PRINT_ALL, "Available modes: '%s'\n", buf);
+    ri.Cvar_Set( "r_availableModes", buf );
+  }
+}
+
 /*
 ** GLW_StartDriverAndSetMode
 */
@@ -804,6 +844,8 @@
     break;
   }
 
+  set_available_modes();
+
   if (!vidscreen)
   {
     ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
@@ -1047,6 +1089,8 @@
 
   r_previousglDriver = ri.Cvar_Get( "r_previousglDriver", "", CVAR_ROM );
 
+  ri.Cvar_Get( "r_availableModes", "", CVAR_ROM );
+
   InitSig();
 
   IN_Init();   // rcg08312005 moved into glimp.

cu
Ludwig

-- 
 (o_   Ludwig Nussel
 //\   SUSE LINUX Products GmbH, Development
 V_/_  http://www.suse.de/




More information about the quake3 mailing list