From a591efbb4d4d2dc0b148b2080b1884c425396f32 Mon Sep 17 00:00:00 2001 From: divverent Date: Fri, 1 Feb 2008 08:56:31 +0000 Subject: [PATCH] - vid_userefreshrate: when 0, a sane default is tried to be used - win32: list valid modes, and use the closest match - win32: vid_forcerefreshrate: don't do the listing, but just try to set it anyway git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8060 d7cf8633-e32d-0410-b094-e92efae38249 --- menu.c | 48 ++++++++++++--------- vid.h | 2 + vid_shared.c | 8 +++- vid_wgl.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 146 insertions(+), 30 deletions(-) diff --git a/menu.c b/menu.c index c0e71be0..2cdae63c 100644 --- a/menu.c +++ b/menu.c @@ -2795,7 +2795,7 @@ video_resolution_t video_resolutions[] = #define VIDEO_ITEMS 10 static int video_cursor = 0; -static int video_cursor_table[] = {56, 68, 88, 100, 112, 132, 162, 170, 178, 186}; +static int video_cursor_table[] = {56, 68, 88, 100, 108, 116, 136, 166, 174, 182, 190}; static int video_resolution; void M_Menu_Video_f (void) @@ -2852,7 +2852,7 @@ static void M_Video_Draw (void) // Current Resolution M_Print(16, video_cursor_table[0], " Current Resolution"); - if (vid_supportrefreshrate && vid.fullscreen) + if (vid_supportrefreshrate && vid.userefreshrate && vid.fullscreen) M_Print(220, video_cursor_table[0], va("%dx%d %dhz", vid.width, vid.height, vid.refreshrate)); else M_Print(220, video_cursor_table[0], va("%dx%d", vid.width, vid.height)); @@ -2867,28 +2867,32 @@ static void M_Video_Draw (void) M_Print(220, video_cursor_table[2], (vid_bitsperpixel.integer == 32) ? "32" : "16"); // Refresh Rate - M_ItemPrint(16, video_cursor_table[3], " Refresh Rate", vid_supportrefreshrate); - M_DrawSlider(220, video_cursor_table[3], vid_refreshrate.integer, 60, 150); + M_ItemPrint(16, video_cursor_table[3], " Use Refresh Rate", vid_supportrefreshrate); + M_DrawCheckbox(220, video_cursor_table[3], vid_userefreshrate.integer); + + // Refresh Rate + M_ItemPrint(16, video_cursor_table[4], " Refresh Rate", vid_supportrefreshrate && vid_userefreshrate.integer); + M_DrawSlider(220, video_cursor_table[4], vid_refreshrate.integer, 60, 150); // Fullscreen - M_Print(16, video_cursor_table[4], " Fullscreen"); - M_DrawCheckbox(220, video_cursor_table[4], vid_fullscreen.integer); + M_Print(16, video_cursor_table[5], " Fullscreen"); + M_DrawCheckbox(220, video_cursor_table[5], vid_fullscreen.integer); // "Apply" button - M_Print(220, video_cursor_table[5], "Apply"); + M_Print(220, video_cursor_table[6], "Apply"); // Vertical Sync - M_ItemPrint(16, video_cursor_table[6], " Vertical Sync", gl_videosyncavailable); - M_DrawCheckbox(220, video_cursor_table[6], vid_vsync.integer); + M_ItemPrint(16, video_cursor_table[7], " Vertical Sync", gl_videosyncavailable); + M_DrawCheckbox(220, video_cursor_table[7], vid_vsync.integer); - M_ItemPrint(16, video_cursor_table[7], " Anisotropic Filter", gl_support_anisotropy); - M_DrawSlider(220, video_cursor_table[7], gl_texture_anisotropy.integer, 1, gl_max_anisotropy); + M_ItemPrint(16, video_cursor_table[8], " Anisotropic Filter", gl_support_anisotropy); + M_DrawSlider(220, video_cursor_table[8], gl_texture_anisotropy.integer, 1, gl_max_anisotropy); - M_ItemPrint(16, video_cursor_table[8], " Texture Quality", true); - M_DrawSlider(220, video_cursor_table[8], gl_picmip.value, 3, 0); + M_ItemPrint(16, video_cursor_table[9], " Texture Quality", true); + M_DrawSlider(220, video_cursor_table[9], gl_picmip.value, 3, 0); - M_ItemPrint(16, video_cursor_table[9], " Texture Compression", gl_support_texture_compression); - M_DrawCheckbox(220, video_cursor_table[9], gl_texturecompression.integer); + M_ItemPrint(16, video_cursor_table[10], " Texture Compression", gl_support_texture_compression); + M_DrawCheckbox(220, video_cursor_table[10], gl_texturecompression.integer); // Cursor M_DrawCharacter(200, video_cursor_table[video_cursor], 12+((int)(realtime*4)&1)); @@ -2924,22 +2928,25 @@ static void M_Menu_Video_AdjustSliders (int dir) break; // Refresh Rate case 3: - Cvar_SetValueQuick (&vid_refreshrate, vid_refreshrate.integer + dir); + Cvar_SetValueQuick (&vid_userefreshrate, !vid_userefreshrate.integer); break; case 4: + Cvar_SetValueQuick (&vid_refreshrate, bound(60, vid_refreshrate.integer + dir, 150)); + break; + case 5: Cvar_SetValueQuick (&vid_fullscreen, !vid_fullscreen.integer); break; - case 6: + case 7: Cvar_SetValueQuick (&vid_vsync, !vid_vsync.integer); break; - case 7: + case 8: Cvar_SetValueQuick (&gl_texture_anisotropy, bound(1, gl_texture_anisotropy.value * (dir < 0 ? 0.5 : 2.0), gl_max_anisotropy)); break; - case 8: + case 9: Cvar_SetValueQuick (&gl_picmip, bound(0, gl_picmip.value - dir, 3)); break; - case 9: + case 10: Cvar_SetValueQuick (&gl_texturecompression, !gl_texturecompression.integer); break; } @@ -2956,6 +2963,7 @@ static void M_Video_Key (int key, char ascii) Cvar_SetValueQuick(&vid_bitsperpixel, vid.bitsperpixel); if (vid_supportrefreshrate) Cvar_SetValueQuick(&vid_refreshrate, vid.refreshrate); + Cvar_SetValueQuick(&vid_userefreshrate, vid.userefreshrate); S_LocalSound ("sound/misc/menu1.wav"); M_Menu_Options_f (); diff --git a/vid.h b/vid.h index 29ab8785..aac4edc3 100644 --- a/vid.h +++ b/vid.h @@ -34,6 +34,7 @@ typedef struct viddef_s int bitsperpixel; int fullscreen; int refreshrate; + qboolean userefreshrate; int stereobuffer; } viddef_t; @@ -53,6 +54,7 @@ extern cvar_t vid_width; extern cvar_t vid_height; extern cvar_t vid_bitsperpixel; extern cvar_t vid_refreshrate; +extern cvar_t vid_userefreshrate; extern cvar_t vid_vsync; extern cvar_t vid_mouse; extern cvar_t vid_grabkeyboard; diff --git a/vid_shared.c b/vid_shared.c index 33c194b0..da1a2e14 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -83,6 +83,7 @@ cvar_t vid_width = {CVAR_SAVE, "vid_width", "640", "resolution"}; cvar_t vid_height = {CVAR_SAVE, "vid_height", "480", "resolution"}; cvar_t vid_bitsperpixel = {CVAR_SAVE, "vid_bitsperpixel", "32", "how many bits per pixel to render at (32 or 16, 32 is recommended)"}; cvar_t vid_refreshrate = {CVAR_SAVE, "vid_refreshrate", "60", "refresh rate to use, in hz (higher values flicker less, if supported by your monitor)"}; +cvar_t vid_userefreshrate = {CVAR_SAVE, "vid_userefreshrate", "0", "set this to 1 to make vid_refreshrate used, or to 0 to let the engine choose a sane default"}; cvar_t vid_stereobuffer = {CVAR_SAVE, "vid_stereobuffer", "0", "enables 'quad-buffered' stereo rendering for stereo shutterglasses, HMD (head mounted display) devices, or polarized stereo LCDs, if supported by your drivers"}; cvar_t vid_vsync = {CVAR_SAVE, "vid_vsync", "0", "sync to vertical blank, prevents 'tearing' (seeing part of one frame and part of another on the screen at the same time), automatically disabled when doing timedemo benchmarks"}; @@ -1051,6 +1052,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&vid_height); Cvar_RegisterVariable(&vid_bitsperpixel); Cvar_RegisterVariable(&vid_refreshrate); + Cvar_RegisterVariable(&vid_userefreshrate); Cvar_RegisterVariable(&vid_stereobuffer); Cvar_RegisterVariable(&vid_vsync); Cvar_RegisterVariable(&vid_mouse); @@ -1071,7 +1073,7 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, int refreshrate, in { cl_ignoremousemoves = 2; Con_Printf("Video: %s %dx%dx%dx%dhz%s\n", fullscreen ? "fullscreen" : "window", width, height, bpp, refreshrate, stereobuffer ? " stereo" : ""); - if (VID_InitMode(fullscreen, width, height, bpp, refreshrate, stereobuffer)) + if (VID_InitMode(fullscreen, width, height, bpp, vid_userefreshrate.integer ? max(1, refreshrate) : 0, stereobuffer)) { vid.fullscreen = fullscreen; vid.width = width; @@ -1079,11 +1081,13 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, int refreshrate, in vid.bitsperpixel = bpp; vid.refreshrate = refreshrate; vid.stereobuffer = stereobuffer; + vid.userefreshrate = vid_userefreshrate.integer; Cvar_SetValueQuick(&vid_fullscreen, fullscreen); Cvar_SetValueQuick(&vid_width, width); Cvar_SetValueQuick(&vid_height, height); Cvar_SetValueQuick(&vid_bitsperpixel, bpp); - Cvar_SetValueQuick(&vid_refreshrate, refreshrate); + if(vid_userefreshrate.integer) + Cvar_SetValueQuick(&vid_refreshrate, refreshrate); Cvar_SetValueQuick(&vid_stereobuffer, stereobuffer); return true; } diff --git a/vid_wgl.c b/vid_wgl.c index 4f97d31a..638c8348 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -78,7 +78,7 @@ static dllfunction_t wglswapintervalfuncs[] = {NULL, NULL} }; -static DEVMODE gdevmode; +static DEVMODE gdevmode, initialdevmode; static qboolean vid_initialized = false; static qboolean vid_wassuspended = false; static qboolean vid_usingmouse = false; @@ -202,6 +202,8 @@ static cvar_t joy_yawsensitivity = {0, "joyyawsensitivity", "-1.0", "how fast th static cvar_t joy_wwhack1 = {0, "joywwhack1", "0.0", "special hack for wingman warrior"}; static cvar_t joy_wwhack2 = {0, "joywwhack2", "0.0", "special hack for wingman warrior"}; +static cvar_t vid_forcerefreshrate = {0, "vid_forcerefreshrate", "0", "try to set the given vid_refreshrate even if Windows doesn't list it as valid video mode"}; + static qboolean joy_avail, joy_advancedinit, joy_haspov; static DWORD joy_oldbuttonstate, joy_oldpovstate; @@ -696,6 +698,9 @@ void VID_Init(void) if (!RegisterClass (&wc)) Con_Printf ("Couldn't register window class\n"); + memset(&initialdevmode, 0, sizeof(initialdevmode)); + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &initialdevmode); + IN_Init(); } @@ -731,6 +736,8 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat int CenterX, CenterY; const char *gldrivername; int depth; + DEVMODE thismode; + qboolean foundmode, foundgoodmode; if (vid_initialized) Sys_Error("VID_InitMode called when video is already initialised"); @@ -766,13 +773,107 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int refreshrat vid_isfullscreen = false; if (fullscreen) { - gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; - gdevmode.dmBitsPerPel = bpp; - gdevmode.dmPelsWidth = width; - gdevmode.dmPelsHeight = height; - gdevmode.dmDisplayFrequency = refreshrate; - gdevmode.dmSize = sizeof (gdevmode); - if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + if(vid_forcerefreshrate.integer) + { + foundmode = true; + gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + gdevmode.dmBitsPerPel = bpp; + gdevmode.dmPelsWidth = width; + gdevmode.dmPelsHeight = height; + gdevmode.dmSize = sizeof (gdevmode); + if(refreshrate) + { + gdevmode.dmFields |= DM_DISPLAYFREQUENCY; + gdevmode.dmDisplayFrequency = refreshrate; + } + } + else + { + if(refreshrate == 0) + refreshrate = initialdevmode.dmDisplayFrequency; // default vid_refreshrate to the rate of the desktop + + foundmode = false; + foundgoodmode = false; + + thismode.dmSize = sizeof(thismode); + thismode.dmDriverExtra = 0; + for(i = 0; EnumDisplaySettings(NULL, i, &thismode); ++i) + { + if(~thismode.dmFields & (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY)) + { + Con_DPrintf("enumerating modes yielded a bogus item... please debug this\n"); + continue; + } + if(developer.integer >= 100) + Con_Printf("Found mode %dx%dx%dbpp %dHz... ", (int)thismode.dmPelsWidth, (int)thismode.dmPelsHeight, (int)thismode.dmBitsPerPel, (int)thismode.dmDisplayFrequency); + if(thismode.dmBitsPerPel != (DWORD)bpp) + { + if(developer.integer >= 100) + Con_Printf("wrong bpp\n"); + continue; + } + if(thismode.dmPelsWidth != (DWORD)width) + { + if(developer.integer >= 100) + Con_Printf("wrong width\n"); + continue; + } + if(thismode.dmPelsHeight != (DWORD)height) + { + if(developer.integer >= 100) + Con_Printf("wrong height\n"); + continue; + } + + if(foundgoodmode) + { + // if we have a good mode, make sure this mode is better than the previous one, and allowed by the refreshrate + if(thismode.dmDisplayFrequency > (DWORD)refreshrate) + { + if(developer.integer >= 100) + Con_Printf("too high refresh rate\n"); + continue; + } + else if(thismode.dmDisplayFrequency <= gdevmode.dmDisplayFrequency) + { + if(developer.integer >= 100) + Con_Printf("doesn't beat previous best match (too low)\n"); + continue; + } + } + else if(foundmode) + { + // we do have one, but it isn't good... make sure it has a lower frequency than the previous one + if(thismode.dmDisplayFrequency >= gdevmode.dmDisplayFrequency) + { + if(developer.integer >= 100) + Con_Printf("doesn't beat previous best match (too high)\n"); + continue; + } + } + // otherwise, take anything + + memcpy(&gdevmode, &thismode, sizeof(gdevmode)); + if(thismode.dmDisplayFrequency <= (DWORD)refreshrate) + foundgoodmode = true; + else + { + if(developer.integer >= 100) + Con_Printf("(out of range)\n"); + } + foundmode = true; + if(developer.integer >= 100) + Con_Printf("accepted\n"); + } + } + + if (!foundmode) + { + VID_Shutdown(); + Con_Printf("Unable to find the requested mode %dx%dx%dbpp\n", width, height, bpp); + return false; + } + else if(ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { VID_Shutdown(); Con_Printf("Unable to change to requested mode %dx%dx%dbpp\n", width, height, bpp); @@ -1774,6 +1875,7 @@ static void IN_Init(void) Cvar_RegisterVariable (&joy_yawsensitivity); Cvar_RegisterVariable (&joy_wwhack1); Cvar_RegisterVariable (&joy_wwhack2); + Cvar_RegisterVariable (&vid_forcerefreshrate); Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f, "applies current joyadv* cvar settings to the joystick driver"); } -- 2.39.2