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 );
for( i = 0; i < 128; i++ )
{
cl.refdef.viewangles[1] = i / 128.0 * 360.0f;
R_RenderFrame( &cl.refdef, true );
RI.viewangles[1] = i / 128.0 * 360.0f;
R_RenderScene();
}
R_EndFrame();
}
@ -470,10 +470,10 @@ void SCR_TimeRefresh_f( void )
{
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_RenderFrame( &cl.refdef, true );
R_RenderScene();
R_EndFrame();
}
}
@ -492,6 +492,6 @@ viewpos (level-designer helper)
*/
void SCR_Viewpos_f( void )
{
Msg( "org ( %g %g %g )\n", cl.refdef.vieworg[0], cl.refdef.vieworg[1], cl.refdef.vieworg[2] );
Msg( "ang ( %g %g %g )\n", cl.refdef.viewangles[0], cl.refdef.viewangles[1], cl.refdef.viewangles[2] );
Msg( "org ( %g %g %g )\n", RI.vieworg[0], RI.vieworg[1], RI.vieworg[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 "client.h"
#include "gl_local.h"
#include "net_encode.h"
#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 ));
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;
// 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
// or lerping will stop working
@ -566,7 +567,7 @@ void CL_ReadDemoUserCmd( qboolean discard )
// record update
a->starttime = demo.timestamp;
VectorCopy( cl.refdef.cmd->viewangles, a->viewangles );
VectorCopy( cl.viewangles, a->viewangles );
demo.lasttime = demo.timestamp;
}
@ -731,7 +732,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
// HACKHACK: changedemo issues
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;
return false; // paused
@ -891,9 +892,9 @@ void CL_DemoInterpolateAngles( void )
AngleQuaternion( next->viewangles, q1, false );
AngleQuaternion( prev->viewangles, q2, false );
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;
event_args_t nullargs, args;
entity_state_t *state;
cl_entity_t *pEnt;
float delay;
memset( &nullargs, 0, sizeof( nullargs ));
@ -461,69 +460,6 @@ void CL_ParseEvent( sizebuf_t *msg )
// Place event on queue
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 )
{
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
if( eventindex < 1 || eventindex > MAX_EVENTS )
@ -546,12 +487,6 @@ void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, floa
return;
}
if( flags & FEV_SERVER )
{
MsgDev( D_WARN, "CL_PlaybackEvent: event with FEV_SERVER flag!\n" );
return;
}
// check event for precached
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_NOTHOST|FEV_HOSTONLY|FEV_GLOBAL);
if( delay < 0.0f ) delay = 0.0f; // fixup negative delays
invokerIndex = cl.playernum + 1; // only local client can issue client events
args.flags = 0;
args.entindex = invokerIndex;
memset( &args, 0, sizeof( args ));
if( !angles || VectorIsNull( angles ))
VectorCopy( cl.refdef.cl_viewangles, args.angles );
else VectorCopy( angles, args.angles );
if( !origin || VectorIsNull( origin ))
{
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;
}
VectorCopy( origin, args.origin );
VectorCopy( angles, args.angles );
VectorCopy( cl.simvel, args.velocity );
args.entindex = cl.playernum + 1;
args.ducking = ( cl.local.usehull == 1 );
args.fparam1 = fparam1;
args.fparam2 = fparam2;

View File

