Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions code/api/shared/q_endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ void CopyLongSwap(void *dest, void *src);
#define LongLongSwap(x) bswap64(x)
#endif

#elif defined(__MINGW32__)

#define ShortSwap(x) __builtin_bswap16(x)
#define LongSwap(x) __builtin_bswap32(x)
#define LongLongSwap(x) __builtin_bswap64(x)

#else

#include <byteswap.h>
Expand Down
8 changes: 5 additions & 3 deletions code/cgame/cg_cvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ CG_CVAR( cg_shadows, "cg_shadows", "1", CVAR_ARCHIVE )
CG_CVAR( cl_maxpackets, "cl_maxpackets", "60", CVAR_ARCHIVE )
CG_CVAR( r_maxpolys, "r_maxpolys", "1800", CVAR_ARCHIVE )
CG_CVAR( r_maxpolyverts, "r_maxpolyverts", "9000", CVAR_ARCHIVE )
CG_CVAR( com_maxfps, "com_maxfps", "85", CVAR_ARCHIVE )
CG_CVAR( com_maxfps, "com_maxfps", "125", CVAR_CHEAT)
CG_CVAR( cl_maxfps, "cl_maxfps", "-1", CVAR_ARCHIVE )
CG_CVAR( cg_blood, "com_blood", "1", CVAR_ARCHIVE )
CG_CVAR( cg_cameraOrbitDelay, "cg_cameraOrbitDelay", "50", CVAR_ARCHIVE )
CG_CVAR( cg_scorePlum, "cg_scorePlums", "1", CVAR_ARCHIVE )
Expand All @@ -163,6 +164,9 @@ CG_CVAR( cg_timescaleFadeEnd, "cg_timescaleFadeEnd", "1", 0 )
CG_CVAR( cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0 )
CG_CVAR( cg_timescale, "timescale", "1", 0 )
CG_CVAR( r_clear, "r_clear", "0", 0 )
CG_CVAR( cg_packetdelay, "cg_packetdelay", "0", CVAR_USERINFO )
CG_CVAR( cl_packetdelay, "cl_packetdelay", "0", CVAR_CHEAT )
CG_CVAR( cg_pmovesmooth, "cg_pmovesmooth", "1", CVAR_ARCHIVE )


