Fixes for widescreen displays (Part 1: 2D)

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Fixes for widescreen displays (Part 1: 2D)

Post by mh »

OK, I posted parts of this one on QuakeSrc back in the day, but it didn't survive the Great Catastrophe, so here it is again in improved, debugged and 2008 form.

If you've ever played Quake on a widescreen display, you'll have noticed that while the width is correct, the top and bottom of the 3D views is cut off. You can obviously fix this by setting the value of the fov cvar to something higher (102 worked well for me), but you shouldn't have to. You'll also have noticed that the console, status bar pictures and menus are stretched. These two tutorials will resolve all of that.

The first one we're going to do is the 2D stuff, but before I even start anything...

BEGIN DISCLAIMER
Some people may feel that a wider FOV is cheating. I'm taking the viewpoint that as Quake lets you set the FOV anyway, there is no cheating involved, at least beyond what's possible with normal Quake. Server administrators should propose a protocol extension that requires servers to examine FOV settings and enforce them on clients if there are any bad feelings about this.
END DISCLAIMER

OK, down to code.

The first thing we're going to do is fix the 2D stuff, so open gl_vidnt.c and pop this function somewhere in it. Near the top is good.

Code: Select all

void Vid_SetConSize (int modewidth, int modeheight)
{
	// adjust conwidth and conheight to match the mode aspect
	// they should be the same aspect as the mode, with width never less than 320 and height never less than 240
	vid.conheight = 240;
	vid.conwidth = 240 * modewidth / modeheight;

	// bring it up to 320
	if (vid.conwidth < 320)
	{
		vid.conwidth = 320;
		vid.conheight = vid.conwidth * modeheight / modewidth;
	}

	// set width and height
	vid.width = vid.conwidth;
	vid.height = vid.conheight;
}
Here we're setting a console size of 320x240, then adjusting for the aspect ratio. We never let width go below 320 or height below 240.

Now we need to call this function, so go to VID_SetMode and slap it above the "window_width = DIBWidth;" line, thusly:

Code: Select all

	Vid_SetConSize (DIBWidth, DIBHeight);

	window_width = DIBWidth;
	window_height = DIBHeight;
	VID_UpdateWindowStatus ();
Compile and run now, and you'll see that you have a huge console (but correctly proportioned), so next up we're going to give you the ability to arbitrarily scale it. Before that, we need to fix the console drawing routine so that it picks up the correct size each time, so open gl_draw.c and replace Draw_ConsoleBackground with this:

Code: Select all

void Draw_ConsoleBackground (int lines)
{
	int y = (vid.height * 3) >> 2;

	conback->width = vid.width;
	conback->height = vid.height;

	if (lines > y)
		Draw_Pic(0, lines - vid.height, conback);
	else
		Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
}
All that we're doing here is updating the console picture size each time it's drawn, so that it's always correct, as we're going to be changing the values of vid.width and vid.height shortly.

Now we need to create a cvar to allow us to control the size, so we open gl_screen.c and declare and register a cvar in the normal fashion. Let's call it "gl_consize". I assume you know how to do this already, but here we go anyway:

Code: Select all

// this one at the top with the other cvars
cvar_t		gl_consize = {"gl_consize", "0.5", true};

	// this one in SCR_Init with the rest of them
	Cvar_RegisterVariable (&gl_consize);
We'll also declare a float to keep track of changes to the value of this, so go find the declaration of oldscreensize and oldfov and change it to:

Code: Select all

float		oldscreensize, oldfov, oldconsize;
Getting there but it does nothing yet, so next we go to SCR_CalcRefdef and squeeze some code in there to re-evaluate the sizes. I've given the lines before and after the inserted block here so you should be able to find it easily.

Code: Select all

	size /= 100.0;

	// bound console size
	if (gl_consize.value < 0) Cvar_Set ("gl_consize", "0");
	if (gl_consize.value > 1) Cvar_Set ("gl_consize", "1");

	// recalculate vid.width and vid.height
	vid.width = (glwidth - vid.conwidth) * gl_consize.value + vid.conwidth;
	vid.height = (glheight - vid.conheight) * gl_consize.value + vid.conheight;

	h = vid.height - sb_lines;
It's important to do this here, as the viewing rectangle will also change it's dimensions (owing to a shrinking or enlarging status bar height), meaning that FOV and everything else will need to be recalculated.

Now we go to SCR_UpdateScreen and pop this code in between the viewsize and fov checks:

Code: Select all

	if (oldconsize != gl_consize.value)
	{
		oldconsize = gl_consize.value;
		vid.recalc_refdef = true;
	}
All we're doing here is checking for a change in it's value, and recalculating the view if so.

And that is that! You could clean up by removing the -conwidth and -conheight command line options, or get fancy and add a menu option to control it, but that's up to you.

Next we're going to fix the FOV in the 3D view... stay tuned...
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

the original quake defaults were 320*200, not 320*240.

a few people prefer to play with the 320*200 aspect instead.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Fixes for widescreen displays (Part 1: 2D)

Post by Baker »

mh wrote:BEGIN DISCLAIMER
Some people may feel that a wider FOV is cheating. I'm taking the viewpoint that as Quake lets you set the FOV anyway, there is no cheating involved, at least beyond what's possible with normal Quake. Server administrators should propose a protocol extension that requires servers to examine FOV settings and enforce them on clients if there are any bad feelings about this.
END DISCLAIMER
My thoughts:

As long as FOV is a slider bar in the menu where everyone can see that it exists, it is a non-controversial thing.

It is unfair if player X is oblivious to it's existence while others are using it.
Post Reply