Add "horplus" cvar to get Hor+ behavior with default FOV

If "horplus" is set, the "fov" cvar is interpreted as the horizontal FOV
in a 4:3 screen, and is adapted automatically to the current screen
aspect ratio accordingly. If not set, use the old Vert- approach.

In addition, "horplus" can also be set from the video menu by selecting
the "Auto" option for aspect ratio, which also resets the FOV value to the
standard 90 degrees.

Finally, add a 5:4 aspect ratio (1280x1024) and correct the 16:9 angle
slightly.
This commit is contained in:
Ricardo Garcia 2012-10-28 10:20:46 +01:00
parent a9bea1ede8
commit 74beca0d11
4 changed files with 85 additions and 12 deletions

View File

@ -24,6 +24,7 @@
* =======================================================================
*/
#include <math.h>
#include "header/client.h"
extern struct model_s *cl_mod_powerscreen;
@ -724,6 +725,28 @@ CL_AddViewWeapon(player_state_t *ps, player_state_t *ops)
V_AddEntity(&gun);
}
/*
* Adapts a 4:3 aspect FOV to the current aspect (Hor+)
*/
static inline float
AdaptFov(float fov, float w, float h)
{
static const float pi = M_PI; /* float instead of double */
if (w <= 0 || h <= 0)
return fov;
/*
* Formula:
*
* fov = 2.0 * atan(width / height * 3.0 / 4.0 * tan(fov43 / 2.0))
*
* The code below is equivalent but precalculates a few values and
* converts between degrees and radians when needed.
*/
return (atanf(tanf(fov / 360.0f * pi) * (w / h * 0.75f)) / pi * 360.0f);
}
/*
* Sets cl.refdef view values
*/
@ -731,7 +754,7 @@ void
CL_CalcViewValues(void)
{
int i;
float lerp, backlerp;
float lerp, backlerp, ifov;
frame_t *oldframe;
player_state_t *ps, *ops;
@ -820,7 +843,15 @@ CL_CalcViewValues(void)
AngleVectors(cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
/* interpolate field of view */
cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
ifov = ops->fov + lerp * (ps->fov - ops->fov);
if (horplus->value)
{
cl.refdef.fov_x = AdaptFov(ifov, cl.refdef.width, cl.refdef.height);
}
else
{
cl.refdef.fov_x = ifov;
}
/* don't interpolate blend color */
for (i = 0; i < 4; i++)

View File

@ -87,6 +87,7 @@ cvar_t *name;
cvar_t *skin;
cvar_t *rate;
cvar_t *fov;
cvar_t *horplus;
cvar_t *msg;
cvar_t *hand;
cvar_t *gender;
@ -538,6 +539,7 @@ CL_InitLocal(void)
msg = Cvar_Get("msg", "1", CVAR_USERINFO | CVAR_ARCHIVE);
hand = Cvar_Get("hand", "0", CVAR_USERINFO | CVAR_ARCHIVE);
fov = Cvar_Get("fov", "90", CVAR_USERINFO | CVAR_ARCHIVE);
horplus = Cvar_Get("horplus", "1", CVAR_ARCHIVE);
gender = Cvar_Get("gender", "male", CVAR_USERINFO | CVAR_ARCHIVE);
gender_auto = Cvar_Get("gender_auto", "1", CVAR_ARCHIVE);
gender->modified = false;

View File

@ -287,6 +287,7 @@ extern cvar_t *cl_lightlevel;
extern cvar_t *cl_paused;
extern cvar_t *cl_timedemo;
extern cvar_t *cl_vwep;
extern cvar_t *horplus;
typedef struct
{

View File

@ -113,8 +113,24 @@ ApplyChanges(void *unused)
Cvar_SetValue("gl_mode", -1);
}
/* fov */
/* horplus */
if (s_aspect_list.curvalue == 0)
{
if (horplus->value != 1)
{
Cvar_SetValue("horplus", 1);
}
}
else
{
if (horplus->value != 0)
{
Cvar_SetValue("horplus", 0);
}
}
/* fov */
if (s_aspect_list.curvalue == 0 || s_aspect_list.curvalue == 1)
{
if (fov->value != 90)
{
@ -122,7 +138,15 @@ ApplyChanges(void *unused)
Cvar_SetValue("fov", 90);
}
}
else if (s_aspect_list.curvalue == 1)
else if (s_aspect_list.curvalue == 2)
{
if (fov->value != 86)
{
/* Restarts automatically */
Cvar_SetValue("fov", 86);
}
}
else if (s_aspect_list.curvalue == 3)
{
if (fov->value != 100)
{
@ -130,12 +154,12 @@ ApplyChanges(void *unused)
Cvar_SetValue("fov", 100);
}
}
else if (s_aspect_list.curvalue == 2)
else if (s_aspect_list.curvalue == 4)
{
if (fov->value != 105)
if (fov->value != 106)
{
/* Restarts automatically */
Cvar_SetValue("fov", 105);
Cvar_SetValue("fov", 106);
}
}
@ -185,7 +209,9 @@ VID_MenuInit(void)
};
static const char *aspect_names[] = {
"Auto",
"4:3",
"5:4",
"16:10",
"16:9",
"Custom",
@ -219,27 +245,40 @@ VID_MenuInit(void)
CVAR_USERINFO | CVAR_ARCHIVE);
}
if (!horplus)
{
horplus = Cvar_Get("horplus", "1", CVAR_ARCHIVE);
}
if (!fov)
{
fov = Cvar_Get("fov", "90", CVAR_USERINFO | CVAR_ARCHIVE);
}
if (fov->value == 90)
if (horplus->value == 1)
{
s_aspect_list.curvalue = 0;
}
else if (fov->value == 100)
else if (fov->value == 90)
{
s_aspect_list.curvalue = 1;
}
else if (fov->value == 105)
else if (fov->value == 86)
{
s_aspect_list.curvalue = 2;
}
else
else if (fov->value == 100)
{
s_aspect_list.curvalue = 3;
}
else if (fov->value == 106)
{
s_aspect_list.curvalue = 4;
}
else
{
s_aspect_list.curvalue = 5;
}
/* custom mode */
if (gl_mode->value >= 0)
@ -270,7 +309,7 @@ VID_MenuInit(void)
s_mode_list.generic.y = 0;
s_mode_list.itemnames = resolutions;
s_aspect_list.generic.type = MTYPE_SPINCONTROL;
s_aspect_list.generic.type = MTYPE_SPINCONTROL;
s_aspect_list.generic.name = "aspect ratio";
s_aspect_list.generic.x = 0;
s_aspect_list.generic.y = 10;