CG_CVAR( r_debugSort, "r_debugSort", "0", CVAR_CHEAT )
Expand Down Expand Up @@ -225,8 +229,6 @@ CG_CVAR( cg_cmdTimeNudge, "cg_cmdTimeNudge", "0", CVAR_ARCHIVE | CVAR_USERI
CG_CVAR( cg_projectileNudge, "cg_projectileNudge", "0", CVAR_ARCHIVE )
CG_CVAR( cg_optimizePrediction, "cg_optimizePrediction", "1", CVAR_ARCHIVE )
CG_CVAR( cl_timeNudge, "cl_timeNudge", "0", CVAR_ARCHIVE | CVAR_USERINFO )
CG_CVAR( cg_latentSnaps, "cg_latentSnaps", "0", CVAR_USERINFO | CVAR_CHEAT )
CG_CVAR( cg_latentCmds, "cg_latentCmds", "0", CVAR_USERINFO | CVAR_CHEAT )
CG_CVAR( cg_plOut, "cg_plOut", "0", CVAR_USERINFO | CVAR_CHEAT )
CG_CVAR( cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE )
CG_CVAR( cg_predictWeapons, "cg_predictWeapons", "0", CVAR_ARCHIVE )
Expand Down
7 changes: 5 additions & 2 deletions code/cgame/cg_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@ typedef struct centity_s {
// exact interpolated position of entity on this frame
vec3_t lerpOrigin;
vec3_t lerpAngles;

} centity_t;


Expand Down Expand Up @@ -764,6 +763,7 @@ typedef struct {
vec3_t kick_origin;

// temp working variables for player view
vec3_t view_org, last_pmove_fixed;
float bobfracsin;
int bobcycle;
float xyspeed;
Expand Down Expand Up @@ -1451,14 +1451,16 @@ typedef struct {
float oldtimescale; // Timescale value prior to pausing

qboolean pmove_fixed;
int pmove_msec;
int pmove_msec;
int pmove_float;

int sv_fps;

qboolean synchronousClients;

qboolean sv_cheats;

int active_maxfps;
} cgs_t;

//==============================================================================
Expand Down Expand Up @@ -2302,5 +2304,6 @@ extern int cvar_developer;
extern int dll_trap_R_AddRefEntityToScene2;
extern int dll_trap_R_AddLinearLightToScene;

void CG_Update_MaxFPS(void);

#endif //__CG_LOCAL_H
19 changes: 13 additions & 6 deletions code/cgame/cg_localents.c
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ static void CG_UntrackPredictedEnt(localEntity_t *le) {

void CG_MatchPredictedEnt(centity_t* cent) {
localEntity_t* match = NULL;
float best = SQR(64);
float best = SQR(32);
vec3_t diff;

// Can only match entities we own.
Expand Down Expand Up @@ -1025,6 +1025,7 @@ void CG_UpdateLocalPredictedEnts(void) {
}

void CG_AddPredictedMissile(entityState_t* ent, vec3_t origin, vec3_t forward) {
usercmd_t cmd;
localEntity_t *le;
int vel, tmod = 0;

Expand Down Expand Up @@ -1058,15 +1059,21 @@ void CG_AddPredictedMissile(entityState_t* ent, vec3_t origin, vec3_t forward) {
le->leFlags = LEF_PREDICTED;
le->pred_weapon = ent->weapon;

// Technically we could chain this from where we predict the event but this
// should always be correct since command generation is tied to frame
// generation.
trap_GetUserCmd( trap_GetCurrentCmdNumber(), &cmd );

le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time - tmod + cl_timeNudge.integer;
le->pos.trTime = cmd.serverTime - tmod + cl_timeNudge.integer;

VectorCopy(origin, le->lerp.trBase);
VectorCopy(origin, le->pos.trBase);
if (ent->weapon == WP_SUPERNAILGUN || ent->weapon == WP_NAILGUN) {
VectorMA(le->pos.trBase, -15, forward, le->pos.trBase);
le->pos.trBase[2] -= 6;
VectorMA(origin, -15, forward, origin);
origin[2] -= 6;
SnapVector(origin);
}
VectorCopy(origin, le->lerp.trBase);
VectorCopy(origin, le->pos.trBase);

VectorScale(forward, vel, le->pos.trDelta );
SnapVector(le->pos.trDelta);
Expand Down
13 changes: 10 additions & 3 deletions code/cgame/cg_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ static cvarLimitTable_t cvarLimitTable[] = {
{ &cl_maxpackets, "cl_maxpackets", 40, 30, -1, 0, 0, qfalse },
{ &r_maxpolys, "r_maxpolys", 1800, 1800, -1, 0, 0, qfalse },
{ &r_maxpolyverts, "r_maxpolyverts", 9000, 9000, -1, 0, 0, qfalse },
{ &com_maxfps, "com_maxfps", 85, 30, 130, 0, 0, qfalse },
{ &cg_fov, "cg_fov", 90, 5, 135, 0, 0, qfalse },
{ &cg_thirdPerson, "cg_thirdPerson", 0, 0, 0, 0, 0, qfalse },
{ &r_lodCurveError, "r_lodCurveError", 250, 1, -1, 0, 0, qfalse },
Expand Down Expand Up @@ -198,8 +197,6 @@ static cvarLimitTable_t cvarLimitTable[] = {
//Unlagged cvars
{ &cg_cmdTimeNudge, "cg_cmdTimeNudge", 0, 0, 999, 0, 0, qtrue },
{ &cl_timeNudge, "cl_timeNudge", 0, -50, 50, 0, 0, qtrue },
{ &cg_latentSnaps, "cg_latentSnaps", 0, 0, 10, 0, 0, qtrue },
{ &cg_latentCmds, "cg_latentCmds", 0, 0, MAX_LATENT_CMDS - 1 , 0, 0, qtrue },
{ &cg_plOut, "cg_plOut", 0, 0, 100 , 0, 0, qtrue },
// hunkmegs
{ &com_hunkmegs, "com_hunkmegs", 128, 128, -1, 0, 0, qfalse },
Expand All @@ -209,6 +206,8 @@ static cvarLimitTable_t cvarLimitTable[] = {
{ &cg_cl_yawspeed, "cl_yawspeed", 140, 0, 0, 0, 0, qfalse },
{ &cg_cl_pitchspeed, "cl_pitchspeed", 140, 0, 0, 0, 0, qfalse },
{ &cg_cl_freelook, "cl_freelook", 1, 1, 1, 0, 0, qfalse },

{ &cg_packetdelay, "cg_packetdelay", 0, 0, 200, 0, 0, qfalse },
};

static const int cvarLimitTableSize = (int)ARRAY_LEN( cvarLimitTable );
Expand Down Expand Up @@ -515,6 +514,8 @@ void CG_UpdateCvars( void ) {
}
else if (cv->vmCvar == &cg_pipeTrail) {
CG_UpdateColorFromCvar(cg_pipeTrail.string, colorPipeTrail, &cg.pipeTrailTeam, cg.pipeTrailColor);
} else if (cv->vmCvar == &cl_maxfps || cv->vmCvar == &com_maxfps) {
CG_Update_MaxFPS();
}
}
}
Expand All @@ -538,6 +539,12 @@ void CG_UpdateCvars( void ) {

// limit cvars
CG_LimitCvars();

// Handle packet delay
if (cg_packetdelay.integer != cl_packetdelay.integer) {
trap_Cvar_Set("cl_packetdelay", cg_packetdelay.string);
trap_Cvar_Update(&cl_packetdelay);
}
}


Expand Down
48 changes: 30 additions & 18 deletions code/cgame/cg_predict.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,11 +664,11 @@ void CG_PredictPlayerState( void ) {
cg.predictedPlayerState = cg.snap->ps;
}

// demo playback just copies the moves
if ( cg.demoPlayback ||
(cg.snap->ps.pm_flags & PMF_FOLLOW) ||
(cg.snap->ps.pm_flags & PMF_CHASE) ) {
// demo playback/spectating just copies the moves
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ||
(cg.snap->ps.pm_flags & PMF_CHASE) ) {
CG_InterpolatePlayerState( qfalse );
VectorCopy( cg.predictedPlayerState.origin, cg.view_org );
return;
}

Expand Down Expand Up @@ -736,6 +736,7 @@ void CG_PredictPlayerState( void ) {

cg_pmove.pmove_fixed = (int)cgs.pmove_fixed;
cg_pmove.pmove_msec = cgs.pmove_msec;
cg_pmove.pmove_float = cgs.pmove_float;

// Like the comments described above, a player's state is entirely
// re-predicted from the last valid snapshot every client frame, which
Expand All @@ -755,10 +756,7 @@ void CG_PredictPlayerState( void ) {
// except a frame following a new snapshot in which there was a prediction
// error. This yeilds anywhere from a 15% to 40% performance increase,
// depending on how much of a bottleneck the CPU is.

// we check for cg_latentCmds because it'll mess up the optimization
// FIXME: make cg_latentCmds work with cg_optimizePrediction?
if ( cg_optimizePrediction.integer && !cg_latentCmds.integer ) {
if ( cg_optimizePrediction.integer) {
if ( cg.nextFrameTeleport || cg.thisFrameTeleport ) {
// do a full predict
cg.lastPredictedCommand = 0;
Expand Down Expand Up @@ -829,10 +827,6 @@ void CG_PredictPlayerState( void ) {
// get the command
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );

if ( cg_pmove.pmove_fixed ) {
PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
}

// don't do anything if the time is before the snapshot player time
if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) {
continue;
Expand Down Expand Up @@ -917,24 +911,21 @@ void CG_PredictPlayerState( void ) {
VectorSet( cg_pmove.groundVelocity, 0, 0, 0 );
}

if ( cg_pmove.pmove_fixed ) {
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + cgs.pmove_msec-1) / cgs.pmove_msec) * cgs.pmove_msec;
}

// ydnar: if server respawning, freeze the player
if ( cg.serverRespawning ) {
cg_pmove.ps->pm_type = PM_FREEZE;
}

cg_pmove.airleft = (cg.waterundertime - cg.time);
cg_pmove.retflags = 0;

if( cg.agentDataEntity && cg.agentDataEntity->currentValid ) {
cg_pmove.agentclass = cg.agentDataEntity->currentState.torsoAnim;
} else {
cg_pmove.agentclass = 0;
}
// we check for cg_latentCmds because it'll mess up the optimization
if ( cg_optimizePrediction.integer && !cg_latentCmds.integer ) {

if ( cg_optimizePrediction.integer ) {
// if we need to predict this command, or we've run out of space in the saved states queue
if ( cmdNum >= predictCmd || (stateIndex + 1) % NUM_SAVED_STATES == cg.stateHead ) {
// run the Pmove
Expand Down Expand Up @@ -985,6 +976,8 @@ void CG_PredictPlayerState( void ) {
//CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
}

VectorCopy( cg.predictedPlayerState.origin, cg.view_org );

if ( cg_showmiss.integer > 1 ) {
CG_Printf( BOX_PRINT_MODE_CHAT, "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
}
Expand Down Expand Up @@ -1016,4 +1009,23 @@ void CG_PredictPlayerState( void ) {
cg.eventSequence = cg.predictedPlayerState.eventSequence;
}
}

// Need to interp with pmove_fixed to avoid effective 1/pmove_msec fps.
if (cgs.pmove_fixed) {
if ((cg_pmove.retflags & PMRF_PMOVE_PARTIAL) == 0) // New full frame
VectorCopy(oldPlayerState.origin, cg.last_pmove_fixed);

// We can be very conservative about when we choose to stitch.
if (cg_pmovesmooth.integer &&
cg.predictedPlayerState.commandTime - oldPlayerState.commandTime <= cgs.pmove_msec &&
DistanceSquared(cg.predictedPlayerState.origin, cg.last_pmove_fixed) < SQR(16) &&
!cg.thisFrameTeleport) {
vec3_t diff;
float dt = 1 + (cg.predictedPlayerState.commandTime % cgs.pmove_msec);
dt /= 1.0 * cgs.pmove_msec;

VectorSubtract(cg.predictedPlayerState.origin, cg.last_pmove_fixed, diff);
VectorMA(cg.last_pmove_fixed, dt, diff, cg.view_org);
}
}
}
22 changes: 22 additions & 0 deletions code/cgame/cg_servercmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ void CG_ParseSysteminfo( void ) {
} else if ( cgs.pmove_msec > 33 ) {
cgs.pmove_msec = 33;
}
cgs.pmove_float = ( atoi( Info_ValueForKey( info, "pmove_float" ) ) ) ? qtrue : qfalse;
CG_Update_MaxFPS();

cgs.sv_fps = Q_atoi( Info_ValueForKey( info, "sv_fps" ) );

Expand Down Expand Up @@ -899,3 +901,23 @@ void CG_ExecuteNewServerCommands( int latestSequence ) {
}
}
}


/*
====================
CG_Update_MaxFPS

Update `com_maxfps` to max allowed value by gamesettings and `cl_maxfps`.
====================
*/
void CG_Update_MaxFPS(void) {
// Temp: Higher than 250 wants changes later in stack at higher pings.
int fps = cl_maxfps.integer == -1 ? 250 : cl_maxfps.integer;
fps = Q_max(Q_min(fps, cgs.pmove_fixed ? 500 : 125), 60);

if (com_maxfps.integer == fps)
return;

trap_Cvar_Set("com_maxfps", va("%d", fps));
trap_Cvar_Update(&com_maxfps);
}
32 changes: 4 additions & 28 deletions code/cgame/cg_snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,26 +306,13 @@ static snapshot_t *CG_ReadNextSnapshot( void ) {
// try to read the snapshot from the client system
cgs.processedSnapshotNum++;
r = trap_GetSnapshot( cgs.processedSnapshotNum, dest );
// the client wants latent snaps and the just-read snapshot is valid
if ( cg_latentSnaps.integer && r ) {
int i = 0, time = dest->serverTime;

// keep grabbing one snapshot earlier until we get to the right time
while ( dest->serverTime > time - cg_latentSnaps.integer * (1000 / cgs.sv_fps) ) {
if ( !(r = trap_GetSnapshot( cgs.processedSnapshotNum - i, dest )) ) {
// the snapshot is not valid, so stop here
break;
}

// go back one more
i++;
}
}

#if 0
// FIXME: why would trap_GetSnapshot return a snapshot with the same server time
if ( cg.snap && r && dest->serverTime == cg.snap->serverTime ) {
//continue;
}
#endif

// if it succeeded, return
if ( r ) {
Expand All @@ -349,7 +336,6 @@ static snapshot_t *CG_ReadNextSnapshot( void ) {
return NULL;
}


/*
============
CG_ProcessSnapshots
Expand Down Expand Up @@ -377,13 +363,8 @@ void CG_ProcessSnapshots( void ) {
trap_GetCurrentSnapshotNumber( &n, &cg.latestSnapshotTime );
if ( n != cg.latestSnapshotNum ) {
if ( n < cg.latestSnapshotNum ) {
// this may actually happen with lag simulation going on
if ( cg_latentSnaps.integer ) {
CG_Printf( BOX_PRINT_MODE_CHAT, "WARNING: CG_ProcessSnapshots: n < cg.latestSnapshotNum\n" );
} else {
// this should never happen
CG_Error( "CG_ProcessSnapshots: n < cg.latestSnapshotNum" );
}
CG_Error( "CG_ProcessSnapshots: n < cg.latestSnapshotNum" );
}
cg.latestSnapshotNum = n;
}
Expand Down Expand Up @@ -423,12 +404,7 @@ void CG_ProcessSnapshots( void ) {

// if time went backwards, we have a level restart
if ( cg.nextSnap->serverTime < cg.snap->serverTime ) {
// this may actually happen with lag simulation going on
if ( cg_latentSnaps.integer ) {
CG_Printf( BOX_PRINT_MODE_CHAT, "WARNING: CG_ProcessSnapshots: Server time went backwards\n" );
} else {
CG_Error( "CG_ProcessSnapshots: Server time went backwards" );
}
CG_Error( "CG_ProcessSnapshots: Server time went backwards" );
}
}

Expand Down
Loading