@ -25,8 +25,6 @@ GNU General Public License for more details.
#include "sound.h"
#include "input.h"
#define MAX_FORWARD 6
qboolean CL_IsPlayerIndex( int idx )
{
if( idx > 0 && idx <= cl.maxclients )
@ -34,17 +32,6 @@ qboolean CL_IsPlayerIndex( int idx )
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 )
{
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.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 extrapolate;
qboolean extrapolate = true;
int i, i0, i1, imod;
float at;
imod = ent->current_position - 1;
i0 = (imod + 1) & HISTORY_MASK;
i1 = imod & HISTORY_MASK;
imod = ent->current_position;
i0 = (imod - 0) & HISTORY_MASK; // curpos (lerp end)
i1 = (imod - 1) & HISTORY_MASK; // oldpos (lerp start)
extrapolate = true;
if( ent->ph[i0].animtime >= targettime )
for( i = 1; i < HISTORY_MAX - 1; i++ )
{
for( i = 0; i < HISTORY_MAX - 2; i++ )
{
at = ent->ph[imod & HISTORY_MASK].animtime;
if( at == 0.0f ) break;
at = ent->ph[( imod - i ) & HISTORY_MASK].animtime;
if( at == 0.0 ) break;
if( at < targettime )
{
i0 = (imod + 1) & HISTORY_MASK;
i1 = imod & HISTORY_MASK;
extrapolate = false;
break;
}
imod--;
if( targettime > at )
{
// found it
i0 = (( imod - i ) + 1 ) & HISTORY_MASK;
i1 = (( imod - i ) + 0 ) & HISTORY_MASK;
extrapolate = false;
break;
}
}
@ -122,6 +125,49 @@ qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, positi
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 )
{
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 )
return 1;
if( cl.predicted.moving && cl.predicted.onground == e->index )
if( cl.local.moving && cl.local.onground == e->index )
return 1;
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;
// 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 );
}
@ -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 )
{
if( !ent || !ent->model )
@ -415,7 +504,7 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
return false;
// 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 )
{
@ -555,8 +644,8 @@ void CL_WeaponAnim( int iAnim, int body )
{
cl_entity_t *view = &clgame.viewent;
cl.weaponstarttime = 0;
cl.weaponsequence = iAnim;
cl.local.weaponstarttime = 0;
cl.local.weaponsequence = iAnim;
// anim is changed. update latchedvars
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

View File

@ -67,7 +67,7 @@ static dllfunc_t cdll_exports[] =
{ "Demo_ReadBuffer", (void **)&clgame.dllFuncs.pfnDemo_ReadBuffer },
{ "CAM_Think", (void **)&clgame.dllFuncs.CAM_Think },
{ "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 },
{ "IN_ActivateMouse", (void **)&clgame.dllFuncs.IN_ActivateMouse },
{ "IN_DeactivateMouse", (void **)&clgame.dllFuncs.IN_DeactivateMouse },
@ -139,7 +139,7 @@ returns true if thirdperson is enabled
*/
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 )
{
xPos = ( clgame.scrInfo.iWidth - width ) * 0.5f;
xPos = ( glState.width - width ) * 0.5f;
}
else
{
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
xPos = x * clgame.scrInfo.iWidth;
xPos = x * glState.width;
}
if( xPos + width > clgame.scrInfo.iWidth )
xPos = clgame.scrInfo.iWidth - width;
if( xPos + width > glState.width )
xPos = glState.width - width;
else if( xPos < 0 )
xPos = 0;
@ -315,19 +315,19 @@ static int CL_AdjustYPos( float y, int height )
if( y == -1 ) // centered?
{
yPos = ( clgame.scrInfo.iHeight - height ) * 0.5f;
yPos = ( glState.height - height ) * 0.5f;
}
else
{
// Alight bottom?
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
yPos = y * clgame.scrInfo.iHeight;
yPos = y * glState.height;
}
if( yPos + height > clgame.scrInfo.iHeight )
yPos = clgame.scrInfo.iHeight - height;
if( yPos + height > glState.height )
yPos = glState.height - height;
else if( 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;
// scale for screen sizes
xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = glState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale;
if( y ) *y *= yscale;
@ -410,8 +410,8 @@ void PicAdjustSize( float *x, float *y, float *w, float *h )
if( !x && !y && !w && !h ) return;
// scale for screen sizes
xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = glState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale;
if( y ) *y *= yscale;
@ -583,7 +583,7 @@ void CL_DrawCenterPrint( void )
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 );
}
y += charHeight;
@ -636,7 +636,7 @@ void CL_DrawScreenFade( void )
if( sf->fadeFlags & FFADE_MODULATE )
GL_SetRenderMode( kRenderTransAdd );
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 );
}
@ -837,7 +837,7 @@ void CL_DrawCrosshair( void )
int x, y, width, height;
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;
pPlayer = CL_GetLocalPlayer();
@ -846,31 +846,31 @@ void CL_DrawCrosshair( void )
return;
// any camera on
if( cl.refdef.viewentity != pPlayer->index )
if( cl.viewentity != pPlayer->index )
return;
// get crosshair dimension
width = clgame.ds.rcCrosshair.right - clgame.ds.rcCrosshair.left;
height = clgame.ds.rcCrosshair.bottom - clgame.ds.rcCrosshair.top;
x = clgame.scrInfo.iWidth / 2;
y = clgame.scrInfo.iHeight / 2;
x = clgame.viewport[0] + ( clgame.viewport[2] >> 1 );
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( !VectorIsNull( cl.refdef.crosshairangle ))
if( !VectorIsNull( cl.crosshairangle ))
{
vec3_t angles;
vec3_t forward;
vec3_t point, screen;
VectorAdd( cl.refdef.viewangles, cl.refdef.crosshairangle, angles );
VectorAdd( cl.viewangles, cl.crosshairangle, angles );
AngleVectors( angles, forward, NULL, NULL );
VectorAdd( cl.refdef.vieworg, forward, point );
VectorAdd( RI.vieworg, forward, point );
R_WorldToScreen( point, screen );
x += 0.5f * screen[0] * scr_width->value + 0.5f;
y += 0.5f * screen[1] * scr_height->value + 0.5f;
x += ( clgame.viewport[2] >> 1 ) * screen[0] + 0.5f;
y += ( clgame.viewport[3] >> 1 ) * screen[1] + 0.5f;
}
clgame.ds.pSprite = clgame.ds.pCrosshair;
@ -899,8 +899,8 @@ static void CL_DrawLoading( float percent )
x = ( clgame.scrInfo.iWidth - width ) >> 1;
y = ( clgame.scrInfo.iHeight - height) >> 1;
xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = glState.height / (float)clgame.scrInfo.iHeight;
x *= xscale;
y *= yscale;
@ -947,8 +947,8 @@ static void CL_DrawPause( void )
x = ( clgame.scrInfo.iWidth - width ) >> 1;
y = ( clgame.scrInfo.iHeight - height) >> 1;
xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
xscale = glState.width / (float)clgame.scrInfo.iWidth;
yscale = glState.height / (float)clgame.scrInfo.iHeight;
x *= xscale;
y *= yscale;
@ -965,7 +965,7 @@ void CL_DrawHUD( int state )
if( state == CL_ACTIVE && !cl.video_prepped )
state = CL_LOADING;
if( state == CL_ACTIVE && cl.refdef.paused )
if( state == CL_ACTIVE && cl.paused )
state = CL_PAUSED;
switch( state )
@ -974,13 +974,13 @@ void CL_DrawHUD( int state )
CL_DrawScreenFade ();
CL_DrawCrosshair ();
CL_DrawCenterPrint ();
clgame.dllFuncs.pfnRedraw( cl.time, cl.refdef.intermission );
clgame.dllFuncs.pfnRedraw( cl.time, cl.intermission );
break;
case CL_PAUSED:
CL_DrawScreenFade ();
CL_DrawCrosshair ();
CL_DrawCenterPrint ();
clgame.dllFuncs.pfnRedraw( cl.time, cl.refdef.intermission );
clgame.dllFuncs.pfnRedraw( cl.time, cl.intermission );
CL_DrawPause();
break;
case CL_LOADING:
@ -1429,10 +1429,11 @@ static int pfnGetScreenInfo( SCREENINFO *pscrinfo )
{
// setup screen info
clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
if( Cvar_VariableInteger( "hud_scale" ))
{
if( scr_width->value < 640 )
if( glState.width < 640 )
{
// virtual screen space 320x200
clgame.scrInfo.iWidth = 320;
@ -1448,8 +1449,8 @@ static int pfnGetScreenInfo( SCREENINFO *pscrinfo )
}
else
{
clgame.scrInfo.iWidth = scr_width->value;
clgame.scrInfo.iHeight = scr_height->value;
clgame.scrInfo.iWidth = glState.width;
clgame.scrInfo.iHeight = glState.height;
clgame.scrInfo.iFlags &= ~SCRINFO_STRETCHED;
}
@ -1590,7 +1591,7 @@ pfnPlaySoundByName
static void pfnPlaySoundByName( const char *szSound, float volume )
{
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 );
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;
if( !string || !*string ) return 0; // silent ignore
clgame.ds.adjust_size = true;
Con_SetFont( con_fontsize->value );
drawLen = Con_DrawString( x, y, string, clgame.ds.textColor );
MakeRGBA( clgame.ds.textColor, 255, 255, 255, 255 );
clgame.ds.adjust_size = false;
Con_RestoreFont();
return (x + drawLen); // exclude color prexfixes
@ -1779,7 +1778,7 @@ return interpolated angles from previous frame
*/
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 )
{
if( angles ) VectorCopy( angles, cl.refdef.cl_viewangles );
if( angles ) VectorCopy( angles, cl.viewangles );
}
/*
@ -2178,9 +2177,7 @@ pfnLocalPlayerDucking
*/
int pfnLocalPlayerDucking( void )
{
if( CL_IsPredicted( ))
return (cl.predicted.usehull == 1);
return cl.frame.client.bInDuck;
return (cl.local.usehull == 1) ? true : false;
}
/*
@ -2191,12 +2188,7 @@ pfnLocalPlayerViewheight
*/
void pfnLocalPlayerViewheight( float *view_ofs )
{
// predicted or smoothed
if( !view_ofs ) return;
if( CL_IsPredicted( ))
VectorCopy( cl.predicted.viewofs, view_ofs );
else VectorCopy( cl.frame.client.view_ofs, view_ofs );
if( view_ofs ) VectorCopy( cl.viewheight, view_ofs );
}
/*
@ -2792,7 +2784,7 @@ pfnPlaySoundVoiceByName
void pfnPlaySoundVoiceByName( char *filename, float volume, int pitch )
{
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 )
{
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 );
screen[0] = 0.5f * screen[0] * (float)cl.refdef.viewport[2];
screen[1] = -0.5f * screen[1] * (float)cl.refdef.viewport[3];
screen[0] += 0.5f * (float)cl.refdef.viewport[2];
screen[1] += 0.5f * (float)cl.refdef.viewport[3];
screen[0] = 0.5f * screen[0] * (float)clgame.viewport[2];
screen[1] = -0.5f * screen[1] * (float)clgame.viewport[3];
screen[0] += 0.5f * (float)clgame.viewport[2];
screen[1] += 0.5f * (float)clgame.viewport[3];
return retval;
}
@ -3938,9 +3930,6 @@ qboolean CL_LoadProgs( const char *name )
if( clgame.hInstance ) CL_UnloadProgs();
// setup globals
cl.refdef.movevars = &clgame.movevars;
// initialize PlayerMove
clgame.pmove = &gpMove;

View File

@ -666,7 +666,10 @@ static void pfnRenderScene( const ref_params_t *fd )
// to avoid division by zero
if( !fd || fd->fov_x <= 0.0f || fd->fov_y <= 0.0f )
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 )
{
return cl.refdef.intermission;
return cl.intermission;
}
qboolean CL_IsPlaybackDemo( void )
@ -125,6 +125,17 @@ char *CL_Userinfo( void )
return cls.userinfo;
}
int CL_IsDevOverviewMode( void )
{
if( gl_overview->value )
{
if( host.developer > 0 || cls.spectator )
return 1;
}
return 0;
}
/*
===============
CL_ChangeGame
@ -258,6 +269,86 @@ static float CL_LerpPoint( void )
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
@ -399,6 +490,35 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
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
@ -408,35 +528,27 @@ void CL_CreateCmd( void )
{
usercmd_t cmd;
runcmd_t *pcmd;
color24 color;
vec3_t angles;
qboolean active;
int input_override;
int i, ms;
ms = host.frametime * 1000;
if( ms > 250 ) ms = 100; // time was unreasonable
else if( ms <= 0 ) ms = 1; // keep time an actual
// store viewangles in case it's frozen
VectorCopy( cl.viewangles, angles );
CL_UpdateClientData();
if( cls.state < ca_connected || cls.state == ca_cinematic )
return;
ms = bound( 1, host.frametime * 1000, 255 );
memset( &cmd, 0, sizeof( cmd ));
input_override = 0;
CL_SetSolidEntities();
CL_PushPMStates();
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.
i = cls.netchan.outgoing_sequence & CL_UPDATE_MASK;
pcmd = &cl.commands[i];
@ -451,20 +563,16 @@ void CL_CreateCmd( void )
pcmd->sendsize = 0;
}
active = ( cls.state == ca_active && !cl.refdef.paused && !cls.demoplayback );
clgame.dllFuncs.CL_CreateMove( cl.time - cl.oldtime, &pcmd->cmd, active );
active = ( cls.state == ca_active && !cl.paused && !cls.demoplayback );
clgame.dllFuncs.CL_CreateMove( host.frametime, &pcmd->cmd, active );
CL_PopPMStates();
if( !cls.demoplayback )
{
R_LightForPoint( cl.frame.client.origin, &color, false, false, 128.0f );
pcmd->cmd.lightlevel = (color.r + color.g + color.b) / 3;
// never let client.dll calc frametime for player
// because is potential backdoor for cheating
CL_ComputeClientInterpolationAmount( &pcmd->cmd );
pcmd->cmd.lightlevel = cl.local.light_level;
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 );
@ -472,13 +580,13 @@ void CL_CreateCmd( void )
if(( cl.background && !cls.demoplayback ) || input_override || cls.changelevel )
{
VectorCopy( angles, cl.refdef.cl_viewangles );
VectorCopy( angles, pcmd->cmd.viewangles );
VectorCopy( angles, cl.viewangles );
pcmd->cmd.msec = 0;
}
// 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 )
@ -525,10 +633,7 @@ void CL_WritePacket( void )
int cmdnumber;
// don't send anything if playing back a demo
if( cls.demoplayback || cls.state == ca_cinematic )
return;
if( cls.state == ca_disconnected || cls.state == ca_connecting )
if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
return;
CL_ComputePacketLoss ();
@ -540,8 +645,8 @@ void CL_WritePacket( void )
if( cls.state == ca_connected ) numbackup = 0;
// clamp cmdrate
if( cl_cmdrate->value < 0 ) Cvar_Set( "cl_cmdrate", "0" );
else if( cl_cmdrate->value > 100 ) Cvar_Set( "cl_cmdrate", "100" );
if( cl_cmdrate->value < 0.0f ) Cvar_SetValue( "cl_cmdrate", 0.0f );
else if( cl_cmdrate->value > 100.0f ) Cvar_SetValue( "cl_cmdrate", 100.0f );
// Check to see if we can actually send this command
@ -563,6 +668,9 @@ void CL_WritePacket( void )
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(( 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.shake, 0, sizeof( clgame.shake ));
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
cl.refdef.movevars = &clgame.movevars;
cl.maxclients = 1; // allow to drawing player in menu
cl.mtime[0] = cl.mtime[1] = 1.0f; // because level starts from 1.0f second
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_loading", 0.0f );
@ -1753,7 +1862,7 @@ void CL_ReadPackets( void )
cl.lerpFrac = CL_LerpPoint();
cl.lerpBack = 1.0f - cl.lerpFrac;
cl.thirdperson = clgame.dllFuncs.CL_IsThirdPerson();
cl.local.thirdperson = clgame.dllFuncs.CL_IsThirdPerson();
#if 0
// keep cheat cvars are unchanged
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
@ -2297,13 +2384,13 @@ void Host_ClientFrame( void )
SCR_UpdateScreen ();
// update audio
S_RenderFrame( &cl.refdef );
SND_UpdateSound ();
// send a new command message to the server
CL_SendCommand();
// predict all unacknowledged movements
CL_PredictMovement();
CL_PredictMovement( false );
// adjust client time
CL_AdjustClock();
@ -2331,7 +2418,6 @@ void CL_Init( void )
if( host.type == HOST_DEDICATED )
return; // nothing running on the client
Con_Init();
CL_InitLocal();
R_Init(); // init renderer

View File

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

View File

@ -433,9 +433,10 @@ void CL_ParseMovevars( sizebuf_t *msg )
R_SetupSky( clgame.movevars.skyName );
memcpy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t ));
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
// keep features an actual!
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 )
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;
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;
pps = &cl.predict[last_predicted].playerstate;
pwd = cl.predict[last_predicted].weapondata;
ppcd = &cl.predict[last_predicted].client;
pps = &cl.predicted_frames[last_predicted].playerstate;
pwd = cl.predicted_frames[last_predicted].weapondata;
ppcd = &cl.predicted_frames[last_predicted].client;
ps = &frame->playerstate[cl.playernum];
wd = frame->weapondata;
@ -853,7 +854,7 @@ void CL_ParseClientData( sizebuf_t *msg )
// clientdata for spectators ends here
if( cls.spectator )
{
cl.predicted.health = 1;
cl.local.health = 1;
return;
}
@ -892,7 +893,10 @@ void CL_ParseClientData( sizebuf_t *msg )
// make a local copy of 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 )
{
cl.refdef.cl_viewangles[0] = MSG_ReadBitAngle( msg, 16 );
cl.refdef.cl_viewangles[1] = MSG_ReadBitAngle( msg, 16 );
cl.refdef.cl_viewangles[2] = MSG_ReadBitAngle( msg, 16 );
cl.viewangles[0] = MSG_ReadBitAngle( msg, 16 );
cl.viewangles[1] = MSG_ReadBitAngle( msg, 16 );
cl.viewangles[2] = MSG_ReadBitAngle( msg, 16 );
}
/*
@ -968,7 +972,7 @@ void CL_ParseAddAngle( sizebuf_t *msg )
float add_angle;
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 )
{
cl.refdef.crosshairangle[0] = MSG_ReadChar( msg ) * 0.2f;
cl.refdef.crosshairangle[1] = MSG_ReadChar( msg ) * 0.2f;
cl.refdef.crosshairangle[2] = 0.0f; // not used for screen space
cl.crosshairangle[0] = MSG_ReadChar( msg ) * 0.2f;
cl.crosshairangle[1] = MSG_ReadChar( msg ) * 0.2f;
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
break;
case svc_setview:
cl.refdef.viewentity = MSG_ReadWord( msg );
cl.viewentity = MSG_ReadWord( msg );
break;
case svc_sound:
case svc_ambientsound:
@ -1692,7 +1696,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_setpause:
cl.refdef.paused = ( MSG_ReadOneBit( msg ) != 0 );
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
break;
case svc_signonnum:
CL_ParseSignon( msg );
@ -1718,7 +1722,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
CL_UpdateUserinfo( msg );
break;
case svc_intermission:
cl.refdef.intermission = true;
cl.intermission = true;
break;
case svc_modelindex:
CL_PrecacheModel( msg );

View File

@ -21,6 +21,11 @@ GNU General Public License for more details.
#include "particledef.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 )
{
clgame.pmove->numtouch = 0;
@ -39,7 +44,7 @@ void CL_PushPMStates( void )
{
if( clgame.pushed )
{
MsgDev( D_ERROR, "PushPMStates called with pushed stack\n");
MsgDev( D_ERROR, "PushPMStates: stack overflow\n");
}
else
{
@ -66,19 +71,115 @@ void CL_PopPMStates( void )
}
else
{
MsgDev( D_ERROR, "PopPMStates called without stack\n");
MsgDev( D_ERROR, "PopPMStates: stack underflow\n");
}
}
/*
=============
CL_ComputePlayerOrigin
FIXME: implement
=============
===============
CL_SetLastUpdate
===============
*/
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;
predicted_player_t *player;
cl_entity_t *clent;
cl_entity_t *ent;
int i;
for( i = 0; i < MAX_CLIENTS; i++ )
@ -107,37 +208,29 @@ void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient )
if( !state->modelindex )
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 )
if( FBitSet( state->effects, EF_NODRAW ) && !bIncludeLocalClient && ( cl.playernum == i ))
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?
if( cl.playernum == i ) continue;
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 );
VectorCopy( state->origin, player->origin );
VectorCopy( state->angles, player->angles );
}
else
{
player->active = true;
player->movetype = state->movetype;
player->solid = state->solid;
player->usehull = state->usehull;
ent = CL_GetEntityByIndex( i + 1 );
// don't rewrite origin and angles of local client
if( cl.playernum == i )
continue;
CL_ComputePlayerOrigin( ent );
VectorCopy( state->origin, player->origin );
VectorCopy( state->angles, player->angles );
VectorCopy( ent->origin, player->origin );
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
CL_FinishPMove( clgame.pmove, to );
cl.predicted.lastground = clgame.pmove->onground;
if( cl.predicted.lastground > 0 && cl.predicted.lastground < clgame.pmove->numphysent )
cl.predicted.lastground = clgame.pmove->physents[cl.predicted.lastground].info;
if( clgame.pmove->onground > 0 && clgame.pmove->onground < clgame.pmove->numphysent )
cl.local.lastground = clgame.pmove->physents[clgame.pmove->onground].info;
else cl.local.lastground = clgame.pmove->onground; // world(0) or in air(-1)
clgame.dllFuncs.pfnPostRunCmd( from, to, &cmd, runfuncs, *time, random_seed );
*time += (double)cmd.msec / 1000.0;
@ -996,42 +1089,41 @@ CL_CheckPredictionError
*/
void CL_CheckPredictionError( void )
{
int frame;
vec3_t delta;
float len, maxspd;
if( !CL_IsPredicted( )) return;
int frame;
vec3_t delta;
float len, maxspd;
static int pos = 0;
// calculate the last usercmd_t we sent that the server has processed
frame = ( cls.netchan.incoming_acknowledged ) & CL_UPDATE_MASK;
// 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 );
len = VectorLength( delta );
// 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 )
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
VectorClear( cl.predicted.error );
VectorClear( cl.local.prediction_error );
}
else
{
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
VectorCopy( delta, cl.predicted.error );
VectorCopy( delta, cl.local.prediction_error );
if(( len > 0.25f ) && ( cl.maxclients > 1 ))
cl.predicted.correction_time = cl_smoothtime->value;
if(( len > MIN_CORRECTION_DISTANCE ) && ( cl.maxclients > 1 ))
cls.correction_time = cl_smoothtime->value;
}
}
@ -1073,7 +1165,7 @@ CL_PredictMovement
Sets cl.predicted.origin and cl.predicted.angles
=================
*/
void CL_PredictMovement( void )
void CL_PredictMovement( qboolean repredicting )
{
double time;
usercmd_t *ucmd;
@ -1086,18 +1178,13 @@ void CL_PredictMovement( void )
if( cls.state != ca_active ) return;
if( cls.demoplayback && cl.refdef.cmd != NULL )
if( cls.demoplayback && cl.cmd != NULL )
CL_DemoInterpolateAngles();
if( !CL_IsInGame( )) return;
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( ))
{
// fake prediction code
@ -1105,14 +1192,14 @@ void CL_PredictMovement( void )
// because cl_lw is enabled by default in Half-Life
if( !cl_lw->value )
{
cl.predicted.viewmodel = cl.frame.client.viewmodel;
cl.local.viewmodel = cl.frame.client.viewmodel;
return;
}
ack = cls.netchan.incoming_acknowledged;
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->client = cl.frame.client;
memcpy( from->weapondata, cl.frame.weapondata, sizeof( from->weapondata ));
@ -1133,7 +1220,7 @@ void CL_PredictMovement( void )
if( current_command >= outgoing_command )
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.commands[current_command_mod].processedfuncs,
@ -1146,14 +1233,14 @@ void CL_PredictMovement( void )
}
if( to )
cl.predicted.viewmodel = to->client.viewmodel;
cl.local.viewmodel = to->client.viewmodel;
return;
}
ack = cls.netchan.incoming_acknowledged;
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 ));
from->playerstate = cl.frame.playerstate[cl.playernum];
from->client = cl.frame.client;
@ -1176,7 +1263,7 @@ void CL_PredictMovement( void )
if( current_command >= outgoing_command )
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;
ucmd = &cl.commands[current_command_mod].cmd;
@ -1184,7 +1271,7 @@ void CL_PredictMovement( void )
cl.commands[current_command_mod].processedfuncs = true;
// 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;
frame++;
@ -1193,7 +1280,7 @@ void CL_PredictMovement( void )
if( to )
{
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;
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[2] - from->playerstate.origin[2] ) > 128.0f )
{
VectorCopy( to->playerstate.origin, cl.predicted.origin );
VectorCopy( to->client.velocity, cl.predicted.velocity );
VectorCopy( to->client.punchangle, cl.predicted.punchangle );
VectorCopy( to->client.view_ofs, cl.predicted.viewofs );
VectorCopy( to->playerstate.origin, cl.simorg );
VectorCopy( to->client.velocity, cl.simvel );
VectorCopy( to->client.punchangle, cl.punchangle );
VectorCopy( to->client.view_ofs, cl.viewheight );
}
else
{
@ -1224,29 +1311,29 @@ void CL_PredictMovement( void )
VectorSubtract( to->client.velocity, from->client.velocity, delta_vel );
VectorSubtract( to->client.punchangle, from->client.punchangle, delta_punch );
VectorMA( from->playerstate.origin, t, delta_origin, cl.predicted.origin );
VectorMA( from->client.velocity, t, delta_vel, cl.predicted.velocity );
VectorMA( from->client.punchangle, t, delta_punch, cl.predicted.punchangle );
VectorMA( from->playerstate.origin, t, delta_origin, cl.simorg );
VectorMA( from->client.velocity, t, delta_vel, cl.simvel );
VectorMA( from->client.punchangle, t, delta_punch, cl.punchangle );
if( from->playerstate.usehull == to->playerstate.usehull )
{
vec3_t 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.predicted.viewmodel = to->client.viewmodel;
cl.predicted.usehull = to->playerstate.usehull;
cl.local.waterlevel = to->client.waterlevel;
cl.local.viewmodel = to->client.viewmodel;
cl.local.usehull = to->playerstate.usehull;
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.predicted.moving = 0;
cl.local.onground = cl.local.lastground;
cl.local.moving = 0;
if( ent )
{
@ -1257,42 +1344,42 @@ void CL_PredictMovement( void )
if( VectorLength( delta ) > 0.0f )
{
cl.predicted.correction_time = 0;
cl.predicted.moving = 1;
cls.correction_time = 0;
cl.local.moving = 1;
}
}
}
else
{
cl.predicted.onground = -1;
cl.predicted.moving = 0;
cl.local.onground = -1;
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;
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 )
Cvar_SetValue( "cl_smoothtime", 0.1 );
if( cl.predicted.correction_time < 0 )
cl.predicted.correction_time = 0;
if( cls.correction_time < 0 )
cls.correction_time = 0;
if( cl_smoothtime->value <= cl.predicted.correction_time )
cl.predicted.correction_time = cl_smoothtime->value;
if( cl_smoothtime->value <= cls.correction_time )
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++ )
{
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();
}

