16 Feb 2017

This commit is contained in:
g-cont 2017-02-16 00:00:00 +03:00 committed by Alibek Omarov
parent ae4275843b
commit 8eb9c6570d
37 changed files with 1108 additions and 981 deletions

View File

@ -461,8 +461,8 @@ void SCR_TimeRefresh_f( void )
R_BeginFrame( false ); R_BeginFrame( false );
for( i = 0; i < 128; i++ ) for( i = 0; i < 128; i++ )
{ {
cl.refdef.viewangles[1] = i / 128.0 * 360.0f; RI.viewangles[1] = i / 128.0 * 360.0f;
R_RenderFrame( &cl.refdef, true ); R_RenderScene();
} }
R_EndFrame(); R_EndFrame();
} }
@ -470,10 +470,10 @@ void SCR_TimeRefresh_f( void )
{ {
for( i = 0; i < 128; i++ ) for( i = 0; i < 128; i++ )
{ {
cl.refdef.viewangles[1] = i / 128.0 * 360.0f; RI.viewangles[1] = i / 128.0 * 360.0f;
R_BeginFrame( true ); R_BeginFrame( true );
R_RenderFrame( &cl.refdef, true ); R_RenderScene();
R_EndFrame(); R_EndFrame();
} }
} }
@ -492,6 +492,6 @@ viewpos (level-designer helper)
*/ */
void SCR_Viewpos_f( void ) void SCR_Viewpos_f( void )
{ {
Msg( "org ( %g %g %g )\n", cl.refdef.vieworg[0], cl.refdef.vieworg[1], cl.refdef.vieworg[2] ); Msg( "org ( %g %g %g )\n", RI.vieworg[0], RI.vieworg[1], RI.vieworg[2] );
Msg( "ang ( %g %g %g )\n", cl.refdef.viewangles[0], cl.refdef.viewangles[1], cl.refdef.viewangles[2] ); Msg( "ang ( %g %g %g )\n", RI.viewangles[0], RI.viewangles[1], RI.viewangles[2] );
} }

View File

