Inside3D!
     

Fixes for widescreen displays (Part 1: 2D)

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> Programming Tutorials
View previous topic :: View next topic  
Author Message
mh



Joined: 12 Jan 2008
Posts: 910

PostPosted: Thu Dec 18, 2008 11:41 pm    Post subject: Fixes for widescreen displays (Part 1: 2D) Reply with quote

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:
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:
   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:
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:
// 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:
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:
   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:
   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...
_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines
Back to top
View user's profile Send private message Visit poster's website
Spike



Joined: 05 Nov 2004
Posts: 944
Location: UK

PostPosted: Fri Dec 19, 2008 2:17 am    Post subject: Reply with quote

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

a few people prefer to play with the 320*200 aspect instead.
_________________
What's a signature?
Back to top
View user's profile Send private message Visit poster's website
Baker



Joined: 14 Mar 2006
Posts: 1538

PostPosted: Fri Dec 19, 2008 3:54 am    Post subject: Re: Fixes for widescreen displays (Part 1: 2D) Reply with quote

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.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> Programming Tutorials All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group