View File

@ -22,8 +22,6 @@ GNU General Public License for more details.
convar_t *scr_centertime;
convar_t *scr_loading;
convar_t *scr_download;
convar_t *scr_width;
convar_t *scr_height;
convar_t *scr_viewsize;
convar_t *cl_testlights;
convar_t *cl_allow_levelshots;
@ -100,7 +98,7 @@ void SCR_DrawFPS( int height )
}
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",
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;
Con_DrawStringLen( NULL, NULL, &height );
@ -180,7 +178,7 @@ void SCR_RSpeeds( void )
char *p, *start, *end;
rgba_t color;
x = scr_width->value - 340;
x = glState.width - 340;
y = 64;
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 );
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 );
}
}
@ -346,7 +344,7 @@ SCR_DirtyScreen
void SCR_DirtyScreen( void )
{
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 )
return; // nothing disturbed
top = cl.refdef.viewport[1];
bottom = top + cl.refdef.viewport[3] - 1;
left = cl.refdef.viewport[0];
right = left + cl.refdef.viewport[2] - 1;
top = RI.viewport[1];
bottom = top + RI.viewport[3] - 1;
left = RI.viewport[0];
right = left + RI.viewport[2] - 1;
if( clear.y1 < top )
{
@ -587,8 +585,8 @@ void SCR_VidInit( void )
memset( &clgame.centerPrint, 0, sizeof( clgame.centerPrint ));
// update screen sizes for menu
gameui.globals->scrWidth = scr_width->value;
gameui.globals->scrHeight = scr_height->value;
gameui.globals->scrWidth = glState.width;
gameui.globals->scrHeight = glState.height;
SCR_RebuildGammaTable();
VGui_Startup ();

View File

@ -2517,7 +2517,7 @@ void CL_UpdateFlashlight( cl_entity_t *pEnt )
if(( pEnt->index - 1 ) == cl.playernum )
{
// get the predicted angles
AngleVectors( cl.refdef.cl_viewangles, forward, NULL, NULL );
AngleVectors( cl.viewangles, forward, NULL, NULL );
}
else
{
@ -2534,7 +2534,7 @@ void CL_UpdateFlashlight( cl_entity_t *pEnt )
VectorClear( view_ofs );
if(( pEnt->index - 1 ) == cl.playernum )
VectorCopy( cl.refdef.viewheight, view_ofs );
VectorCopy( cl.viewheight, view_ofs );
VectorAdd( pEnt->origin, view_ofs, vecSrc );
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
@ -2584,7 +2584,7 @@ void CL_TestLights( void )
f = 64 * ( i / 4) + 128;
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.g = ((((i % 6) + 1) & 2)>>1) * 255;

View File

@ -205,7 +205,7 @@ qboolean SCR_DrawCinematic( void )
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;
}

View File

@ -20,6 +20,123 @@ GNU General Public License for more details.
#include "gl_local.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
===============
*/
void V_MergeOverviewRefdef( void )
void V_RefParamsApplyOverview( ref_params_t *fd )
{
ref_overview_t *ov = &clgame.overView;
float aspect;
float size_x, size_y;
vec2_t mins, maxs;
if( !gl_overview->value ) return;
if( !CL_IsDevOverviewMode( ))
return;
// NOTE: Xash3D may use 16:9 or 16:10 aspects
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 );
}
VectorCopy( ov->origin, cl.refdef.vieworg );
cl.refdef.vieworg[2] = ov->zFar + ov->zNear;
Vector2Copy( cl.refdef.vieworg, mins );
Vector2Copy( cl.refdef.vieworg, maxs );
VectorCopy( ov->origin, fd->vieworg );
fd->vieworg[2] = ov->zFar + ov->zNear;
Vector2Copy( fd->vieworg, mins );
Vector2Copy( fd->vieworg, maxs );
mins[!ov->rotated] += ov->xLeft;
maxs[!ov->rotated] += ov->xRight;
mins[ov->rotated] += ov->xTop;
maxs[ov->rotated] += ov->xBottom;
cl.refdef.viewangles[0] = 90.0f;
cl.refdef.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[0] = 90.0f;
fd->viewangles[1] = 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 );
}
/*
===============
V_CalcViewRect
calc frame rectangle (Quake1 style)
===============
=============
V_GetRefParams
=============
*/
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 )
sb_lines = 0; // no status bar at all
else if( scr_viewsize->value >= 110 )
sb_lines = 24; // no inventory
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;
// part2: really used updates
VectorCopy( fd->crosshairangle, cl.crosshairangle );
VectorCopy( fd->cl_viewangles, cl.viewangles );
cl.intermission = fd->intermission; // Quake Remake compatibility
}
/*
@ -203,7 +238,7 @@ qboolean V_PreRender( void )
return false;
}
R_BeginFrame( !cl.refdef.paused );
R_BeginFrame( !cl.paused );
return true;
}
@ -218,34 +253,50 @@ V_RenderView
*/
void V_RenderView( void )
{
ref_params_t rp;
int viewnum = 0;
if( !cl.video_prepped || ( UI_IsVisible() && !cl.background ))
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;
R_ClearScene ();
CL_AddEntities ();
V_SetupRefDef ();
}
V_CalcViewRect (); // compute viewport rectangle
V_SetRefParams( &rp );
V_SetupViewModel ();
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
do
{
clgame.dllFuncs.pfnCalcRefdef( &cl.refdef );
V_MergeOverviewRefdef();
R_RenderFrame( &cl.refdef, true );
cl.refdef.onlyClientDraw = false;
} while( cl.refdef.nextView );
clgame.dllFuncs.pfnCalcRefdef( &rp );
V_RefParamsApplyOverview( &rp );
V_GetRefParams( &rp );
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
SV_DrawDebugTriangles ();
GL_BackendEndFrame ();
}
/*

View File

@ -24,6 +24,7 @@ GNU General Public License for more details.
#include "mod_local.h"
#include "pm_defs.h"
#include "pm_movevars.h"
#include "ref_params.h"
#include "render_api.h"
#include "cdll_exp.h"
#include "screenfade.h"
@ -101,27 +102,45 @@ extern int CL_UPDATE_BACKUP;
#define SIGNONS 2 // signon messages to receive before connected
#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_clientframetime() (cl.time - cl.oldtime)
typedef struct
{
vec3_t origin; // generated by CL_PredictMovement
vec3_t viewofs;
vec3_t velocity;
vec3_t punchangle;
vec3_t origins[CMD_BACKUP];
vec3_t error;
// got from prediction system
vec3_t predicted_origins[CMD_BACKUP];
vec3_t prediction_error;
vec3_t lastorigin;
double correction_time;
int lastground;
// interp info
float interp_amount;
// misc local info
qboolean thirdperson;
float idealpitch;
int viewmodel;
int health; // client health
int onground;
int light_level;
int waterlevel;
int usehull;
int moving;
int lastground;
} cl_predicted_data_t; // data we got from prediction system
int pushmsec;
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
// server map change
@ -139,6 +158,7 @@ typedef struct
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 force_refdef; // vid has changed, so we can't use a paused refdef
qboolean paused;
int delta_sequence; // acknowledged sequence number
@ -148,20 +168,17 @@ typedef struct
int last_incoming_sequence;
qboolean send_reply;
qboolean thirdperson;
qboolean background; // not real game, just a background
qboolean first_frame; // first rendering frame
qboolean proxy_redirect; // spectator stuff
uint checksum; // for catching cheater maps
client_data_t data; // some clientdata holds
frame_t frame; // received from server
frame_t frames[MULTIPLAYER_BACKUP]; // alloced on svc_serverdata
runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds
local_state_t predict[MULTIPLAYER_BACKUP]; // local client state
frame_t frames[MULTIPLAYER_BACKUP]; // alloced on svc_serverdata
runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds
local_state_t predicted_frames[MULTIPLAYER_BACKUP]; // local client state
double time; // this is the time value that the client
// is rendering at. always <= cls.realtime
@ -172,14 +189,27 @@ typedef struct
float lerpFrac; // interpolation value
float lerpBack; // invert interpolation value
float timedelta; // floating delta between two updates
ref_params_t refdef; // shared refdef
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;
// predicting stuff
cl_predicted_data_t predicted; // generated from CL_PredictMovement
// predicting stuff but not only...
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
int playernum;
@ -196,11 +226,6 @@ typedef struct
cl_entity_t *world;
model_t *worldmodel; // pointer to world
// weapon predict stuff
float scr_fov;
float weaponstarttime;
int weaponsequence;
} client_t;
/*
@ -298,12 +323,11 @@ typedef struct
typedef struct cl_predicted_player_s
{
int flags;
int movetype;
int solid;
int usehull;
qboolean active;
vec3_t origin; // predicted origin
vec3_t origin; // interpolated origin
vec3_t angles;
} predicted_player_t;
@ -411,6 +435,8 @@ typedef struct
model_t sprites[MAX_IMAGES]; // client spritetextures
int load_sequence; // for unloading unneeded sprites
int viewport[4]; // viewport sizes
client_draw_t ds; // draw2d stuff (hud, weaponmenu etc)
screenfade_t fade; // screen fade
screen_shake_t shake; // screen shake
@ -499,6 +525,7 @@ typedef struct
float nextcmdtime; // when can we send the next command packet?
int lastoutgoingcommand; // sequence number of last outgoing command
int lastupdate_sequence; // prediction stuff
// internal images
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]
predicted_player_t predicted_players[MAX_CLIENTS];
double correction_time;
scrshot_t scrshot_request; // request for screen shot
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_WriteUsercmd( sizebuf_t *msg, int from, int to );
void CL_GetChallengePacket( void );
int CL_IsDevOverviewMode( void );
void CL_PingServers_f( void );
void CL_SignonReply( void );
void CL_ClearState( void );
@ -755,7 +784,6 @@ void V_Shutdown( void );
qboolean V_PreRender( void );
void V_PostRender( void );
void V_RenderView( void );
void V_SetupRefDef( void );
//
// cl_pmove.c
@ -763,7 +791,7 @@ void V_SetupRefDef( void );
void CL_SetSolidEntities( void );
void CL_SetSolidPlayers( int playernum );
void CL_InitClientMove( void );
void CL_PredictMovement( void );
void CL_PredictMovement( qboolean repredicting );
void CL_CheckPredictionError( void );
qboolean CL_IsPredicted( void );
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 );
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 );
void CL_SetLastUpdate( void );
void CL_RedoPrediction( void );
void CL_ClearPhysEnts( void );
void CL_PushPMStates( 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 );
qboolean CL_GetEntitySpatialization( struct channel_s *ch );
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
void CL_ComputePlayerOrigin( cl_entity_t *clent );
void CL_UpdateEntityFields( cl_entity_t *ent );
qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void );
@ -841,7 +872,6 @@ void CL_RunLightStyles( void );
//
extern convar_t *con_fontsize;
qboolean Con_Visible( void );
void Con_Init( void );
void Con_VidInit( void );
void Con_Shutdown( 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_FadeMusicVolume( float fadePercent );
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 );
//

View File

@ -48,11 +48,9 @@ qboolean R_SpeedsMessage( char *out, size_t size )
GL_BackendStartFrame
==============
*/
void GL_BackendStartFrame( const ref_params_t *fd )
void GL_BackendStartFrame( void )
{
if( !fd->nextView ) r_speeds_msg[0] = '\0';
if( !RI.drawWorld ) R_Set2DMode( false );
r_speeds_msg[0] = '\0';
}
/*
@ -60,12 +58,9 @@ void GL_BackendStartFrame( const ref_params_t *fd )
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( !RI.drawWorld ) R_Set2DMode( true );
if( r_speeds->value <= 0 || !RI.drawWorld || fd->nextView )
if( r_speeds->value <= 0 || !RI.drawWorld )
return;
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 ));
// use client vieworg
if( !vieworg ) vieworg = cl.refdef.vieworg;
if( !vieworg ) vieworg = RI.vieworg;
for( i = 0; i < 6; i++ )
{

View File

@ -109,7 +109,7 @@ static qboolean ComputeBeamEntPosition( int beamEnt, vec3_t pt )
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
pEnt = &clgame.viewent;
@ -1230,13 +1230,13 @@ void CL_UpdateBeam( BEAM *pbeam, float frametime )
pbeam->freq += frametime;
// Generate fractal noise
if( CL_IsInGame() && !cl.refdef.paused )
if( CL_IsInGame() && !cl.paused )
{
rgNoise[0] = 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 )
{

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 ))
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 ))
return 1;

View File

@ -19,7 +19,6 @@ GNU General Public License for more details.
#include "gl_export.h"
#include "com_model.h"
#include "cl_entity.h"
#include "ref_params.h"
#include "render_api.h"
#include "protocol.h"
#include "dlight.h"
@ -103,9 +102,10 @@ typedef struct
qboolean drawWorld; // ignore world for drawing PlayerModel
qboolean thirdPerson; // thirdperson camera is enabled
qboolean isSkyVisible; // sky is visible
qboolean onlyClientDraw; // disabled by client request
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;
model_t *currentmodel;
@ -118,6 +118,7 @@ typedef struct
mleaf_t *oldviewleaf;
vec3_t pvsorigin;
vec3_t vieworg; // locked vieworigin
vec3_t viewangles;
vec3_t vforward;
vec3_t vright;
vec3_t vup;
@ -236,7 +237,6 @@ typedef struct
} ref_speeds_t;
extern ref_speeds_t r_stats;
extern ref_params_t r_lastRefdef;
extern ref_instance_t RI;
extern ref_globals_t tr;
@ -255,8 +255,8 @@ extern struct particle_s *cl_free_trails;
//
// gl_backend.c
//
void GL_BackendStartFrame( const ref_params_t *fd );
void GL_BackendEndFrame( const ref_params_t *fd );
void GL_BackendStartFrame( void );
void GL_BackendEndFrame( void );
void GL_CleanUpTextureUnits( int last );
void GL_Bind( GLint tmu, GLenum texnum );
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_EndDrawMirror( void );
void R_DrawMirrors( void );
void R_FindMirrors( const ref_params_t *fd );
void R_FindMirrors( void );
//
// gl_refrag.c
@ -351,7 +351,7 @@ int R_CountDlights( void );
//
void R_ClearScene( 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_TranslateForEntity( 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 );
void VID_RestoreGamma( void );
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_ClearScene( void );
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].type = PLANE_NONAXIAL;
RI.refdef.viewangles[0] = anglemod( angles[0] );
RI.refdef.viewangles[1] = anglemod( angles[1] );
RI.refdef.viewangles[2] = anglemod( angles[2] );
VectorCopy( origin, RI.refdef.vieworg );
RI.viewangles[0] = anglemod( angles[0] );
RI.viewangles[1] = anglemod( angles[1] );
RI.viewangles[2] = anglemod( angles[2] );
VectorCopy( origin, RI.vieworg );
VectorCopy( origin, RI.cullorigin );
// put pvsorigin before the mirror plane to avoid get full visibility on world mirrors
@ -305,7 +305,7 @@ void R_DrawMirrors( void )
}
tr.framecount++;
R_RenderScene( &RI.refdef );
R_RenderScene();
r_stats.c_mirror_passes++;
es->mirrortexturenum = R_AllocateMirrorTexture();
@ -584,51 +584,16 @@ R_FindMirrors
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.refdef.onlyClientDraw || !cl.worldmodel )
if( !world.has_mirrors || RI.drawOrtho || !RI.drawWorld || RI.onlyClientDraw || !cl.worldmodel )
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
if( cl.thirdperson )
{
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_SetupFrustum ();
R_FindViewLeaf ();
R_MarkLeaves ();
VectorCopy( RI.cullorigin, tr.modelorg );

View File

@ -37,6 +37,7 @@ void CL_RunLightStyles( void )
{
int i, k, flight, clight;
float l, c, lerpfrac, backlerp;
float frametime = (cl.time - cl.oldtime);
float scale;
lightstyle_t *ls;
@ -56,8 +57,8 @@ void CL_RunLightStyles( void )
continue;
}
if( !RI.refdef.paused && RI.refdef.frametime <= 0.1f )
ls->time += RI.refdef.frametime; // evaluate local time
if( !cl.paused && frametime <= 0.1f )
ls->time += frametime; // evaluate local time
flight = (int)Q_floor( 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;
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
if( !cl.worldmodel || !cl.worldmodel->lightdata )
{
ambientLight->r = TextureToTexGamma( cl.refdef.movevars->skycolor_r );
ambientLight->g = TextureToTexGamma( cl.refdef.movevars->skycolor_g );
ambientLight->b = TextureToTexGamma( cl.refdef.movevars->skycolor_b );
ambientLight->r = TextureToTexGamma( clgame.movevars.skycolor_r );
ambientLight->g = TextureToTexGamma( clgame.movevars.skycolor_g );
ambientLight->b = TextureToTexGamma( clgame.movevars.skycolor_b );
return;
}

View File

@ -27,8 +27,7 @@ GNU General Public License for more details.
msurface_t *r_debug_surface;
const char *r_debug_hitbox;
float gldepthmin, gldepthmax;
ref_params_t r_lastRefdef;
ref_instance_t RI, prevRI;
ref_instance_t RI;
static int R_RankForRenderMode( cl_entity_t *ent )
{
@ -271,16 +270,16 @@ int R_ComputeFxBlend( cl_entity_t *e )
switch( e->curstate.renderfx )
{
case kRenderFxPulseSlowWide:
blend = renderAmt + 0x40 * sin( RI.refdef.time * 2 + offset );
blend = renderAmt + 0x40 * sin( cl.time * 2 + offset );
break;
case kRenderFxPulseFastWide:
blend = renderAmt + 0x40 * sin( RI.refdef.time * 8 + offset );
blend = renderAmt + 0x40 * sin( cl.time * 8 + offset );
break;
case kRenderFxPulseSlow:
blend = renderAmt + 0x10 * sin( RI.refdef.time * 2 + offset );
blend = renderAmt + 0x10 * sin( cl.time * 2 + offset );
break;
case kRenderFxPulseFast:
blend = renderAmt + 0x10 * sin( RI.refdef.time * 8 + offset );
blend = renderAmt + 0x10 * sin( cl.time * 8 + offset );
break;
// JAY: HACK for now -- not time based
case kRenderFxFadeSlow:
@ -308,35 +307,35 @@ int R_ComputeFxBlend( cl_entity_t *e )
blend = renderAmt;
break;
case kRenderFxStrobeSlow:
blend = 20 * sin( RI.refdef.time * 4 + offset );
blend = 20 * sin( cl.time * 4 + offset );
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxStrobeFast:
blend = 20 * sin( RI.refdef.time * 16 + offset );
blend = 20 * sin( cl.time * 16 + offset );
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
case kRenderFxStrobeFaster:
blend = 20 * sin( RI.refdef.time * 36 + offset );
blend = 20 * sin( cl.time * 36 + offset );
if( blend < 0 ) blend = 0;
else blend = renderAmt;
break;
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;
else blend = renderAmt;
break;
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;
else blend = renderAmt;
break;
case kRenderFxHologram:
case kRenderFxDistort:
VectorCopy( e->origin, tmp );
VectorSubtract( tmp, RI.refdef.vieworg, tmp );
dist = DotProduct( tmp, RI.refdef.forward );
VectorSubtract( tmp, RI.vieworg, tmp );
dist = DotProduct( tmp, RI.vforward );
// Turn off distance fade
if( e->curstate.renderfx == kRenderFxDistort )
@ -515,7 +514,7 @@ R_GetFarClip
static float R_GetFarClip( void )
{
if( cl.worldmodel && RI.drawWorld )
return cl.refdef.movevars->zmax * 1.5f;
return clgame.movevars.zmax * 1.73f;
return 2048.0f;
}
@ -578,12 +577,23 @@ void R_SetupFrustum( void )
vec3_t farPoint;
int i;
// 0 - left
// 1 - right
// 2 - down
// 3 - up
// 4 - farclip
// 5 - nearclip
// first we need to compute FOV and other things that needs for frustum properly work
RI.fov_y = V_CalcFov( &RI.fov_x, RI.viewport[2], RI.viewport[3] );
// adjust FOV for widescreen
if( glState.wideScreen && RI.drawWorld && r_adjust_fov->value )
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 )
{
@ -591,14 +601,21 @@ void R_SetupFrustum( void )
return;
}
// 0 - left
// 1 - right
// 2 - down
// 3 - up
// 4 - farclip
// 5 - nearclip
// 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
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
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
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
VectorNegate( RI.cull_vforward, RI.frustum[4].normal );
@ -620,7 +637,7 @@ void R_SetupFrustum( void )
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;
@ -637,10 +654,10 @@ static void R_SetupProjectionMatrix( const ref_params_t *fd, matrix4x4 m )
zNear = 4.0f;
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;
xMax = zNear * tan( fd->fov_x * M_PI / 360.0 );
xMax = zNear * tan( RI.fov_x * M_PI / 360.0 );
xMin = -xMax;
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
=============
*/
static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m )
static void R_SetupModelviewMatrix( matrix4x4 m )
{
#if 0
Matrix4x4_LoadIdentity( m );
@ -660,10 +677,10 @@ static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m )
#else
Matrix4x4_CreateModelview( m );
#endif
Matrix4x4_ConcatRotate( m, -fd->viewangles[2], 1, 0, 0 );
Matrix4x4_ConcatRotate( m, -fd->viewangles[0], 0, 1, 0 );
Matrix4x4_ConcatRotate( m, -fd->viewangles[1], 0, 0, 1 );
Matrix4x4_ConcatTranslate( m, -fd->vieworg[0], -fd->vieworg[1], -fd->vieworg[2] );
Matrix4x4_ConcatRotate( m, -RI.viewangles[2], 1, 0, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[0], 0, 1, 0 );
Matrix4x4_ConcatRotate( m, -RI.viewangles[1], 0, 0, 1 );
Matrix4x4_ConcatTranslate( m, -RI.vieworg[0], -RI.vieworg[1], -RI.vieworg[2] );
}
/*
@ -753,28 +770,10 @@ R_SetupFrame
*/
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
RI.viewplanedist = DotProduct( RI.vieworg, RI.vforward );
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 );
}
// prepare events for viewmodel (e.g. muzzleflashes)
R_RunViewmodelEvents();
// 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 )
{
if( RI.refdef.waterlevel >= 3 )
if( RP_NORMALPASS() && ( cl.local.waterlevel >= 3 ))
{
float f;
f = sin( cl.time * 0.4f * ( M_PI * 2.7f ));
RI.refdef.fov_x += f;
RI.refdef.fov_y -= f;
RI.fov_x += f;
RI.fov_y -= f;
}
R_SetupModelviewMatrix( &RI.refdef, RI.worldviewMatrix );
R_SetupProjectionMatrix( &RI.refdef, RI.projectionMatrix );
R_SetupModelviewMatrix( RI.worldviewMatrix );
R_SetupProjectionMatrix( RI.projectionMatrix );
// if( RI.params & RP_MIRRORVIEW ) RI.projectionMatrix[0][0] = -RI.projectionMatrix[0][0];
Matrix4x4_Concat( RI.worldviewProjectionMatrix, RI.projectionMatrix, RI.worldviewMatrix );
@ -965,7 +964,7 @@ static void R_CheckFog( void )
RI.fogEnabled = false;
if( RI.refdef.waterlevel < 2 || !RI.drawWorld || !RI.viewleaf )
if( cl.local.waterlevel < 2 || !RI.drawWorld || !RI.viewleaf )
return;
ent = CL_GetWaterEntity( RI.vieworg );
@ -979,7 +978,7 @@ static void R_CheckFog( void )
return;
}
if( RI.refdef.waterlevel < 3 ) return;
if( cl.local.waterlevel < 3 ) return;
if( !IsLiquidContents( RI.cached_contents ) && IsLiquidContents( cnt ))
{
@ -1034,7 +1033,7 @@ R_DrawFog
*/
void R_DrawFog( void )
{
if( !RI.fogEnabled || RI.refdef.onlyClientDraw )
if( !RI.fogEnabled || RI.onlyClientDraw )
return;
pglEnable( GL_FOG );
@ -1059,11 +1058,8 @@ void R_DrawEntitiesOnList( void )
R_DrawFog ();
// 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.currentmodel = RI.currententity->model;
@ -1086,7 +1082,7 @@ void R_DrawEntitiesOnList( void )
}
}
if( !RI.refdef.onlyClientDraw )
if( !RI.onlyClientDraw )
{
CL_DrawBeams( false );
}
@ -1105,11 +1101,8 @@ void R_DrawEntitiesOnList( void )
glState.drawTrans = true;
// 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.currentmodel = RI.currententity->model;
@ -1138,7 +1131,7 @@ void R_DrawEntitiesOnList( void )
clgame.dllFuncs.pfnDrawTransparentTriangles ();
}
if( !RI.refdef.onlyClientDraw )
if( !RI.onlyClientDraw )
{
CL_DrawBeams( true );
CL_DrawParticles();
@ -1161,20 +1154,18 @@ void R_DrawEntitiesOnList( void )
================
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 )
Host_Error( "R_RenderView: NULL worldmodel\n" );
R_PushDlights();
R_SetupFrame();
R_SetupFrustum();
R_SetupFrame();
R_SetupGL();
R_Clear( ~0 );
@ -1238,12 +1229,43 @@ void R_BeginFrame( qboolean clearScene )
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
===============
*/
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 )
return;
@ -1264,26 +1286,7 @@ void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld )
}
}
if( drawWorld ) r_lastRefdef = *fd;
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];
R_SetupRefParams( fd, drawWorld, fov );
if( gl_finish->value && drawWorld )
pglFinish();
@ -1291,13 +1294,11 @@ void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld )
if( gl_allow_mirrors->value )
{
// render mirrors
R_FindMirrors( fd );
R_FindMirrors ();
R_DrawMirrors ();
}
R_RenderScene( fd );
GL_BackendEndFrame( fd );
R_RenderScene();
}
/*
@ -1324,34 +1325,33 @@ R_DrawCubemapView
*/
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( origin, angles, size ))
return;
}
fd = &RI.refdef;
*fd = r_lastRefdef;
fd->time = 0;
fd->viewport[0] = 0;
fd->viewport[1] = 0;
fd->viewport[2] = size;
fd->viewport[3] = size;
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];
// basic params
RI.params = RP_NONE;
RI.drawWorld = true;
RI.thirdPerson = RI.drawOrtho = false;
RI.clipFlags = 15; // top, bottom, left, right
RI.onlyClientDraw = false;
RI.farClip = 0;
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
}

