Here we go again.mh wrote: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
This one is even easier than the last, as it all revolves around the SCR_CalcRefdef and CalcFov functions in gl_screen.c; so let's jump right in.
The first thing we do is replace CalcFov with these two:
Code: Select all
float SCR_CalcFovX (float fov_y, float width, float height)
{
float a;
float y;
// bound, don't crash
if (fov_y < 1) fov_y = 1;
if (fov_y > 179) fov_y = 179;
y = height / tan (fov_y / 360 * M_PI);
a = atan (width / y);
a = a * 360 / M_PI;
return a;
}
float SCR_CalcFovY (float fov_x, float width, float height)
{
float a;
float x;
// bound, don't crash
if (fov_x < 1) fov_x = 1;
if (fov_x > 179) fov_x = 179;
x = width / tan (fov_x / 360 * M_PI);
a = atan (height / x);
a = a * 360 / M_PI;
return a;
}
Speaking of obvious, all we're doing here is calculating an X FOV from a given Y FOV and vice-versa.
Now we need to actually use them, so pop this code into SCR_CalcRefdef. Again, I've given the line just before and after so you'll know where to insert it:
Code: Select all
r_refdef.fov_x = scr_fov.value;
// calculate y fov as if the screen was 640 x 432; this ensures that the top and bottom
// don't get clipped off if we have a widescreen display
r_refdef.fov_y = SCR_CalcFovY (r_refdef.fov_x, 640, 432);
// now recalculate fov_x so that it's correctly proportioned for fov_y
r_refdef.fov_x = SCR_CalcFovX (r_refdef.fov_y, r_refdef.vrect.width, r_refdef.vrect.height);
scr_vrect = r_refdef.vrect;
This code, by the way, will work for any aspect ratio - there's no need to check for a widescreen display aspect as part of it. However, you might notice that if you have a display that's narrower than 4:3 you'll start losing stuff at the sides. Fortunately, this is rarer, and even at the only common resolution it affects (1280 x 1024) there's no dramatic loss.
We really should fix that too, though, but that's a project for another day!