Video Mode Change in (Windows) GLQuake
Video Mode Change in (Windows) GLQuake
Downloads
1. Changed source files (5) (download)
heavy changes: gl_vidnt.c
very minor changes: host.c, menu.c, menu.h, vid.h
2. Example glquake.exe (download)
Due to the complexity of the changes in gl_vidnt.c you may be better off using a file comparison tool to assist like [free + gpl] WinMerge or another comparison tool (link) to assist adding this in to an engine rather than using the tutorial. Here are some WinMerge screenshots, but there are several file comparison tools that do a good job.
Adding Video Mode Change To GLQuake
This ranks up there as one of the more complicated things to add to the GLQuake engine. As a result, not many have this but this number is now up at least 6: DarkPlaces, FTEQW, Fitzquake, ezQuake, Qrack, ProQuake 3.99 .. I'm not aware of any others but maybe some other actively developed engine has this or will have in the next version (MHQuake?).
This tutorial is going to be based mostly on the FitzQuake version of video mode [except we aren't going to allow bits-per-pixel mode switching] and partially on the Qrack version. Additionally, this is double initialization where GLQuake will start up and set the video mode possibly twice.
To support video mode switching, we'll need to restructure the fun things that need done once, to be done once. We'll need to restructure things that need done every time you do a mode change for that as well.
In addition, we'll be addressing 2 issues:
1. Increasing max video modes to 600 (was 30).
2. Because it is in this file, fixing the ALT-TAB problem where with some video cards you can gradually get the screen more and more offcenter.
And ...
3. We'll need a menu to control this.
4. We'll need to alter the writing of the cvars to config.
Due to the complexity, I'll upload the changed glquake source files too.
Begin:
Let's hit the easy files first before hitting the big dawg, gl_vidnt.c
1. vid.h
Which we will do next time in 18 easy steps!
This ranks up there as one of the more complicated things to add to the GLQuake engine. As a result, not many have this but this number is now up at least 6: DarkPlaces, FTEQW, Fitzquake, ezQuake, Qrack, ProQuake 3.99 .. I'm not aware of any others but maybe some other actively developed engine has this or will have in the next version (MHQuake?).
This tutorial is going to be based mostly on the FitzQuake version of video mode [except we aren't going to allow bits-per-pixel mode switching] and partially on the Qrack version. Additionally, this is double initialization where GLQuake will start up and set the video mode possibly twice.
The Basics of What Needs DoneBits per pixel. That requires a lot more work, maybe some time in the future I'll add that into this tutorial but the reason is that you need to clear and reload the textures ... especially the 2D graphics ... and maybe some other fun stuff.
To support video mode switching, we'll need to restructure the fun things that need done once, to be done once. We'll need to restructure things that need done every time you do a mode change for that as well.
In addition, we'll be addressing 2 issues:
1. Increasing max video modes to 600 (was 30).
2. Because it is in this file, fixing the ALT-TAB problem where with some video cards you can gradually get the screen more and more offcenter.
And ...
3. We'll need a menu to control this.
4. We'll need to alter the writing of the cvars to config.
Due to the complexity, I'll upload the changed glquake source files too.
Begin:
Let's hit the easy files first before hitting the big dawg, gl_vidnt.c
1. vid.h
2. menu.cOpen vid.h and find "extern void (*vid_menukeyfn)(int key);" and add immediately after:
Code: Select all
#ifdef GLQUAKE extern void (*vid_menucmdfn)(void); //johnfitz #endif
3. menu.hLocate this: Add the yellow and delete/cut the red text:
We are moving m_state to menu.h.void (*vid_menucmdfn)(void); //johnfitz
void (*vid_menudrawfn)(void);
void (*vid_menukeyfn)(int key);
enum {m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_net, m_options, m_video, m_keys, m_help, m_quit, m_serialconfig, m_modemconfig, m_lanconfig, m_gameoptions, m_search, m_slist} m_state;
4. host.cAdd this to the bottom of menu.h
enum {m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_net, m_options, m_video, m_keys, m_help, m_quit, m_serialconfig, m_modemconfig, m_lanconfig, m_gameoptions, m_search, m_slist} m_state;
All the easy files have been done. All that remains is gl_vidnt.c.In Host_WriteConfiguration add the yellow text:
We need to refresh the vid_width, vid_height, etc. values before writing them to the config. We are hackily adding a vid_restart command to the end of config.cfg.VID_SyncCvars (); //johnfitz -- write actual current mode to config file, in case cvars were messed with
Key_WriteBindings (f);
Cvar_WriteVariables (f);
fprintf (f, "vid_restart\n");
A better way would be to read the vid_width and vid_height values after reading the configuration file and checking to see if they changed. Maybe.
Which we will do next time in 18 easy steps!
gl_vidnt.c
5.1 Locate and make alike:
5.2 Locate, add the yellow for refresh rate support:
These are our supporting cvars and other variables that allow us do this and keep track of things:
5.1 Locate and make alike:
30 video modes is too few on displays that support a lot of different width x height x bpp x refresh rate hz combinations.#define MAX_MODE_LIST 600
5.2 Locate, add the yellow for refresh rate support:
5.3 Find the declaration of cvar_t vid_mode and add the yellow:typedef struct {
modestate_t type;
int width;
int height;
int modenum;
int dib;
int fullscreen;
int bpp;
int refreshrate; //johnfitz
int halfscreen;
char modedesc[17];
} vmode_t;
These are our supporting cvars and other variables that allow us do this and keep track of things:
qboolean gl_mtexable = false;
qboolean video_options_disabled = false;
int desktop_bpp; // query this @ startup and when entering the video menu
void VID_Menu_Init (void); //johnfitz
void VID_Menu_f (void); //johnfitz
qboolean vid_locked = false; //johnfitz
int vid_current_bpp;//R00k
void GL_SetupState (void); //johnfitz
//====================================
//johnfitz -- new cvars
cvar_t vid_fullscreen = {"vid_fullscreen", "1", true};
cvar_t vid_width = {"vid_width", "640", true};
cvar_t vid_height = {"vid_height", "480", true};
int vid_bpp;
cvar_t vid_refreshrate = {"vid_refreshrate", "60", true};
//johnfitz
cvar_t vid_mode = {"vid_mode","0", false};
5.4 In VID_SetWindowedMode, locate this:
Replace with this so the console width and height change as needed on restart in windowed mode.
5.5 VID_SetFullDIBMode, add the yellow to store refresh rate:
Add our new supporting functions for VID_Restart, sync'ing the cvars, and our "VID_Test".
(Your VID_Test won't wait 5 seconds and revert like FitzQuake .. if you want that, borrow the changes to scr_modalmessage in FitzQuake to add a timeout option.)
Code: Select all
if (vid.conheight > modelist[modenum].height)
vid.conheight = modelist[modenum].height;
if (vid.conwidth > modelist[modenum].width)
vid.conwidth = modelist[modenum].width;
vid.width = vid.conwidth;
vid.height = vid.conheight;
Code: Select all
//johnfitz -- stuff
vid.width = modelist[modenum].width;
vid.height = modelist[modenum].height;
vid.conwidth = vid.width & 0xFFFFFFF8;
vid.conheight = vid.conwidth * vid.height / vid.width;
//johnfitz
5.6 VID_SetFullDIBMode (again!), comment old old console sizing stuff with /* --- */ and add the yellow. Console sizing again:gdevmode.dmPelsHeight = modelist[modenum].height;
gdevmode.dmDisplayFrequency = modelist[modenum].refreshrate; //johnfitz -- refreshrate
gdevmode.dmSize = sizeof (gdevmode);
5.7 VID_SetMode, locate and add the yellow. This restarts the mouse -- particularly important with -dinput command line parameter./* if (vid.conheight > modelist[modenum].height)
vid.conheight = modelist[modenum].height;
if (vid.conwidth > modelist[modenum].width)
vid.conwidth = modelist[modenum].width; */
vid.width = modelist[modenum].width;
vid.height = modelist[modenum].height;
vid.conwidth = vid.width & 0xFFFFFFF8;
vid.conheight = vid.conwidth * vid.height / vid.width;
vid.numpages = 2;
5.8 Above this:VID_SetPalette (palette);
vid.recalc_refdef = 1;
//R00k mouse died on mode change
IN_StartupMouse ();
return true;
}
Code: Select all
/*
================
VID_UpdateWindowStatus
================
*/
(Your VID_Test won't wait 5 seconds and revert like FitzQuake .. if you want that, borrow the changes to scr_modalmessage in FitzQuake to add a timeout option.)
Code: Select all
/*
===================
VID_Restart -- johnfitz -- change video modes on the fly
===================
*/
void VID_SyncCvars (void);
//void VID_Conwidth_Reset (void);
void VID_Restart (void)
{
HDC hdc;
HGLRC hrc;
int i;
qboolean mode_changed = false;
vmode_t oldmode;
if (vid_locked)
return;
//
// check cvars against current mode
//
if (vid_fullscreen.value)
{
if (modelist[vid_default].type == MS_WINDOWED)
mode_changed = true;
else if (modelist[vid_default].refreshrate != (int)vid_refreshrate.value)
mode_changed = true;
}
else
if (modelist[vid_default].type != MS_WINDOWED)
mode_changed = true;
if (modelist[vid_default].width != (int)vid_width.value ||
modelist[vid_default].height != (int)vid_height.value)
mode_changed = true;
if (mode_changed)
{
//
// decide which mode to set
//
oldmode = modelist[vid_default];
if (vid_fullscreen.value)
{
for (i=1; i<nummodes; i++)
{
if (modelist[i].width == (int)vid_width.value &&
modelist[i].height == (int)vid_height.value &&
modelist[i].bpp == (int)vid_bpp &&
modelist[i].refreshrate == (int)vid_refreshrate.value)
{
break;
}
}
if (i == nummodes)
{
Con_Printf ("%dx%dx%d %dHz is not a valid fullscreen mode\n",
(int)vid_width.value,
(int)vid_height.value,
(int)vid_bpp,
(int)vid_refreshrate.value);
return;
}
windowed = false;
vid_default = i;
}
else //not fullscreen
{
hdc = GetDC (NULL);
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
{
Con_Printf ("Can't run windowed on non-RGB desktop\n");
ReleaseDC (NULL, hdc);
return;
}
ReleaseDC (NULL, hdc);
if (vid_width.value < 320)
{
Con_Printf ("Window width can't be less than 320\n");
return;
}
if (vid_height.value < 200)
{
Con_Printf ("Window height can't be less than 200\n");
return;
}
modelist[0].width = (int)vid_width.value;
modelist[0].height = (int)vid_height.value;
sprintf (modelist[0].modedesc, "%dx%dx%d %dHz",
modelist[0].width,
modelist[0].height,
modelist[0].bpp,
modelist[0].refreshrate);
windowed = true;
vid_default = 0;
}
//
// destroy current window
//
hrc = wglGetCurrentContext();
hdc = wglGetCurrentDC();
wglMakeCurrent(NULL, NULL);
vid_canalttab = false;
if (hdc && dibwindow)
ReleaseDC (dibwindow, hdc);
if (modestate == MS_FULLDIB)
ChangeDisplaySettings (NULL, 0);
if (maindc && dibwindow)
ReleaseDC (dibwindow, maindc);
maindc = NULL;
if (dibwindow)
DestroyWindow (dibwindow);
//
// set new mode
//
VID_SetMode (vid_default, host_basepal);
maindc = GetDC(mainwindow);
bSetupPixelFormat(maindc);
// if bpp changes, recreate render context and reload textures
if (modelist[vid_default].bpp != oldmode.bpp)
{
wglDeleteContext (hrc);
hrc = wglCreateContext (maindc);
if (!wglMakeCurrent (maindc, hrc))
Sys_Error ("VID_Restart: wglMakeCurrent failed");
GL_SetupState ();
}
else
if (!wglMakeCurrent (maindc, hrc))
#if 1
{
char szBuf[80];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
sprintf(szBuf, "VID_Restart: wglMakeCurrent failed with error %d: %s", dw, lpMsgBuf);
Sys_Error (szBuf);
}
#else
Sys_Error ("VID_Restart: wglMakeCurrent failed");
#endif
vid_canalttab = true;
}
}
/*
================
VID_Test -- johnfitz -- like vid_restart, but asks for confirmation after switching modes
================
*/
void VID_Test (void)
{
vmode_t oldmode;
qboolean mode_changed = false;
if (vid_locked)
return;
//
// check cvars against current mode
//
if (vid_fullscreen.value)
{
if (modelist[vid_default].type == MS_WINDOWED)
mode_changed = true;
/* else if (modelist[vid_default].bpp != (int)vid_bpp.value)
mode_changed = true; */
else if (modelist[vid_default].refreshrate != (int)vid_refreshrate.value)
mode_changed = true;
}
else
if (modelist[vid_default].type != MS_WINDOWED)
mode_changed = true;
if (modelist[vid_default].width != (int)vid_width.value ||
modelist[vid_default].height != (int)vid_height.value)
mode_changed = true;
if (!mode_changed)
return;
//
// now try the switch
//
oldmode = modelist[vid_default];
VID_Restart ();
//pop up confirmation dialoge
if (!SCR_ModalMessage("Would you like to keep this\nvideo mode? (y/n)\n"))
{
//revert cvars and mode
Cvar_Set ("vid_width", va("%i", oldmode.width));
Cvar_Set ("vid_height", va("%i", oldmode.height));
Cvar_Set ("vid_bpp", va("%i", oldmode.bpp));
Cvar_Set ("vid_refreshrate", va("%i", oldmode.refreshrate));
Cvar_Set ("vid_fullscreen", (oldmode.type == MS_WINDOWED) ? "0" : "1");
VID_Restart ();
}
}
/*
================
VID_Unlock -- johnfitz
================
*/
void VID_Unlock (void)
{
vid_locked = false;
//sync up cvars in case they were changed during the lock
Cvar_Set ("vid_width", va("%i", modelist[vid_default].width));
Cvar_Set ("vid_height", va("%i", modelist[vid_default].height));
Cvar_Set ("vid_refreshrate", va("%i", modelist[vid_default].refreshrate));
Cvar_Set ("vid_fullscreen", (windowed) ? "0" : "1");
}
5.9 Now we need the GL initiation split into 2 pieces, the part that needs done once vs. the setup that needs to occur duriing any video mode switch.
So the Locate GL_Init, Find this and ....
And replace with this:
5.10 Find VID_InitDIB and add or match with the yellow:
This is to support our refreshrate hz.
So the Locate GL_Init, Find this and ....
Code: Select all
/*
===============
GL_Init
===============
*/
void GL_Init (void)
{
gl_vendor = glGetString (GL_VENDOR);
Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
gl_renderer = glGetString (GL_RENDERER);
Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
gl_version = glGetString (GL_VERSION);
Con_Printf ("GL_VERSION: %s\n", gl_version);
gl_extensions = glGetString (GL_EXTENSIONS);
Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
if (strnicmp(gl_renderer,"PowerVR",7)==0)
fullsbardraw = true;
if (strnicmp(gl_renderer,"Permedia",8)==0)
isPermedia = true;
CheckTextureExtensions ();
CheckMultiTextureExtensions ();
glClearColor (1,0,0,0);
glCullFace(GL_FRONT);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.666);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glShadeModel (GL_FLAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#if 0
CheckArrayExtensions ();
glEnable (GL_VERTEX_ARRAY_EXT);
glEnable (GL_TEXTURE_COORD_ARRAY_EXT);
glVertexPointerEXT (3, GL_FLOAT, 0, 0, &glv.x);
glTexCoordPointerEXT (2, GL_FLOAT, 0, 0, &glv.s);
glColorPointerEXT (3, GL_FLOAT, 0, 0, &glv.r);
#endif
}
Code: Select all
/*
===============
GL_SetupState -- johnfitz
does all the stuff from GL_Init that needs to be done every time a new GL render context is created
GL_Init will still do the stuff that only needs to be done once
===============
*/
void GL_SetupState (void) {
glClearColor (1,0,0,0);
glCullFace(GL_FRONT);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.666);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glShadeModel (GL_FLAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
/*
===============
GL_Init
===============
*/
void GL_Init (void)
{
gl_vendor = glGetString (GL_VENDOR);
Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
gl_renderer = glGetString (GL_RENDERER);
Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
gl_version = glGetString (GL_VERSION);
Con_Printf ("GL_VERSION: %s\n", gl_version);
gl_extensions = glGetString (GL_EXTENSIONS);
Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
if (strnicmp(gl_renderer,"PowerVR",7)==0)
fullsbardraw = true;
if (strnicmp(gl_renderer,"Permedia",8)==0)
isPermedia = true;
CheckTextureExtensions ();
CheckMultiTextureExtensions ();
#if 0
CheckArrayExtensions ();
glEnable (GL_VERTEX_ARRAY_EXT);
glEnable (GL_TEXTURE_COORD_ARRAY_EXT);
glVertexPointerEXT (3, GL_FLOAT, 0, 0, &glv.x);
glTexCoordPointerEXT (2, GL_FLOAT, 0, 0, &glv.s);
glColorPointerEXT (3, GL_FLOAT, 0, 0, &glv.r);
#endif
GL_SetupState (); //johnfitz
}
5.11 In "VID_InitFullDIB" add or change to the yellow:void VID_InitDIB (HINSTANCE hInstance)
{
DEVMODE devmode; //johnfitz
WNDCLASS wc;
HDC hdc;
int i;
/* Register the frame class */
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = "WinQuake";
if (!RegisterClass (&wc) )
Sys_Error ("Couldn't register window class");
modelist[0].type = MS_WINDOWED;
if (COM_CheckParm("-width"))
modelist[0].width = Q_atoi(com_argv[COM_CheckParm("-width")+1]);
else
modelist[0].width = 640;
if (modelist[0].width < 320)
modelist[0].width = 320;
if (COM_CheckParm("-height"))
modelist[0].height= Q_atoi(com_argv[COM_CheckParm("-height")+1]);
else
modelist[0].height = modelist[0].width * 240/320;
if (modelist[0].height < 200) //johnfitz -- was 240
modelist[0].height = 200; //johnfitz -- was 240
//johnfitz -- get desktop bit depth
hdc = GetDC(NULL);
modelist[0].bpp = desktop_bpp = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(NULL, hdc);
//johnfitz
//johnfitz -- get refreshrate
if (EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &devmode))
modelist[0].refreshrate = devmode.dmDisplayFrequency;
//johnfitz
sprintf (modelist[0].modedesc, "%dx%dx%d %dHz", //johnfitz -- added bpp, refreshrate
modelist[0].width,
modelist[0].height,
modelist[0].bpp, //johnfitz -- added bpp
modelist[0].refreshrate); //johnfitz -- added refreshrate
modelist[0].modenum = MODE_WINDOWED;
modelist[0].dib = 1;
modelist[0].fullscreen = 0;
modelist[0].halfscreen = 0;
// modelist[0].bpp = 0; // Baker says <--- no! Keep same bpp!
nummodes = 1;
}
This is to support our refreshrate hz.
/*
=================
VID_InitFullDIB
=================
*/
void VID_InitFullDIB (HINSTANCE hInstance)
{
DEVMODE devmode;
int i, modenum, cmodes, originalnummodes, existingmode, numlowresmodes;
int j, bpp, done;
BOOL stat;
// enumerate >8 bpp modes
originalnummodes = nummodes;
modenum = 0;
do
{
stat = EnumDisplaySettings (NULL, modenum, &devmode);
if ((devmode.dmBitsPerPel >= 15) &&
(devmode.dmPelsWidth <= MAXWIDTH) &&
(devmode.dmPelsHeight <= MAXHEIGHT) &&
(nummodes < MAX_MODE_LIST))
{
devmode.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_DISPLAYFREQUENCY; //johnfitz -- refreshrate
if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) ==
DISP_CHANGE_SUCCESSFUL)
{
modelist[nummodes].type = MS_FULLDIB;
modelist[nummodes].width = devmode.dmPelsWidth;
modelist[nummodes].height = devmode.dmPelsHeight;
modelist[nummodes].modenum = 0;
modelist[nummodes].halfscreen = 0;
modelist[nummodes].dib = 1;
modelist[nummodes].fullscreen = 1;
modelist[nummodes].bpp = devmode.dmBitsPerPel;
modelist[nummodes].refreshrate = devmode.dmDisplayFrequency; //johnfitz -- refreshrate
sprintf (modelist[nummodes].modedesc, "%dx%dx%d %dHz", //johnfitz -- refreshrate
devmode.dmPelsWidth,
devmode.dmPelsHeight,
devmode.dmBitsPerPel,
devmode.dmDisplayFrequency); //johnfitz -- refreshrate
// if the width is more than twice the height, reduce it by half because this
// is probably a dual-screen monitor
if (!COM_CheckParm("-noadjustaspect"))
{
if (modelist[nummodes].width > (modelist[nummodes].height << 1))
{
modelist[nummodes].width >>= 1;
modelist[nummodes].halfscreen = 1;
sprintf (modelist[nummodes].modedesc, "%dx%dx%d %dHz", //johnfitz -- refreshrate
modelist[nummodes].width,
modelist[nummodes].height,
modelist[nummodes].bpp,
modelist[nummodes].refreshrate); //johnfitz -- refreshrate
}
}
for (i=originalnummodes, existingmode = 0 ; i<nummodes ; i++)
{
if ((modelist[nummodes].width == modelist.width) &&
(modelist[nummodes].height == modelist.height) &&
(modelist[nummodes].bpp == modelist.bpp) &&
(modelist[nummodes].refreshrate == modelist.refreshrate)) //johnfitz -- refreshrate
{
existingmode = 1;
break;
}
}
if (!existingmode)
{
nummodes++;
}
}
}
modenum++;
} while (stat);
// see if there are any low-res modes that aren't being reported
numlowresmodes = sizeof(lowresmodes) / sizeof(lowresmodes[0]);
bpp = 16;
done = 0;
do
{
for (j=0 ; (j<numlowresmodes) && (nummodes < MAX_MODE_LIST) ; j++)
{
devmode.dmBitsPerPel = bpp;
devmode.dmPelsWidth = lowresmodes[j].width;
devmode.dmPelsHeight = lowresmodes[j].height;
devmode.dmFields = DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
DM_DISPLAYFREQUENCY; //johnfitz -- refreshrate;
if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) ==
DISP_CHANGE_SUCCESSFUL)
{
modelist[nummodes].type = MS_FULLDIB;
modelist[nummodes].width = devmode.dmPelsWidth;
modelist[nummodes].height = devmode.dmPelsHeight;
modelist[nummodes].modenum = 0;
modelist[nummodes].halfscreen = 0;
modelist[nummodes].dib = 1;
modelist[nummodes].fullscreen = 1;
modelist[nummodes].bpp = devmode.dmBitsPerPel;
modelist[nummodes].refreshrate = devmode.dmDisplayFrequency; //johnfitz -- refreshrate
sprintf (modelist[nummodes].modedesc, "%dx%dx%d %dHz", //johnfitz -- refreshrate
devmode.dmPelsWidth,
devmode.dmPelsHeight,
devmode.dmBitsPerPel,
devmode.dmDisplayFrequency); //johnfitz -- refreshrate
for (i=originalnummodes, existingmode = 0 ; i<nummodes ; i++)
{
if ((modelist[nummodes].width == modelist.width) &&
(modelist[nummodes].height == modelist.height) &&
(modelist[nummodes].bpp == modelist.bpp) &&
(modelist[nummodes].refreshrate == modelist.refreshrate)) //johnfitz -- refreshrate
{
existingmode = 1;
break;
}
}
if (!existingmode)
{
nummodes++;
}
}
}
switch (bpp)
{
case 16:
bpp = 32;
break;
case 32:
bpp = 24;
break;
case 24:
done = 1;
break;
}
} while (!done);
if (nummodes == originalnummodes)
Con_SafePrintf ("No fullscreen DIB modes found\n");
}
5.12 In VID_Init, add the yellow
/*
===================
VID_Init
===================
*/
void VID_Init (unsigned char *palette)
{
int i, existingmode;
int basenummodes, width, height, bpp, findbpp, done;
byte *ptmp;
char gldir[MAX_OSPATH];
HDC hdc;
DEVMODE devmode;
memset(&devmode, 0, sizeof(devmode));
Cvar_RegisterVariable (&vid_fullscreen); //johnfitz
Cvar_RegisterVariable (&vid_width); //johnfitz
Cvar_RegisterVariable (&vid_height); //johnfitz
Cvar_RegisterVariable (&vid_refreshrate); //johnfitz
Cmd_AddCommand ("vid_unlock", VID_Unlock); //johnfitz
Cmd_AddCommand ("vid_restart", VID_Restart); //johnfitz
Cmd_AddCommand ("vid_test", VID_Test); //johnfitz
Cvar_RegisterVariable (&vid_mode);
Cvar_RegisterVariable (&vid_wait);
Cvar_RegisterVariable (&vid_nopageflip);
Cvar_RegisterVariable (&_vid_wait_override);
Cvar_RegisterVariable (&_vid_default_mode);
Cvar_RegisterVariable (&_vid_default_mode_win);
Cvar_RegisterVariable (&vid_config_x);
Cvar_RegisterVariable (&vid_config_y);
Cvar_RegisterVariable (&vid_stretch_by_2);
Cvar_RegisterVariable (&_windowed_mouse);
Cvar_RegisterVariable (&gl_ztrick);
Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f);
Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f);
Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f);
hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2));
InitCommonControls();
VID_InitDIB (global_hInstance);
basenummodes = nummodes = 1;
VID_InitFullDIB (global_hInstance);
if (COM_CheckParm("-window"))
{
hdc = GetDC (NULL);
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
{
Sys_Error ("Can't run in non-RGB mode");
}
ReleaseDC (NULL, hdc);
windowed = true;
video_options_disabled = true;
vid_default = MODE_WINDOWED;
}
else
{
if (nummodes == 1)
Sys_Error ("No RGB fullscreen modes available");
windowed = false;
if (COM_CheckParm("-mode"))
{
vid_default = Q_atoi(com_argv[COM_CheckParm("-mode")+1]);
}
else
{
if (COM_CheckParm("-current"))
{
modelist[MODE_FULLSCREEN_DEFAULT].width =
GetSystemMetrics (SM_CXSCREEN);
modelist[MODE_FULLSCREEN_DEFAULT].height =
GetSystemMetrics (SM_CYSCREEN);
vid_default = MODE_FULLSCREEN_DEFAULT;
leavecurrentmode = 1;
}
else
{
if (COM_CheckParm("-width"))
{
width = Q_atoi(com_argv[COM_CheckParm("-width")+1]);
}
else
{
width = 640;
}
if (COM_CheckParm("-bpp"))
{
bpp = Q_atoi(com_argv[COM_CheckParm("-bpp")+1]);
findbpp = 0;
}
else
{
bpp = desktop_bpp; // Baker: match the desktop bpp if not specified, was 15
findbpp = 1;
}
if (COM_CheckParm("-height"))
height = Q_atoi(com_argv[COM_CheckParm("-height")+1]);
// if they want to force it, add the specified mode to the list
if (COM_CheckParm("-force") && (nummodes < MAX_MODE_LIST))
{
modelist[nummodes].type = MS_FULLDIB;
modelist[nummodes].width = width;
modelist[nummodes].height = height;
modelist[nummodes].modenum = 0;
modelist[nummodes].halfscreen = 0;
modelist[nummodes].dib = 1;
modelist[nummodes].fullscreen = 1;
modelist[nummodes].bpp = bpp;
sprintf (modelist[nummodes].modedesc, "%dx%dx%d %dHz", //johnfitz -- refreshrate
devmode.dmPelsWidth,
devmode.dmPelsHeight,
devmode.dmBitsPerPel,
devmode.dmDisplayFrequency); //johnfitz -- refreshrate
for (i=nummodes, existingmode = 0 ; i<nummodes ; i++)
{
if ((modelist[nummodes].width == modelist.width) &&
(modelist[nummodes].height == modelist.height) &&
(modelist[nummodes].bpp == modelist.bpp) &&
(modelist[nummodes].refreshrate == modelist.refreshrate)) //johnfitz -- refreshrate
{
existingmode = 1;
break;
}
}
if (!existingmode)
{
nummodes++;
}
}
done = 0;
do
{
if (COM_CheckParm("-height"))
{
height = Q_atoi(com_argv[COM_CheckParm("-height")+1]);
for (i=1, vid_default=0 ; i<nummodes ; i++)
{
if ((modelist.width == width) &&
(modelist.height == height) &&
(modelist.bpp == bpp))
{
vid_default = i;
done = 1;
break;
}
}
}
else
{
for (i=1, vid_default=0 ; i<nummodes ; i++)
{
if ((modelist.width == width) && (modelist.bpp == bpp))
{
vid_default = i;
done = 1;
break;
}
}
}
if (!done)
{
if (findbpp)
{
switch (bpp)
{
case 15:
bpp = 16;
break;
case 16:
bpp = 32;
break;
case 32:
bpp = 24;
break;
case 24:
done = 1;
break;
}
}
else
{
done = 1;
}
}
} while (!done);
vid_bpp = bpp;
if (!vid_default)
{
Sys_Error ("Specified video mode not available");
}
}
}
}
vid_initialized = true;
if ((i = COM_CheckParm("-conwidth")) != 0)
vid.conwidth = Q_atoi(com_argv[i+1]);
else
vid.conwidth = 640;
vid.conwidth &= 0xfff8; // make it a multiple of eight
if (vid.conwidth < 320)
vid.conwidth = 320;
// pick a conheight that matches with correct aspect
vid.conheight = vid.conwidth*3 / 4;
if ((i = COM_CheckParm("-conheight")) != 0)
vid.conheight = Q_atoi(com_argv[i+1]);
if (vid.conheight < 200)
vid.conheight = 200;
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
vid.colormap = host_colormap;
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
DestroyWindow (hwnd_dialog);
Check_Gamma(palette);
VID_SetPalette (palette);
VID_SetMode (vid_default, palette);
maindc = GetDC(mainwindow);
bSetupPixelFormat(maindc);
baseRC = wglCreateContext( maindc );
if (!baseRC)
Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\nMake sure you in are 65535 color mode, and try running -window.");
if (!wglMakeCurrent( maindc, baseRC ))
Sys_Error ("wglMakeCurrent failed");
GL_Init ();
sprintf (gldir, "%s/glquake", com_gamedir);
Sys_mkdir (gldir);
vid_realmode = vid_modenum;
// Check for 3DFX Extensions and initialize them.
VID_Init8bitPalette();
vid_menucmdfn = VID_Menu_f; //johnfitz
vid_menudrawfn = VID_MenuDraw;
vid_menukeyfn = VID_MenuKey;
strcpy (badmode.modedesc, "Bad mode");
vid_canalttab = true;
if (COM_CheckParm("-fullsbar"))
fullsbardraw = true;
VID_Menu_Init(); //johnfitz
//johnfitz -- command line vid settings should override config file settings.
//so we have to lock the vid mode from now until after all config files are read.
if (COM_CheckParm("-width") || COM_CheckParm("-height") || COM_CheckParm("-bpp") || COM_CheckParm("-window"))
{
vid_locked = true;
}
//johnfitz
}
AND FINALLY:
5.13 Find all this code:
I guess the changes to gl_vidnt.c can be done in 13 steps, not 18.
Your new cvars are:
5.13 Find all this code:
And replace with our new video menu:Code: Select all
//======================================================== // Video menu stuff //======================================================== extern void M_Menu_Options_f (void); extern void M_Print (int cx, int cy, char *str); extern void M_PrintWhite (int cx, int cy, char *str); extern void M_DrawCharacter (int cx, int line, int num); extern void M_DrawTransPic (int x, int y, qpic_t *pic); extern void M_DrawPic (int x, int y, qpic_t *pic); static int vid_line, vid_wmodes; typedef struct { int modenum; char *desc; int iscur; } modedesc_t; #define MAX_COLUMN_SIZE 9 #define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 2) #define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) static modedesc_t modedescs[MAX_MODEDESCS]; /* ================ VID_MenuDraw ================ */ void VID_MenuDraw (void) { qpic_t *p; char *ptr; int lnummodes, i, j, k, column, row, dup, dupmode; char temp[100]; vmode_t *pv; p = Draw_CachePic ("gfx/vidmodes.lmp"); M_DrawPic ( (320-p->width)/2, 4, p); vid_wmodes = 0; lnummodes = VID_NumModes (); for (i=1 ; (i<lnummodes) && (vid_wmodes < MAX_MODEDESCS) ; i++) { ptr = VID_GetModeDescription (i); pv = VID_GetModePtr (i); k = vid_wmodes; modedescs[k].modenum = i; modedescs[k].desc = ptr; modedescs[k].iscur = 0; if (i == vid_modenum) modedescs[k].iscur = 1; vid_wmodes++; } if (vid_wmodes > 0) { M_Print (2*8, 36+0*8, "Fullscreen Modes (WIDTHxHEIGHTxBPP)"); column = 8; row = 36+2*8; for (i=0 ; i<vid_wmodes ; i++) { if (modedescs[i].iscur) M_PrintWhite (column, row, modedescs[i].desc); else M_Print (column, row, modedescs[i].desc); column += 13*8; if ((i % VID_ROW_SIZE) == (VID_ROW_SIZE - 1)) { column = 8; row += 8; } } } M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*2, "Video modes must be set from the"); M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*3, "command line with -width <width>"); M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, "and -bpp <bits-per-pixel>"); M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*6, "Select windowed mode with -window"); } /* ================ VID_MenuKey ================ */ void VID_MenuKey (int key) { switch (key) { case K_ESCAPE: S_LocalSound ("misc/menu1.wav"); M_Menu_Options_f (); break; default: break; } }
And we are done. Compile and run.Code: Select all
/* ================ VID_SyncCvars -- johnfitz -- set vid cvars to match current video mode ================ */ extern qboolean vid_consize_ignore_callback; void VID_SyncCvars (void) { Cvar_Set ("vid_width", va("%i", modelist[vid_default].width)); Cvar_Set ("vid_height", va("%i", modelist[vid_default].height)); Cvar_Set ("vid_refreshrate", va("%i", modelist[vid_default].refreshrate)); Cvar_Set ("vid_fullscreen", (windowed) ? "0" : "1"); } //========================================================================== // // NEW VIDEO MENU -- johnfitz // //========================================================================== extern void M_Menu_Options_f (void); extern void M_Print (int cx, int cy, char *str); extern void M_PrintWhite (int cx, int cy, char *str); extern void M_DrawCharacter (int cx, int line, int num); extern void M_DrawTransPic (int x, int y, qpic_t *pic); extern void M_DrawPic (int x, int y, qpic_t *pic); extern void M_DrawCheckbox (int x, int y, int on); extern qboolean m_entersound; #define VIDEO_OPTIONS_ITEMS 6 int video_cursor_table[] = {48, 56, 64, 72, 88, 96}; int video_options_cursor = 0; typedef struct {int width,height;} vid_menu_mode; //TODO: replace these fixed-length arrays with hunk_allocated buffers vid_menu_mode vid_menu_modes[MAX_MODE_LIST]; int vid_menu_nummodes=0; //int vid_menu_bpps[4]; //int vid_menu_numbpps=0; int vid_menu_rates[20]; int vid_menu_numrates=0; /* ================ VID_Menu_Init ================ */ void VID_Menu_Init (void) { int i,j,h,w; for (i=1;i<nummodes;i++) //start i at mode 1 because 0 is windowed mode { w = modelist[i].width; h = modelist[i].height; for (j=0;j<vid_menu_nummodes;j++) { if (vid_menu_modes[j].width == w && vid_menu_modes[j].height == h) break; } if (j==vid_menu_nummodes) { vid_menu_modes[j].width = w; vid_menu_modes[j].height = h; vid_menu_nummodes++; } } } /* ================ VID_Menu_RebuildRateList regenerates rate list based on current vid_width, vid_height and vid_bpp ================ */ void VID_Menu_RebuildRateList (void) { int i,j,r; vid_menu_numrates=0; for (i=1;i<nummodes;i++) //start i at mode 1 because 0 is windowed mode { //rate list is limited to rates available with current width/height/bpp if (modelist[i].width != vid_width.value || modelist[i].height != vid_height.value /*|| modelist[i].bpp != vid_bpp.value*/) continue; r = modelist[i].refreshrate; for (j=0;j<vid_menu_numrates;j++) { if (vid_menu_rates[j] == r) break; } if (j==vid_menu_numrates) { vid_menu_rates[j] = r; vid_menu_numrates++; } } //if vid_refreshrate is not in the new list, change vid_refreshrate for (i=0;i<vid_menu_numrates;i++) if (vid_menu_rates[i] == (int)(vid_refreshrate.value)) break; if (i==vid_menu_numrates) Cvar_Set ("vid_refreshrate",va("%i",vid_menu_rates[0])); } /* ================ VID_Menu_ChooseNextMode chooses next resolution in order, then updates vid_width and vid_height cvars, then updates bpp and refreshrate lists ================ */ void VID_Menu_ChooseNextMode (int dir) { int i; for (i=0;i<vid_menu_nummodes;i++) { if (vid_menu_modes[i].width == vid_width.value && vid_menu_modes[i].height == vid_height.value) break; } if (i==vid_menu_nummodes) //can't find it in list, so it must be a custom windowed res { i = 0; } else { i+=dir; if (i>=vid_menu_nummodes) i = 0; else if (i<0) i = vid_menu_nummodes-1; } Cvar_Set ("vid_width",va("%i",vid_menu_modes[i].width)); Cvar_Set ("vid_height",va("%i",vid_menu_modes[i].height)); VID_Menu_RebuildRateList (); } /* ================ VID_Menu_ChooseNextRate chooses next refresh rate in order, then updates vid_refreshrate cvar ================ */ void VID_Menu_ChooseNextRate (int dir) { int i; for (i=0;i<vid_menu_numrates;i++) { if (vid_menu_rates[i] == vid_refreshrate.value) break; } if (i==vid_menu_numrates) //can't find it in list { i = 0; } else { i+=dir; if (i>=vid_menu_numrates) i = 0; else if (i<0) i = vid_menu_numrates-1; } Cvar_Set ("vid_refreshrate",va("%i",vid_menu_rates[i])); } /* ================ VID_MenuKey ================ */ void VID_MenuKey (int key) { switch (key) { case K_ESCAPE: VID_SyncCvars (); //sync cvars before leaving menu. FIXME: there are other ways to leave menu S_LocalSound ("misc/menu1.wav"); M_Menu_Options_f (); break; case K_UPARROW: S_LocalSound ("misc/menu1.wav"); video_options_cursor--; if (video_options_cursor < 0) video_options_cursor = VIDEO_OPTIONS_ITEMS-1; break; case K_DOWNARROW: S_LocalSound ("misc/menu1.wav"); video_options_cursor++; if (video_options_cursor >= VIDEO_OPTIONS_ITEMS) video_options_cursor = 0; break; case K_LEFTARROW: S_LocalSound ("misc/menu3.wav"); switch (video_options_cursor) { case 0: VID_Menu_ChooseNextMode (-1); break; case 1: //VID_Menu_ChooseNextBpp (-1); break; case 2: VID_Menu_ChooseNextRate (-1); break; case 3: Cbuf_AddText ("toggle vid_fullscreen\n"); break; case 4: case 5: default: break; } break; case K_RIGHTARROW: S_LocalSound ("misc/menu3.wav"); switch (video_options_cursor) { case 0: VID_Menu_ChooseNextMode (1); break; case 1: //VID_Menu_ChooseNextBpp (1); break; case 2: VID_Menu_ChooseNextRate (1); break; case 3: if (vid_bpp == desktop_bpp) Cbuf_AddText ("toggle vid_fullscreen\n"); break; case 4: case 5: default: break; } break; case K_ENTER: m_entersound = true; switch (video_options_cursor) { case 0: VID_Menu_ChooseNextMode (1); break; case 1: //VID_Menu_ChooseNextBpp (1); break; case 2: VID_Menu_ChooseNextRate (1); break; case 3: if (vid_bpp == desktop_bpp) Cbuf_AddText ("toggle vid_fullscreen\n"); break; case 4: Cbuf_AddText ("vid_test\n"); break; case 5: Cbuf_AddText ("vid_restart\n"); break; default: break; } break; default: break; } } /* ================ VID_MenuDraw ================ */ void VID_MenuDraw (void) { int i = 0; qpic_t *p; char *title; M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp")); //p = Draw_CachePic ("gfx/vidmodes.lmp"); p = Draw_CachePic ("gfx/p_option.lmp"); M_DrawPic ( (320-p->width)/2, 4, p); // title title = "Video Options"; M_PrintWhite ((320-8*strlen(title))/2, 32, title); // options M_Print (16, video_cursor_table[i], " Video mode"); M_Print (216, video_cursor_table[i], va("%ix%i", (int)vid_width.value, (int)vid_height.value)); i++; M_Print (16, video_cursor_table[i], " Color depth"); M_Print (216, video_cursor_table[i], va("%i [locked]", (int)vid_bpp)); i++; M_Print (16, video_cursor_table[i], " Refresh rate"); M_Print (216, video_cursor_table[i], va("%i Hz", (int)vid_refreshrate.value)); i++; M_Print (16, video_cursor_table[i], " Fullscreen"); if (vid_bpp == desktop_bpp) M_DrawCheckbox (216, video_cursor_table[i], (int)vid_fullscreen.value); else M_Print (216, video_cursor_table[i], va("%s [locked]", (int)vid_fullscreen.value ? "on" : "off")); i++; M_Print (16, video_cursor_table[i], " Test changes"); i++; M_Print (16, video_cursor_table[i], " Apply changes"); // cursor M_DrawCharacter (200, video_cursor_table[video_options_cursor], 12+((int)(realtime*4)&1)); // notes "345678901234567890123456789012345678" // M_Print (16, 172, "Windowed modes always use the desk- "); // M_Print (16, 180, "top color depth, and can never be "); // M_Print (16, 188, "larger than the desktop resolution. "); } /* ================ VID_Menu_f ================ */ void VID_Menu_f (void) { key_dest = key_menu; m_state = m_video; m_entersound = true; //set all the cvars to match the current mode when entering the menu VID_SyncCvars (); //set up bpp and rate lists based on current cvars VID_Menu_RebuildRateList (); }
I guess the changes to gl_vidnt.c can be done in 13 steps, not 18.
Your new cvars are:
THE ENDvid_width
vid_height
vid_fullscreen
and so forth
Your new commands are vid_restart and vid_test.
To change the video mode, go Options -> Video Mode.
To create an ALT-ENTER like alias, you could create an alias like:
alias fullscreen_toggle "toggle vid_fullscreen; vid_restart"
Except GLQuake doesn't have a toggle command, but you could borrow the toggle command from cvar.c in FitzQuake 0.80 if you wanted.
Then if you wanted ALT-ENTER support, go to keys.c and detect ENTER with a ALT state of down and have it execute "toggle vid_fullscreen; vid_restart"if you like.
Find note, you should really do this as well in gl_vidnt.c. I didn't include it in the above:
Additionally in gl_vidnt.c, really you should add the Nvidia ALT-TAB fix. I forgot to include this in the above:r00k wrote:In my addition to adding alt-enter,
i had to implement this bitCode: Select all
case WM_ACTIVATE: fActive = LOWORD(wParam); fMinimized = (BOOL) HIWORD(wParam); AppActivate(!(fActive == WA_INACTIVE), fMinimized); // fix the leftover Alt from any Alt-Tab or the like that switched us away Key_ClearAllStates(); //R00k re-init the mouse after alt-tabbing please... (v1.9) if (!mouseactive) { IN_Shutdown (); IN_StartupMouse(); IN_ActivateMouse (); IN_HideMouse (); } break;
This keeps the window from drifting off center, a flaw in the Nvidia OpenGL drivers.AppActivate in gl_vidnt.c wrote: if (fActive) {
if (modestate == MS_FULLDIB) {
IN_ActivateMouse ();
IN_HideMouse ();
if (vid_canalttab && vid_wassuspended) {
vid_wassuspended = false;
ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN);
ShowWindow(mainwindow, SW_SHOWNORMAL);
// Baker 3.80x - Fix for alt-tab bug in NVidia drivers from JoeQuake
MoveWindow (mainwindow, 0, 0, gdevmode.dmPelsWidth, gdevmode.dmPelsHeight, false);
}
} else if ((modestate == MS_WINDOWED) && _windowed_mouse.value && key_dest == key_game) {
IN_ActivateMouse ();
IN_HideMouse ();
}
}
'uknown command: toggle'.
other than that, an ATI driver will 90% bug on you. Not instantly, but perhaps after a few map changes.
Run it windowed and just change the framebuffer size, and the next textures that are loaded (next map?) will be corrupted.
This is the method that carmack reported that *all* cards bugged out on in one way or another.
A more reliable way is to compleatly shut down the opengl renderer, and create a fresh new context. You'll need to load new textures, but quake doesn't really use anything that matters.
other than that, an ATI driver will 90% bug on you. Not instantly, but perhaps after a few map changes.
Run it windowed and just change the framebuffer size, and the next textures that are loaded (next map?) will be corrupted.
This is the method that carmack reported that *all* cards bugged out on in one way or another.
A more reliable way is to compleatly shut down the opengl renderer, and create a fresh new context. You'll need to load new textures, but quake doesn't really use anything that matters.
Baker, I think Spike is referring to the bug you yourself reported to me, where your (Intel?) card would report "wglMakeCurrent failed" when you tried to switch just resolution, but it worked if you also changed color depth. I sent you a patch that addressed it, but as you mentioned above, you can't really create a new context without a good way to reload textures, which isn't available in stock glquake.Spike wrote:This is the method that carmack reported that *all* cards bugged out on in one way or another. A more reliable way is to compleatly shut down the opengl renderer, and create a fresh new context.
Oversight. That's right, the FitzQuake fullscreen vs. windowed mode menu uses the toggle command and I didn't change it or add it in.Spike wrote:'uknown command: toggle'.
Must fix tutorial. Thanks for the heads up.
I tested from the console and then did a quick and dirty menu test but didn't think to try to fullscreen ON/OFF in the menu.
I don't have a machine with an ATI card to test, but I'll research the above more and see if I can do it "right" next the time I get a chance.other than that, an ATI driver will 90% bug on you. Not instantly, but perhaps after a few map changes.
Run it windowed and just change the framebuffer size, and the next textures that are loaded (next map?) will be corrupted.
This is the method that carmack reported that *all* cards bugged out on in one way or another.
A more reliable way is to compleatly shut down the opengl renderer, and create a fresh new context. You'll need to load new textures, but quake doesn't really use anything that matters.
Sometime I'll have more time to finish studying the FitzQuake texture manager and incorporate the "re-use context" patch.metlslime wrote:Baker, I think Spike is referring to the bug you yourself reported to me, where your (Intel?) card would report "wglMakeCurrent failed" when you tried to switch just resolution, but it worked if you also changed color depth. I sent you a patch that addressed it, but as you mentioned above, you can't really create a new context without a good way to reload textures, which isn't available in stock glquake.
I know the above isn't absolutely perfect yet (aside from the accidental incorporation of the toggle command, which I will fix).
/By the way, the machine with the "wglMakeCurrent failed" issue was a GeForce Go 6150, not an Intel.
GLQuake as it is (was) is not really a good engine to mod.ceriux wrote:hey i went to do this tutorial, but all the things you said to replace or what ever were already done when i used your download files. but the thing is, my console looks weird now...
You'll have to fix 50 things before you get it to be "decent" or maybe just 10-12 if you want it to be merely "ok".
Why not use FitzQuake 0.85 as a starting point --- it already has this kind of feature too while retaining stock GLQuake compatibility from all other aspects?
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..