View File

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

View File

@ -222,7 +222,7 @@ void GL_SetupFogColorForSurfaces( void )
vec3_t fogColor;
float factor, div;
if(( !RI.fogEnabled && !RI.fogCustom ) || RI.refdef.onlyClientDraw || !RI.currententity )
if(( !RI.fogEnabled && !RI.fogCustom ) || RI.onlyClientDraw || !RI.currententity )
return;
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
@ -242,7 +242,7 @@ void GL_SetupFogColorForSurfaces( void )
void GL_ResetFogColor( void )
{
// restore fog here
if(( RI.fogEnabled || RI.fogCustom ) && !RI.refdef.onlyClientDraw )
if(( RI.fogEnabled || RI.fogCustom ) && !RI.onlyClientDraw )
pglFogfv( GL_FOG_COLOR, RI.fogColor );
}
@ -742,8 +742,8 @@ void DrawGLPoly( glpoly_t *p, float xScale, float yScale )
flAngle = ( flConveyorSpeed >= 0 ) ? 180 : 0;
SinCos( flAngle * ( M_PI / 180.0f ), &sy, &cy );
sOffset = RI.refdef.time * cy * flRate;
tOffset = RI.refdef.time * sy * flRate;
sOffset = cl.time * cy * flRate;
tOffset = cl.time * sy * flRate;
// make sure that we are positive
if( sOffset < 0.0f ) sOffset += 1.0f + -(int)sOffset;
@ -988,7 +988,7 @@ void R_RenderFullbrights( void )
if( !draw_fullbrights )
return;
if( RI.fogEnabled && !RI.refdef.onlyClientDraw )
if( RI.fogEnabled && !RI.onlyClientDraw )
pglDisable( GL_FOG );
pglEnable( GL_BLEND );
@ -1021,7 +1021,7 @@ void R_RenderFullbrights( void )
draw_fullbrights = false;
// restore for here
if( RI.fogEnabled && !RI.refdef.onlyClientDraw )
if( RI.fogEnabled && !RI.onlyClientDraw )
pglEnable( GL_FOG );
}
@ -1283,7 +1283,7 @@ void R_DrawTextureChains( void )
if( !s || ( i == tr.skytexturenum ))
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
for( ; s != NULL; s = s->texturechain )
@ -1305,11 +1305,11 @@ void R_DrawWaterSurfaces( void )
msurface_t *s;
texture_t *t;
if( !RI.drawWorld || RI.refdef.onlyClientDraw )
if( !RI.drawWorld || RI.onlyClientDraw )
return;
// non-transparent water is already drawed
if( cl.refdef.movevars->wateralpha >= 1.0f )
if( clgame.movevars.wateralpha >= 1.0f )
return;
// restore worldmodel
@ -1324,7 +1324,7 @@ void R_DrawWaterSurfaces( void )
pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
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++ )
{
@ -1909,7 +1909,7 @@ void R_DrawWorld( void )
RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model;
if( !RI.drawWorld || RI.refdef.onlyClientDraw )
if( !RI.drawWorld || RI.onlyClientDraw )
return;
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 )
{
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
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
// or change model on replace delta-entity
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
lerpFrac = 1.0f;
}
if( ent->latched.prevanimtime < RI.refdef.time )
if( ent->latched.prevanimtime < cl.time )
{
if( frame != ent->latched.prevblending[1] )
{
ent->latched.prevblending[0] = ent->latched.prevblending[1];
ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f;
}
else lerpFrac = (RI.refdef.time - ent->latched.prevanimtime) * 10;
else lerpFrac = (cl.time - ent->latched.prevanimtime) * 10;
}
else
{
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f;
}
}
@ -586,7 +586,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
{
// reset interpolation on change model
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f;
}
@ -601,7 +601,7 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
jinterval = pintervals[1] - pintervals[0];
time = RI.refdef.time;
time = cl.time;
jtime = 0.0f;
// 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
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 )
{
@ -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
// or change model on replace delta-entity
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
lerpFrac = 1.0f;
}
if( ent->latched.prevanimtime < RI.refdef.time )
if( ent->latched.prevanimtime < cl.time )
{
if( frame != ent->latched.prevblending[1] )
{
ent->latched.prevblending[0] = ent->latched.prevblending[1];
ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
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
{
ent->latched.prevblending[0] = ent->latched.prevblending[1] = frame;
ent->latched.prevanimtime = RI.refdef.time;
ent->latched.prevanimtime = cl.time;
lerpFrac = 0.0f;
}
}
@ -816,9 +816,9 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, int *alpha, float *psc
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
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
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_shadowalpha = { "r_shadowalpha", "0.5", 0, 0.8f };
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 vec3_t g_chrome_origin;
static vec2_t g_chrome[MAXSTUDIOVERTS]; // texture coords for surface normals
@ -138,8 +136,6 @@ R_StudioInit
*/
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_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" );
@ -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
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 );
g_nStudioCount = 0;
@ -412,8 +397,8 @@ pfnGetAliasScale
*/
static void pfnGetAliasScale( float *x, float *y )
{
if( x ) *x = aliasXscale;
if( y ) *y = aliasYscale;
if( x ) *x = 1.0f;
if( y ) *y = 1.0f;
}
/*
@ -446,7 +431,7 @@ pfnStudioGetAliasTransform
*/
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.
// 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.
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 );
// Msg( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, RI.refdef.time );
f = ( cl.time - e->curstate.animtime ) / ( e->curstate.animtime - e->latched.prevanimtime );
// Msg( "%4.2f %.2f %.2f\n", f, e->curstate.animtime, cl.time );
}
if( m_fDoInterp )
@ -601,8 +586,8 @@ float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc )
if( m_fDoInterp )
{
if( RI.refdef.time < e->curstate.animtime ) dfdt = 0.0;
else dfdt = (RI.refdef.time - e->curstate.animtime) * e->curstate.framerate * pseqdesc->fps;
if( cl.time < e->curstate.animtime ) dfdt = 0.0;
else dfdt = (cl.time - e->curstate.animtime) * e->curstate.framerate * pseqdesc->fps;
}
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 ))
{
dadt = ( RI.refdef.time - e->curstate.animtime ) / 0.1f;
dadt = ( cl.time - e->curstate.animtime ) / 0.1f;
if( dadt > 2.0f ) dadt = 2.0f;
}
return dadt;
@ -729,7 +714,7 @@ void R_StudioFxTransform( cl_entity_t *ent, matrix3x4 transform )
{
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%
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
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 );
}
else
@ -1306,7 +1291,7 @@ void R_StudioSetupChrome( float *pchrome, int bone, vec3_t normal )
float angle, sr, cr;
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 );
for( i = 0; i < 3; i++ )
@ -1425,10 +1410,8 @@ void R_StudioGetShadowImpactAndDir( void )
float angle;
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
VectorAngles( (float *)&cl.refdef.movevars->skyvec_x, skyAngles );
VectorAngles( (float *)&clgame.movevars.skyvec_x, skyAngles );
angle = skyAngles[YAW] / 180 * M_PI;
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 );
// setup light dir
if( cl.refdef.movevars )
{
// pre-defined light vector
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 );
plight->lightvec[0] = clgame.movevars.skyvec_x;
plight->lightvec[1] = clgame.movevars.skyvec_y;
plight->lightvec[2] = clgame.movevars.skyvec_z;
if( VectorIsNull( plight->lightvec ))
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++ )
{
if( dl->die < RI.refdef.time || !dl->radius )
if( dl->die < cl.time || !dl->radius )
continue;
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++ )
{
if( el->die < RI.refdef.time || !el->radius )
if( el->die < cl.time || !el->radius )
continue;
VectorSubtract( el->origin, origin, direction );
@ -2833,7 +2811,7 @@ void R_StudioEstimateGait( entity_state_t *pplayer )
vec3_t est_velocity;
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 )
{
@ -2902,7 +2880,7 @@ void R_StudioProcessGait( entity_state_t *pplayer )
RI.currententity->latched.prevblending[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 );
// calc side to side turning
@ -3309,7 +3287,7 @@ R_RunViewmodelEvents
*/
void R_RunViewmodelEvents( void )
{
if( cl.refdef.nextView || cl.thirdperson || RI.params & RP_NONVIEWERREF )
if( cl.local.thirdperson || RI.params & RP_NONVIEWERREF )
return;
if( !Mod_Extradata( clgame.viewent.model ))
@ -3319,9 +3297,9 @@ void R_RunViewmodelEvents( void )
RI.currentmodel = RI.currententity->model;
if( !RI.currentmodel ) return;
if( !cl.weaponstarttime ) cl.weaponstarttime = cl.time;
RI.currententity->curstate.animtime = cl.weaponstarttime;
RI.currententity->curstate.sequence = cl.weaponsequence;
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = cl.time;
RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.local.weaponsequence;
pStudioDraw->StudioDrawModel( STUDIO_EVENTS );
@ -3336,14 +3314,14 @@ R_DrawViewModel
*/
void R_DrawViewModel( void )
{
if( RI.refdef.onlyClientDraw || r_drawviewmodel->value == 0 )
if( RI.onlyClientDraw || r_drawviewmodel->value == 0 )
return;
// 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;
if( cl.refdef.nextView || RI.params & RP_NONVIEWERREF )
if( RI.params & RP_NONVIEWERREF )
return;
if( !Mod_Extradata( clgame.viewent.model ))
@ -3362,9 +3340,9 @@ void R_DrawViewModel( void )
if( r_lefthand->value == 1 || g_iBackFaceCull )
GL_FrontFace( !glState.frontFace );
if( !cl.weaponstarttime ) cl.weaponstarttime = cl.time;
RI.currententity->curstate.animtime = cl.weaponstarttime;
RI.currententity->curstate.sequence = cl.weaponsequence;
if( !cl.local.weaponstarttime ) cl.local.weaponstarttime = cl.time;
RI.currententity->curstate.animtime = cl.local.weaponstarttime;
RI.currententity->curstate.sequence = cl.local.weaponsequence;
pStudioDraw->StudioDrawModel( STUDIO_RENDER );

View File

@ -1062,6 +1062,19 @@ void VID_RestoreGamma( void )
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
@ -1155,9 +1168,6 @@ void R_SaveVideoMode( int vid_mode )
glState.width = vidmode[mode].width;
glState.height = vidmode[mode].height;
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
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 );
width = scr_width->value;
height = scr_height->value;
width = glState.width;
height = glState.height;
// check our desktop attributes
hDC = GetDC( GetDesktopWindow( ));
@ -1708,7 +1718,7 @@ void R_RenderInfo_f( void )
}
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( "\n" );
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 );
// 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;
else waveHeight = RI.currententity->curstate.scale;