@ -15,6 +15,7 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "client.h" #include "client.h"
#include "gl_local.h"
#include "net_encode.h" #include "net_encode.h"
#define dem_unknown 0 // unknown command #define dem_unknown 0 // unknown command
@ -486,7 +487,7 @@ void CL_DrawDemoRecording( void )
Q_memprint( pos ), (int)(cls.demotime / 60.0f ), (int)fmod( cls.demotime, 60.0f )); Q_memprint( pos ), (int)(cls.demotime / 60.0f ), (int)fmod( cls.demotime, 60.0f ));
Con_DrawStringLen( string, &len, NULL ); Con_DrawStringLen( string, &len, NULL );
Con_DrawString(((int)scr_width->value - len) >> 1, (int)scr_height->value >> 2, string, color ); Con_DrawString(( glState.width - len ) >> 1, glState.height >> 2, string, color );
} }
/* /*
@ -552,9 +553,9 @@ void CL_ReadDemoUserCmd( qboolean discard )
pcmd->sendsize = 1; pcmd->sendsize = 1;
// always delta'ing from null // always delta'ing from null
cl.refdef.cmd = &pcmd->cmd; cl.cmd = &pcmd->cmd;
MSG_ReadDeltaUsercmd( &buf, &nullcmd, cl.refdef.cmd ); MSG_ReadDeltaUsercmd( &buf, &nullcmd, cl.cmd );
// make sure what interp info contain angles from different frames // make sure what interp info contain angles from different frames
// or lerping will stop working // or lerping will stop working
@ -566,7 +567,7 @@ void CL_ReadDemoUserCmd( qboolean discard )
// record update // record update
a->starttime = demo.timestamp; a->starttime = demo.timestamp;
VectorCopy( cl.refdef.cmd->viewangles, a->viewangles ); VectorCopy( cl.viewangles, a->viewangles );
demo.lasttime = demo.timestamp; demo.lasttime = demo.timestamp;
} }
@ -731,7 +732,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
// HACKHACK: changedemo issues // HACKHACK: changedemo issues
if( !cls.netchan.remote_address.type ) cls.netchan.remote_address.type = NA_LOOPBACK; if( !cls.netchan.remote_address.type ) cls.netchan.remote_address.type = NA_LOOPBACK;
if(( !cl.background && ( cl.refdef.paused || cls.key_dest != key_game )) || cls.key_dest == key_console ) if(( !cl.background && ( cl.paused || cls.key_dest != key_game )) || cls.key_dest == key_console )
{ {
demo.starttime += host.frametime; demo.starttime += host.frametime;
return false; // paused return false; // paused
@ -891,9 +892,9 @@ void CL_DemoInterpolateAngles( void )
AngleQuaternion( next->viewangles, q1, false ); AngleQuaternion( next->viewangles, q1, false );
AngleQuaternion( prev->viewangles, q2, false ); AngleQuaternion( prev->viewangles, q2, false );
QuaternionSlerp( q2, q1, frac, q ); QuaternionSlerp( q2, q1, frac, q );
QuaternionAngle( q, cl.refdef.cl_viewangles ); QuaternionAngle( q, cl.viewangles );
} }
else VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles ); else VectorCopy( cl.cmd->viewangles, cl.viewangles );
} }
/* /*

View File

@ -397,7 +397,6 @@ void CL_ParseEvent( sizebuf_t *msg )
int packet_index; int packet_index;
event_args_t nullargs, args; event_args_t nullargs, args;
entity_state_t *state; entity_state_t *state;
cl_entity_t *pEnt;
float delay; float delay;
memset( &nullargs, 0, sizeof( nullargs )); memset( &nullargs, 0, sizeof( nullargs ));
@ -461,69 +460,6 @@ void CL_ParseEvent( sizebuf_t *msg )
// Place event on queue // Place event on queue
CL_QueueEvent( FEV_SERVER, event_index, delay, &args ); CL_QueueEvent( FEV_SERVER, event_index, delay, &args );
} }
#if 0
if( packet_index != -1 )
state = &cls.packet_entities[(cl.frame.first_entity+packet_index)%cls.num_client_entities];
else state = NULL;
// it's a client. Override some params
if( args.entindex >= 1 && args.entindex <= cl.maxclients )
{
if(( args.entindex - 1 ) == cl.playernum )
{
if( state && !CL_IsPredicted( ))
{
// restore viewangles from angles
args.angles[PITCH] = -state->angles[PITCH] * 3;
args.angles[YAW] = state->angles[YAW];
args.angles[ROLL] = 0; // no roll
}
else
{
// get the predicted angles
VectorCopy( cl.refdef.cl_viewangles, args.angles );
}
VectorCopy( cl.frame.client.origin, args.origin );
VectorCopy( cl.frame.client.velocity, args.velocity );
}
else if( state )
{
// restore viewangles from angles
args.angles[PITCH] = -state->angles[PITCH] * 3;
args.angles[YAW] = state->angles[YAW];
args.angles[ROLL] = 0; // no roll
if( VectorIsNull( args.origin ))
VectorCopy( state->origin, args.origin );
if( VectorIsNull( args.velocity ))
VectorCopy( state->velocity, args.velocity );
}
COM_NormalizeAngles( args.angles );
}
else if( state )
{
if( VectorIsNull( args.origin ))
VectorCopy( state->origin, args.origin );
if( VectorIsNull( args.angles ))
VectorCopy( state->angles, args.angles );
if( VectorIsNull( args.velocity ))
VectorCopy( state->velocity, args.velocity );
}
else if(( pEnt = CL_GetEntityByIndex( args.entindex )) != NULL )
{
if( VectorIsNull( args.origin ))
VectorCopy( pEnt->curstate.origin, args.origin );
if( VectorIsNull( args.angles ))
VectorCopy( pEnt->curstate.angles, args.angles );
if( VectorIsNull( args.velocity ))
VectorCopy( pEnt->curstate.velocity, args.velocity );
}
// g-cont. should we need find the event with same index?
CL_QueueEvent( FEV_SERVER, event_index, delay, &args );
#endif
} }
} }
@ -537,7 +473,12 @@ void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, floa
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 )
{ {
event_args_t args; event_args_t args;
int invokerIndex = 0;
if( flags & FEV_SERVER )
{
MsgDev( D_WARN, "CL_PlaybackEvent: event with FEV_SERVER flag!\n" );
return;
}
// first check event for out of bounds // first check event for out of bounds
if( eventindex < 1 || eventindex > MAX_EVENTS ) if( eventindex < 1 || eventindex > MAX_EVENTS )
@ -546,12 +487,6 @@ void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, floa
return; return;
} }
if( flags & FEV_SERVER )
{
MsgDev( D_WARN, "CL_PlaybackEvent: event with FEV_SERVER flag!\n" );
return;
}
// check event for precached // check event for precached
if( !CL_EventIndex( cl.event_precache[eventindex] )) if( !CL_EventIndex( cl.event_precache[eventindex] ))
{ {
@ -561,34 +496,15 @@ void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, floa
flags |= FEV_CLIENT; // it's a client event flags |= FEV_CLIENT; // it's a client event
flags &= ~(FEV_NOTHOST|FEV_HOSTONLY|FEV_GLOBAL); flags &= ~(FEV_NOTHOST|FEV_HOSTONLY|FEV_GLOBAL);
if( delay < 0.0f ) delay = 0.0f; // fixup negative delays if( delay < 0.0f ) delay = 0.0f; // fixup negative delays
invokerIndex = cl.playernum + 1; // only local client can issue client events
args.flags = 0; memset( &args, 0, sizeof( args ));
args.entindex = invokerIndex;
if( !angles || VectorIsNull( angles )) VectorCopy( origin, args.origin );
VectorCopy( cl.refdef.cl_viewangles, args.angles ); VectorCopy( angles, args.angles );
else VectorCopy( angles, args.angles ); VectorCopy( cl.simvel, args.velocity );
args.entindex = cl.playernum + 1;
if( !origin || VectorIsNull( origin )) args.ducking = ( cl.local.usehull == 1 );
{
if( CL_IsPredicted( )) VectorCopy( cl.predicted.origin, args.origin );
else VectorCopy( cl.frame.client.origin, args.origin );
}
else VectorCopy( origin, args.origin );
if( CL_IsPredicted( ))
{
VectorCopy( cl.predicted.velocity, args.velocity );
args.ducking = (cl.predicted.usehull == 1);
}
else
{
VectorCopy( cl.frame.client.velocity, args.velocity );
args.ducking = cl.frame.client.bInDuck;
}
args.fparam1 = fparam1; args.fparam1 = fparam1;
args.fparam2 = fparam2; args.fparam2 = fparam2;

View File

@ -25,8 +25,6 @@ GNU General Public License for more details.
#include "sound.h" #include "sound.h"
#include "input.h" #include "input.h"
#define MAX_FORWARD 6
qboolean CL_IsPlayerIndex( int idx ) qboolean CL_IsPlayerIndex( int idx )
{ {
if( idx > 0 && idx <= cl.maxclients ) if( idx > 0 && idx <= cl.maxclients )
@ -34,17 +32,6 @@ qboolean CL_IsPlayerIndex( int idx )
return false; return false;
} }
qboolean CL_IsPredicted( void )
{
if( cl_nopred->value || !cl.frame.valid || cl.background || cls.spectator )
return false;
if( !cl.validsequence || ( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
return false;
return true;
}
int CL_PushMoveFilter( physent_t *pe ) int CL_PushMoveFilter( physent_t *pe )
{ {
if( !pe || pe->solid != SOLID_BSP || pe->movetype != MOVETYPE_PUSH ) if( !pe || pe->solid != SOLID_BSP || pe->movetype != MOVETYPE_PUSH )
@ -82,36 +69,52 @@ void CL_UpdatePositions( cl_entity_t *ent )
VectorCopy( ent->curstate.origin, ph->origin ); VectorCopy( ent->curstate.origin, ph->origin );
VectorCopy( ent->curstate.angles, ph->angles ); VectorCopy( ent->curstate.angles, ph->angles );
ph->animtime = cl.mtime[0]; ph->animtime = ent->curstate.animtime; // !!!
}
/*
==================
CL_ResetPositions
Interpolation init or reset after teleporting
==================
*/
void CL_ResetPositions( cl_entity_t *ent )
{
position_history_t store;
if( !ent ) return;
store = ent->ph[ent->current_position];
ent->current_position = 1;
memset( ent->ph, 0, sizeof( position_history_t ) * HISTORY_MAX );
memcpy( &ent->ph[1], &store, sizeof( position_history_t ));
memcpy( &ent->ph[0], &store, sizeof( position_history_t ));
} }
qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, position_history_t **ph0, position_history_t **ph1, int *ph0Index ) qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, position_history_t **ph0, position_history_t **ph1, int *ph0Index )
{ {
qboolean extrapolate; qboolean extrapolate = true;
int i, i0, i1, imod; int i, i0, i1, imod;
float at; float at;
imod = ent->current_position - 1; imod = ent->current_position;
i0 = (imod + 1) & HISTORY_MASK; i0 = (imod - 0) & HISTORY_MASK; // curpos (lerp end)
i1 = imod & HISTORY_MASK; i1 = (imod - 1) & HISTORY_MASK; // oldpos (lerp start)
extrapolate = true; for( i = 1; i < HISTORY_MAX - 1; i++ )
if( ent->ph[i0].animtime >= targettime )
{ {
for( i = 0; i < HISTORY_MAX - 2; i++ ) at = ent->ph[( imod - i ) & HISTORY_MASK].animtime;
{ if( at == 0.0 ) break;
at = ent->ph[imod & HISTORY_MASK].animtime;
if( at == 0.0f ) break;
if( at < targettime ) if( targettime > at )
{ {
i0 = (imod + 1) & HISTORY_MASK; // found it
i1 = imod & HISTORY_MASK; i0 = (( imod - i ) + 1 ) & HISTORY_MASK;
extrapolate = false; i1 = (( imod - i ) + 0 ) & HISTORY_MASK;
break; extrapolate = false;
} break;
imod--;
} }
} }
@ -122,6 +125,49 @@ qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, positi
return extrapolate; return extrapolate;
} }
void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangles )
{
qboolean extrapolate;
float t1, t0, frac;
position_history_t *ph0, *ph1;
vec3_t delta;
// NOTE: ph0 is next, ph1 is a prev
extrapolate = CL_FindInterpolationUpdates( ent, t, &ph0, &ph1, NULL );
if ( !ph0 || !ph1 )
return;
t0 = ph0->animtime;
t1 = ph1->animtime;
if( t0 != 0.0f )
{
vec4_t q, q1, q2;
VectorSubtract( ph0->origin, ph1->origin, delta );
if( t0 != t1 )
frac = ( t - t1 ) / ( t0 - t1 );
else frac = 1.0f;
frac = bound( 0.0f, frac, 1.2f );
VectorMA( ph1->origin, frac, delta, outorigin );
AngleQuaternion( ph0->angles, q1, false );
AngleQuaternion( ph1->angles, q2, false );
QuaternionSlerp( q2, q1, frac, q );
QuaternionAngle( q, outangles );
}
else
{
// no backup found
VectorCopy( ph1->origin, outorigin );
VectorCopy( ph1->angles, outangles );
}
}
int CL_InterpolateModel( cl_entity_t *e ) int CL_InterpolateModel( cl_entity_t *e )
{ {
position_history_t *ph0 = NULL, *ph1 = NULL; position_history_t *ph0 = NULL, *ph1 = NULL;
@ -137,7 +183,7 @@ int CL_InterpolateModel( cl_entity_t *e )
if( !e->model || ( e->model->name[0] == '*' && !cl_bmodelinterp->value ) || RP_LOCALCLIENT( e ) || cl.maxclients <= 1 ) if( !e->model || ( e->model->name[0] == '*' && !cl_bmodelinterp->value ) || RP_LOCALCLIENT( e ) || cl.maxclients <= 1 )
return 1; return 1;
if( cl.predicted.moving && cl.predicted.onground == e->index ) if( cl.local.moving && cl.local.onground == e->index )
return 1; return 1;
if( e->curstate.starttime != 0.0f && e->curstate.impacttime != 0.0f ) if( e->curstate.starttime != 0.0f && e->curstate.impacttime != 0.0f )
@ -256,7 +302,7 @@ void CL_UpdateEntityFields( cl_entity_t *ent )
ent->angles[PITCH] = -ent->angles[PITCH] / 3.0f; ent->angles[PITCH] = -ent->angles[PITCH] / 3.0f;
// make me lerp (multiplayer only. this code visually breaks XashXT parent system) // make me lerp (multiplayer only. this code visually breaks XashXT parent system)
if( ent->index == cl.predicted.onground && cl.predicted.moving && ( cl.maxclients > 1 )) if( ent->index == cl.local.onground && cl.local.moving && ( cl.maxclients > 1 ))
{ {
CL_InterpolateMovingEntity( ent ); CL_InterpolateMovingEntity( ent );
} }
@ -389,6 +435,49 @@ void CL_UpdateEntityFields( cl_entity_t *ent )
} }
} }
/*
=============
CL_ComputePlayerOrigin
interpolate non-local clients
=============
*/
void CL_ComputePlayerOrigin( cl_entity_t *ent )
{
float targettime;
vec3_t origin;
vec3_t angles;
if( !ent->player || ent->index == ( cl.playernum + 1 ))
return;
targettime = cl.time - cl_interp->value;
CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles );
VectorCopy( origin, ent->origin );
}
/*
=============
CL_InterpolateEntity
interpolate entity movement
=============
*/
void CL_InterpolateEntity( cl_entity_t *ent )
{
float targettime;
vec3_t origin;
vec3_t angles;
targettime = cl.time - cl_interp->value;
CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles );
VectorCopy( origin, ent->origin );
}
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType ) qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
{ {
if( !ent || !ent->model ) if( !ent || !ent->model )
@ -415,7 +504,7 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
return false; return false;
// don't add himself on firstperson // don't add himself on firstperson
if( RP_LOCALCLIENT( ent ) && !cl.thirdperson && cls.key_dest != key_menu && cl.refdef.viewentity == ( cl.playernum + 1 )) if( RP_LOCALCLIENT( ent ) && !cl.local.thirdperson && cls.key_dest != key_menu && cl.viewentity == ( cl.playernum + 1 ))
{ {
if( gl_allow_mirrors->value && world.has_mirrors ) if( gl_allow_mirrors->value && world.has_mirrors )
{ {
@ -555,8 +644,8 @@ void CL_WeaponAnim( int iAnim, int body )
{ {
cl_entity_t *view = &clgame.viewent; cl_entity_t *view = &clgame.viewent;
cl.weaponstarttime = 0; cl.local.weaponstarttime = 0;
cl.weaponsequence = iAnim; cl.local.weaponsequence = iAnim;
// anim is changed. update latchedvars // anim is changed. update latchedvars
if( iAnim != view->curstate.sequence ) if( iAnim != view->curstate.sequence )
@ -1064,83 +1153,6 @@ INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS
========================================================================== ==========================================================================
*/ */
/*
===============
CL_SetIdealPitch
===============
*/
void CL_SetIdealPitch( void )
{
float angleval, sinval, cosval;
float z[MAX_FORWARD], view_z;
vec3_t top, bottom, origin;
int i, j;
int step, dir, steps;
pmtrace_t tr;
if( !( cl.frame.client.flags & FL_ONGROUND ))
return;
if( CL_IsPredicted( ))
{
VectorCopy( cl.predicted.origin, origin );
view_z = cl.predicted.viewofs[2];
}
else
{
VectorCopy( cl.frame.client.origin, origin );
view_z = cl.frame.client.view_ofs[2];
}
angleval = cl.frame.playerstate[cl.playernum].angles[YAW] * M_PI2 / 360.0f;
SinCos( angleval, &sinval, &cosval );
for( i = 0; i < MAX_FORWARD; i++ )
{
top[0] = origin[0] + cosval * (i + 3.0f) * 12.0f;
top[1] = origin[1] + sinval * (i + 3.0f) * 12.0f;
top[2] = origin[2] + view_z;
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160.0f;
// skip any monsters (only world and brush models)
tr = CL_TraceLine( top, bottom, PM_STUDIO_IGNORE );
if( tr.allsolid ) return; // looking at a wall, leave ideal the way is was
if( tr.fraction == 1.0f )
return; // near a dropoff
z[i] = top[2] + tr.fraction * (bottom[2] - top[2]);
}
dir = 0;
steps = 0;
for( j = 1; j < i; j++ )
{
step = z[j] - z[j-1];
if( step > -ON_EPSILON && step < ON_EPSILON )
continue;
if( dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ))
return; // mixed changes
steps++;
dir = step;
}
if( !dir )
{
cl.refdef.idealpitch = 0.0f;
return;
}
if( steps < 2 ) return;
cl.refdef.idealpitch = -dir * cl_idealpitchscale->value;
}
/* /*
=============== ===============
CL_AddPacketEntities CL_AddPacketEntities

View File

@ -67,7 +67,7 @@ static dllfunc_t cdll_exports[] =
{ "Demo_ReadBuffer", (void **)&clgame.dllFuncs.pfnDemo_ReadBuffer }, { "Demo_ReadBuffer", (void **)&clgame.dllFuncs.pfnDemo_ReadBuffer },
{ "CAM_Think", (void **)&clgame.dllFuncs.CAM_Think }, { "CAM_Think", (void **)&clgame.dllFuncs.CAM_Think },
{ "CL_IsThirdPerson", (void **)&clgame.dllFuncs.CL_IsThirdPerson }, { "CL_IsThirdPerson", (void **)&clgame.dllFuncs.CL_IsThirdPerson },
{ "CL_CameraOffset", (void **)&clgame.dllFuncs.CL_CameraOffset }, { "CL_CameraOffset", (void **)&clgame.dllFuncs.CL_CameraOffset }, // unused callback. Now camera code is completely moved to the user area
{ "CL_CreateMove", (void **)&clgame.dllFuncs.CL_CreateMove }, { "CL_CreateMove", (void **)&clgame.dllFuncs.CL_CreateMove },
{ "IN_ActivateMouse", (void **)&clgame.dllFuncs.IN_ActivateMouse }, { "IN_ActivateMouse", (void **)&clgame.dllFuncs.IN_ActivateMouse },
{ "IN_DeactivateMouse", (void **)&clgame.dllFuncs.IN_DeactivateMouse }, { "IN_DeactivateMouse", (void **)&clgame.dllFuncs.IN_DeactivateMouse },
@ -139,7 +139,7 @@ returns true if thirdperson is enabled
*/ */
qboolean CL_IsThirdPerson( void ) qboolean CL_IsThirdPerson( void )
{ {
return cl.thirdperson; return cl.local.thirdperson;
} }
/* /*
@ -284,18 +284,18 @@ static int CL_AdjustXPos( float x, int width, int totalWidth )
if( x == -1 ) if( x == -1 )
{ {
xPos = ( clgame.scrInfo.iWidth - width ) * 0.5f; xPos = ( glState.width - width ) * 0.5f;
} }
else else
{ {
if ( x < 0 ) if ( x < 0 )
xPos = (1.0f + x) * clgame.scrInfo.iWidth - totalWidth; // Alight right xPos = (1.0f + x) * glState.width - totalWidth; // Alight right
else // align left else // align left
xPos = x * clgame.scrInfo.iWidth; xPos = x * glState.width;
} }
if( xPos + width > clgame.scrInfo.iWidth ) if( xPos + width > glState.width )
xPos = clgame.scrInfo.iWidth - width; xPos = glState.width - width;
else if( xPos < 0 ) else if( xPos < 0 )
xPos = 0; xPos = 0;
@ -315,19 +315,19 @@ static int CL_AdjustYPos( float y, int height )
if( y == -1 ) // centered? if( y == -1 ) // centered?
{ {
yPos = ( clgame.scrInfo.iHeight - height ) * 0.5f; yPos = ( glState.height - height ) * 0.5f;
} }
else else
{ {
// Alight bottom? // Alight bottom?
if( y < 0 ) if( y < 0 )
yPos = (1.0f + y) * clgame.scrInfo.iHeight - height; // Alight bottom yPos = (1.0f + y) * glState.height - height; // Alight bottom
else // align top else // align top
yPos = y * clgame.scrInfo.iHeight; yPos = y * glState.height;
} }
if( yPos + height > clgame.scrInfo.iHeight ) if( yPos + height > glState.height )
yPos = clgame.scrInfo.iHeight - height; yPos = glState.height - height;
else if( yPos < 0 ) else if( yPos < 0 )
yPos = 0; yPos = 0;
@ -386,8 +386,8 @@ static void SPR_AdjustSize( float *x, float *y, float *w, float *h )
if( !x && !y && !w && !h ) return; if( !x && !y && !w && !h ) return;
// scale for screen sizes // scale for screen sizes
xscale = scr_width->value / (float)clgame.scrInfo.iWidth; xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight; yscale = glState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale; if( x ) *x *= xscale;
if( y ) *y *= yscale; if( y ) *y *= yscale;
@ -410,8 +410,8 @@ void PicAdjustSize( float *x, float *y, float *w, float *h )
if( !x && !y && !w && !h ) return; if( !x && !y && !w && !h ) return;
// scale for screen sizes // scale for screen sizes
xscale = scr_width->value / (float)clgame.scrInfo.iWidth; xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight; yscale = glState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale; if( x ) *x *= xscale;
if( y ) *y *= yscale; if( y ) *y *= yscale;
@ -583,7 +583,7 @@ void CL_DrawCenterPrint( void )
for( j = 0; j < lineLength; j++ ) for( j = 0; j < lineLength; j++ )
{ {
if( x >= 0 && y >= 0 && x <= clgame.scrInfo.iWidth ) if( x >= 0 && y >= 0 && x <= glState.width )
x += Con_DrawCharacter( x, y, line[j], colorDefault ); x += Con_DrawCharacter( x, y, line[j], colorDefault );
} }
y += charHeight; y += charHeight;
@ -636,7 +636,7 @@ void CL_DrawScreenFade( void )
if( sf->fadeFlags & FFADE_MODULATE ) if( sf->fadeFlags & FFADE_MODULATE )
GL_SetRenderMode( kRenderTransAdd ); GL_SetRenderMode( kRenderTransAdd );
else GL_SetRenderMode( kRenderTransTexture ); else GL_SetRenderMode( kRenderTransTexture );
R_DrawStretchPic( 0, 0, scr_width->value, scr_height->value, 0, 0, 1, 1, cls.fillImage ); R_DrawStretchPic( 0, 0, glState.width, glState.height, 0, 0, 1, 1, cls.fillImage );
pglColor4ub( 255, 255, 255, 255 ); pglColor4ub( 255, 255, 255, 255 );
} }
@ -837,7 +837,7 @@ void CL_DrawCrosshair( void )
int x, y, width, height; int x, y, width, height;
cl_entity_t *pPlayer; cl_entity_t *pPlayer;
if( !clgame.ds.pCrosshair || cl.refdef.crosshairangle[2] || !cl_crosshair->value ) if( !clgame.ds.pCrosshair || cl.crosshairangle[2] || !cl_crosshair->value )
return; return;
pPlayer = CL_GetLocalPlayer(); pPlayer = CL_GetLocalPlayer();
@ -846,31 +846,31 @@ void CL_DrawCrosshair( void )
return; return;
// any camera on // any camera on
if( cl.refdef.viewentity != pPlayer->index ) if( cl.viewentity != pPlayer->index )
return; return;
// get crosshair dimension // get crosshair dimension
width = clgame.ds.rcCrosshair.right - clgame.ds.rcCrosshair.left; width = clgame.ds.rcCrosshair.right - clgame.ds.rcCrosshair.left;
height = clgame.ds.rcCrosshair.bottom - clgame.ds.rcCrosshair.top; height = clgame.ds.rcCrosshair.bottom - clgame.ds.rcCrosshair.top;
x = clgame.scrInfo.iWidth / 2; x = clgame.viewport[0] + ( clgame.viewport[2] >> 1 );
y = clgame.scrInfo.iHeight / 2; y = clgame.viewport[1] + ( clgame.viewport[3] >> 1 );
// g-cont - cl.refdef.crosshairangle is the autoaim angle. // g-cont - cl.crosshairangle is the autoaim angle.
// if we're not using autoaim, just draw in the middle of the screen // if we're not using autoaim, just draw in the middle of the screen
if( !VectorIsNull( cl.refdef.crosshairangle )) if( !VectorIsNull( cl.crosshairangle ))
{ {
vec3_t angles; vec3_t angles;
vec3_t forward; vec3_t forward;
vec3_t point, screen; vec3_t point, screen;
VectorAdd( cl.refdef.viewangles, cl.refdef.crosshairangle, angles ); VectorAdd( cl.viewangles, cl.crosshairangle, angles );
AngleVectors( angles, forward, NULL, NULL ); AngleVectors( angles, forward, NULL, NULL );
VectorAdd( cl.refdef.vieworg, forward, point ); VectorAdd( RI.vieworg, forward, point );
R_WorldToScreen( point, screen ); R_WorldToScreen( point, screen );
x += 0.5f * screen[0] * scr_width->value + 0.5f; x += ( clgame.viewport[2] >> 1 ) * screen[0] + 0.5f;
y += 0.5f * screen[1] * scr_height->value + 0.5f; y += ( clgame.viewport[3] >> 1 ) * screen[1] + 0.5f;
} }
clgame.ds.pSprite = clgame.ds.pCrosshair; clgame.ds.pSprite = clgame.ds.pCrosshair;
@ -899,8 +899,8 @@ static void CL_DrawLoading( float percent )
x = ( clgame.scrInfo.iWidth - width ) >> 1; x = ( clgame.scrInfo.iWidth - width ) >> 1;
y = ( clgame.scrInfo.iHeight - height) >> 1; y = ( clgame.scrInfo.iHeight - height) >> 1;
xscale = scr_width->value / (float)clgame.scrInfo.iWidth; xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight; yscale = glState.height / (float)clgame.scrInfo.iHeight;
x *= xscale; x *= xscale;
y *= yscale; y *= yscale;
@ -947,8 +947,8 @@ static void CL_DrawPause( void )
x = ( clgame.scrInfo.iWidth - width ) >> 1; x = ( clgame.scrInfo.iWidth - width ) >> 1;
y = ( clgame.scrInfo.iHeight - height) >> 1; y = ( clgame.scrInfo.iHeight - height) >> 1;
xscale = scr_width->value / (float)clgame.scrInfo.iWidth; xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight; yscale = glState.height / (float)clgame.scrInfo.iHeight;
x *= xscale; x *= xscale;
y *= yscale; y *= yscale;
@ -965,7 +965,7 @@ void CL_DrawHUD( int state )
if( state == CL_ACTIVE && !cl.video_prepped ) if( state == CL_ACTIVE && !cl.video_prepped )
state = CL_LOADING; state = CL_LOADING;
if( state == CL_ACTIVE && cl.refdef.paused ) if( state == CL_ACTIVE && cl.paused )
state = CL_PAUSED; state = CL_PAUSED;
switch( state ) switch( state )
@ -974,13 +974,13 @@ void CL_DrawHUD( int state )
CL_DrawScreenFade (); CL_DrawScreenFade ();
CL_DrawCrosshair (); CL_DrawCrosshair ();
CL_DrawCenterPrint (); CL_DrawCenterPrint ();
clgame.dllFuncs.pfnRedraw( cl.time, cl.refdef.intermission ); clgame.dllFuncs.pfnRedraw( cl.time, cl.intermission );
break; break;
case CL_PAUSED: case CL_PAUSED:
CL_DrawScreenFade (); CL_DrawScreenFade ();
CL_DrawCrosshair (); CL_DrawCrosshair ();
CL_DrawCenterPrint (); CL_DrawCenterPrint ();
clgame.dllFuncs.pfnRedraw( cl.time, cl.refdef.intermission ); clgame.dllFuncs.pfnRedraw( cl.time, cl.intermission );
CL_DrawPause(); CL_DrawPause();
break; break;
case CL_LOADING: case CL_LOADING:
@ -1429,10 +1429,11 @@ static int pfnGetScreenInfo( SCREENINFO *pscrinfo )
{ {
// setup screen info // setup screen info
clgame.scrInfo.iSize = sizeof( clgame.scrInfo ); clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
if( Cvar_VariableInteger( "hud_scale" )) if( Cvar_VariableInteger( "hud_scale" ))
{ {
if( scr_width->value < 640 ) if( glState.width < 640 )
{ {
// virtual screen space 320x200 // virtual screen space 320x200
clgame.scrInfo.iWidth = 320; clgame.scrInfo.iWidth = 320;
@ -1448,8 +1449,8 @@ static int pfnGetScreenInfo( SCREENINFO *pscrinfo )
} }
else else
{ {
clgame.scrInfo.iWidth = scr_width->value; clgame.scrInfo.iWidth = glState.width;
clgame.scrInfo.iHeight = scr_height->value; clgame.scrInfo.iHeight = glState.height;
clgame.scrInfo.iFlags &= ~SCRINFO_STRETCHED; clgame.scrInfo.iFlags &= ~SCRINFO_STRETCHED;
} }
@ -1590,7 +1591,7 @@ pfnPlaySoundByName
static void pfnPlaySoundByName( const char *szSound, float volume ) static void pfnPlaySoundByName( const char *szSound, float volume )
{ {
int hSound = S_RegisterSound( szSound ); int hSound = S_RegisterSound( szSound );
S_StartSound( NULL, cl.refdef.viewentity, CHAN_ITEM, hSound, volume, ATTN_NORM, PITCH_NORM, SND_STOP_LOOPING ); S_StartSound( NULL, cl.viewentity, CHAN_ITEM, hSound, volume, ATTN_NORM, PITCH_NORM, SND_STOP_LOOPING );
} }
/* /*
@ -1612,7 +1613,7 @@ static void pfnPlaySoundByIndex( int iSound, float volume )
MsgDev( D_ERROR, "CL_PlaySoundByIndex: invalid sound handle %i\n", iSound ); MsgDev( D_ERROR, "CL_PlaySoundByIndex: invalid sound handle %i\n", iSound );
return; return;
} }
S_StartSound( NULL, cl.refdef.viewentity, CHAN_ITEM, hSound, volume, ATTN_NORM, PITCH_NORM, SND_STOP_LOOPING ); S_StartSound( NULL, cl.viewentity, CHAN_ITEM, hSound, volume, ATTN_NORM, PITCH_NORM, SND_STOP_LOOPING );
} }
/* /*
@ -1680,11 +1681,9 @@ int pfnDrawConsoleString( int x, int y, char *string )
int drawLen; int drawLen;
if( !string || !*string ) return 0; // silent ignore if( !string || !*string ) return 0; // silent ignore
clgame.ds.adjust_size = true;
Con_SetFont( con_fontsize->value ); Con_SetFont( con_fontsize->value );
drawLen = Con_DrawString( x, y, string, clgame.ds.textColor ); drawLen = Con_DrawString( x, y, string, clgame.ds.textColor );
MakeRGBA( clgame.ds.textColor, 255, 255, 255, 255 ); MakeRGBA( clgame.ds.textColor, 255, 255, 255, 255 );
clgame.ds.adjust_size = false;
Con_RestoreFont(); Con_RestoreFont();
return (x + drawLen); // exclude color prexfixes return (x + drawLen); // exclude color prexfixes
@ -1779,7 +1778,7 @@ return interpolated angles from previous frame
*/ */
static void pfnGetViewAngles( float *angles ) static void pfnGetViewAngles( float *angles )
{ {
if( angles ) VectorCopy( cl.refdef.cl_viewangles, angles ); if( angles ) VectorCopy( cl.viewangles, angles );
} }
/* /*
@ -1791,7 +1790,7 @@ return interpolated angles from previous frame
*/ */
static void pfnSetViewAngles( float *angles ) static void pfnSetViewAngles( float *angles )
{ {
if( angles ) VectorCopy( angles, cl.refdef.cl_viewangles ); if( angles ) VectorCopy( angles, cl.viewangles );
} }
/* /*
@ -2178,9 +2177,7 @@ pfnLocalPlayerDucking
*/ */
int pfnLocalPlayerDucking( void ) int pfnLocalPlayerDucking( void )
{ {
if( CL_IsPredicted( )) return (cl.local.usehull == 1) ? true : false;
return (cl.predicted.usehull == 1);
return cl.frame.client.bInDuck;
} }
/* /*
@ -2191,12 +2188,7 @@ pfnLocalPlayerViewheight
*/ */
void pfnLocalPlayerViewheight( float *view_ofs ) void pfnLocalPlayerViewheight( float *view_ofs )
{ {
// predicted or smoothed if( view_ofs ) VectorCopy( cl.viewheight, view_ofs );
if( !view_ofs ) return;
if( CL_IsPredicted( ))
VectorCopy( cl.predicted.viewofs, view_ofs );
else VectorCopy( cl.frame.client.view_ofs, view_ofs );
} }
/* /*
@ -2792,7 +2784,7 @@ pfnPlaySoundVoiceByName
void pfnPlaySoundVoiceByName( char *filename, float volume, int pitch ) void pfnPlaySoundVoiceByName( char *filename, float volume, int pitch )
{ {
int hSound = S_RegisterSound( filename ); int hSound = S_RegisterSound( filename );
S_StartSound( NULL, cl.refdef.viewentity, CHAN_AUTO, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING ); S_StartSound( NULL, cl.viewentity, CHAN_AUTO, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING );
} }
/* /*
@ -2828,7 +2820,7 @@ pfnPlaySoundByNameAtPitch
void pfnPlaySoundByNameAtPitch( char *filename, float volume, int pitch ) void pfnPlaySoundByNameAtPitch( char *filename, float volume, int pitch )
{ {
int hSound = S_RegisterSound( filename ); int hSound = S_RegisterSound( filename );
S_StartSound( NULL, cl.refdef.viewentity, CHAN_STATIC, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING ); S_StartSound( NULL, cl.viewentity, CHAN_STATIC, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING );
} }
/* /*
@ -3119,10 +3111,10 @@ int TriWorldToScreen( float *world, float *screen )
retval = R_WorldToScreen( world, screen ); retval = R_WorldToScreen( world, screen );
screen[0] = 0.5f * screen[0] * (float)cl.refdef.viewport[2]; screen[0] = 0.5f * screen[0] * (float)clgame.viewport[2];
screen[1] = -0.5f * screen[1] * (float)cl.refdef.viewport[3]; screen[1] = -0.5f * screen[1] * (float)clgame.viewport[3];
screen[0] += 0.5f * (float)cl.refdef.viewport[2]; screen[0] += 0.5f * (float)clgame.viewport[2];
screen[1] += 0.5f * (float)cl.refdef.viewport[3]; screen[1] += 0.5f * (float)clgame.viewport[3];
return retval; return retval;
} }
@ -3938,9 +3930,6 @@ qboolean CL_LoadProgs( const char *name )
if( clgame.hInstance ) CL_UnloadProgs(); if( clgame.hInstance ) CL_UnloadProgs();
// setup globals
cl.refdef.movevars = &clgame.movevars;
// initialize PlayerMove // initialize PlayerMove
clgame.pmove = &gpMove; clgame.pmove = &gpMove;

View File

@ -666,7 +666,10 @@ static void pfnRenderScene( const ref_params_t *fd )
// to avoid division by zero // to avoid division by zero
if( !fd || fd->fov_x <= 0.0f || fd->fov_y <= 0.0f ) if( !fd || fd->fov_x <= 0.0f || fd->fov_y <= 0.0f )
return; return;
R_RenderFrame( fd, false );
R_Set2DMode( false );
R_RenderFrame( fd, false, fd->fov_x );
R_Set2DMode( true );
} }
/* /*

View File

@ -92,7 +92,7 @@ qboolean CL_IsInConsole( void )
qboolean CL_IsIntermission( void ) qboolean CL_IsIntermission( void )
{ {
return cl.refdef.intermission; return cl.intermission;
} }
qboolean CL_IsPlaybackDemo( void ) qboolean CL_IsPlaybackDemo( void )
@ -125,6 +125,17 @@ char *CL_Userinfo( void )
return cls.userinfo; return cls.userinfo;
} }
int CL_IsDevOverviewMode( void )
{
if( gl_overview->value )
{
if( host.developer > 0 || cls.spectator )
return 1;
}
return 0;
}
/* /*
=============== ===============
CL_ChangeGame CL_ChangeGame
@ -258,6 +269,86 @@ static float CL_LerpPoint( void )
return frac; return frac;
} }
/*
===============
CL_DriftInterpolationAmount
Drift interpolation value (this is used for server unlag system)
===============
*/
int CL_DriftInterpolationAmount( int goal )
{
float fgoal, maxmove, diff;
int msec;
fgoal = (float)goal / 1000.0f;
if( fgoal != cl.local.interp_amount )
{
maxmove = host.frametime * 0.05;
diff = fgoal - cl.local.interp_amount;
diff = bound( -maxmove, diff, maxmove );
cl.local.interp_amount += diff;
}
msec = cl.local.interp_amount * 1000.0f;
msec = bound( 0, msec, 100 );
return msec;
}
/*
===============
CL_ComputeClientInterpolationAmount
Validate interpolation cvars, calc interpolation window
===============
*/
void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
{
int min_interp = MIN_EX_INTERP;
int max_interp = MAX_EX_INTERP;
int interpolation_msec;
qboolean forced = false;
if( cl_updaterate->value < MIN_UPDATERATE )
{
Con_Printf( "cl_updaterate minimum is %f, resetting to default (20)\n", MIN_UPDATERATE );
Cvar_Reset( "cl_updaterate" );
}
if( cl_updaterate->value > MAX_UPDATERATE )
{
Con_Printf( "cl_updaterate clamped at maximum (%f)\n", MAX_UPDATERATE );
Cvar_SetValue( "cl_updaterate", MAX_UPDATERATE );
}
if( cls.spectator )
max_interp = 200;
min_interp = 1000.0f / cl_updaterate->value;
min_interp = Q_max( 1, min_interp );
interpolation_msec = cl_interp->value * 1000.0f;
if(( interpolation_msec + 1 ) < min_interp )
{
MsgDev( D_INFO, "ex_interp forced up to %i msec\n", interpolation_msec );
interpolation_msec = min_interp;
forced = true;
}
else if(( interpolation_msec - 1 ) > max_interp )
{
MsgDev( D_INFO, "ex_interp forced down to %i msec\n", interpolation_msec );
interpolation_msec = max_interp;
forced = true;
}
if( forced ) Cvar_SetValue( "ex_interp", (float)interpolation_msec * 0.001f );
interpolation_msec = bound( min_interp, interpolation_msec, max_interp );
cmd->lerp_msec = CL_DriftInterpolationAmount( interpolation_msec );
}
/* /*
================= =================
CL_ComputePacketLoss CL_ComputePacketLoss
@ -399,6 +490,35 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
return true; return true;
} }
/*
=================
CL_UpdateClientData
tell the client.dll about player origin, angles, fov, etc
=================
*/
void CL_UpdateClientData( void )
{
client_data_t cdat;
if( cls.state != ca_active )
return;
memset( &cdat, 0, sizeof( cdat ) );
VectorCopy( cl.viewangles, cdat.viewangles );
VectorCopy( clgame.entities[cl.viewentity].origin, cdat.origin );
cdat.iWeaponBits = cl.local.weapons;
cdat.fov = cl.local.scr_fov;
if( clgame.dllFuncs.pfnUpdateClientData( &cdat, cl.time ))
{
// grab changes if successful
VectorCopy( cdat.viewangles, cl.viewangles );
cl.local.scr_fov = cdat.fov;
}
}
/* /*
================= =================
CL_CreateCmd CL_CreateCmd
@ -408,35 +528,27 @@ void CL_CreateCmd( void )
{ {
usercmd_t cmd; usercmd_t cmd;
runcmd_t *pcmd; runcmd_t *pcmd;
color24 color;
vec3_t angles; vec3_t angles;
qboolean active; qboolean active;
int input_override; int input_override;
int i, ms; int i, ms;
ms = host.frametime * 1000; // store viewangles in case it's frozen
if( ms > 250 ) ms = 100; // time was unreasonable VectorCopy( cl.viewangles, angles );
else if( ms <= 0 ) ms = 1; // keep time an actual
CL_UpdateClientData();
if( cls.state < ca_connected || cls.state == ca_cinematic )
return;
ms = bound( 1, host.frametime * 1000, 255 );
memset( &cmd, 0, sizeof( cmd )); memset( &cmd, 0, sizeof( cmd ));
input_override = 0; input_override = 0;
CL_SetSolidEntities();
CL_PushPMStates(); CL_PushPMStates();
CL_SetSolidPlayers( cl.playernum ); CL_SetSolidPlayers( cl.playernum );
VectorCopy( cl.refdef.cl_viewangles, angles );
VectorCopy( cl.frame.client.origin, cl.data.origin );
VectorCopy( cl.refdef.cl_viewangles, cl.data.viewangles );
cl.data.iWeaponBits = cl.frame.client.weapons;
cl.data.fov = cl.scr_fov;
if( clgame.dllFuncs.pfnUpdateClientData( &cl.data, cl.time ))
{
// grab changes if successful
VectorCopy( cl.data.viewangles, cl.refdef.cl_viewangles );
cl.scr_fov = cl.data.fov;
}
// message we are constructing. // message we are constructing.
i = cls.netchan.outgoing_sequence & CL_UPDATE_MASK; i = cls.netchan.outgoing_sequence & CL_UPDATE_MASK;
pcmd = &cl.commands[i]; pcmd = &cl.commands[i];
@ -451,20 +563,16 @@ void CL_CreateCmd( void )
pcmd->sendsize = 0; pcmd->sendsize = 0;
} }
active = ( cls.state == ca_active && !cl.refdef.paused && !cls.demoplayback ); active = ( cls.state == ca_active && !cl.paused && !cls.demoplayback );
clgame.dllFuncs.CL_CreateMove( cl.time - cl.oldtime, &pcmd->cmd, active ); clgame.dllFuncs.CL_CreateMove( host.frametime, &pcmd->cmd, active );
CL_PopPMStates(); CL_PopPMStates();
if( !cls.demoplayback ) if( !cls.demoplayback )
{ {
R_LightForPoint( cl.frame.client.origin, &color, false, false, 128.0f ); CL_ComputeClientInterpolationAmount( &pcmd->cmd );
pcmd->cmd.lightlevel = (color.r + color.g + color.b) / 3; pcmd->cmd.lightlevel = cl.local.light_level;
// never let client.dll calc frametime for player
// because is potential backdoor for cheating
pcmd->cmd.msec = ms; pcmd->cmd.msec = ms;
pcmd->cmd.lerp_msec = cl_interp->value * 1000;
pcmd->cmd.lerp_msec = bound( 0, cmd.lerp_msec, 250 );
} }
input_override |= CL_ProcessOverviewCmds( &pcmd->cmd ); input_override |= CL_ProcessOverviewCmds( &pcmd->cmd );
@ -472,13 +580,13 @@ void CL_CreateCmd( void )
if(( cl.background && !cls.demoplayback ) || input_override || cls.changelevel ) if(( cl.background && !cls.demoplayback ) || input_override || cls.changelevel )
{ {
VectorCopy( angles, cl.refdef.cl_viewangles );
VectorCopy( angles, pcmd->cmd.viewangles ); VectorCopy( angles, pcmd->cmd.viewangles );
VectorCopy( angles, cl.viewangles );
pcmd->cmd.msec = 0; pcmd->cmd.msec = 0;
} }
// demo always have commands so don't overwrite them // demo always have commands so don't overwrite them
if( !cls.demoplayback ) cl.refdef.cmd = &pcmd->cmd; if( !cls.demoplayback ) cl.cmd = &pcmd->cmd;
} }
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to ) void CL_WriteUsercmd( sizebuf_t *msg, int from, int to )
@ -525,10 +633,7 @@ void CL_WritePacket( void )
int cmdnumber; int cmdnumber;
// don't send anything if playing back a demo // don't send anything if playing back a demo
if( cls.demoplayback || cls.state == ca_cinematic ) if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
return;
if( cls.state == ca_disconnected || cls.state == ca_connecting )
return; return;
CL_ComputePacketLoss (); CL_ComputePacketLoss ();
@ -540,8 +645,8 @@ void CL_WritePacket( void )
if( cls.state == ca_connected ) numbackup = 0; if( cls.state == ca_connected ) numbackup = 0;
// clamp cmdrate // clamp cmdrate
if( cl_cmdrate->value < 0 ) Cvar_Set( "cl_cmdrate", "0" ); if( cl_cmdrate->value < 0.0f ) Cvar_SetValue( "cl_cmdrate", 0.0f );
else if( cl_cmdrate->value > 100 ) Cvar_Set( "cl_cmdrate", "100" ); else if( cl_cmdrate->value > 100.0f ) Cvar_SetValue( "cl_cmdrate", 100.0f );
// Check to see if we can actually send this command // Check to see if we can actually send this command
@ -563,6 +668,9 @@ void CL_WritePacket( void )
send_command = true; send_command = true;
} }
// spectator is not sending cmds to server
if( cls.spectator ) return;
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK ) if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
{ {
if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME ) if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME )
@ -911,11 +1019,12 @@ void CL_ClearState( void )
memset( &clgame.fade, 0, sizeof( clgame.fade )); memset( &clgame.fade, 0, sizeof( clgame.fade ));
memset( &clgame.shake, 0, sizeof( clgame.shake )); memset( &clgame.shake, 0, sizeof( clgame.shake ));
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
cl.refdef.movevars = &clgame.movevars;
cl.maxclients = 1; // allow to drawing player in menu cl.maxclients = 1; // allow to drawing player in menu
cl.mtime[0] = cl.mtime[1] = 1.0f; // because level starts from 1.0f second cl.mtime[0] = cl.mtime[1] = 1.0f; // because level starts from 1.0f second
NetAPI_CancelAllRequests(); NetAPI_CancelAllRequests();
cl.scr_fov = 90.0f;
cl.local.interp_amount = 0.1f;
cl.local.scr_fov = 90.0f;
Cvar_SetValue( "scr_download", 0.0f ); Cvar_SetValue( "scr_download", 0.0f );
Cvar_SetValue( "scr_loading", 0.0f ); Cvar_SetValue( "scr_loading", 0.0f );
@ -1753,7 +1862,7 @@ void CL_ReadPackets( void )
cl.lerpFrac = CL_LerpPoint(); cl.lerpFrac = CL_LerpPoint();
cl.lerpBack = 1.0f - cl.lerpFrac; cl.lerpBack = 1.0f - cl.lerpFrac;
cl.thirdperson = clgame.dllFuncs.CL_IsThirdPerson(); cl.local.thirdperson = clgame.dllFuncs.CL_IsThirdPerson();
#if 0 #if 0
// keep cheat cvars are unchanged // keep cheat cvars are unchanged
if( cl.maxclients > 1 && cls.state == ca_active && host.developer <= 1 ) if( cl.maxclients > 1 && cls.state == ca_active && host.developer <= 1 )
@ -2160,28 +2269,6 @@ void CL_AdjustClock( void )
} }
} }
/*
==================
CL_PrepareFrame
setup camera, update visible ents
==================
*/
void CL_PrepareFrame( void )
{
if( cls.state != ca_active )
return; // not in game
if( !cl.video_prepped || ( UI_IsVisible() && !cl.background ))
return; // still loading
if( cl.frame.valid && ( cl.force_refdef || !cl.refdef.paused ))
{
cl.force_refdef = false;
V_SetupRefDef ();
}
}
/* /*
================== ==================
Host_ClientFrame Host_ClientFrame
@ -2297,13 +2384,13 @@ void Host_ClientFrame( void )
SCR_UpdateScreen (); SCR_UpdateScreen ();
// update audio // update audio
S_RenderFrame( &cl.refdef ); SND_UpdateSound ();
// send a new command message to the server // send a new command message to the server
CL_SendCommand(); CL_SendCommand();
// predict all unacknowledged movements // predict all unacknowledged movements
CL_PredictMovement(); CL_PredictMovement( false );
// adjust client time // adjust client time
CL_AdjustClock(); CL_AdjustClock();
@ -2331,7 +2418,6 @@ void CL_Init( void )
if( host.type == HOST_DEDICATED ) if( host.type == HOST_DEDICATED )
return; // nothing running on the client return; // nothing running on the client
Con_Init();
CL_InitLocal(); CL_InitLocal();
R_Init(); // init renderer R_Init(); // init renderer

View File

@ -444,8 +444,8 @@ NetGraph_GetScreenPos
void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y ) void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y )
{ {
rect->left = rect->top = 0; rect->left = rect->top = 0;
rect->right = clgame.scrInfo.iWidth; rect->right = glState.width;
rect->bottom = clgame.scrInfo.iHeight; rect->bottom = glState.height;
*w = Q_min( NET_TIMINGS, net_graphwidth->value ); *w = Q_min( NET_TIMINGS, net_graphwidth->value );
if( rect->right < *w + 10 ) if( rect->right < *w + 10 )

View File

@ -433,9 +433,10 @@ void CL_ParseMovevars( sizebuf_t *msg )
R_SetupSky( clgame.movevars.skyName ); R_SetupSky( clgame.movevars.skyName );
memcpy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t )); memcpy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t ));
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
// keep features an actual! // keep features an actual!
clgame.oldmovevars.features = clgame.movevars.features = host.features; clgame.oldmovevars.features = clgame.movevars.features = host.features;
clgame.entities->curstate.scale = cl.refdef.movevars->waveHeight;
} }
/* /*
@ -684,7 +685,7 @@ void CL_ParseServerData( sizebuf_t *msg )
else if( !cls.demoplayback ) else if( !cls.demoplayback )
Key_SetKeyDest( key_menu ); Key_SetKeyDest( key_menu );
cl.refdef.viewentity = cl.playernum + 1; // always keep viewent an actual cl.viewentity = cl.playernum + 1; // always keep viewent an actual
gameui.globals->maxClients = cl.maxclients; gameui.globals->maxClients = cl.maxclients;
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle )); Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
@ -799,9 +800,9 @@ void CL_ParseClientData( sizebuf_t *msg )
{ {
last_predicted = ( cl.last_incoming_sequence + ( command_ack - cl.last_command_ack )) & CL_UPDATE_MASK; last_predicted = ( cl.last_incoming_sequence + ( command_ack - cl.last_command_ack )) & CL_UPDATE_MASK;
pps = &cl.predict[last_predicted].playerstate; pps = &cl.predicted_frames[last_predicted].playerstate;
pwd = cl.predict[last_predicted].weapondata; pwd = cl.predicted_frames[last_predicted].weapondata;
ppcd = &cl.predict[last_predicted].client; ppcd = &cl.predicted_frames[last_predicted].client;
ps = &frame->playerstate[cl.playernum]; ps = &frame->playerstate[cl.playernum];
wd = frame->weapondata; wd = frame->weapondata;
@ -853,7 +854,7 @@ void CL_ParseClientData( sizebuf_t *msg )
// clientdata for spectators ends here // clientdata for spectators ends here
if( cls.spectator ) if( cls.spectator )
{ {
cl.predicted.health = 1; cl.local.health = 1;
return; return;
} }
@ -892,7 +893,10 @@ void CL_ParseClientData( sizebuf_t *msg )
// make a local copy of physinfo // make a local copy of physinfo
Q_strncpy( cls.physinfo, frame->client.physinfo, sizeof( cls.physinfo )); Q_strncpy( cls.physinfo, frame->client.physinfo, sizeof( cls.physinfo ));
cl.predicted.health = frame->client.health; cl.local.maxspeed = frame->client.maxspeed;
cl.local.pushmsec = frame->client.pushmsec;
cl.local.weapons = frame->client.weapons; // g-cont 32-bit predictable weapon limit !!!
cl.local.health = frame->client.health;
} }
/* /*
@ -951,9 +955,9 @@ set the view angle to this absolute value
*/ */
void CL_ParseSetAngle( sizebuf_t *msg ) void CL_ParseSetAngle( sizebuf_t *msg )
{ {
cl.refdef.cl_viewangles[0] = MSG_ReadBitAngle( msg, 16 ); cl.viewangles[0] = MSG_ReadBitAngle( msg, 16 );
cl.refdef.cl_viewangles[1] = MSG_ReadBitAngle( msg, 16 ); cl.viewangles[1] = MSG_ReadBitAngle( msg, 16 );
cl.refdef.cl_viewangles[2] = MSG_ReadBitAngle( msg, 16 ); cl.viewangles[2] = MSG_ReadBitAngle( msg, 16 );
} }
/* /*
@ -968,7 +972,7 @@ void CL_ParseAddAngle( sizebuf_t *msg )
float add_angle; float add_angle;
add_angle = MSG_ReadBitAngle( msg, 16 ); add_angle = MSG_ReadBitAngle( msg, 16 );
cl.refdef.cl_viewangles[1] += add_angle; cl.viewangles[YAW] += add_angle;
} }
/* /*
@ -980,9 +984,9 @@ offset crosshair angles
*/ */
void CL_ParseCrosshairAngle( sizebuf_t *msg ) void CL_ParseCrosshairAngle( sizebuf_t *msg )
{ {
cl.refdef.crosshairangle[0] = MSG_ReadChar( msg ) * 0.2f; cl.crosshairangle[0] = MSG_ReadChar( msg ) * 0.2f;
cl.refdef.crosshairangle[1] = MSG_ReadChar( msg ) * 0.2f; cl.crosshairangle[1] = MSG_ReadChar( msg ) * 0.2f;
cl.refdef.crosshairangle[2] = 0.0f; // not used for screen space cl.crosshairangle[2] = 0.0f; // not used for screen space
} }
/* /*
@ -1619,7 +1623,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
break; break;
case svc_setview: case svc_setview:
cl.refdef.viewentity = MSG_ReadWord( msg ); cl.viewentity = MSG_ReadWord( msg );
break; break;
case svc_sound: case svc_sound:
case svc_ambientsound: case svc_ambientsound:
@ -1692,7 +1696,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart; cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
break; break;
case svc_setpause: case svc_setpause:
cl.refdef.paused = ( MSG_ReadOneBit( msg ) != 0 ); cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
break; break;
case svc_signonnum: case svc_signonnum:
CL_ParseSignon( msg ); CL_ParseSignon( msg );
@ -1718,7 +1722,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
CL_UpdateUserinfo( msg ); CL_UpdateUserinfo( msg );
break; break;
case svc_intermission: case svc_intermission:
cl.refdef.intermission = true; cl.intermission = true;
break; break;
case svc_modelindex: case svc_modelindex:
CL_PrecacheModel( msg ); CL_PrecacheModel( msg );

View File

@ -21,6 +21,11 @@ GNU General Public License for more details.
#include "particledef.h" #include "particledef.h"
#include "studio.h" #include "studio.h"
#define MAX_FORWARD 6 // forward probes for set idealpitch
#define MIN_CORRECTION_DISTANCE 0.25f // use smoothing if error is > this
#define MIN_PREDICTION_EPSILON 0.5f // complain if error is > this and we have cl_showerror set
#define MAX_PREDICTION_ERROR 64.0f // above this is assumed to be a teleport, don't smooth, etc.
void CL_ClearPhysEnts( void ) void CL_ClearPhysEnts( void )
{ {
clgame.pmove->numtouch = 0; clgame.pmove->numtouch = 0;
@ -39,7 +44,7 @@ void CL_PushPMStates( void )
{ {
if( clgame.pushed ) if( clgame.pushed )
{ {
MsgDev( D_ERROR, "PushPMStates called with pushed stack\n"); MsgDev( D_ERROR, "PushPMStates: stack overflow\n");
} }
else else
{ {
@ -66,19 +71,115 @@ void CL_PopPMStates( void )
} }
else else
{ {
MsgDev( D_ERROR, "PopPMStates called without stack\n"); MsgDev( D_ERROR, "PopPMStates: stack underflow\n");
} }
} }
/* /*
============= ===============
CL_ComputePlayerOrigin CL_SetLastUpdate
===============
FIXME: implement
=============
*/ */
void CL_ComputePlayerOrigin( cl_entity_t *clent ) void CL_SetLastUpdate( void )
{ {
cls.lastupdate_sequence = cls.netchan.incoming_sequence;
}
/*
===============
CL_RedoPrediction
===============
*/
void CL_RedoPrediction( void )
{
if ( cls.netchan.incoming_sequence != cls.lastupdate_sequence )
{
CL_PredictMovement( true );
CL_CheckPredictionError();
}
}
/*
===============
CL_IsPredicted
===============
*/
qboolean CL_IsPredicted( void )
{
if( cl_nopred->value || !cl.frame.valid || cl.background || cls.spectator )
return false;
if( !cl.validsequence || ( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
return false;
return true;
}
/*
===============
CL_SetIdealPitch
===============
*/
void CL_SetIdealPitch( void )
{
float angleval, sinval, cosval;
int i, j, step, dir, steps;
float z[MAX_FORWARD];
vec3_t top, bottom;
pmtrace_t tr;
if( cl.local.onground == -1 )
return;
angleval = cl.viewangles[YAW] * M_PI2 / 360.0f;
SinCos( angleval, &sinval, &cosval );
// Now move forward by 36, 48, 60, etc. units from the eye position and drop lines straight down
// 160 or so units to see what's below
for( i = 0; i < MAX_FORWARD; i++ )
{
top[0] = cl.simorg[0] + cosval * (i + 3.0f) * 12.0f;
top[1] = cl.simorg[1] + sinval * (i + 3.0f) * 12.0f;
top[2] = cl.simorg[2] + cl.viewheight[2];
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160.0f;
// skip any monsters (only world and brush models)
tr = CL_TraceLine( top, bottom, PM_STUDIO_BOX );
if( tr.allsolid ) return; // looking at a wall, leave ideal the way is was
if( tr.fraction == 1.0f )
return; // near a dropoff
z[i] = top[2] + tr.fraction * (bottom[2] - top[2]);
}
dir = 0;
steps = 0;
for( j = 1; j < i; j++ )
{
step = z[j] - z[j-1];
if( step > -ON_EPSILON && step < ON_EPSILON )
continue;
if( dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ))
return; // mixed changes
steps++;
dir = step;
}
if( !dir )
{
cl.local.idealpitch = 0.0f;
return;
}
if( steps < 2 ) return;
cl.local.idealpitch = -dir * cl_idealpitchscale->value;
} }
/* /*
@ -91,7 +192,7 @@ void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient )
{ {
entity_state_t *state; entity_state_t *state;
predicted_player_t *player; predicted_player_t *player;
cl_entity_t *clent; cl_entity_t *ent;
int i; int i;
for( i = 0; i < MAX_CLIENTS; i++ ) for( i = 0; i < MAX_CLIENTS; i++ )
@ -107,37 +208,29 @@ void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient )
if( !state->modelindex ) if( !state->modelindex )
continue; continue;
clent = CL_GetEntityByIndex( i + 1 ); player->active = true;
player->movetype = state->movetype;
player->solid = state->solid;
player->usehull = state->usehull;
// special for EF_NODRAW and local client? if( FBitSet( state->effects, EF_NODRAW ) && !bIncludeLocalClient && ( cl.playernum == i ))
if( FBitSet( state->effects, EF_NODRAW ) && !bIncludeLocalClient ) continue;
// note that the local player is special, since he moves locally
// we use his last predicted postition
if( cl.playernum == i )
{ {
// don't include local player? VectorCopy( state->origin, player->origin );
if( cl.playernum == i ) continue; VectorCopy( state->angles, player->angles );
player->active = true;
player->movetype = state->movetype;
player->solid = state->solid;
player->usehull = state->usehull;
CL_ComputePlayerOrigin( clent );
VectorCopy( clent->origin, player->origin );
VectorCopy( clent->angles, player->angles );
} }
else else
{ {
player->active = true; ent = CL_GetEntityByIndex( i + 1 );
player->movetype = state->movetype;
player->solid = state->solid;
player->usehull = state->usehull;
// don't rewrite origin and angles of local client CL_ComputePlayerOrigin( ent );
if( cl.playernum == i )
continue;
VectorCopy( state->origin, player->origin ); VectorCopy( ent->origin, player->origin );
VectorCopy( state->angles, player->angles ); VectorCopy( ent->angles, player->angles );
} }
} }
} }
@ -981,9 +1074,9 @@ void CL_RunUsercmd( local_state_t *from, local_state_t *to, usercmd_t *u, qboole
// copy results back to client // copy results back to client
CL_FinishPMove( clgame.pmove, to ); CL_FinishPMove( clgame.pmove, to );
cl.predicted.lastground = clgame.pmove->onground; if( clgame.pmove->onground > 0 && clgame.pmove->onground < clgame.pmove->numphysent )
if( cl.predicted.lastground > 0 && cl.predicted.lastground < clgame.pmove->numphysent ) cl.local.lastground = clgame.pmove->physents[clgame.pmove->onground].info;
cl.predicted.lastground = clgame.pmove->physents[cl.predicted.lastground].info; else cl.local.lastground = clgame.pmove->onground; // world(0) or in air(-1)
clgame.dllFuncs.pfnPostRunCmd( from, to, &cmd, runfuncs, *time, random_seed ); clgame.dllFuncs.pfnPostRunCmd( from, to, &cmd, runfuncs, *time, random_seed );
*time += (double)cmd.msec / 1000.0; *time += (double)cmd.msec / 1000.0;
@ -996,42 +1089,41 @@ CL_CheckPredictionError
*/ */
void CL_CheckPredictionError( void ) void CL_CheckPredictionError( void )
{ {
int frame; int frame;
vec3_t delta; vec3_t delta;
float len, maxspd; float len, maxspd;
static int pos = 0;
if( !CL_IsPredicted( )) return;
// calculate the last usercmd_t we sent that the server has processed // calculate the last usercmd_t we sent that the server has processed
frame = ( cls.netchan.incoming_acknowledged ) & CL_UPDATE_MASK; frame = ( cls.netchan.incoming_acknowledged ) & CL_UPDATE_MASK;
// compare what the server returned with what we had predicted it to be // compare what the server returned with what we had predicted it to be
VectorSubtract( cl.frame.playerstate[cl.playernum].origin, cl.predicted.origins[frame], delta ); VectorSubtract( cl.frame.playerstate[cl.playernum].origin, cl.local.predicted_origins[frame], delta );
maxspd = ( clgame.movevars.maxvelocity * host.frametime ); maxspd = ( clgame.movevars.maxvelocity * host.frametime );
len = VectorLength( delta ); len = VectorLength( delta );
// save the prediction error for interpolation // save the prediction error for interpolation
if( FBitSet( cl.frame.client.flags, EF_NOINTERP ) || ( len > ( maxspd * 2.0f ))) if( FBitSet( cl.frame.client.flags, EF_NOINTERP ) || ( len > ( maxspd * 2.0f )) || len > MAX_PREDICTION_ERROR )
{ {
if( cl_showerror->value && ( len > ( maxspd * 2.0f )) && host.developer >= D_ERROR ) if( cl_showerror->value && ( len > ( maxspd * 2.0f )) && host.developer >= D_ERROR )
MsgDev( D_INFO, "CL_Predict: player teleported on %i: %g > %g\n", cl.parsecount, len, ( maxspd * 2.0f )); Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", len );
// a teleport or something or gamepaused // a teleport or something or gamepaused
VectorClear( cl.predicted.error ); VectorClear( cl.local.prediction_error );
} }
else else
{ {
if( cl_showerror->value && len > 0.25f && host.developer >= D_ERROR ) if( cl_showerror->value && len > 0.25f && host.developer >= D_ERROR )
MsgDev( D_INFO, "CL_Predict: prediction error on %i: %g\n", cl.parsecount, len ); Con_NPrintf( 10 + ( ++pos & 3 ), "^1prediction error:^7 %.3f units\n", cl.parsecount, len );
VectorCopy( cl.frame.playerstate[cl.playernum].origin, cl.predicted.origins[frame] ); VectorCopy( cl.frame.playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] );
// save for error interpolation // save for error interpolation
VectorCopy( delta, cl.predicted.error ); VectorCopy( delta, cl.local.prediction_error );
if(( len > 0.25f ) && ( cl.maxclients > 1 )) if(( len > MIN_CORRECTION_DISTANCE ) && ( cl.maxclients > 1 ))
cl.predicted.correction_time = cl_smoothtime->value; cls.correction_time = cl_smoothtime->value;
} }
} }
@ -1073,7 +1165,7 @@ CL_PredictMovement
Sets cl.predicted.origin and cl.predicted.angles Sets cl.predicted.origin and cl.predicted.angles
================= =================
*/ */
void CL_PredictMovement( void ) void CL_PredictMovement( qboolean repredicting )
{ {
double time; double time;
usercmd_t *ucmd; usercmd_t *ucmd;
@ -1086,18 +1178,13 @@ void CL_PredictMovement( void )
if( cls.state != ca_active ) return; if( cls.state != ca_active ) return;
if( cls.demoplayback && cl.refdef.cmd != NULL ) if( cls.demoplayback && cl.cmd != NULL )
CL_DemoInterpolateAngles(); CL_DemoInterpolateAngles();
if( !CL_IsInGame( )) return; if( !CL_IsInGame( )) return;
CL_SetUpPlayerPrediction( false, false ); CL_SetUpPlayerPrediction( false, false );
// unpredicted pure angled values converted into axis
AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );
ASSERT( cl.refdef.cmd != NULL );
if( !CL_IsPredicted( )) if( !CL_IsPredicted( ))
{ {
// fake prediction code // fake prediction code
@ -1105,14 +1192,14 @@ void CL_PredictMovement( void )
// because cl_lw is enabled by default in Half-Life // because cl_lw is enabled by default in Half-Life
if( !cl_lw->value ) if( !cl_lw->value )
{ {
cl.predicted.viewmodel = cl.frame.client.viewmodel; cl.local.viewmodel = cl.frame.client.viewmodel;
return; return;
} }
ack = cls.netchan.incoming_acknowledged; ack = cls.netchan.incoming_acknowledged;
outgoing_command = cls.netchan.outgoing_sequence; outgoing_command = cls.netchan.outgoing_sequence;
from = &cl.predict[cl.parsecountmod]; from = &cl.predicted_frames[cl.parsecountmod];
from->playerstate = cl.frame.playerstate[cl.playernum]; from->playerstate = cl.frame.playerstate[cl.playernum];
from->client = cl.frame.client; from->client = cl.frame.client;
memcpy( from->weapondata, cl.frame.weapondata, sizeof( from->weapondata )); memcpy( from->weapondata, cl.frame.weapondata, sizeof( from->weapondata ));
@ -1133,7 +1220,7 @@ void CL_PredictMovement( void )
if( current_command >= outgoing_command ) if( current_command >= outgoing_command )
break; break;
to = &cl.predict[( cl.parsecountmod + frame ) & CL_UPDATE_MASK]; to = &cl.predicted_frames[( cl.parsecountmod + frame ) & CL_UPDATE_MASK];
CL_FakeUsercmd( from, to, &cl.commands[current_command_mod].cmd, CL_FakeUsercmd( from, to, &cl.commands[current_command_mod].cmd,
!cl.commands[current_command_mod].processedfuncs, !cl.commands[current_command_mod].processedfuncs,
@ -1146,14 +1233,14 @@ void CL_PredictMovement( void )
} }
if( to ) if( to )
cl.predicted.viewmodel = to->client.viewmodel; cl.local.viewmodel = to->client.viewmodel;
return; return;
} }
ack = cls.netchan.incoming_acknowledged; ack = cls.netchan.incoming_acknowledged;
outgoing_command = cls.netchan.outgoing_sequence; outgoing_command = cls.netchan.outgoing_sequence;
from = &cl.predict[cl.parsecountmod]; from = &cl.predicted_frames[cl.parsecountmod];
memcpy( from->weapondata, cl.frame.weapondata, sizeof( from->weapondata )); memcpy( from->weapondata, cl.frame.weapondata, sizeof( from->weapondata ));
from->playerstate = cl.frame.playerstate[cl.playernum]; from->playerstate = cl.frame.playerstate[cl.playernum];
from->client = cl.frame.client; from->client = cl.frame.client;
@ -1176,7 +1263,7 @@ void CL_PredictMovement( void )
if( current_command >= outgoing_command ) if( current_command >= outgoing_command )
break; break;
to = &cl.predict[( cl.parsecountmod + frame ) & CL_UPDATE_MASK]; to = &cl.predicted_frames[( cl.parsecountmod + frame ) & CL_UPDATE_MASK];
runfuncs = !cl.commands[current_command_mod].processedfuncs; runfuncs = !cl.commands[current_command_mod].processedfuncs;
ucmd = &cl.commands[current_command_mod].cmd; ucmd = &cl.commands[current_command_mod].cmd;
@ -1184,7 +1271,7 @@ void CL_PredictMovement( void )
cl.commands[current_command_mod].processedfuncs = true; cl.commands[current_command_mod].processedfuncs = true;
// save for debug checking // save for debug checking
VectorCopy( to->playerstate.origin, cl.predicted.origins[current_command_mod] ); VectorCopy( to->playerstate.origin, cl.local.predicted_origins[current_command_mod] );
from = to; from = to;
frame++; frame++;
@ -1193,7 +1280,7 @@ void CL_PredictMovement( void )
if( to ) if( to )
{ {
float t0 = cl.commands[( cl.parsecountmod + frame - 1) & CL_UPDATE_MASK].senttime; float t0 = cl.commands[( cl.parsecountmod + frame - 1) & CL_UPDATE_MASK].senttime;
float t1 = cl.commands[( cl.parsecountmod + frame ) & CL_UPDATE_MASK].senttime; float t1 = cl.commands[( cl.parsecountmod + frame - 0) & CL_UPDATE_MASK].senttime;
float t; float t;
if( t0 == t1 ) if( t0 == t1 )
@ -1211,10 +1298,10 @@ void CL_PredictMovement( void )
fabs( to->playerstate.origin[1] - from->playerstate.origin[1] ) > 128.0f || fabs( to->playerstate.origin[1] - from->playerstate.origin[1] ) > 128.0f ||
fabs( to->playerstate.origin[2] - from->playerstate.origin[2] ) > 128.0f ) fabs( to->playerstate.origin[2] - from->playerstate.origin[2] ) > 128.0f )
{ {
VectorCopy( to->playerstate.origin, cl.predicted.origin ); VectorCopy( to->playerstate.origin, cl.simorg );
VectorCopy( to->client.velocity, cl.predicted.velocity ); VectorCopy( to->client.velocity, cl.simvel );
VectorCopy( to->client.punchangle, cl.predicted.punchangle ); VectorCopy( to->client.punchangle, cl.punchangle );
VectorCopy( to->client.view_ofs, cl.predicted.viewofs ); VectorCopy( to->client.view_ofs, cl.viewheight );
} }
else else
{ {
@ -1224,29 +1311,29 @@ void CL_PredictMovement( void )
VectorSubtract( to->client.velocity, from->client.velocity, delta_vel ); VectorSubtract( to->client.velocity, from->client.velocity, delta_vel );
VectorSubtract( to->client.punchangle, from->client.punchangle, delta_punch ); VectorSubtract( to->client.punchangle, from->client.punchangle, delta_punch );
VectorMA( from->playerstate.origin, t, delta_origin, cl.predicted.origin ); VectorMA( from->playerstate.origin, t, delta_origin, cl.simorg );
VectorMA( from->client.velocity, t, delta_vel, cl.predicted.velocity ); VectorMA( from->client.velocity, t, delta_vel, cl.simvel );
VectorMA( from->client.punchangle, t, delta_punch, cl.predicted.punchangle ); VectorMA( from->client.punchangle, t, delta_punch, cl.punchangle );
if( from->playerstate.usehull == to->playerstate.usehull ) if( from->playerstate.usehull == to->playerstate.usehull )
{ {
vec3_t delta_viewofs; vec3_t delta_viewofs;
VectorSubtract( to->client.view_ofs, from->client.view_ofs, delta_viewofs ); VectorSubtract( to->client.view_ofs, from->client.view_ofs, delta_viewofs );
VectorMA( from->client.view_ofs, t, delta_viewofs, cl.predicted.viewofs ); VectorMA( from->client.view_ofs, t, delta_viewofs, cl.viewheight );
} }
} }
cl.predicted.waterlevel = to->client.waterlevel; cl.local.waterlevel = to->client.waterlevel;
cl.predicted.viewmodel = to->client.viewmodel; cl.local.viewmodel = to->client.viewmodel;
cl.predicted.usehull = to->playerstate.usehull; cl.local.usehull = to->playerstate.usehull;
if( FBitSet( to->client.flags, FL_ONGROUND )) if( FBitSet( to->client.flags, FL_ONGROUND ))
{ {
cl_entity_t *ent = CL_GetEntityByIndex( cl.predicted.lastground ); cl_entity_t *ent = CL_GetEntityByIndex( cl.local.lastground );
cl.predicted.onground = cl.predicted.lastground; cl.local.onground = cl.local.lastground;
cl.predicted.moving = 0; cl.local.moving = 0;
if( ent ) if( ent )
{ {
@ -1257,42 +1344,42 @@ void CL_PredictMovement( void )
if( VectorLength( delta ) > 0.0f ) if( VectorLength( delta ) > 0.0f )
{ {
cl.predicted.correction_time = 0; cls.correction_time = 0;
cl.predicted.moving = 1; cl.local.moving = 1;
} }
} }
} }
else else
{ {
cl.predicted.onground = -1; cl.local.onground = -1;
cl.predicted.moving = 0; cl.local.moving = 0;
} }
if( cl.predicted.correction_time > 0.0 && !cl_nosmooth->value && cl_smoothtime->value ) if( cls.correction_time > 0.0 && !cl_nosmooth->value && cl_smoothtime->value )
{ {
float d; float d;
int i; int i;
cl.predicted.correction_time = cl.predicted.correction_time - host.frametime; cls.correction_time = cls.correction_time - host.frametime;
if( cl_smoothtime->value <= 0 ) if( cl_smoothtime->value <= 0 )
Cvar_SetValue( "cl_smoothtime", 0.1 ); Cvar_SetValue( "cl_smoothtime", 0.1 );
if( cl.predicted.correction_time < 0 ) if( cls.correction_time < 0 )
cl.predicted.correction_time = 0; cls.correction_time = 0;
if( cl_smoothtime->value <= cl.predicted.correction_time ) if( cl_smoothtime->value <= cls.correction_time )
cl.predicted.correction_time = cl_smoothtime->value; cls.correction_time = cl_smoothtime->value;
d = cl.predicted.correction_time / cl_smoothtime->value; d = cls.correction_time / cl_smoothtime->value;
for( i = 0; i < 3; i++ ) for( i = 0; i < 3; i++ )
{ {
cl.predicted.origin[i] = cl.predicted.lastorigin[i] + ( cl.predicted.origin[i] - cl.predicted.lastorigin[i] ) * (1.0 - d); cl.simorg[i] = cl.local.lastorigin[i] + ( cl.simorg[i] - cl.local.lastorigin[i] ) * (1.0 - d);
} }
} }
VectorCopy( cl.predicted.origin, cl.predicted.lastorigin ); VectorCopy( cl.simorg, cl.local.lastorigin );
CL_SetIdealPitch(); CL_SetIdealPitch();
} }

View File

@ -22,8 +22,6 @@ GNU General Public License for more details.
convar_t *scr_centertime; convar_t *scr_centertime;
convar_t *scr_loading; convar_t *scr_loading;
convar_t *scr_download; convar_t *scr_download;
convar_t *scr_width;
convar_t *scr_height;
convar_t *scr_viewsize; convar_t *scr_viewsize;
convar_t *cl_testlights; convar_t *cl_testlights;
convar_t *cl_allow_levelshots; convar_t *cl_allow_levelshots;
@ -100,7 +98,7 @@ void SCR_DrawFPS( int height )
} }
Con_DrawStringLen( fpsstring, &offset, NULL ); Con_DrawStringLen( fpsstring, &offset, NULL );
Con_DrawString( scr_width->value - offset - 4, height, fpsstring, color ); Con_DrawString( glState.width - offset - 4, height, fpsstring, color );
} }
/* /*
@ -144,7 +142,7 @@ void SCR_NetSpeeds( void )
Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal sended to server: %s\nTotal received from server: %s\n", Q_snprintf( msg, sizeof( msg ), "sv fps: ^1%4i min, ^3%4i cur, ^2%4i max\ncl fps: ^1%4i min, ^3%4i cur, ^2%4i max\nGame Time: %02d:%02d\nTotal sended to server: %s\nTotal received from server: %s\n",
min_svfps, cur_svfps, max_svfps, min_clfps, cur_clfps, max_clfps, (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_sended ), Q_memprint( cls.netchan.total_received )); min_svfps, cur_svfps, max_svfps, min_clfps, cur_clfps, max_clfps, (int)(time / 60.0f ), (int)fmod( time, 60.0f ), Q_memprint( cls.netchan.total_sended ), Q_memprint( cls.netchan.total_received ));
x = scr_width->value - 320; x = glState.width - 320;
y = 384; y = 384;
Con_DrawStringLen( NULL, NULL, &height ); Con_DrawStringLen( NULL, NULL, &height );
@ -180,7 +178,7 @@ void SCR_RSpeeds( void )
char *p, *start, *end; char *p, *start, *end;
rgba_t color; rgba_t color;
x = scr_width->value - 340; x = glState.width - 340;
y = 64; y = 64;
Con_DrawStringLen( NULL, NULL, &height ); Con_DrawStringLen( NULL, NULL, &height );
@ -288,7 +286,7 @@ void SCR_DrawPlaque( void )
{ {
int levelshot = GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE, NULL ); int levelshot = GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE, NULL );
GL_SetRenderMode( kRenderNormal ); GL_SetRenderMode( kRenderNormal );
R_DrawStretchPic( 0, 0, scr_width->value, scr_height->value, 0, 0, 1, 1, levelshot ); R_DrawStretchPic( 0, 0, glState.width, glState.height, 0, 0, 1, 1, levelshot );
if( !cl.background ) CL_DrawHUD( CL_LOADING ); if( !cl.background ) CL_DrawHUD( CL_LOADING );
} }
} }
@ -346,7 +344,7 @@ SCR_DirtyScreen
void SCR_DirtyScreen( void ) void SCR_DirtyScreen( void )
{ {
SCR_AddDirtyPoint( 0, 0 ); SCR_AddDirtyPoint( 0, 0 );
SCR_AddDirtyPoint( scr_width->value - 1, scr_height->value - 1 ); SCR_AddDirtyPoint( glState.width - 1, glState.height - 1 );
} }
/* /*
@ -389,10 +387,10 @@ void SCR_TileClear( void )
if( clear.y2 <= clear.y1 ) if( clear.y2 <= clear.y1 )
return; // nothing disturbed return; // nothing disturbed
top = cl.refdef.viewport[1]; top = RI.viewport[1];
bottom = top + cl.refdef.viewport[3] - 1; bottom = top + RI.viewport[3] - 1;
left = cl.refdef.viewport[0]; left = RI.viewport[0];
right = left + cl.refdef.viewport[2] - 1; right = left + RI.viewport[2] - 1;
if( clear.y1 < top ) if( clear.y1 < top )
{ {
@ -587,8 +585,8 @@ void SCR_VidInit( void )
memset( &clgame.centerPrint, 0, sizeof( clgame.centerPrint )); memset( &clgame.centerPrint, 0, sizeof( clgame.centerPrint ));
// update screen sizes for menu // update screen sizes for menu
gameui.globals->scrWidth = scr_width->value; gameui.globals->scrWidth = glState.width;
gameui.globals->scrHeight = scr_height->value; gameui.globals->scrHeight = glState.height;
SCR_RebuildGammaTable(); SCR_RebuildGammaTable();
VGui_Startup (); VGui_Startup ();

View File

@ -2517,7 +2517,7 @@ void CL_UpdateFlashlight( cl_entity_t *pEnt )
if(( pEnt->index - 1 ) == cl.playernum ) if(( pEnt->index - 1 ) == cl.playernum )
{ {
// get the predicted angles // get the predicted angles
AngleVectors( cl.refdef.cl_viewangles, forward, NULL, NULL ); AngleVectors( cl.viewangles, forward, NULL, NULL );
} }
else else
{ {
@ -2534,7 +2534,7 @@ void CL_UpdateFlashlight( cl_entity_t *pEnt )
VectorClear( view_ofs ); VectorClear( view_ofs );
if(( pEnt->index - 1 ) == cl.playernum ) if(( pEnt->index - 1 ) == cl.playernum )
VectorCopy( cl.refdef.viewheight, view_ofs ); VectorCopy( cl.viewheight, view_ofs );
VectorAdd( pEnt->origin, view_ofs, vecSrc ); VectorAdd( pEnt->origin, view_ofs, vecSrc );
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd ); VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
@ -2584,7 +2584,7 @@ void CL_TestLights( void )
f = 64 * ( i / 4) + 128; f = 64 * ( i / 4) + 128;
for( j = 0; j < 3; j++ ) for( j = 0; j < 3; j++ )
dl->origin[j] = cl.refdef.vieworg[j] + cl.refdef.forward[j] * f + cl.refdef.right[j] * r; dl->origin[j] = RI.vieworg[j] + RI.vforward[j] * f + RI.vright[j] * r;
dl->color.r = ((((i % 6) + 1) & 1)>>0) * 255; dl->color.r = ((((i % 6) + 1) & 1)>>0) * 255;
dl->color.g = ((((i % 6) + 1) & 2)>>1) * 255; dl->color.g = ((((i % 6) + 1) & 2)>>1) * 255;

View File

@ -205,7 +205,7 @@ qboolean SCR_DrawCinematic( void )
redraw = true; redraw = true;
} }
R_DrawStretchRaw( 0, 0, scr_width->value, scr_height->value, xres, yres, frame, redraw ); R_DrawStretchRaw( 0, 0, glState.width, glState.height, xres, yres, frame, redraw );
return true; return true;
} }

View File

@ -20,6 +20,123 @@ GNU General Public License for more details.
#include "gl_local.h" #include "gl_local.h"
#include "vgui_draw.h" #include "vgui_draw.h"
/*
===============
V_CalcViewRect
calc frame rectangle (Quake1 style)
===============
*/
void V_CalcViewRect( void )
{
int size, sb_lines;
if( scr_viewsize->value >= 120.0f )
sb_lines = 0; // no status bar at all
else if( scr_viewsize->value >= 110.0f )
sb_lines = 24; // no inventory
else sb_lines = 48;
size = Q_min( scr_viewsize->value, 100 );
clgame.viewport[2] = glState.width * size / 100;
clgame.viewport[3] = glState.height * size / 100;
if( clgame.viewport[3] > glState.height - sb_lines )
clgame.viewport[3] = glState.height - sb_lines;
if( clgame.viewport[3] > glState.height )
clgame.viewport[3] = glState.height;
clgame.viewport[0] = ( glState.width - clgame.viewport[2] ) / 2;
clgame.viewport[1] = ( glState.height - sb_lines - clgame.viewport[3] ) / 2;
}
/*
===============
V_SetupViewModel
===============
*/
void V_SetupViewModel( void )
{
cl_entity_t *view = &clgame.viewent;
// setup the viewent variables
view->model = Mod_Handle( cl.local.viewmodel );
view->curstate.modelindex = cl.local.viewmodel;
view->curstate.number = cl.playernum + 1;
view->index = cl.playernum + 1;
view->curstate.colormap = 0;
view->curstate.frame = 0;
}
/*
===============
V_SetRefParams
===============
*/
void V_SetRefParams( ref_params_t *fd )
{
memset( fd, 0, sizeof( ref_params_t ));
// probably this is not needs
VectorCopy( RI.vieworg, fd->vieworg );
VectorCopy( RI.viewangles, fd->viewangles );
fd->frametime = host.frametime;
fd->time = cl.time;
fd->intermission = cl.intermission; // Quake Remake compatibility
fd->paused = (cl.paused != 0);
fd->spectator = (cls.spectator != 0);
fd->onground = (cl.local.onground != -1);
fd->waterlevel = cl.local.waterlevel;
VectorCopy( cl.simvel, fd->simvel );
VectorCopy( cl.simorg, fd->simorg );
VectorCopy( cl.viewheight, fd->viewheight );
fd->idealpitch = cl.local.idealpitch;
VectorCopy( cl.viewangles, fd->cl_viewangles );
fd->health = cl.local.health;
VectorCopy( cl.crosshairangle, fd->crosshairangle );
fd->viewsize = scr_viewsize->value;
VectorCopy( cl.punchangle, fd->punchangle );
fd->maxclients = cl.maxclients;
fd->viewentity = cl.viewentity;
fd->playernum = cl.playernum;
fd->max_entities = clgame.maxEntities;
fd->demoplayback = cls.demoplayback;
fd->hardware = 1; // OpenGL
if( cl.first_frame ) fd->smoothing = true; // NOTE: currently this used to prevent ugly un-duck effect while level is changed
else fd->smoothing = cl.local.pushmsec; // enable smoothing in multiplayer by server request (AMX uses)
// get pointers to movement vars and user cmd
fd->movevars = &clgame.movevars;
fd->cmd = cl.cmd;
// setup viewport
fd->viewport[0] = clgame.viewport[0];
fd->viewport[1] = clgame.viewport[1];
fd->viewport[2] = clgame.viewport[2];
fd->viewport[3] = clgame.viewport[3];
fd->onlyClientDraw = 0; // reset clientdraw
fd->nextView = 0; // reset nextview
// Xash3D extension. FIXME: it's needs to be removed...
// calc FOV
fd->fov_x = bound( 1.0f, cl.local.scr_fov, 179.0f ); // this is a final fov value
fd->fov_y = V_CalcFov( &fd->fov_x, clgame.viewport[2], clgame.viewport[3] );
// adjust FOV for widescreen
if( glState.wideScreen && r_adjust_fov->value )
V_AdjustFov( &fd->fov_x, &fd->fov_y, clgame.viewport[2], clgame.viewport[3], false );
}
/* /*
=============== ===============
@ -28,14 +145,15 @@ V_MergeOverviewRefdef
merge refdef with overview settings merge refdef with overview settings
=============== ===============
*/ */
void V_MergeOverviewRefdef( void ) void V_RefParamsApplyOverview( ref_params_t *fd )
{ {
ref_overview_t *ov = &clgame.overView; ref_overview_t *ov = &clgame.overView;
float aspect; float aspect;
float size_x, size_y; float size_x, size_y;
vec2_t mins, maxs; vec2_t mins, maxs;
if( !gl_overview->value ) return; if( !CL_IsDevOverviewMode( ))
return;
// NOTE: Xash3D may use 16:9 or 16:10 aspects // NOTE: Xash3D may use 16:9 or 16:10 aspects
aspect = (float)glState.width / (float)glState.height; aspect = (float)glState.width / (float)glState.height;
@ -55,123 +173,40 @@ void V_MergeOverviewRefdef( void )
ov->flZoom, ov->origin[0], ov->origin[1], ov->origin[2], ov->zNear, ov->zFar, ov->rotated ); ov->flZoom, ov->origin[0], ov->origin[1], ov->origin[2], ov->zNear, ov->zFar, ov->rotated );
} }
VectorCopy( ov->origin, cl.refdef.vieworg ); VectorCopy( ov->origin, fd->vieworg );
cl.refdef.vieworg[2] = ov->zFar + ov->zNear; fd->vieworg[2] = ov->zFar + ov->zNear;
Vector2Copy( cl.refdef.vieworg, mins ); Vector2Copy( fd->vieworg, mins );
Vector2Copy( cl.refdef.vieworg, maxs ); Vector2Copy( fd->vieworg, maxs );
mins[!ov->rotated] += ov->xLeft; mins[!ov->rotated] += ov->xLeft;
maxs[!ov->rotated] += ov->xRight; maxs[!ov->rotated] += ov->xRight;
mins[ov->rotated] += ov->xTop; mins[ov->rotated] += ov->xTop;
maxs[ov->rotated] += ov->xBottom; maxs[ov->rotated] += ov->xBottom;
cl.refdef.viewangles[0] = 90.0f; fd->viewangles[0] = 90.0f;
cl.refdef.viewangles[1] = 90.0f; fd->viewangles[1] = 90.0f;
cl.refdef.viewangles[2] = (ov->rotated) ? (ov->flZoom < 0.0f) ? 180.0f : 0.0f : (ov->flZoom < 0.0f) ? -90.0f : 90.0f; fd->viewangles[2] = (ov->rotated) ? (ov->flZoom < 0.0f) ? 180.0f : 0.0f : (ov->flZoom < 0.0f) ? -90.0f : 90.0f;
Mod_SetOrthoBounds( mins, maxs ); Mod_SetOrthoBounds( mins, maxs );
} }
/* /*
=============== =============
V_CalcViewRect V_GetRefParams
=============
calc frame rectangle (Quake1 style)
===============
*/ */
void V_CalcViewRect( void ) void V_GetRefParams( ref_params_t *fd )
{ {
int size, sb_lines; // part1: deniable updates
VectorCopy( fd->simvel, cl.simvel );
VectorCopy( fd->simorg, cl.simorg );
VectorCopy( fd->punchangle, cl.punchangle );
VectorCopy( fd->viewheight, cl.viewheight );
if( scr_viewsize->value >= 120 ) // part2: really used updates
sb_lines = 0; // no status bar at all VectorCopy( fd->crosshairangle, cl.crosshairangle );
else if( scr_viewsize->value >= 110 ) VectorCopy( fd->cl_viewangles, cl.viewangles );
sb_lines = 24; // no inventory cl.intermission = fd->intermission; // Quake Remake compatibility
else sb_lines = 48;
size = Q_min( scr_viewsize->value, 100 );
cl.refdef.viewport[2] = scr_width->value * size / 100;
cl.refdef.viewport[3] = scr_height->value * size / 100;
if( cl.refdef.viewport[3] > scr_height->value - sb_lines )
cl.refdef.viewport[3] = scr_height->value - sb_lines;
if( cl.refdef.viewport[3] > scr_height->value )
cl.refdef.viewport[3] = scr_height->value;
cl.refdef.viewport[0] = ( scr_width->value - cl.refdef.viewport[2] ) / 2;
cl.refdef.viewport[1] = ( scr_height->value - sb_lines - cl.refdef.viewport[3] ) / 2;
}
/*
===============
V_SetupRefDef
update refdef values each frame
===============
*/
void V_SetupRefDef( void )
{
cl_entity_t *clent;
// compute viewport rectangle
V_CalcViewRect();
clent = CL_GetLocalPlayer ();
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
cl.refdef.movevars = &clgame.movevars;
cl.refdef.health = cl.frame.client.health;
cl.refdef.playernum = cl.playernum;
cl.refdef.max_entities = clgame.maxEntities;
cl.refdef.maxclients = cl.maxclients;
cl.refdef.time = cl.time;
cl.refdef.frametime = cl.time - cl.oldtime;
cl.refdef.demoplayback = cls.demoplayback;
cl.refdef.viewsize = scr_viewsize->value;
cl.refdef.onlyClientDraw = 0; // reset clientdraw
cl.refdef.hardware = true; // always true
cl.refdef.spectator = (cls.spectator != 0);
cl.refdef.smoothing = cl.first_frame; // NOTE: currently this used to prevent ugly un-duck effect while level is changed
cl.scr_fov = bound( 1.0f, cl.scr_fov, 179.0f );
cl.refdef.nextView = 0;
// calc FOV
cl.refdef.fov_x = cl.scr_fov; // this is a final fov value
cl.refdef.fov_y = V_CalcFov( &cl.refdef.fov_x, cl.refdef.viewport[2], cl.refdef.viewport[3] );
// adjust FOV for widescreen
if( glState.wideScreen && r_adjust_fov->value )
V_AdjustFov( &cl.refdef.fov_x, &cl.refdef.fov_y, cl.refdef.viewport[2], cl.refdef.viewport[3], false );
if( CL_IsPredicted( ) && !cl.first_frame )
{
VectorCopy( cl.predicted.origin, cl.refdef.simorg );
VectorCopy( cl.predicted.velocity, cl.refdef.simvel );
VectorCopy( cl.predicted.viewofs, cl.refdef.viewheight );
VectorCopy( cl.predicted.punchangle, cl.refdef.punchangle );
cl.refdef.onground = ( cl.predicted.onground == -1 ) ? false : true;
cl.refdef.waterlevel = cl.predicted.waterlevel;
}
else
{
VectorCopy( cl.frame.client.origin, cl.refdef.simorg );
VectorCopy( cl.frame.client.view_ofs, cl.refdef.viewheight );
VectorCopy( cl.frame.client.velocity, cl.refdef.simvel );
VectorCopy( cl.frame.client.punchangle, cl.refdef.punchangle );
cl.refdef.onground = (cl.frame.client.flags & FL_ONGROUND) ? 1 : 0;
cl.refdef.waterlevel = cl.frame.client.waterlevel;
}
// setup the viewent variables
if( cl_lw->value ) clgame.viewent.curstate.modelindex = cl.predicted.viewmodel;
else clgame.viewent.curstate.modelindex = cl.frame.client.viewmodel;
clgame.viewent.model = Mod_Handle( clgame.viewent.curstate.modelindex );
clgame.viewent.curstate.number = cl.playernum + 1;
clgame.viewent.curstate.entityType = ET_NORMAL;
clgame.viewent.index = cl.playernum + 1;
} }
/* /*
@ -203,7 +238,7 @@ qboolean V_PreRender( void )
return false; return false;
} }
R_BeginFrame( !cl.refdef.paused ); R_BeginFrame( !cl.paused );
return true; return true;
} }
@ -218,34 +253,50 @@ V_RenderView
*/ */
void V_RenderView( void ) void V_RenderView( void )
{ {
ref_params_t rp;
int viewnum = 0;
if( !cl.video_prepped || ( UI_IsVisible() && !cl.background )) if( !cl.video_prepped || ( UI_IsVisible() && !cl.background ))
return; // still loading return; // still loading
if( cl.frame.valid && ( cl.force_refdef || !cl.refdef.paused )) if( cl.frame.valid && ( cl.force_refdef || !cl.paused ))
{ {
cl.force_refdef = false; cl.force_refdef = false;
R_ClearScene (); R_ClearScene ();
CL_AddEntities (); CL_AddEntities ();
V_SetupRefDef ();
} }
V_CalcViewRect (); // compute viewport rectangle
V_SetRefParams( &rp );
V_SetupViewModel ();
R_Set2DMode( false ); R_Set2DMode( false );
SCR_AddDirtyPoint( 0, 0 );
SCR_AddDirtyPoint( scr_width->value - 1, scr_height->value - 1 );
SCR_AddDirtyPoint( 0, 0 );
SCR_AddDirtyPoint( clgame.viewport[2] - 1, clgame.viewport[3] - 1 );
GL_BackendStartFrame ();
tr.framecount++; // g-cont. keep actual frame for all viewpasses tr.framecount++; // g-cont. keep actual frame for all viewpasses
do do
{ {
clgame.dllFuncs.pfnCalcRefdef( &cl.refdef ); clgame.dllFuncs.pfnCalcRefdef( &rp );
V_MergeOverviewRefdef(); V_RefParamsApplyOverview( &rp );
R_RenderFrame( &cl.refdef, true ); V_GetRefParams( &rp );
cl.refdef.onlyClientDraw = false;
} while( cl.refdef.nextView ); if ( viewnum == 0 && rp.onlyClientDraw )
{
pglClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
pglClear( GL_COLOR_BUFFER_BIT );
}
R_RenderFrame( &rp, true, cl.local.scr_fov );
viewnum++;
} while( rp.nextView );
// draw debug triangles on a server // draw debug triangles on a server
SV_DrawDebugTriangles (); SV_DrawDebugTriangles ();
GL_BackendEndFrame ();
} }
/* /*

View File

@ -24,6 +24,7 @@ GNU General Public License for more details.
#include "mod_local.h" #include "mod_local.h"
#include "pm_defs.h" #include "pm_defs.h"
#include "pm_movevars.h" #include "pm_movevars.h"
#include "ref_params.h"
#include "render_api.h" #include "render_api.h"
#include "cdll_exp.h" #include "cdll_exp.h"
#include "screenfade.h" #include "screenfade.h"
@ -101,27 +102,45 @@ extern int CL_UPDATE_BACKUP;
#define SIGNONS 2 // signon messages to receive before connected #define SIGNONS 2 // signon messages to receive before connected
#define INVALID_HANDLE 0xFFFF // for XashXT cache system #define INVALID_HANDLE 0xFFFF // for XashXT cache system
#define MIN_UPDATERATE 10.0f
#define MAX_UPDATERATE 102.0f
#define MIN_EX_INTERP 50.0f
#define MAX_EX_INTERP 100.0f
#define cl_serverframetime() (cl.mtime[0] - cl.mtime[1]) #define cl_serverframetime() (cl.mtime[0] - cl.mtime[1])
#define cl_clientframetime() (cl.time - cl.oldtime) #define cl_clientframetime() (cl.time - cl.oldtime)
typedef struct typedef struct
{ {
vec3_t origin; // generated by CL_PredictMovement // got from prediction system
vec3_t viewofs; vec3_t predicted_origins[CMD_BACKUP];
vec3_t velocity; vec3_t prediction_error;
vec3_t punchangle;
vec3_t origins[CMD_BACKUP];
vec3_t error;
vec3_t lastorigin; vec3_t lastorigin;
double correction_time; int lastground;
// interp info
float interp_amount;
// misc local info
qboolean thirdperson;
float idealpitch;
int viewmodel; int viewmodel;
int health; // client health int health; // client health
int onground; int onground;
int light_level;
int waterlevel; int waterlevel;
int usehull; int usehull;
int moving; int moving;
int lastground; int pushmsec;
} cl_predicted_data_t; // data we got from prediction system int weapons;
float maxspeed;
float scr_fov;
// weapon predict stuff
int weaponsequence;
float weaponstarttime;
} cl_local_data_t;
// the client_t structure is wiped completely at every // the client_t structure is wiped completely at every
// server map change // server map change
@ -139,6 +158,7 @@ typedef struct
qboolean video_prepped; // false if on new level or new ref dll qboolean video_prepped; // false if on new level or new ref dll
qboolean audio_prepped; // false if on new level or new snd dll qboolean audio_prepped; // false if on new level or new snd dll
qboolean force_refdef; // vid has changed, so we can't use a paused refdef qboolean force_refdef; // vid has changed, so we can't use a paused refdef
qboolean paused;
int delta_sequence; // acknowledged sequence number int delta_sequence; // acknowledged sequence number
@ -148,20 +168,17 @@ typedef struct
int last_incoming_sequence; int last_incoming_sequence;
qboolean send_reply; qboolean send_reply;
qboolean thirdperson;
qboolean background; // not real game, just a background qboolean background; // not real game, just a background
qboolean first_frame; // first rendering frame qboolean first_frame; // first rendering frame
qboolean proxy_redirect; // spectator stuff qboolean proxy_redirect; // spectator stuff
uint checksum; // for catching cheater maps uint checksum; // for catching cheater maps
client_data_t data; // some clientdata holds
frame_t frame; // received from server frame_t frame; // received from server
frame_t frames[MULTIPLAYER_BACKUP]; // alloced on svc_serverdata frame_t frames[MULTIPLAYER_BACKUP]; // alloced on svc_serverdata
runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds
local_state_t predict[MULTIPLAYER_BACKUP]; // local client state local_state_t predicted_frames[MULTIPLAYER_BACKUP]; // local client state
double time; // this is the time value that the client double time; // this is the time value that the client
// is rendering at. always <= cls.realtime // is rendering at. always <= cls.realtime
@ -172,14 +189,27 @@ typedef struct
float lerpFrac; // interpolation value float lerpFrac; // interpolation value
float lerpBack; // invert interpolation value float lerpBack; // invert interpolation value
float timedelta; // floating delta between two updates float timedelta; // floating delta between two updates
ref_params_t refdef; // shared refdef
char serverinfo[MAX_SERVERINFO_STRING]; char serverinfo[MAX_SERVERINFO_STRING];
player_info_t players[MAX_CLIENTS]; player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
event_state_t events; event_state_t events;
// predicting stuff // predicting stuff but not only...
cl_predicted_data_t predicted; // generated from CL_PredictMovement cl_local_data_t local;
// player final info
usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd
int viewentity;
vec3_t viewangles;
vec3_t viewheight;
vec3_t punchangle;
int intermission; // don't change view angle, full screen, et
vec3_t crosshairangle;
// predicted origin and velocity
vec3_t simorg;
vec3_t simvel;
// server state information // server state information
int playernum; int playernum;
@ -196,11 +226,6 @@ typedef struct
cl_entity_t *world; cl_entity_t *world;
model_t *worldmodel; // pointer to world model_t *worldmodel; // pointer to world
// weapon predict stuff
float scr_fov;
float weaponstarttime;
int weaponsequence;
} client_t; } client_t;
/* /*
@ -298,12 +323,11 @@ typedef struct
typedef struct cl_predicted_player_s typedef struct cl_predicted_player_s
{ {
int flags;
int movetype; int movetype;
int solid; int solid;
int usehull; int usehull;
qboolean active; qboolean active;
vec3_t origin; // predicted origin vec3_t origin; // interpolated origin
vec3_t angles; vec3_t angles;
} predicted_player_t; } predicted_player_t;
@ -411,6 +435,8 @@ typedef struct
model_t sprites[MAX_IMAGES]; // client spritetextures model_t sprites[MAX_IMAGES]; // client spritetextures
int load_sequence; // for unloading unneeded sprites int load_sequence; // for unloading unneeded sprites
int viewport[4]; // viewport sizes
client_draw_t ds; // draw2d stuff (hud, weaponmenu etc) client_draw_t ds; // draw2d stuff (hud, weaponmenu etc)
screenfade_t fade; // screen fade screenfade_t fade; // screen fade
screen_shake_t shake; // screen shake screen_shake_t shake; // screen shake
@ -499,6 +525,7 @@ typedef struct
float nextcmdtime; // when can we send the next command packet? float nextcmdtime; // when can we send the next command packet?
int lastoutgoingcommand; // sequence number of last outgoing command int lastoutgoingcommand; // sequence number of last outgoing command
int lastupdate_sequence; // prediction stuff
// internal images // internal images
int fillImage; // used for emulate FillRGBA to avoid wrong draw-sort int fillImage; // used for emulate FillRGBA to avoid wrong draw-sort
@ -517,6 +544,7 @@ typedef struct
entity_state_t *packet_entities; // [num_client_entities] entity_state_t *packet_entities; // [num_client_entities]
predicted_player_t predicted_players[MAX_CLIENTS]; predicted_player_t predicted_players[MAX_CLIENTS];
double correction_time;
scrshot_t scrshot_request; // request for screen shot scrshot_t scrshot_request; // request for screen shot
scrshot_t scrshot_action; // in-action scrshot_t scrshot_action; // in-action
@ -636,6 +664,7 @@ void CL_Disconnect_f( void );
void CL_ProcessFile( qboolean successfully_received, const char *filename ); void CL_ProcessFile( qboolean successfully_received, const char *filename );
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to ); void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
void CL_GetChallengePacket( void ); void CL_GetChallengePacket( void );
int CL_IsDevOverviewMode( void );
void CL_PingServers_f( void ); void CL_PingServers_f( void );
void CL_SignonReply( void ); void CL_SignonReply( void );
void CL_ClearState( void ); void CL_ClearState( void );
@ -755,7 +784,6 @@ void V_Shutdown( void );
qboolean V_PreRender( void ); qboolean V_PreRender( void );
void V_PostRender( void ); void V_PostRender( void );
void V_RenderView( void ); void V_RenderView( void );
void V_SetupRefDef( void );
// //
// cl_pmove.c // cl_pmove.c
@ -763,7 +791,7 @@ void V_SetupRefDef( void );
void CL_SetSolidEntities( void ); void CL_SetSolidEntities( void );
void CL_SetSolidPlayers( int playernum ); void CL_SetSolidPlayers( int playernum );
void CL_InitClientMove( void ); void CL_InitClientMove( void );
void CL_PredictMovement( void ); void CL_PredictMovement( qboolean repredicting );
void CL_CheckPredictionError( void ); void CL_CheckPredictionError( void );
qboolean CL_IsPredicted( void ); qboolean CL_IsPredicted( void );
int CL_TruePointContents( const vec3_t p ); int CL_TruePointContents( const vec3_t p );
@ -772,6 +800,8 @@ int CL_WaterEntity( const float *rgflPos );
cl_entity_t *CL_GetWaterEntity( const float *rgflPos ); cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time ); void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time );
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags ); pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
void CL_SetLastUpdate( void );
void CL_RedoPrediction( void );
void CL_ClearPhysEnts( void ); void CL_ClearPhysEnts( void );
void CL_PushPMStates( void ); void CL_PushPMStates( void );
void CL_PopPMStates( void ); void CL_PopPMStates( void );
@ -790,6 +820,7 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean noInterp ); void CL_UpdateStudioVars( cl_entity_t *ent, entity_state_t *newstate, qboolean noInterp );
qboolean CL_GetEntitySpatialization( struct channel_s *ch ); qboolean CL_GetEntitySpatialization( struct channel_s *ch );
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch ); qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
void CL_ComputePlayerOrigin( cl_entity_t *clent );
void CL_UpdateEntityFields( cl_entity_t *ent ); void CL_UpdateEntityFields( cl_entity_t *ent );
qboolean CL_IsPlayerIndex( int idx ); qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void ); void CL_SetIdealPitch( void );
@ -841,7 +872,6 @@ void CL_RunLightStyles( void );
// //
extern convar_t *con_fontsize; extern convar_t *con_fontsize;
qboolean Con_Visible( void ); qboolean Con_Visible( void );
void Con_Init( void );
void Con_VidInit( void ); void Con_VidInit( void );
void Con_Shutdown( void ); void Con_Shutdown( void );
void Con_ToggleConsole_f( void ); void Con_ToggleConsole_f( void );
@ -881,7 +911,7 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds ); void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds );
void S_FadeMusicVolume( float fadePercent ); void S_FadeMusicVolume( float fadePercent );
void S_StartLocalSound( const char *name, float volume, qboolean reliable ); void S_StartLocalSound( const char *name, float volume, qboolean reliable );
void S_RenderFrame( struct ref_params_s *fd ); void SND_UpdateSound( void );
void S_ExtraUpdate( void ); void S_ExtraUpdate( void );
// //

View File

@ -48,11 +48,9 @@ qboolean R_SpeedsMessage( char *out, size_t size )
GL_BackendStartFrame GL_BackendStartFrame
============== ==============
*/ */
void GL_BackendStartFrame( const ref_params_t *fd ) void GL_BackendStartFrame( void )
{ {
if( !fd->nextView ) r_speeds_msg[0] = '\0'; r_speeds_msg[0] = '\0';
if( !RI.drawWorld ) R_Set2DMode( false );
} }
/* /*
@ -60,12 +58,9 @@ void GL_BackendStartFrame( const ref_params_t *fd )
GL_BackendEndFrame GL_BackendEndFrame
============== ==============
*/ */
void GL_BackendEndFrame( const ref_params_t *fd ) void GL_BackendEndFrame( void )
{ {
// go into 2D mode (in case we draw PlayerSetup between two 2d calls) if( r_speeds->value <= 0 || !RI.drawWorld )
if( !RI.drawWorld ) R_Set2DMode( true );
if( r_speeds->value <= 0 || !RI.drawWorld || fd->nextView )
return; return;
switch( (int)r_speeds->value ) switch( (int)r_speeds->value )
@ -608,7 +603,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo
r_side = Mem_Alloc( r_temppool, sizeof( rgbdata_t )); r_side = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
// use client vieworg // use client vieworg
if( !vieworg ) vieworg = cl.refdef.vieworg; if( !vieworg ) vieworg = RI.vieworg;
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {

View File

@ -109,7 +109,7 @@ static qboolean ComputeBeamEntPosition( int beamEnt, vec3_t pt )
return false; return false;
} }
if(( pEnt->index - 1 ) == cl.playernum && !cl.thirdperson ) if(( pEnt->index - 1 ) == cl.playernum && !cl.local.thirdperson )
{ {
// if we view beam at firstperson use viewmodel instead // if we view beam at firstperson use viewmodel instead
pEnt = &clgame.viewent; pEnt = &clgame.viewent;
@ -1230,13 +1230,13 @@ void CL_UpdateBeam( BEAM *pbeam, float frametime )
pbeam->freq += frametime; pbeam->freq += frametime;
// Generate fractal noise // Generate fractal noise
if( CL_IsInGame() && !cl.refdef.paused ) if( CL_IsInGame() && !cl.paused )
{ {
rgNoise[0] = 0; rgNoise[0] = 0;
rgNoise[NOISE_DIVISIONS] = 0; rgNoise[NOISE_DIVISIONS] = 0;
} }
if( pbeam->amplitude != 0 && CL_IsInGame() && !cl.refdef.paused ) if( pbeam->amplitude != 0 && CL_IsInGame() && !cl.paused )
{ {
if( pbeam->flags & FBEAM_SINENOISE ) if( pbeam->flags & FBEAM_SINENOISE )
{ {

View File

@ -134,7 +134,7 @@ int R_CullModel( cl_entity_t *e, vec3_t origin, vec3_t mins, vec3_t maxs, float
if( e->curstate.effects & EF_REFLECTONLY && !( RI.params & RP_MIRRORVIEW )) if( e->curstate.effects & EF_REFLECTONLY && !( RI.params & RP_MIRRORVIEW ))
return 1; return 1;
if( RP_LOCALCLIENT( e ) && !RI.thirdPerson && cl.refdef.viewentity == ( cl.playernum + 1 )) if( RP_LOCALCLIENT( e ) && !RI.thirdPerson && cl.viewentity == ( cl.playernum + 1 ))
{ {
if(!( RI.params & RP_MIRRORVIEW )) if(!( RI.params & RP_MIRRORVIEW ))
return 1; return 1;

View File

@ -19,7 +19,6 @@ GNU General Public License for more details.
#include "gl_export.h" #include "gl_export.h"
#include "com_model.h" #include "com_model.h"
#include "cl_entity.h" #include "cl_entity.h"
#include "ref_params.h"
#include "render_api.h" #include "render_api.h"
#include "protocol.h" #include "protocol.h"
#include "dlight.h" #include "dlight.h"
@ -103,9 +102,10 @@ typedef struct
qboolean drawWorld; // ignore world for drawing PlayerModel qboolean drawWorld; // ignore world for drawing PlayerModel
qboolean thirdPerson; // thirdperson camera is enabled qboolean thirdPerson; // thirdperson camera is enabled
qboolean isSkyVisible; // sky is visible qboolean isSkyVisible; // sky is visible
qboolean onlyClientDraw; // disabled by client request
qboolean drawOrtho; // draw world as orthogonal projection qboolean drawOrtho; // draw world as orthogonal projection
ref_params_t refdef; // actual refdef float fov_x, fov_y; // current view fov
cl_entity_t *currententity; cl_entity_t *currententity;
model_t *currentmodel; model_t *currentmodel;
@ -118,6 +118,7 @@ typedef struct
mleaf_t *oldviewleaf; mleaf_t *oldviewleaf;
vec3_t pvsorigin; vec3_t pvsorigin;
vec3_t vieworg; // locked vieworigin vec3_t vieworg; // locked vieworigin
vec3_t viewangles;
vec3_t vforward; vec3_t vforward;
vec3_t vright; vec3_t vright;
vec3_t vup; vec3_t vup;
@ -236,7 +237,6 @@ typedef struct
} ref_speeds_t; } ref_speeds_t;
extern ref_speeds_t r_stats; extern ref_speeds_t r_stats;
extern ref_params_t r_lastRefdef;
extern ref_instance_t RI; extern ref_instance_t RI;
extern ref_globals_t tr; extern ref_globals_t tr;
@ -255,8 +255,8 @@ extern struct particle_s *cl_free_trails;
// //
// gl_backend.c // gl_backend.c
// //
void GL_BackendStartFrame( const ref_params_t *fd ); void GL_BackendStartFrame( void );
void GL_BackendEndFrame( const ref_params_t *fd ); void GL_BackendEndFrame( void );
void GL_CleanUpTextureUnits( int last ); void GL_CleanUpTextureUnits( int last );
void GL_Bind( GLint tmu, GLenum texnum ); void GL_Bind( GLint tmu, GLenum texnum );
void GL_MultiTexCoord2f( GLenum texture, GLfloat s, GLfloat t ); void GL_MultiTexCoord2f( GLenum texture, GLfloat s, GLfloat t );
@ -327,7 +327,7 @@ void R_ShutdownImages( void );
void R_BeginDrawMirror( msurface_t *fa ); void R_BeginDrawMirror( msurface_t *fa );
void R_EndDrawMirror( void ); void R_EndDrawMirror( void );
void R_DrawMirrors( void ); void R_DrawMirrors( void );
void R_FindMirrors( const ref_params_t *fd ); void R_FindMirrors( void );
// //
// gl_refrag.c // gl_refrag.c
@ -351,7 +351,7 @@ int R_CountDlights( void );
// //
void R_ClearScene( void ); void R_ClearScene( void );
void R_LoadIdentity( void ); void R_LoadIdentity( void );
void R_RenderScene( const ref_params_t *fd ); void R_RenderScene( void );
void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size ); void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size );
void R_TranslateForEntity( cl_entity_t *e ); void R_TranslateForEntity( cl_entity_t *e );
void R_RotateForEntity( cl_entity_t *e ); void R_RotateForEntity( cl_entity_t *e );
@ -455,7 +455,7 @@ qboolean VID_ScreenShot( const char *filename, int shot_type );
qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot ); qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot );
void VID_RestoreGamma( void ); void VID_RestoreGamma( void );
void R_BeginFrame( qboolean clearScene ); void R_BeginFrame( qboolean clearScene );
void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld ); void R_RenderFrame( const struct ref_params_s *fd, qboolean drawWorld, float fov );
void R_EndFrame( void ); void R_EndFrame( void );
void R_ClearScene( void ); void R_ClearScene( void );
void R_GetTextureParms( int *w, int *h, int texnum ); void R_GetTextureParms( int *w, int *h, int texnum );

View File

@ -271,10 +271,10 @@ void R_DrawMirrors( void )
RI.frustum[5].signbits = SignbitsForPlane( RI.frustum[5].normal ); RI.frustum[5].signbits = SignbitsForPlane( RI.frustum[5].normal );
RI.frustum[5].type = PLANE_NONAXIAL; RI.frustum[5].type = PLANE_NONAXIAL;
RI.refdef.viewangles[0] = anglemod( angles[0] ); RI.viewangles[0] = anglemod( angles[0] );
RI.refdef.viewangles[1] = anglemod( angles[1] ); RI.viewangles[1] = anglemod( angles[1] );
RI.refdef.viewangles[2] = anglemod( angles[2] ); RI.viewangles[2] = anglemod( angles[2] );
VectorCopy( origin, RI.refdef.vieworg ); VectorCopy( origin, RI.vieworg );
VectorCopy( origin, RI.cullorigin ); VectorCopy( origin, RI.cullorigin );
// put pvsorigin before the mirror plane to avoid get full visibility on world mirrors // put pvsorigin before the mirror plane to avoid get full visibility on world mirrors
@ -305,7 +305,7 @@ void R_DrawMirrors( void )
} }
tr.framecount++; tr.framecount++;
R_RenderScene( &RI.refdef ); R_RenderScene();
r_stats.c_mirror_passes++; r_stats.c_mirror_passes++;
es->mirrortexturenum = R_AllocateMirrorTexture(); es->mirrortexturenum = R_AllocateMirrorTexture();
@ -584,51 +584,16 @@ R_FindMirrors
Build mirror chains for this frame Build mirror chains for this frame
================ ================
*/ */
void R_FindMirrors( const ref_params_t *fd ) void R_FindMirrors( void )
{ {
vec3_t viewOrg, viewAng; if( !world.has_mirrors || RI.drawOrtho || !RI.drawWorld || RI.onlyClientDraw || !cl.worldmodel )
if( !world.has_mirrors || RI.drawOrtho || !RI.drawWorld || RI.refdef.onlyClientDraw || !cl.worldmodel )
return; return;
RI.refdef = *fd; // NOTE: we already has initial params at this point like vieworg, viewangles
// all other will be sets into R_SetupFrustum
// build the transformation matrix for the given view angles R_SetupFrustum ();
if( cl.thirdperson ) R_FindViewLeaf ();
{
vec3_t cam_ofs, vpn;
clgame.dllFuncs.CL_CameraOffset( cam_ofs );
viewAng[PITCH] = cam_ofs[PITCH];
viewAng[YAW] = cam_ofs[YAW];
viewAng[ROLL] = 0;
AngleVectors( viewAng, vpn, NULL, NULL );
VectorMA( RI.refdef.vieworg, -cam_ofs[ROLL], vpn, viewOrg );
}
else
{
VectorCopy( RI.refdef.vieworg, viewOrg );
VectorCopy( RI.refdef.viewangles, viewAng );
}
// build the transformation matrix for the given view angles
VectorCopy( viewOrg, RI.vieworg );
AngleVectors( viewAng, RI.vforward, RI.vright, RI.vup );
VectorCopy( RI.vieworg, RI.pvsorigin );
if( !r_lockcull->value )
{
VectorCopy( RI.vieworg, RI.cullorigin );
VectorCopy( RI.vforward, RI.cull_vforward );
VectorCopy( RI.vright, RI.cull_vright );
VectorCopy( RI.vup, RI.cull_vup );
}
R_FindViewLeaf();
R_SetupFrustum();
R_MarkLeaves (); R_MarkLeaves ();
VectorCopy( RI.cullorigin, tr.modelorg ); VectorCopy( RI.cullorigin, tr.modelorg );

View File

@ -37,6 +37,7 @@ void CL_RunLightStyles( void )
{ {
int i, k, flight, clight; int i, k, flight, clight;
float l, c, lerpfrac, backlerp; float l, c, lerpfrac, backlerp;
float frametime = (cl.time - cl.oldtime);
float scale; float scale;
lightstyle_t *ls; lightstyle_t *ls;
@ -56,8 +57,8 @@ void CL_RunLightStyles( void )
continue; continue;
} }
if( !RI.refdef.paused && RI.refdef.frametime <= 0.1f ) if( !cl.paused && frametime <= 0.1f )
ls->time += RI.refdef.frametime; // evaluate local time ls->time += frametime; // evaluate local time
flight = (int)Q_floor( ls->time * 10 ); flight = (int)Q_floor( ls->time * 10 );
clight = (int)Q_ceil( ls->time * 10 ); clight = (int)Q_ceil( ls->time * 10 );
@ -337,20 +338,12 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
model_t *pmodel; model_t *pmodel;
mnode_t *pnodes; mnode_t *pnodes;
if( !cl.refdef.movevars )
{
ambientLight->r = 255;
ambientLight->g = 255;
ambientLight->b = 255;
return;
}
// set to full bright if no light data // set to full bright if no light data
if( !cl.worldmodel || !cl.worldmodel->lightdata ) if( !cl.worldmodel || !cl.worldmodel->lightdata )
{ {
ambientLight->r = TextureToTexGamma( cl.refdef.movevars->skycolor_r ); ambientLight->r = TextureToTexGamma( clgame.movevars.skycolor_r );
ambientLight->g = TextureToTexGamma( cl.refdef.movevars->skycolor_g ); ambientLight->g = TextureToTexGamma( clgame.movevars.skycolor_g );
ambientLight->b = TextureToTexGamma( cl.refdef.movevars->skycolor_b ); ambientLight->b = TextureToTexGamma( clgame.movevars.skycolor_b );
return; return;
} }

View File

@ -27,8 +27,7 @@ GNU General Public License for more details.
msurface_t *r_debug_surface; msurface_t *r_debug_surface;
const char *r_debug_hitbox; const char *r_debug_hitbox;
float gldepthmin, gldepthmax; float gldepthmin, gldepthmax;
ref_params_t r_lastRefdef; ref_instance_t RI;
ref_instance_t RI, prevRI;
static int R_RankForRenderMode( cl_entity_t *ent ) static int R_RankForRenderMode( cl_entity_t *ent )
{ {
@ -271,16 +270,16 @@ int R_ComputeFxBlend( cl_entity_t *e )
switch( e->curstate.renderfx ) switch( e->curstate.renderfx )
{ {
case kRenderFxPulseSlowWide: case kRenderFxPulseSlowWide:
blend = renderAmt + 0x40 * sin( RI.refdef.time * 2 + offset ); blend = renderAmt + 0x40 * sin( cl.time * 2 + offset );
break; break;
case kRenderFxPulseFastWide: case kRenderFxPulseFastWide:
blend = renderAmt + 0x40 * sin( RI.refdef.time * 8 + offset ); blend = renderAmt + 0x40 * sin( cl.time * 8 + offset );
break; break;
case kRenderFxPulseSlow: case kRenderFxPulseSlow:
blend = renderAmt + 0x10 * sin( RI.refdef.time * 2 + offset ); blend = renderAmt + 0x10 * sin( cl.time * 2 + offset );
break; break;
case kRenderFxPulseFast: case kRenderFxPulseFast:
blend = renderAmt + 0x10 * sin( RI.refdef.time * 8 + offset ); blend = renderAmt + 0x10 * sin( cl.time * 8 + offset );
break; break;
// JAY: HACK for now -- not time based // JAY: HACK for now -- not time based
case kRenderFxFadeSlow: case kRenderFxFadeSlow:
@ -308,35 +307,35 @@ int R_ComputeFxBlend( cl_entity_t *e )
blend = renderAmt; blend = renderAmt;
break; break;
case kRenderFxStrobeSlow: case kRenderFxStrobeSlow:
blend = 20 * sin( RI.refdef.time * 4 + offset ); blend = 20 * sin( cl.time * 4 + offset );
if( blend < 0 ) blend = 0; if( blend < 0 ) blend = 0;
else blend = renderAmt; else blend = renderAmt;
break; break;
case kRenderFxStrobeFast: case kRenderFxStrobeFast:
blend = 20 * sin( RI.refdef.time * 16 + offset ); blend = 20 * sin( cl.time * 16 + offset );
if( blend < 0 ) blend = 0; if( blend < 0 ) blend = 0;
else blend = renderAmt; else blend = renderAmt;
break; break;
case kRenderFxStrobeFaster: case kRenderFxStrobeFaster:
blend = 20 * sin( RI.refdef.time * 36 + offset ); blend = 20 * sin( cl.time * 36 + offset );
if( blend < 0 ) blend = 0; if( blend < 0 ) blend = 0;
else blend = renderAmt; else blend = renderAmt;
break; break;
case kRenderFxFlickerSlow: case kRenderFxFlickerSlow:
blend = 20 * (sin( RI.refdef.time * 2 ) + sin( RI.refdef.time * 17 + offset )); blend = 20 * (sin( cl.time * 2 ) + sin( cl.time * 17 + offset ));
if( blend < 0 ) blend = 0; if( blend < 0 ) blend = 0;
else blend = renderAmt; else blend = renderAmt;
break; break;
case kRenderFxFlickerFast: case kRenderFxFlickerFast:
blend = 20 * (sin( RI.refdef.time * 16 ) + sin( RI.refdef.time * 23 + offset )); blend = 20 * (sin( cl.time * 16 ) + sin( cl.time * 23 + offset ));
if( blend < 0 ) blend = 0; if( blend < 0 ) blend = 0;
else blend = renderAmt; else blend = renderAmt;
break; break;
case kRenderFxHologram: case kRenderFxHologram:
case kRenderFxDistort: case kRenderFxDistort:
VectorCopy( e->origin, tmp ); VectorCopy( e->origin, tmp );
VectorSubtract( tmp, RI.refdef.vieworg, tmp ); VectorSubtract( tmp, RI.vieworg, tmp );
dist = DotProduct( tmp, RI.refdef.forward ); dist = DotProduct( tmp, RI.vforward );
// Turn off distance fade // Turn off distance fade
if( e->curstate.renderfx == kRenderFxDistort ) if( e->curstate.renderfx == kRenderFxDistort )
@ -515,7 +514,7 @@ R_GetFarClip
static float R_GetFarClip( void ) static float R_GetFarClip( void )
{ {
if( cl.worldmodel && RI.drawWorld ) if( cl.worldmodel && RI.drawWorld )
return cl.refdef.movevars->zmax * 1.5f; return clgame.movevars.zmax * 1.73f;
return 2048.0f; return 2048.0f;
} }
@ -578,12 +577,23 @@ void R_SetupFrustum( void )
vec3_t farPoint; vec3_t farPoint;
int i; int i;
// 0 - left // first we need to compute FOV and other things that needs for frustum properly work
// 1 - right RI.fov_y = V_CalcFov( &RI.fov_x, RI.viewport[2], RI.viewport[3] );
// 2 - down
// 3 - up // adjust FOV for widescreen
// 4 - farclip if( glState.wideScreen && RI.drawWorld && r_adjust_fov->value )
// 5 - nearclip V_AdjustFov( &RI.fov_x, &RI.fov_y, RI.viewport[2], RI.viewport[3], false );
// build the transformation matrix for the given view angles
AngleVectors( RI.viewangles, RI.vforward, RI.vright, RI.vup );
if( !r_lockcull->value )
{
VectorCopy( RI.vieworg, RI.cullorigin );
VectorCopy( RI.vforward, RI.cull_vforward );
VectorCopy( RI.vright, RI.cull_vright );
VectorCopy( RI.vup, RI.cull_vup );
}
if( RI.drawOrtho ) if( RI.drawOrtho )
{ {
@ -591,14 +601,21 @@ void R_SetupFrustum( void )
return; return;
} }
// 0 - left
// 1 - right
// 2 - down
// 3 - up
// 4 - farclip
// 5 - nearclip
// rotate RI.vforward right by FOV_X/2 degrees // rotate RI.vforward right by FOV_X/2 degrees
RotatePointAroundVector( RI.frustum[0].normal, RI.cull_vup, RI.cull_vforward, -( 90 - RI.refdef.fov_x / 2 )); RotatePointAroundVector( RI.frustum[0].normal, RI.cull_vup, RI.cull_vforward, -( 90 - RI.fov_x / 2 ));
// rotate RI.vforward left by FOV_X/2 degrees // rotate RI.vforward left by FOV_X/2 degrees
RotatePointAroundVector( RI.frustum[1].normal, RI.cull_vup, RI.cull_vforward, 90 - RI.refdef.fov_x / 2 ); RotatePointAroundVector( RI.frustum[1].normal, RI.cull_vup, RI.cull_vforward, 90 - RI.fov_x / 2 );
// rotate RI.vforward up by FOV_X/2 degrees // rotate RI.vforward up by FOV_X/2 degrees
RotatePointAroundVector( RI.frustum[2].normal, RI.cull_vright, RI.cull_vforward, 90 - RI.refdef.fov_y / 2 ); RotatePointAroundVector( RI.frustum[2].normal, RI.cull_vright, RI.cull_vforward, 90 - RI.fov_y / 2 );
// rotate RI.vforward down by FOV_X/2 degrees // rotate RI.vforward down by FOV_X/2 degrees
RotatePointAroundVector( RI.frustum[3].normal, RI.cull_vright, RI.cull_vforward, -( 90 - RI.refdef.fov_y / 2 )); RotatePointAroundVector( RI.frustum[3].normal, RI.cull_vright, RI.cull_vforward, -( 90 - RI.fov_y / 2 ));
// negate forward vector // negate forward vector
VectorNegate( RI.cull_vforward, RI.frustum[4].normal ); VectorNegate( RI.cull_vforward, RI.frustum[4].normal );
@ -620,7 +637,7 @@ void R_SetupFrustum( void )
R_SetupProjectionMatrix R_SetupProjectionMatrix
============= =============
*/ */
static void R_SetupProjectionMatrix( const ref_params_t *fd, matrix4x4 m ) static void R_SetupProjectionMatrix( matrix4x4 m )
{ {
GLdouble xMin, xMax, yMin, yMax, zNear, zFar; GLdouble xMin, xMax, yMin, yMax, zNear, zFar;
@ -637,10 +654,10 @@ static void R_SetupProjectionMatrix( const ref_params_t *fd, matrix4x4 m )
zNear = 4.0f; zNear = 4.0f;
zFar = max( 256.0f, RI.farClip ); zFar = max( 256.0f, RI.farClip );
yMax = zNear * tan( fd->fov_y * M_PI / 360.0 ); yMax = zNear * tan( RI.fov_y * M_PI / 360.0 );
yMin = -yMax; yMin = -yMax;
xMax = zNear * tan( fd->fov_x * M_PI / 360.0 ); xMax = zNear * tan( RI.fov_x * M_PI / 360.0 );
xMin = -xMax; xMin = -xMax;
Matrix4x4_CreateProjection( m, xMax, xMin, yMax, yMin, zNear, zFar ); Matrix4x4_CreateProjection( m, xMax, xMin, yMax, yMin, zNear, zFar );
@ -651,7 +668,7 @@ static void R_SetupProjectionMatrix( const ref_params_t *fd, matrix4x4 m )
R_SetupModelviewMatrix R_SetupModelviewMatrix
============= =============
*/ */
static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m ) static void R_SetupModelviewMatrix( matrix4x4 m )
{ {
#if 0 #if 0
Matrix4x4_LoadIdentity( m ); Matrix4x4_LoadIdentity( m );
@ -660,10 +677,10 @@ static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m )
#else #else
Matrix4x4_CreateModelview( m ); Matrix4x4_CreateModelview( m );
#endif #endif
Matrix4x4_ConcatRotate( m, -fd->viewangles[2], 1, 0, 0 ); Matrix4x4_ConcatRotate( m, -RI.viewangles[2], 1, 0, 0 );
Matrix4x4_ConcatRotate( m, -fd->viewangles[0], 0, 1, 0 ); Matrix4x4_ConcatRotate( m, -RI.viewangles[0], 0, 1, 0 );
Matrix4x4_ConcatRotate( m, -fd->viewangles[1], 0, 0, 1 ); Matrix4x4_ConcatRotate( m, -RI.viewangles[1], 0, 0, 1 );
Matrix4x4_ConcatTranslate( m, -fd->vieworg[0], -fd->vieworg[1], -fd->vieworg[2] ); Matrix4x4_ConcatTranslate( m, -RI.vieworg[0], -RI.vieworg[1], -RI.vieworg[2] );
} }
/* /*
@ -753,28 +770,10 @@ R_SetupFrame
*/ */
static void R_SetupFrame( void ) static void R_SetupFrame( void )
{ {
vec3_t viewOrg, viewAng;
VectorCopy( RI.refdef.vieworg, viewOrg );
VectorCopy( RI.refdef.viewangles, viewAng );
// build the transformation matrix for the given view angles
VectorCopy( viewOrg, RI.vieworg );
AngleVectors( viewAng, RI.vforward, RI.vright, RI.vup );
// setup viewplane dist // setup viewplane dist
RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward ); RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward );
VectorCopy( RI.vieworg, RI.pvsorigin ); // prepare events for viewmodel (e.g. muzzleflashes)
if( !r_lockcull->value )
{
VectorCopy( RI.vieworg, RI.cullorigin );
VectorCopy( RI.vforward, RI.cull_vforward );
VectorCopy( RI.vright, RI.cull_vright );
VectorCopy( RI.vup, RI.cull_vup );
}
R_RunViewmodelEvents(); R_RunViewmodelEvents();
// sort opaque entities by model type to avoid drawing model shadows under alpha-surfaces // sort opaque entities by model type to avoid drawing model shadows under alpha-surfaces
@ -801,16 +800,16 @@ R_SetupGL
*/ */
static void R_SetupGL( void ) static void R_SetupGL( void )
{ {
if( RI.refdef.waterlevel >= 3 ) if( RP_NORMALPASS() && ( cl.local.waterlevel >= 3 ))
{ {
float f; float f;
f = sin( cl.time * 0.4f * ( M_PI * 2.7f )); f = sin( cl.time * 0.4f * ( M_PI * 2.7f ));
RI.refdef.fov_x += f; RI.fov_x += f;
RI.refdef.fov_y -= f; RI.fov_y -= f;
} }
R_SetupModelviewMatrix( &RI.refdef, RI.worldviewMatrix ); R_SetupModelviewMatrix( RI.worldviewMatrix );
R_SetupProjectionMatrix( &RI.refdef, RI.projectionMatrix ); R_SetupProjectionMatrix( RI.projectionMatrix );
// if( RI.params & RP_MIRRORVIEW ) RI.projectionMatrix[0][0] = -RI.projectionMatrix[0][0]; // if( RI.params & RP_MIRRORVIEW ) RI.projectionMatrix[0][0] = -RI.projectionMatrix[0][0];
Matrix4x4_Concat( RI.worldviewProjectionMatrix, RI.projectionMatrix, RI.worldviewMatrix ); Matrix4x4_Concat( RI.worldviewProjectionMatrix, RI.projectionMatrix, RI.worldviewMatrix );
@ -965,7 +964,7 @@ static void R_CheckFog( void )
RI.fogEnabled = false; RI.fogEnabled = false;
if( RI.refdef.waterlevel < 2 || !RI.drawWorld || !RI.viewleaf ) if( cl.local.waterlevel < 2 || !RI.drawWorld || !RI.viewleaf )
return; return;
ent = CL_GetWaterEntity( RI.vieworg ); ent = CL_GetWaterEntity( RI.vieworg );
@ -979,7 +978,7 @@ static void R_CheckFog( void )
return; return;
} }
if( RI.refdef.waterlevel < 3 ) return; if( cl.local.waterlevel < 3 ) return;
if( !IsLiquidContents( RI.cached_contents ) && IsLiquidContents( cnt )) if( !IsLiquidContents( RI.cached_contents ) && IsLiquidContents( cnt ))
{ {
@ -1034,7 +1033,7 @@ R_DrawFog
*/ */
void R_DrawFog( void ) void R_DrawFog( void )
{ {
if( !RI.fogEnabled || RI.refdef.onlyClientDraw ) if( !RI.fogEnabled || RI.onlyClientDraw )
return; return;
pglEnable( GL_FOG ); pglEnable( GL_FOG );
@ -1059,11 +1058,8 @@ void R_DrawEntitiesOnList( void )
R_DrawFog (); R_DrawFog ();
// first draw solid entities // first draw solid entities
for( i = 0; i < tr.num_solid_entities; i++ ) for( i = 0; i < tr.num_solid_entities && !RI.onlyClientDraw; i++ )
{ {
if( RI.refdef.onlyClientDraw )
break;
RI.currententity = tr.solid_entities[i]; RI.currententity = tr.solid_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@ -1086,7 +1082,7 @@ void R_DrawEntitiesOnList( void )
} }
} }
if( !RI.refdef.onlyClientDraw ) if( !RI.onlyClientDraw )
{ {
CL_DrawBeams( false ); CL_DrawBeams( false );
} }
@ -1105,11 +1101,8 @@ void R_DrawEntitiesOnList( void )
glState.drawTrans = true; glState.drawTrans = true;
// then draw translucent entities // then draw translucent entities
for( i = 0; i < tr.num_trans_entities; i++ ) for( i = 0; i < tr.num_trans_entities && !RI.onlyClientDraw; i++ )
{ {
if( RI.refdef.onlyClientDraw )
break;
RI.currententity = tr.trans_entities[i]; RI.currententity = tr.trans_entities[i];
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
@ -1138,7 +1131,7 @@ void R_DrawEntitiesOnList( void )
clgame.dllFuncs.pfnDrawTransparentTriangles (); clgame.dllFuncs.pfnDrawTransparentTriangles ();
} }
if( !RI.refdef.onlyClientDraw ) if( !RI.onlyClientDraw )
{ {
CL_DrawBeams( true ); CL_DrawBeams( true );
CL_DrawParticles(); CL_DrawParticles();
@ -1161,20 +1154,18 @@ void R_DrawEntitiesOnList( void )
================ ================
R_RenderScene R_RenderScene
RI.refdef must be set before the first call R_SetupRefParams must be called right before
================ ================
*/ */
void R_RenderScene( const ref_params_t *fd ) void R_RenderScene( void )
{ {
RI.refdef = *fd;
if( !cl.worldmodel && RI.drawWorld ) if( !cl.worldmodel && RI.drawWorld )
Host_Error( "R_RenderView: NULL worldmodel\n" ); Host_Error( "R_RenderView: NULL worldmodel\n" );
R_PushDlights(); R_PushDlights();
R_SetupFrame();
R_SetupFrustum(); R_SetupFrustum();
R_SetupFrame();
R_SetupGL(); R_SetupGL();
R_Clear( ~0 ); R_Clear( ~0 );
@ -1238,12 +1229,43 @@ void R_BeginFrame( qboolean clearScene )
CL_ExtraUpdate (); CL_ExtraUpdate ();
} }
/*
===============
R_SetupRefParams
set initial params for renderer
===============
*/
void R_SetupRefParams( const ref_params_t *fd, qboolean drawWorld, float fov )
{
RI.params = RP_NONE;
RI.drawWorld = drawWorld;
RI.thirdPerson = cl.local.thirdperson;
RI.drawOrtho = (drawWorld) ? (int)gl_overview->value : 0;
RI.clipFlags = 15; // top, bottom, left, right
RI.onlyClientDraw = fd->onlyClientDraw;
RI.farClip = 0;
// setup viewport
RI.viewport[0] = fd->viewport[0];
RI.viewport[1] = fd->viewport[1];
RI.viewport[2] = fd->viewport[2];
RI.viewport[3] = fd->viewport[3];
// calc FOV
RI.fov_x = fov; // this is a final fov value
VectorCopy( fd->vieworg, RI.vieworg );
VectorCopy( fd->viewangles, RI.viewangles );
VectorCopy( fd->vieworg, RI.pvsorigin );
}
/* /*
=============== ===============
R_RenderFrame R_RenderFrame
=============== ===============
*/ */
void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld ) void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld, float fov )
{ {
if( r_norefresh->value ) if( r_norefresh->value )
return; return;
@ -1264,26 +1286,7 @@ void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld )
} }
} }
if( drawWorld ) r_lastRefdef = *fd; R_SetupRefParams( fd, drawWorld, fov );
RI.params = RP_NONE;
RI.farClip = 0;
RI.clipFlags = 15;
RI.drawWorld = drawWorld;
RI.thirdPerson = cl.thirdperson;
RI.drawOrtho = (RI.drawWorld) ? gl_overview->value : 0;
GL_BackendStartFrame( fd );
if( !r_lockcull->value )
VectorCopy( fd->vieworg, RI.cullorigin );
VectorCopy( fd->vieworg, RI.pvsorigin );
// setup viewport
RI.viewport[0] = fd->viewport[0];
RI.viewport[1] = fd->viewport[1];
RI.viewport[2] = fd->viewport[2];
RI.viewport[3] = fd->viewport[3];
if( gl_finish->value && drawWorld ) if( gl_finish->value && drawWorld )
pglFinish(); pglFinish();
@ -1291,13 +1294,11 @@ void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld )
if( gl_allow_mirrors->value ) if( gl_allow_mirrors->value )
{ {
// render mirrors // render mirrors
R_FindMirrors( fd ); R_FindMirrors ();
R_DrawMirrors (); R_DrawMirrors ();
} }
R_RenderScene( fd ); R_RenderScene();
GL_BackendEndFrame( fd );
} }
/* /*
@ -1324,34 +1325,33 @@ R_DrawCubemapView
*/ */
void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size ) void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size )
{ {
ref_params_t *fd;
if( clgame.drawFuncs.R_DrawCubemapView != NULL ) if( clgame.drawFuncs.R_DrawCubemapView != NULL )
{ {
if( clgame.drawFuncs.R_DrawCubemapView( origin, angles, size )) if( clgame.drawFuncs.R_DrawCubemapView( origin, angles, size ))
return; return;
} }
fd = &RI.refdef; // basic params
*fd = r_lastRefdef; RI.params = RP_NONE;
fd->time = 0; RI.drawWorld = true;
fd->viewport[0] = 0; RI.thirdPerson = RI.drawOrtho = false;
fd->viewport[1] = 0; RI.clipFlags = 15; // top, bottom, left, right
fd->viewport[2] = size; RI.onlyClientDraw = false;
fd->viewport[3] = size; RI.farClip = 0;
fd->fov_x = 90;
fd->fov_y = 90;
VectorCopy( origin, fd->vieworg );
VectorCopy( angles, fd->viewangles );
VectorCopy( fd->vieworg, RI.pvsorigin );
// setup viewport
RI.viewport[0] = fd->viewport[0];
RI.viewport[1] = fd->viewport[1];
RI.viewport[2] = fd->viewport[2];
RI.viewport[3] = fd->viewport[3];
R_RenderScene( fd ); // setup viewport
RI.viewport[0] = RI.viewport[1] = 0;
RI.viewport[2] = RI.viewport[3] = size;
// calc FOV
RI.fov_x = 90.0f; // this is a final fov value
// setup origin & angles
VectorCopy( origin, RI.vieworg );
VectorCopy( angles, RI.viewangles );
VectorCopy( origin, RI.pvsorigin );
R_RenderScene ();
RI.oldviewleaf = RI.viewleaf = NULL; // force markleafs next frame RI.oldviewleaf = RI.viewleaf = NULL; // force markleafs next frame
} }

View File

@ -474,7 +474,7 @@ void R_NewMap( void )
tx->texturechain = NULL; tx->texturechain = NULL;
} }
R_SetupSky( cl.refdef.movevars->skyName ); R_SetupSky( clgame.movevars.skyName );
GL_BuildLightmaps (); GL_BuildLightmaps ();
} }