View File

@ -17,7 +17,7 @@ GNU General Public License for more details.
#include "sound.h"
#include "client.h"
#include "con_nprint.h"
#include "ref_params.h"
#include "gl_local.h"
#include "pm_local.h"
#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;
}
if( !pos ) pos = cl.refdef.vieworg;
if( !pos ) pos = RI.vieworg;
// pick a channel to play on
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
============
*/
void S_RenderFrame( ref_params_t *fd )
void SND_UpdateSound( void )
{
int i, j, total;
channel_t *ch, *combine;
con_nprint_t info;
if( !dma.initialized ) return;
if( !fd ) return; // too early
// if the loading plaque is up, clear everything
// 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
S_FreeIdleRawChannels();
s_listener.entnum = fd->viewentity; // can be camera entity too
s_listener.frametime = fd->frametime;
s_listener.waterlevel = fd->waterlevel;
s_listener.entnum = cl.viewentity; // can be camera entity too
s_listener.frametime = (cl.time - cl.oldtime);
s_listener.waterlevel = cl.local.waterlevel;
s_listener.active = CL_IsInGame();
s_listener.inmenu = CL_IsInMenu();
s_listener.paused = fd->paused;
s_listener.paused = cl.paused;
VectorCopy( fd->vieworg, s_listener.origin );
VectorCopy( fd->simvel, s_listener.velocity );
AngleVectors( fd->viewangles, s_listener.forward, s_listener.right, s_listener.up );
VectorCopy( RI.vieworg, s_listener.origin );
VectorCopy( cl.simvel, s_listener.velocity );
AngleVectors( RI.viewangles, s_listener.forward, s_listener.right, s_listener.up );
if( cl.worldmodel != NULL )
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 )
{
if( cls.key_dest != key_game || cl.refdef.paused )
if( cls.key_dest != key_game || cl.paused )
return;
if( host.mouse_visible )

View File

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

View File

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

View File

@ -26,6 +26,7 @@ convar_t *scr_conspeed;
convar_t *con_fontsize;
#define CON_TIMES 4 // notify lines
#define CON_MAX_TIMES 64 // notify max lines
#define COLOR_DEFAULT '7'
#define CON_HISTORY 64
#define MAX_DBG_NOTIFY 128
@ -87,6 +88,7 @@ typedef struct
int lines_first; // cyclic buffer
int lines_count;
int num_times; // overlay lines count
// console scroll
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
@ -447,7 +468,7 @@ void Con_CheckResize( void )
if( con.curFont && con.curFont->hFontTexture )
charWidth = con.curFont->charWidths['M'] - 1;
width = ( scr_width->value / charWidth ) - 2;
width = ( glState.width / charWidth ) - 2;
if( !glw_state.initialized ) width = 78;
if( width == con.linewidth )
@ -574,9 +595,9 @@ static void Con_LoadConchars( void )
Con_LoadConsoleFont( i, con.chars + i );
// select properly fontsize
if( scr_width->value <= 640 )
if( glState.width <= 640 )
fontSize = 0;
else if( scr_width->value >= 1280 )
else if( glState.width >= 1280 )
fontSize = 2;
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;
// scale for screen sizes
xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
xscale = (float)glState.width / (float)clgame.scrInfo.iWidth;
yscale = (float)glState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale;
if( y ) *y *= yscale;
@ -824,9 +845,10 @@ void Con_Init( void )
{
int i;
if( host.type == HOST_DEDICATED )
return; // dedicated server already have console
// 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" );
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)" );
@ -837,6 +859,7 @@ void Con_Init( void )
con.maxlines = CON_MAXLINES;
con.lines = (con_lineinfo_t *)Z_Malloc( con.maxlines * sizeof( *con.lines ));
con.lines_first = con.lines_count = 0;
con.num_times = CON_TIMES; // default as 4
Con_CheckResize();
@ -857,9 +880,10 @@ void Con_Init( void )
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
Cmd_AddCommand( "messagemode", Con_MessageMode_f, "enable message mode \"say\"" );
Cmd_AddCommand( "messagemode2", Con_MessageMode2_f, "enable message mode \"say_team\"" );
MsgDev( D_REPORT, "Console initialized.\n" );
Cmd_AddCommand( "contimes", Con_SetTimes_f, "change number of console overlay lines (4-64)" );
con.initialized = true;
MsgDev( D_INFO, "Console initialized.\n" );
}
/*
@ -1694,10 +1718,10 @@ int Con_DrawDebugLines( void )
int 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;
if( y + fontTall > (int)scr_height->value - 20 )
if( y + fontTall > glState.height - 20 )
return count;
count++;
@ -1746,7 +1770,7 @@ void Con_DrawNotify( void )
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 );
@ -1846,7 +1870,7 @@ void Con_DrawSolidConsole( int lines )
// draw the background
GL_SetRenderMode( kRenderNormal );
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 )
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( ));
Con_DrawStringLen( curbuild, &stringLen, &charH );
start = scr_width->value - stringLen;
start = glState.width - stringLen;
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
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 )
con.vislines = con.showlines = 0;
else con.vislines = con.showlines = scr_height->value;
else con.vislines = con.showlines = glState.height;
}
else
{
if( host.developer >= 4 )
{
con.vislines = ((int)scr_height->value >> 1); // keep console open
con.vislines = (glState.height >> 1); // keep console open
}
else
{
@ -1957,7 +1981,7 @@ void Con_DrawConsole( void )
case ca_disconnected:
if( cls.key_dest != key_menu && host.developer )
{
Con_DrawSolidConsole( scr_height->value );
Con_DrawSolidConsole( glState.height );
Key_SetKeyDest( key_console );
}
break;
@ -1975,7 +1999,7 @@ void Con_DrawConsole( void )
if( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" ))
{
if( cls.key_dest == key_console )
Con_DrawSolidConsole( scr_height->value );
Con_DrawSolidConsole( glState.height );
}
else
{
@ -2002,7 +2026,7 @@ void Con_DrawVersion( void )
// draws the current build
byte *color = g_color_table[7];
int i, stringLen, width = 0, charH;
int start, height = scr_height->value;
int start, height = glState.height;
qboolean draw_version = false;
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( ));
else Q_snprintf( curbuild, MAX_STRING, "v%i/%g (build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildnum( ));
Con_DrawStringLen( curbuild, &stringLen, &charH );
start = scr_width->value - stringLen * 1.05f;
start = glState.width - stringLen * 1.05f;
stringLen = Con_StringLength( curbuild );
height -= charH * 1.05f;
@ -2047,12 +2071,12 @@ void Con_RunConsole( void )
if( host.developer && cls.key_dest == key_console )
{
if( cls.state == ca_disconnected )
con.showlines = scr_height->value; // full screen
else con.showlines = ((int)scr_height->value >> 1); // half screen
con.showlines = glState.height; // full screen
else con.showlines = (glState.height >> 1); // half screen
}
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 )
lines_per_frame = 0;
@ -2119,18 +2143,9 @@ void Con_VidInit( void )
if( !con.background )
{
if( scr_width->value < 640 )
{
if( FS_FileExists( "cached/conback400", false ))
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 );
}
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
@ -2141,18 +2156,9 @@ void Con_VidInit( void )
if( !con.background )
{
if( scr_width->value < 640 )
{
if( FS_FileExists( "cached/loading400", false ))
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 );
}
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 "math.h" // fabs...
convar_t *cvar_vars; // head of list
convar_t *cmd_scripting;

View File

@ -847,14 +847,18 @@ void Host_InitCommon( const char *progname, qboolean bChangeGame )
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" );
// get default screen res
VID_InitDefaultResolution();
// startup cmds and cvars subsystem
Cmd_Init();
Cvar_Init();
Con_Init(); // early console running to catch all the messages
// share developer level across all dlls
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
if( cl.refdef.paused && cls.key_dest == key_game )
if( cl.paused && cls.key_dest == key_game )
shutdownMouse = true;
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.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.topColor );