View File

@ -222,7 +222,7 @@ void GL_SetupFogColorForSurfaces( void )
vec3_t fogColor; vec3_t fogColor;
float factor, div; float factor, div;
if(( !RI.fogEnabled && !RI.fogCustom ) || RI.refdef.onlyClientDraw || !RI.currententity ) if(( !RI.fogEnabled && !RI.fogCustom ) || RI.onlyClientDraw || !RI.currententity )
return; return;
if( RI.currententity->curstate.rendermode == kRenderTransTexture ) if( RI.currententity->curstate.rendermode == kRenderTransTexture )
@ -242,7 +242,7 @@ void GL_SetupFogColorForSurfaces( void )
void GL_ResetFogColor( void ) void GL_ResetFogColor( void )
{ {
// restore fog here // restore fog here
if(( RI.fogEnabled || RI.fogCustom ) && !RI.refdef.onlyClientDraw ) if(( RI.fogEnabled || RI.fogCustom ) && !RI.onlyClientDraw )
pglFogfv( GL_FOG_COLOR, RI.fogColor ); pglFogfv( GL_FOG_COLOR, RI.fogColor );
} }
@ -742,8 +742,8 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
flAngle = ( flConveyorSpeed >= 0 ) ? 180 : 0; flAngle = ( flConveyorSpeed >= 0 ) ? 180 : 0;
SinCos( flAngle * ( M_PI / 180.0f ), &sy, &cy ); SinCos( flAngle * ( M_PI / 180.0f ), &sy, &cy );
sOffset = RI.refdef.time * cy * flRate; sOffset = cl.time * cy * flRate;
tOffset = RI.refdef.time * sy * flRate; tOffset = cl.time * sy * flRate;
// make sure that we are positive // make sure that we are positive
if( sOffset < 0.0f ) sOffset += 1.0f + -(int)sOffset; if( sOffset < 0.0f ) sOffset += 1.0f + -(int)sOffset;
@ -988,7 +988,7 @@ void R_RenderFullbrights( void )
if( !draw_fullbrights ) if( !draw_fullbrights )
return; return;
if( RI.fogEnabled && !RI.refdef.onlyClientDraw ) if( RI.fogEnabled && !RI.onlyClientDraw )
pglDisable( GL_FOG ); pglDisable( GL_FOG );
pglEnable( GL_BLEND ); pglEnable( GL_BLEND );
@ -1021,7 +1021,7 @@ void R_RenderFullbrights( void )
draw_fullbrights = false; draw_fullbrights = false;
// restore for here // restore for here
if( RI.fogEnabled && !RI.refdef.onlyClientDraw ) if( RI.fogEnabled && !RI.onlyClientDraw )
pglEnable( GL_FOG ); pglEnable( GL_FOG );
} }
@ -1283,7 +1283,7 @@ void R_DrawTextureChains( void )
if( !s || ( i == tr.skytexturenum )) if( !s || ( i == tr.skytexturenum ))
continue; continue;
if(( s->flags & SURF_DRAWTURB ) && cl.refdef.movevars->wateralpha < 1.0f ) if(( s->flags & SURF_DRAWTURB ) && clgame.movevars.wateralpha < 1.0f )
continue; // draw translucent water later continue; // draw translucent water later
for( ; s != NULL; s = s->texturechain ) for( ; s != NULL; s = s->texturechain )
@ -1305,11 +1305,11 @@ void R_DrawWaterSurfaces( void )
msurface_t *s; msurface_t *s;
texture_t *t; texture_t *t;
if( !RI.drawWorld || RI.refdef.onlyClientDraw ) if( !RI.drawWorld || RI.onlyClientDraw )
return; return;
// non-transparent water is already drawed // non-transparent water is already drawed
if( cl.refdef.movevars->wateralpha >= 1.0f ) if( clgame.movevars.wateralpha >= 1.0f )
return; return;
// restore worldmodel // restore worldmodel
@ -1324,7 +1324,7 @@ void R_DrawWaterSurfaces( void )
pglDisable( GL_ALPHA_TEST ); pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4f( 1.0f, 1.0f, 1.0f, cl.refdef.movevars->wateralpha ); pglColor4f( 1.0f, 1.0f, 1.0f, clgame.movevars.wateralpha );
for( i = 0; i < cl.worldmodel->numtextures; i++ ) for( i = 0; i < cl.worldmodel->numtextures; i++ )
{ {
@ -1909,7 +1909,7 @@ void R_DrawWorld( void )
RI.currententity = clgame.entities; RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
if( !RI.drawWorld || RI.refdef.onlyClientDraw ) if( !RI.drawWorld || RI.onlyClientDraw )
return; return;
VectorCopy( RI.cullorigin, tr.modelorg ); VectorCopy( RI.cullorigin, tr.modelorg );

View File

@ -499,7 +499,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
} }
else if( psprite->frames[frame].type == FRAME_ANGLED ) else if( psprite->frames[frame].type == FRAME_ANGLED )
{ {
int angleframe = (int)(Q_rint(( RI.refdef.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7; int angleframe = (int)(Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7;
// e.g. doom-style sprite monsters // e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
@ -554,25 +554,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
// this can be happens when rendering switched between single and angled frames // this can be happens when rendering switched between single and angled frames
// or change model on replace delta-entity // or change model on replace delta-entity
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 1.0f; lerpFrac = 1.0f;
} }
if( ent->latched.prevanimtime < RI.refdef.time ) if( ent->latched.prevanimtime < cl.time )
{ {
if( frame != ent->latched.prevblending[1] ) if( frame != ent->latched.prevblending[1] )
{ {
ent->latched.prevblending[0] = ent->latched.prevblending[1]; ent->latched.prevblending[0] = ent->latched.prevblending[1];
ent->latched.prevblending[1] = frame; ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
else lerpFrac = (RI.refdef.time - ent->latched.prevanimtime) * 10; else lerpFrac = (cl.time - ent->latched.prevanimtime) * 10;
} }
else else
{ {
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
} }
@ -586,7 +586,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
{ {
// reset interpolation on change model // reset interpolation on change model
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
@ -601,7 +601,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
numframes = pspritegroup->numframes; numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1]; fullinterval = pintervals[numframes-1];
jinterval = pintervals[1] - pintervals[0]; jinterval = pintervals[1] - pintervals[0];
time = RI.refdef.time; time = cl.time;
jtime = 0.0f; jtime = 0.0f;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
@ -631,7 +631,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
{ {
// e.g. doom-style sprite monsters // e.g. doom-style sprite monsters
float yaw = ent->angles[YAW]; float yaw = ent->angles[YAW];
int angleframe = (int)(Q_rint(( RI.refdef.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7; int angleframe = (int)(Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7;
if( m_fDoInterp ) if( m_fDoInterp )
{ {
@ -640,25 +640,25 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
// this can be happens when rendering switched between single and angled frames // this can be happens when rendering switched between single and angled frames
// or change model on replace delta-entity // or change model on replace delta-entity
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 1.0f; lerpFrac = 1.0f;
} }
if( ent->latched.prevanimtime < RI.refdef.time ) if( ent->latched.prevanimtime < cl.time )
{ {
if( frame != ent->latched.prevblending[1] ) if( frame != ent->latched.prevblending[1] )
{ {
ent->latched.prevblending[0] = ent->latched.prevblending[1]; ent->latched.prevblending[0] = ent->latched.prevblending[1];
ent->latched.prevblending[1] = frame; ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
else lerpFrac = (RI.refdef.time - ent->latched.prevanimtime) * ent->curstate.framerate; else lerpFrac = (cl.time - ent->latched.prevanimtime) * ent->curstate.framerate;
} }
else else
{ {
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame; ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time; ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f; lerpFrac = 0.0f;
} }
} }
@ -816,9 +816,9 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, int *alpha, float *psc
TriWorldToScreen( origin, v ); TriWorldToScreen( origin, v );
if( v[0] < RI.refdef.viewport[0] || v[0] > RI.refdef.viewport[0] + RI.refdef.viewport[2] ) if( v[0] < RI.viewport[0] || v[0] > RI.viewport[0] + RI.viewport[2] )
return true; // do scissor return true; // do scissor
if( v[1] < RI.refdef.viewport[1] || v[1] > RI.refdef.viewport[1] + RI.refdef.viewport[3] ) if( v[1] < RI.viewport[1] || v[1] > RI.viewport[1] + RI.viewport[3] )
return true; // do scissor return true; // do scissor
blend *= R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, *alpha, pscale ); blend *= R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, *alpha, pscale );

View File

@ -87,8 +87,6 @@ convar_t *cl_himodels;
cvar_t r_shadows = { "r_shadows", "0", 0, 0 }; // dead cvar. especially disabled cvar_t r_shadows = { "r_shadows", "0", 0, 0 }; // dead cvar. especially disabled
cvar_t r_shadowalpha = { "r_shadowalpha", "0.5", 0, 0.8f }; cvar_t r_shadowalpha = { "r_shadowalpha", "0.5", 0, 0.8f };
static r_studio_interface_t *pStudioDraw; static r_studio_interface_t *pStudioDraw;
static float aliasXscale, aliasYscale; // software renderer scale
static matrix3x4 g_aliastransform; // software renderer transform
static matrix3x4 g_rotationmatrix; static matrix3x4 g_rotationmatrix;
static vec3_t g_chrome_origin; static vec3_t g_chrome_origin;
static vec2_t g_chrome[MAXSTUDIOVERTS]; // texture coords for surface normals static vec2_t g_chrome[MAXSTUDIOVERTS]; // texture coords for surface normals
@ -138,8 +136,6 @@ R_StudioInit
*/ */
void R_StudioInit( void ) void R_StudioInit( void )
{ {
float pixelAspect, fov_x = 90.0f, fov_y;
r_studio_lambert = Cvar_Get( "r_studio_lambert", "2", FCVAR_ARCHIVE, "bonelighting lambert value" ); r_studio_lambert = Cvar_Get( "r_studio_lambert", "2", FCVAR_ARCHIVE, "bonelighting lambert value" );
r_studio_lerping = Cvar_Get( "r_studio_lerping", "1", FCVAR_ARCHIVE, "enables studio animation lerping" ); r_studio_lerping = Cvar_Get( "r_studio_lerping", "1", FCVAR_ARCHIVE, "enables studio animation lerping" );
r_drawviewmodel = Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" ); r_drawviewmodel = Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
@ -150,17 +146,6 @@ void R_StudioInit( void )
// NOTE: some mods with custom studiomodel renderer may cause error when menu trying draw player model out of the loaded game // NOTE: some mods with custom studiomodel renderer may cause error when menu trying draw player model out of the loaded game
r_customdraw_playermodel = Cvar_Get( "r_customdraw_playermodel", "0", FCVAR_ARCHIVE, "allow to drawing playermodel in menu with client renderer" ); r_customdraw_playermodel = Cvar_Get( "r_customdraw_playermodel", "0", FCVAR_ARCHIVE, "allow to drawing playermodel in menu with client renderer" );
// recalc software X and Y alias scale (this stuff is used only by HL software renderer but who knews...)
pixelAspect = ((float)scr_height->value / (float)scr_width->value);
if( scr_width->value < 640 )
pixelAspect *= (320.0f / 240.0f);
else pixelAspect *= (640.0f / 480.0f);
fov_y = V_CalcFov( &fov_x, scr_width->value, scr_height->value );
aliasXscale = (float)scr_width->value / fov_y; // stub
aliasYscale = aliasXscale * pixelAspect;
Matrix3x4_LoadIdentity( g_aliastransform );
Matrix3x4_LoadIdentity( g_rotationmatrix ); Matrix3x4_LoadIdentity( g_rotationmatrix );
g_nStudioCount = 0; g_nStudioCount = 0;
@ -412,8 +397,8 @@ pfnGetAliasScale
*/ */
static void pfnGetAliasScale( float *x, float *y ) static void pfnGetAliasScale( float *x, float *y )
{ {
if( x ) *x = aliasXscale; if( x ) *x = 1.0f;
if( y ) *y = aliasYscale; if( y ) *y = 1.0f;
} }
/* /*
@ -446,7 +431,7 @@ pfnStudioGetAliasTransform
*/ */
static float ***pfnStudioGetAliasTransform( void ) static float ***pfnStudioGetAliasTransform( void )
{ {
return (float ***)g_aliastransform; return NULL;
} }
/* /*
@ -539,10 +524,10 @@ void R_StudioSetUpTransform( cl_entity_t *e )
// don't do it if the goalstarttime hasn't updated in a while. // don't do it if the goalstarttime hasn't updated in a while.
// NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit
// was increased to 1.0 s., which is 2x the max lag we are accounting for. // was increased to 1.0 s., which is 2x the max lag we are accounting for.
if( m_fDoInterp && ( RI.refdef.time < e->curstate.animtime + 1.0f ) && ( e->curstate.animtime != e->latched.prevanimtime )) if( m_fDoInterp && ( cl.time < e->curstate.animtime + 1.0f ) && ( e->curstate.animtime != e->latched.prevanimtime ))
{ {
f = ( RI.refdef.time - e->curstate.animtime ) / ( e->curstate.animtime - e->latched.prevanimtime ); f = ( cl.time - e->curstate.animtime ) / ( e->curstate.animtime - e->latched.prevanimtime );
// Msg( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, RI.refdef.time ); // Msg( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, cl.time );
} }
if( m_fDoInterp ) if( m_fDoInterp )
@ -601,8 +586,8 @@ float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc )
if( m_fDoInterp ) if( m_fDoInterp )
{ {
if( RI.refdef.time < e->curstate.animtime ) dfdt = 0.0; if( cl.time < e->curstate.animtime ) dfdt = 0.0;
else dfdt = (RI.refdef.time - e->curstate.animtime) * e->curstate.framerate * pseqdesc->fps; else dfdt = (cl.time - e->curstate.animtime) * e->curstate.framerate * pseqdesc->fps;
} }
else dfdt = 0; else dfdt = 0;
@ -638,7 +623,7 @@ float R_StudioEstimateInterpolant( cl_entity_t *e )
if( m_fDoInterp && ( e->curstate.animtime >= e->latched.prevanimtime + 0.01f )) if( m_fDoInterp && ( e->curstate.animtime >= e->latched.prevanimtime + 0.01f ))
{ {
dadt = ( RI.refdef.time - e->curstate.animtime ) / 0.1f; dadt = ( cl.time - e->curstate.animtime ) / 0.1f;
if( dadt > 2.0f ) dadt = 2.0f; if( dadt > 2.0f ) dadt = 2.0f;
} }
return dadt; return dadt;
@ -729,7 +714,7 @@ void R_StudioFxTransform( cl_entity_t *ent, matrix3x4 transform )
{ {
float scale; float scale;
scale = 1.0f + ( RI.refdef.time - ent->curstate.animtime ) * 10.0f; scale = 1.0f + ( cl.time - ent->curstate.animtime ) * 10.0f;
if( scale > 2.0f ) scale = 2.0f; // don't blow up more than 200% if( scale > 2.0f ) scale = 2.0f; // don't blow up more than 200%
transform[0][1] *= scale; transform[0][1] *= scale;
@ -1158,7 +1143,7 @@ void R_StudioSetupBones( cl_entity_t *e )
} }
} }
if( m_fDoInterp && e->latched.sequencetime && ( e->latched.sequencetime + 0.2f > RI.refdef.time) && ( e->latched.prevsequence < m_pStudioHeader->numseq )) if( m_fDoInterp && e->latched.sequencetime && ( e->latched.sequencetime + 0.2f > cl.time) && ( e->latched.prevsequence < m_pStudioHeader->numseq ))
{ {
// blend from last sequence // blend from last sequence
static vec3_t pos1b[MAXSTUDIOBONES]; static vec3_t pos1b[MAXSTUDIOBONES];
@ -1195,7 +1180,7 @@ void R_StudioSetupBones( cl_entity_t *e )
} }
} }
s = 1.0f - ( RI.refdef.time - e->latched.sequencetime ) / 0.2f; s = 1.0f - ( cl.time - e->latched.sequencetime ) / 0.2f;
R_StudioSlerpBones( q, pos, q1b, pos1b, s ); R_StudioSlerpBones( q, pos, q1b, pos1b, s );
} }
else else
@ -1306,7 +1291,7 @@ void R_StudioSetupChrome( float *pchrome, int bone, vec3_t normal )
float angle, sr, cr; float angle, sr, cr;
int i; int i;
angle = anglemod( RI.refdef.time * 40 ) * (M_PI2 / 360.0f); angle = anglemod( cl.time * 40 ) * (M_PI2 / 360.0f);
SinCos( angle, &sr, &cr ); SinCos( angle, &sr, &cr );
for( i = 0; i < 3; i++ ) for( i = 0; i < 3; i++ )
@ -1425,10 +1410,8 @@ void R_StudioGetShadowImpactAndDir( void )
float angle; float angle;
vec3_t skyAngles, origin, end; vec3_t skyAngles, origin, end;
if( !cl.refdef.movevars ) return; // e.g. in menu
// convert skyvec into angles then back into vector to avoid 0 0 0 direction // convert skyvec into angles then back into vector to avoid 0 0 0 direction
VectorAngles( (float *)&cl.refdef.movevars->skyvec_x, skyAngles ); VectorAngles( (float *)&clgame.movevars.skyvec_x, skyAngles );
angle = skyAngles[YAW] / 180 * M_PI; angle = skyAngles[YAW] / 180 * M_PI;
Matrix3x4_OriginFromMatrix( g_bonestransform[0], origin ); Matrix3x4_OriginFromMatrix( g_bonestransform[0], origin );
@ -1477,14 +1460,9 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo )
else Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin ); else Matrix3x4_OriginFromMatrix( g_rotationmatrix, origin );
// setup light dir // setup light dir
if( cl.refdef.movevars ) plight->lightvec[0] = clgame.movevars.skyvec_x;
{ plight->lightvec[1] = clgame.movevars.skyvec_y;
// pre-defined light vector plight->lightvec[2] = clgame.movevars.skyvec_z;
plight->lightvec[0] = cl.refdef.movevars->skyvec_x;
plight->lightvec[1] = cl.refdef.movevars->skyvec_y;
plight->lightvec[2] = cl.refdef.movevars->skyvec_z;
}
else VectorSet( plight->lightvec, 0.0f, 0.0f, -1.0f );
if( VectorIsNull( plight->lightvec )) if( VectorIsNull( plight->lightvec ))
VectorSet( plight->lightvec, 0.0f, 0.0f, -1.0f ); VectorSet( plight->lightvec, 0.0f, 0.0f, -1.0f );
@ -1510,7 +1488,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo )
for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ ) for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
{ {
if( dl->die < RI.refdef.time || !dl->radius ) if( dl->die < cl.time || !dl->radius )
continue; continue;
VectorSubtract( dl->origin, origin, direction ); VectorSubtract( dl->origin, origin, direction );
@ -1596,7 +1574,7 @@ void R_StudioEntityLight( alight_t *lightinfo )
for( lnum = 0, el = cl_elights; lnum < MAX_ELIGHTS; lnum++, el++ ) for( lnum = 0, el = cl_elights; lnum < MAX_ELIGHTS; lnum++, el++ )
{ {
if( el->die < RI.refdef.time || !el->radius ) if( el->die < cl.time || !el->radius )
continue; continue;
VectorSubtract( el->origin, origin, direction ); VectorSubtract( el->origin, origin, direction );
@ -2833,7 +2811,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer )
vec3_t est_velocity; vec3_t est_velocity;
float dt; float dt;
dt = bound( 0.0f, (RI.refdef.time - cl.oldtime), 1.0f ); dt = bound( 0.0f, (cl.time - cl.oldtime), 1.0f );
if( dt == 0.0f || m_pPlayerInfo->renderframe == tr.framecount ) if( dt == 0.0f || m_pPlayerInfo->renderframe == tr.framecount )
{ {
@ -2902,7 +2880,7 @@ void R_StudioProcessGait( entity_state_t *pplayer )
RI.currententity->latched.prevblending[0] = RI.currententity->curstate.blending[0]; RI.currententity->latched.prevblending[0] = RI.currententity->curstate.blending[0];
RI.currententity->latched.prevseqblending[0] = RI.currententity->curstate.blending[0]; RI.currententity->latched.prevseqblending[0] = RI.currententity->curstate.blending[0];
dt = bound( 0.0f, (RI.refdef.time - cl.oldtime), 1.0f ); dt = bound( 0.0f, (cl.time - cl.oldtime), 1.0f );
R_StudioEstimateGait( pplayer ); R_StudioEstimateGait( pplayer );
// calc side to side turning // calc side to side turning
@ -3309,7 +3287,7 @@ R_RunViewmodelEvents
*/ */
void R_RunViewmodelEvents( void ) void R_RunViewmodelEvents( void )
{ {
if( cl.refdef.nextView || cl.thirdperson || RI.params & RP_NONVIEWERREF ) if( cl.local.thirdperson || RI.params & RP_NONVIEWERREF )
return; return;
if( !Mod_Extradata( clgame.viewent.model )) if( !Mod_Extradata( clgame.viewent.model ))
@ -3319,9 +3297,9 @@ void R_RunViewmodelEvents( void )
RI.currentmodel = RI.currententity->model; RI.currentmodel = RI.currententity->model;
if( !RI.currentmodel ) return; if( !RI.currentmodel ) return;
if( !cl.weaponstarttime ) cl.weaponstarttime = cl.time; if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = cl.time;
RI.currententity->curstate.animtime = cl.weaponstarttime; RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.weaponsequence; RI.currententity->curstate.sequence = cl.local.weaponsequence;
pStudioDraw->StudioDrawModel( STUDIO_EVENTS ); pStudioDraw->StudioDrawModel( STUDIO_EVENTS );
@ -3336,14 +3314,14 @@ R_DrawViewModel
*/ */
void R_DrawViewModel( void ) void R_DrawViewModel( void )
{ {
if( RI.refdef.onlyClientDraw || r_drawviewmodel->value == 0 ) if( RI.onlyClientDraw || r_drawviewmodel->value == 0 )
return; return;
// ignore in thirdperson, camera view or client is died // ignore in thirdperson, camera view or client is died
if( cl.thirdperson || cl.refdef.health <= 0 || cl.refdef.viewentity != ( cl.playernum + 1 )) if( cl.local.thirdperson || cl.local.health <= 0 || cl.viewentity != ( cl.playernum + 1 ))
return; return;
if( cl.refdef.nextView || RI.params & RP_NONVIEWERREF ) if( RI.params & RP_NONVIEWERREF )
return; return;
if( !Mod_Extradata( clgame.viewent.model )) if( !Mod_Extradata( clgame.viewent.model ))
@ -3362,9 +3340,9 @@ void R_DrawViewModel( void )
if( r_lefthand->value == 1 || g_iBackFaceCull ) if( r_lefthand->value == 1 || g_iBackFaceCull )
GL_FrontFace( !glState.frontFace ); GL_FrontFace( !glState.frontFace );
if( !cl.weaponstarttime ) cl.weaponstarttime = cl.time; if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = cl.time;
RI.currententity->curstate.animtime = cl.weaponstarttime; RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.weaponsequence; RI.currententity->curstate.sequence = cl.local.weaponsequence;
pStudioDraw->StudioDrawModel( STUDIO_RENDER ); pStudioDraw->StudioDrawModel( STUDIO_RENDER );

View File

@ -1062,6 +1062,19 @@ void VID_RestoreGamma( void )
SetDeviceGammaRamp( glw_state.hDC, glState.stateRamp ); SetDeviceGammaRamp( glw_state.hDC, glState.stateRamp );
} }
/*
=================
VID_InitDefaultResolution
=================
*/
void VID_InitDefaultResolution( void )
{
// we need to have something valid here
// until video subsystem initialized
glState.width = 640;
glState.height = 480;
}
/* /*
================= =================
GL_SetPixelformat GL_SetPixelformat
@ -1155,9 +1168,6 @@ void R_SaveVideoMode( int vid_mode )
glState.width = vidmode[mode].width; glState.width = vidmode[mode].width;
glState.height = vidmode[mode].height; glState.height = vidmode[mode].height;
glState.wideScreen = vidmode[mode].wideScreen; glState.wideScreen = vidmode[mode].wideScreen;
Cvar_FullSet( "width", va( "%i", vidmode[mode].width ), FCVAR_READ_ONLY );
Cvar_FullSet( "height", va( "%i", vidmode[mode].height ), FCVAR_READ_ONLY );
Cvar_SetValue( "vid_mode", mode ); // merge if it out of bounds Cvar_SetValue( "vid_mode", mode ); // merge if it out of bounds
MsgDev( D_NOTE, "Set: %s [%dx%d]\n", vidmode[mode].desc, vidmode[mode].width, vidmode[mode].height ); MsgDev( D_NOTE, "Set: %s [%dx%d]\n", vidmode[mode].desc, vidmode[mode].width, vidmode[mode].height );
@ -1375,8 +1385,8 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen )
R_SaveVideoMode( vid_mode ); R_SaveVideoMode( vid_mode );
width = scr_width->value; width = glState.width;
height = scr_height->value; height = glState.height;
// check our desktop attributes // check our desktop attributes
hDC = GetDC( GetDesktopWindow( )); hDC = GetDC( GetDesktopWindow( ));
@ -1708,7 +1718,7 @@ void R_RenderInfo_f( void )
} }
Msg( "\n" ); Msg( "\n" );
Msg( "MODE: %i, %i x %i %s\n", vid_mode->value, scr_width->value, scr_height->value, vidmode[(int)vid_mode->value].desc ); Msg( "MODE: %i, %i x %i %s\n", vid_mode->value, glState.width, glState.height, vidmode[(int)vid_mode->value].desc );
Msg( "GAMMA: %s\n", (glConfig.deviceSupportsGamma) ? "hardware" : "software" ); Msg( "GAMMA: %s\n", (glConfig.deviceSupportsGamma) ? "hardware" : "software" );
Msg( "\n" ); Msg( "\n" );
Msg( "PICMIP: %i\n", gl_picmip->value ); Msg( "PICMIP: %i\n", gl_picmip->value );

View File

@ -788,7 +788,7 @@ void EmitWaterPolys( glpoly_t *polys, qboolean noCull, qboolean direction )
if( noCull ) pglDisable( GL_CULL_FACE ); if( noCull ) pglDisable( GL_CULL_FACE );
// set the current waveheight // set the current waveheight
if( p->verts[0][2] >= RI.refdef.vieworg[2] ) if( p->verts[0][2] >= RI.vieworg[2] )
waveHeight = -RI.currententity->curstate.scale; waveHeight = -RI.currententity->curstate.scale;
else waveHeight = RI.currententity->curstate.scale; else waveHeight = RI.currententity->curstate.scale;

View File

@ -17,7 +17,7 @@ GNU General Public License for more details.
#include "sound.h" #include "sound.h"
#include "client.h" #include "client.h"
#include "con_nprint.h" #include "con_nprint.h"
#include "ref_params.h" #include "gl_local.h"
#include "pm_local.h" #include "pm_local.h"
#define SND_CLIP_DISTANCE (float)(GI->soundclip_dist) #define SND_CLIP_DISTANCE (float)(GI->soundclip_dist)
@ -881,7 +881,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
return; return;
} }
if( !pos ) pos = cl.refdef.vieworg; if( !pos ) pos = RI.vieworg;
// pick a channel to play on // pick a channel to play on
if( chan == CHAN_STATIC ) target_chan = SND_PickStaticChannel( ent, sfx ); if( chan == CHAN_STATIC ) target_chan = SND_PickStaticChannel( ent, sfx );
@ -1850,19 +1850,18 @@ void S_ExtraUpdate( void )
/* /*
============ ============
S_RenderFrame SND_UpdateSound
Called once each time through the main loop Called once each time through the main loop
============ ============
*/ */
void S_RenderFrame( ref_params_t *fd ) void SND_UpdateSound( void )
{ {
int i, j, total; int i, j, total;
channel_t *ch, *combine; channel_t *ch, *combine;
con_nprint_t info; con_nprint_t info;
if( !dma.initialized ) return; if( !dma.initialized ) return;
if( !fd ) return; // too early
// if the loading plaque is up, clear everything // if the loading plaque is up, clear everything
// out to make sure we aren't looping a dirty // out to make sure we aren't looping a dirty
@ -1873,16 +1872,16 @@ void S_RenderFrame( ref_params_t *fd )
// release raw-channels that no longer used more than 10 secs // release raw-channels that no longer used more than 10 secs
S_FreeIdleRawChannels(); S_FreeIdleRawChannels();
s_listener.entnum = fd->viewentity; // can be camera entity too s_listener.entnum = cl.viewentity; // can be camera entity too
s_listener.frametime = fd->frametime; s_listener.frametime = (cl.time - cl.oldtime);
s_listener.waterlevel = fd->waterlevel; s_listener.waterlevel = cl.local.waterlevel;
s_listener.active = CL_IsInGame(); s_listener.active = CL_IsInGame();
s_listener.inmenu = CL_IsInMenu(); s_listener.inmenu = CL_IsInMenu();
s_listener.paused = fd->paused; s_listener.paused = cl.paused;
VectorCopy( fd->vieworg, s_listener.origin ); VectorCopy( RI.vieworg, s_listener.origin );
VectorCopy( fd->simvel, s_listener.velocity ); VectorCopy( cl.simvel, s_listener.velocity );
AngleVectors( fd->viewangles, s_listener.forward, s_listener.right, s_listener.up ); AngleVectors( RI.viewangles, s_listener.forward, s_listener.right, s_listener.up );
if( cl.worldmodel != NULL ) if( cl.worldmodel != NULL )
Mod_FatPVS( s_listener.origin, FATPHS_RADIUS, s_listener.pasbytes, world.visbytes, false, !s_phs->value ); Mod_FatPVS( s_listener.origin, FATPHS_RADIUS, s_listener.pasbytes, world.visbytes, false, !s_phs->value );

View File

@ -83,7 +83,7 @@ void VGUI_CursorSelect( Cursor *cursor )
void VGUI_ActivateCurrentCursor( void ) void VGUI_ActivateCurrentCursor( void )
{ {
if( cls.key_dest != key_game || cl.refdef.paused ) if( cls.key_dest != key_game || cl.paused )
return; return;
if( host.mouse_visible ) if( host.mouse_visible )

View File

@ -1016,7 +1016,7 @@ void Cmd_ForwardToServer( void )
if( cls.demoplayback ) if( cls.demoplayback )
{ {
if( !Q_stricmp( Cmd_Argv( 0 ), "pause" )) if( !Q_stricmp( Cmd_Argv( 0 ), "pause" ))
cl.refdef.paused ^= 1; cl.paused ^= 1;
return; return;
} }

View File

@ -90,7 +90,6 @@ typedef enum
} instance_t; } instance_t;
#include "system.h" #include "system.h"
#include "ref_params.h"
#include "com_model.h" #include "com_model.h"
#include "crtlib.h" #include "crtlib.h"
#include "cvar.h" #include "cvar.h"
@ -144,8 +143,6 @@ void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile,
#endif #endif
extern convar_t *gl_vsync; extern convar_t *gl_vsync;
extern convar_t *scr_width;
extern convar_t *scr_height;
extern convar_t *scr_loading; extern convar_t *scr_loading;
extern convar_t *scr_download; extern convar_t *scr_download;
extern convar_t *cmd_scripting; extern convar_t *cmd_scripting;
@ -857,6 +854,7 @@ void CL_Crashed( void );
qboolean CL_NextDemo( void ); qboolean CL_NextDemo( void );
char *SV_Serverinfo( void ); char *SV_Serverinfo( void );
void CL_Drop( void ); void CL_Drop( void );
void Con_Init( void );
void SCR_Init( void ); void SCR_Init( void );
void SCR_UpdateScreen( void ); void SCR_UpdateScreen( void );
void SCR_BeginLoadingPlaque( qboolean is_background ); void SCR_BeginLoadingPlaque( qboolean is_background );
@ -887,6 +885,7 @@ float Com_RandomFloat( float fMin, float fMax );
void TrimSpace( const char *source, char *dest ); void TrimSpace( const char *source, char *dest );
const byte *GL_TextureData( unsigned int texnum ); const byte *GL_TextureData( unsigned int texnum );
void GL_FreeImage( const char *name ); void GL_FreeImage( const char *name );
void VID_InitDefaultResolution( void );
void VID_RestoreGamma( void ); void VID_RestoreGamma( void );
void UI_SetActiveMenu( qboolean fActive ); void UI_SetActiveMenu( qboolean fActive );
struct cmd_s *Cmd_GetFirstFunctionHandle( void ); struct cmd_s *Cmd_GetFirstFunctionHandle( void );

View File

@ -26,6 +26,7 @@ convar_t *scr_conspeed;
convar_t *con_fontsize; convar_t *con_fontsize;
#define CON_TIMES 4 // notify lines #define CON_TIMES 4 // notify lines
#define CON_MAX_TIMES 64 // notify max lines
#define COLOR_DEFAULT '7' #define COLOR_DEFAULT '7'
#define CON_HISTORY 64 #define CON_HISTORY 64
#define MAX_DBG_NOTIFY 128 #define MAX_DBG_NOTIFY 128
@ -87,6 +88,7 @@ typedef struct
int lines_first; // cyclic buffer int lines_first; // cyclic buffer
int lines_count; int lines_count;
int num_times; // overlay lines count
// console scroll // console scroll
int backscroll; // lines up from bottom to display int backscroll; // lines up from bottom to display
@ -303,6 +305,25 @@ void Con_ToggleConsole_f( void )
} }
} }
/*
================
Con_SetTimes_f
================
*/
void Con_SetTimes_f( void )
{
int newtimes;
if( Cmd_Argc() != 2 )
{
Msg( "Usage: contimes <n lines>\n" );
return;
}
newtimes = Q_atoi( Cmd_Argv( 1 ) );
con.num_times = bound( CON_TIMES, newtimes, CON_MAX_TIMES );
}
/* /*
================ ================
Con_FixTimes Con_FixTimes
@ -447,7 +468,7 @@ void Con_CheckResize( void )
if( con.curFont && con.curFont->hFontTexture ) if( con.curFont && con.curFont->hFontTexture )
charWidth = con.curFont->charWidths['M'] - 1; charWidth = con.curFont->charWidths['M'] - 1;
width = ( scr_width->value / charWidth ) - 2; width = ( glState.width / charWidth ) - 2;
if( !glw_state.initialized ) width = 78; if( !glw_state.initialized ) width = 78;
if( width == con.linewidth ) if( width == con.linewidth )
@ -574,9 +595,9 @@ static void Con_LoadConchars( void )
Con_LoadConsoleFont( i, con.chars + i ); Con_LoadConsoleFont( i, con.chars + i );
// select properly fontsize // select properly fontsize
if( scr_width->value <= 640 ) if( glState.width <= 640 )
fontSize = 0; fontSize = 0;
else if( scr_width->value >= 1280 ) else if( glState.width >= 1280 )
fontSize = 2; fontSize = 2;
else fontSize = 1; else fontSize = 1;
@ -599,8 +620,8 @@ static void Con_TextAdjustSize( int *x, int *y, int *w, int *h )
if( !x && !y && !w && !h ) return; if( !x && !y && !w && !h ) return;
// scale for screen sizes // scale for screen sizes
xscale = scr_width->value / (float)clgame.scrInfo.iWidth; xscale = (float)glState.width / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight; yscale = (float)glState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale; if( x ) *x *= xscale;
if( y ) *y *= yscale; if( y ) *y *= yscale;
@ -824,9 +845,10 @@ void Con_Init( void )
{ {
int i; int i;
if( host.type == HOST_DEDICATED )
return; // dedicated server already have console
// must be init before startup video subsystem // must be init before startup video subsystem
scr_width = Cvar_Get( "width", "640", FCVAR_READ_ONLY, "screen width" );
scr_height = Cvar_Get( "height", "480", FCVAR_READ_ONLY, "screen height" );
scr_conspeed = Cvar_Get( "scr_conspeed", "600", FCVAR_ARCHIVE, "console moving speed" ); scr_conspeed = Cvar_Get( "scr_conspeed", "600", FCVAR_ARCHIVE, "console moving speed" );
con_notifytime = Cvar_Get( "con_notifytime", "3", FCVAR_ARCHIVE, "notify time to live" ); con_notifytime = Cvar_Get( "con_notifytime", "3", FCVAR_ARCHIVE, "notify time to live" );
con_fontsize = Cvar_Get( "con_fontsize", "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" ); con_fontsize = Cvar_Get( "con_fontsize", "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
@ -837,6 +859,7 @@ void Con_Init( void )
con.maxlines = CON_MAXLINES; con.maxlines = CON_MAXLINES;
con.lines = (con_lineinfo_t *)Z_Malloc( con.maxlines * sizeof( *con.lines )); con.lines = (con_lineinfo_t *)Z_Malloc( con.maxlines * sizeof( *con.lines ));
con.lines_first = con.lines_count = 0; con.lines_first = con.lines_count = 0;
con.num_times = CON_TIMES; // default as 4
Con_CheckResize(); Con_CheckResize();
@ -857,9 +880,10 @@ void Con_Init( void )
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" ); Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
Cmd_AddCommand( "messagemode", Con_MessageMode_f, "enable message mode \"say\"" ); Cmd_AddCommand( "messagemode", Con_MessageMode_f, "enable message mode \"say\"" );
Cmd_AddCommand( "messagemode2", Con_MessageMode2_f, "enable message mode \"say_team\"" ); Cmd_AddCommand( "messagemode2", Con_MessageMode2_f, "enable message mode \"say_team\"" );
Cmd_AddCommand( "contimes", Con_SetTimes_f, "change number of console overlay lines (4-64)" );
MsgDev( D_REPORT, "Console initialized.\n" );
con.initialized = true; con.initialized = true;
MsgDev( D_INFO, "Console initialized.\n" );
} }
/* /*
@ -1694,10 +1718,10 @@ int Con_DrawDebugLines( void )
int fontTall; int fontTall;
Con_DrawStringLen( con.notify[i].szNotify, &len, &fontTall ); Con_DrawStringLen( con.notify[i].szNotify, &len, &fontTall );
x = scr_width->value - Q_max( defaultX, len ) - 10; x = glState.width - Q_max( defaultX, len ) - 10;
fontTall += 1; fontTall += 1;
if( y + fontTall > (int)scr_height->value - 20 ) if( y + fontTall > glState.height - 20 )
return count; return count;
count++; count++;
@ -1746,7 +1770,7 @@ void Con_DrawNotify( void )
if( host.developer && ( !Cvar_VariableInteger( "cl_background" ) && !Cvar_VariableInteger( "sv_background" ))) if( host.developer && ( !Cvar_VariableInteger( "cl_background" ) && !Cvar_VariableInteger( "sv_background" )))
{ {
for( i = CON_LINES_COUNT - CON_TIMES; i < CON_LINES_COUNT; i++ ) for( i = CON_LINES_COUNT - con.num_times; i < CON_LINES_COUNT; i++ )
{ {
con_lineinfo_t *l = &CON_LINES( i ); con_lineinfo_t *l = &CON_LINES( i );
@ -1846,7 +1870,7 @@ void Con_DrawSolidConsole( int lines )
// draw the background // draw the background
GL_SetRenderMode( kRenderNormal ); GL_SetRenderMode( kRenderNormal );
pglColor4ub( 255, 255, 255, 255 ); // to prevent grab color from screenfade pglColor4ub( 255, 255, 255, 255 ); // to prevent grab color from screenfade
R_DrawStretchPic( 0, lines - scr_height->value, scr_width->value, scr_height->value, 0, 0, 1, 1, con.background ); R_DrawStretchPic( 0, lines - glState.height, glState.width, glState.height, 0, 0, 1, 1, con.background );
if( !con.curFont || host.developer <= 0 ) if( !con.curFont || host.developer <= 0 )
return; // nothing to draw return; // nothing to draw
@ -1862,10 +1886,10 @@ void Con_DrawSolidConsole( int lines )
Q_snprintf( curbuild, MAX_STRING, "Xash3D %i/%g (hw build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); Q_snprintf( curbuild, MAX_STRING, "Xash3D %i/%g (hw build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
Con_DrawStringLen( curbuild, &stringLen, &charH ); Con_DrawStringLen( curbuild, &stringLen, &charH );
start = scr_width->value - stringLen; start = glState.width - stringLen;
stringLen = Con_StringLength( curbuild ); stringLen = Con_StringLength( curbuild );
fraction = lines / (float)scr_height->value; fraction = lines / (float)glState.height;
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
for( i = 0; i < stringLen; i++ ) for( i = 0; i < stringLen; i++ )
@ -1932,13 +1956,13 @@ void Con_DrawConsole( void )
{ {
if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console ) if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
con.vislines = con.showlines = 0; con.vislines = con.showlines = 0;
else con.vislines = con.showlines = scr_height->value; else con.vislines = con.showlines = glState.height;
} }
else else
{ {
if( host.developer >= 4 ) if( host.developer >= 4 )
{ {
con.vislines = ((int)scr_height->value >> 1); // keep console open con.vislines = (glState.height >> 1); // keep console open
} }
else else
{ {
@ -1957,7 +1981,7 @@ void Con_DrawConsole( void )
case ca_disconnected: case ca_disconnected:
if( cls.key_dest != key_menu && host.developer ) if( cls.key_dest != key_menu && host.developer )
{ {
Con_DrawSolidConsole( scr_height->value ); Con_DrawSolidConsole( glState.height );
Key_SetKeyDest( key_console ); Key_SetKeyDest( key_console );
} }
break; break;
@ -1975,7 +1999,7 @@ void Con_DrawConsole( void )
if( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) if( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" ))
{ {
if( cls.key_dest == key_console ) if( cls.key_dest == key_console )
Con_DrawSolidConsole( scr_height->value ); Con_DrawSolidConsole( glState.height );
} }
else else
{ {
@ -2002,7 +2026,7 @@ void Con_DrawVersion( void )
// draws the current build // draws the current build
byte *color = g_color_table[7]; byte *color = g_color_table[7];
int i, stringLen, width = 0, charH; int i, stringLen, width = 0, charH;
int start, height = scr_height->value; int start, height = glState.height;
qboolean draw_version = false; qboolean draw_version = false;
string curbuild; string curbuild;
@ -2024,7 +2048,7 @@ void Con_DrawVersion( void )
Q_snprintf( curbuild, MAX_STRING, "Xash3D v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); Q_snprintf( curbuild, MAX_STRING, "Xash3D v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
else Q_snprintf( curbuild, MAX_STRING, "v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( )); else Q_snprintf( curbuild, MAX_STRING, "v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
Con_DrawStringLen( curbuild, &stringLen, &charH ); Con_DrawStringLen( curbuild, &stringLen, &charH );
start = scr_width->value - stringLen * 1.05f; start = glState.width - stringLen * 1.05f;
stringLen = Con_StringLength( curbuild ); stringLen = Con_StringLength( curbuild );
height -= charH * 1.05f; height -= charH * 1.05f;
@ -2047,12 +2071,12 @@ void Con_RunConsole( void )
if( host.developer && cls.key_dest == key_console ) if( host.developer && cls.key_dest == key_console )
{ {
if( cls.state == ca_disconnected ) if( cls.state == ca_disconnected )
con.showlines = scr_height->value; // full screen con.showlines = glState.height; // full screen
else con.showlines = ((int)scr_height->value >> 1); // half screen else con.showlines = (glState.height >> 1); // half screen
} }
else con.showlines = 0; // none visible else con.showlines = 0; // none visible
lines_per_frame = bound( 1, fabs( scr_conspeed->value ) * host.realframetime, scr_height->value ); lines_per_frame = bound( 1, fabs( scr_conspeed->value ) * host.realframetime, glState.height );
if( cls.state == ca_connecting || cls.state == ca_connected ) if( cls.state == ca_connecting || cls.state == ca_connected )
lines_per_frame = 0; lines_per_frame = 0;
@ -2119,18 +2143,9 @@ void Con_VidInit( void )
if( !con.background ) if( !con.background )
{ {
if( scr_width->value < 640 ) if( FS_FileExists( "cached/conback640", false ))
{ con.background = GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE, NULL );
if( FS_FileExists( "cached/conback400", false )) else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE, NULL );
con.background = GL_LoadTexture( "cached/conback400", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE, NULL );
}
else
{
if( FS_FileExists( "cached/conback640", false ))
con.background = GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE, NULL );
}
} }
} }
else else
@ -2141,18 +2156,9 @@ void Con_VidInit( void )
if( !con.background ) if( !con.background )
{ {
if( scr_width->value < 640 ) if( FS_FileExists( "cached/loading640", false ))
{ con.background = GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE, NULL );
if( FS_FileExists( "cached/loading400", false )) else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE, NULL );
con.background = GL_LoadTexture( "cached/loading400", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE, NULL );
}
else
{
if( FS_FileExists( "cached/loading640", false ))
con.background = GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE, NULL );
else con.background = GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE, NULL );
}
} }
} }

View File

@ -14,6 +14,7 @@ GNU General Public License for more details.
*/ */
#include "common.h" #include "common.h"
#include "math.h" // fabs...
convar_t *cvar_vars; // head of list convar_t *cvar_vars; // head of list
convar_t *cmd_scripting; convar_t *cmd_scripting;

View File

@ -847,14 +847,18 @@ void Host_InitCommon( const char *progname, qboolean bChangeGame )
host.old_developer = host.developer; host.old_developer = host.developer;
Con_CreateConsole(); Con_CreateConsole(); // system console used by dedicated server or show fatal errors
// first text message into console or log // NOTE: this message couldn't be passed into game console but it doesn't matter
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading xash.dll - ok\n" ); MsgDev( D_NOTE, "Sys_LoadLibrary: Loading xash.dll - ok\n" );
// get default screen res
VID_InitDefaultResolution();
// startup cmds and cvars subsystem // startup cmds and cvars subsystem
Cmd_Init(); Cmd_Init();
Cvar_Init(); Cvar_Init();
Con_Init(); // early console running to catch all the messages
// share developer level across all dlls // share developer level across all dlls
Q_snprintf( dev_level, sizeof( dev_level ), "%i", host.developer ); Q_snprintf( dev_level, sizeof( dev_level ), "%i", host.developer );

View File

@ -393,7 +393,7 @@ void Host_InputFrame( void )
} }
// release mouse during pause or console typeing // release mouse during pause or console typeing
if( cl.refdef.paused && cls.key_dest == key_game ) if( cl.paused && cls.key_dest == key_game )
shutdownMouse = true; shutdownMouse = true;
if( shutdownMouse && !Cvar_VariableInteger( "fullscreen" )) if( shutdownMouse && !Cvar_VariableInteger( "fullscreen" ))

View File

@ -479,7 +479,7 @@ static void UI_PlayerSetup_Init( void )
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.view ); UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.view );
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.name ); UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.name );
if( !gMenu.m_gameinfo.flags & GFL_NOMODELS ) if( !( gMenu.m_gameinfo.flags & GFL_NOMODELS ))
{ {
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.model ); UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.model );
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.topColor ); UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.topColor );