Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add com_gameHz to play with higher HZ/FPS #297

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions neo/d3xp/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ void idCameraAnim::Think( void ) {
return;
}

if ( frameRate == USERCMD_HZ ) {
if ( frameRate == gameLocal.gameFps ) {
frameTime = gameLocal.time - starttime;
frame = frameTime / gameLocal.msec;
} else {
Expand Down Expand Up @@ -568,7 +568,7 @@ void idCameraAnim::GetViewParms( renderView_t *view ) {
SetTimeState ts( timeGroup );
#endif

if ( frameRate == USERCMD_HZ ) {
if ( frameRate == gameLocal.gameFps ) {
frameTime = gameLocal.time - starttime;
frame = frameTime / gameLocal.msec;
lerp = 0.0f;
Expand Down
55 changes: 36 additions & 19 deletions neo/d3xp/Game_local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ void idGameLocal::Clear( void ) {
framenum = 0;
previousTime = 0;
time = 0;
preciseTime = 0.0f;
vacuumAreaNum = 0;
mapFileName.Clear();
mapFile = NULL;
Expand Down Expand Up @@ -309,6 +310,10 @@ void idGameLocal::Init( void ) {
const idDict *dict;
idAAS *aas;

msec = 16.0; //60fps
Copy link
Member

@DanielGibson DanielGibson Jun 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please put a space after "//", e.g. // 60fps (yes, always, not just here), like it's done in the existing code

(it also just looks better)

gameMsec = msec;
gameFps = 60; //60fps

#ifndef GAME_DLL

TestGameAPI();
Expand All @@ -326,6 +331,12 @@ void idGameLocal::Init( void ) {

#endif

//Update MSEC and gameFps
gameFps = cvarSystem->GetCVarInteger("com_gameHz");
msec = 1000.0f / cvarSystem->GetCVarFloat("com_gameHz");
msec *= 0.96f*0.96f; //HACK to emulate OG D3 msec error, in order to have exactly the same game logic speed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 0.96f*0.96f ?
I get that 16 / 16.666 == 0.96, but why square it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was a mistake from me. I thought that I needed to do that twice because common frame was already working at 16.666 hz, but multiplying by 0.96f twice was a mistake.

In fact that product for 0.96f is something I don't like at all. It is some kind of "duct-tape" ugly code. I will look at this feature in some days or weeks in order to see if with a fresh mind I can actually figure out something better.

gameMsec = msec;

Printf( "----- Initializing Game -----\n" );
Printf( "gamename: %s\n", GAME_VERSION );
Printf( "gamedate: %s\n", __DATE__ );
Expand Down Expand Up @@ -594,12 +605,14 @@ void idGameLocal::SaveGame( idFile *f ) {
savegame.WriteBool( isMultiplayer );
savegame.WriteInt( gameType );

savegame.WriteFloat(preciseTime);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this breaks savegame compatibility :-(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for letting me know this. I will try to find a way to avoid that, in fact I was looking at the BFG Edition code like a lot, and there are many things that I don't like about this pull request after looking at that. So I will try to find a way to improve this or actually try this again but most similar to the BFG Edition approach.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best way to do this is to bump BUILD_NUMBER and in idGameLocal::InitFromSaveGame() you can check savegame.GetBuildNumber() and only if it's the new number you read preciseTime, otherwise you set preciseTime to some sane default value.


savegame.WriteInt( framenum );
savegame.WriteInt( previousTime );
savegame.WriteInt( time );

#ifdef _D3XP
savegame.WriteInt( msec );
savegame.WriteFloat( msec );
#endif

savegame.WriteInt( vacuumAreaNum );
Expand Down Expand Up @@ -1000,6 +1013,7 @@ void idGameLocal::LoadMap( const char *mapName, int randseed ) {

previousTime = 0;
time = 0;
preciseTime = 0.0f;
framenum = 0;
sessionCommand = "";
nextGibTime = 0;
Expand Down Expand Up @@ -1473,12 +1487,14 @@ bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWo
savegame.ReadBool( isMultiplayer );
savegame.ReadInt( (int &)gameType );

savegame.ReadFloat(preciseTime);

savegame.ReadInt( framenum );
savegame.ReadInt( previousTime );
savegame.ReadInt( time );

#ifdef _D3XP
savegame.ReadInt( msec );
savegame.ReadFloat( msec );
#endif

savegame.ReadInt( vacuumAreaNum );
Expand Down Expand Up @@ -1520,7 +1536,7 @@ bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWo
}
}
if ( gameSoundWorld ) {
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)gameMsec );
}
#endif

Expand Down Expand Up @@ -2431,7 +2447,8 @@ gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds ) {
// update the game time
framenum++;
previousTime = time;
time += msec;
preciseTime += msec;
time = (int)idMath::Rint(preciseTime);
realClientTime = time;

#ifdef _D3XP
Expand Down Expand Up @@ -3812,7 +3829,7 @@ idGameLocal::AlertAI
void idGameLocal::AlertAI( idEntity *ent ) {
if ( ent && ent->IsType( idActor::Type ) ) {
// alert them for the next frame
lastAIAlertTime = time + msec;
lastAIAlertTime = time + (int)idMath::Rint(msec);
lastAIAlertEntity = static_cast<idActor *>( ent );
}
}
Expand Down Expand Up @@ -4225,7 +4242,7 @@ void idGameLocal::SetCamera( idCamera *cam ) {

} else {
inCinematic = false;
cinematicStopTime = time + msec;
cinematicStopTime = time + idMath::Rint(msec);

// restore r_znear
cvarSystem->SetCVarFloat( "r_znear", 3.0f );
Expand Down Expand Up @@ -4821,7 +4838,7 @@ void idGameLocal::ComputeSlowMsec() {

// stop the state
slowmoState = SLOWMO_STATE_OFF;
slowmoMsec = USERCMD_MSEC;
slowmoMsec = gameMsec;
}

// check the player state
Expand All @@ -4842,7 +4859,7 @@ void idGameLocal::ComputeSlowMsec() {
slowmoMsec = msec;
if ( gameSoundWorld ) {
gameSoundWorld->SetSlowmo( true );
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / gameMsec );
}
}
else if ( !powerupOn && slowmoState == SLOWMO_STATE_ON ) {
Expand All @@ -4856,25 +4873,25 @@ void idGameLocal::ComputeSlowMsec() {

// do any necessary ramping
if ( slowmoState == SLOWMO_STATE_RAMPUP ) {
delta = 4 - slowmoMsec;
delta = 4.0 * 60.0 / (float)gameFps - slowmoMsec;

if ( fabs( delta ) < g_slowmoStepRate.GetFloat() ) {
slowmoMsec = 4;
slowmoMsec = 4.0 * 60.0 / (float)gameFps;
slowmoState = SLOWMO_STATE_ON;
}
else {
slowmoMsec += delta * g_slowmoStepRate.GetFloat();
}

if ( gameSoundWorld ) {
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / gameMsec );
}
}
else if ( slowmoState == SLOWMO_STATE_RAMPDOWN ) {
delta = 16 - slowmoMsec;
delta = 16.0 * 60.0 / gameFps - slowmoMsec;

if ( fabs( delta ) < g_slowmoStepRate.GetFloat() ) {
slowmoMsec = 16;
slowmoMsec = 16.0*60.0/(float)gameFps;
slowmoState = SLOWMO_STATE_OFF;
if ( gameSoundWorld ) {
gameSoundWorld->SetSlowmo( false );
Expand All @@ -4885,7 +4902,7 @@ void idGameLocal::ComputeSlowMsec() {
}

if ( gameSoundWorld ) {
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / gameMsec );
}
}
}
Expand All @@ -4896,19 +4913,19 @@ idGameLocal::ResetSlowTimeVars
============
*/
void idGameLocal::ResetSlowTimeVars() {
msec = USERCMD_MSEC;
slowmoMsec = USERCMD_MSEC;
msec = gameMsec;
slowmoMsec = gameMsec;
slowmoState = SLOWMO_STATE_OFF;

fast.framenum = 0;
fast.previousTime = 0;
fast.time = 0;
fast.msec = USERCMD_MSEC;
fast.msec = gameMsec;

slow.framenum = 0;
slow.previousTime = 0;
slow.time = 0;
slow.msec = USERCMD_MSEC;
slow.msec = gameMsec;
}

/*
Expand Down Expand Up @@ -4985,4 +5002,4 @@ void idGameLocal::SwitchTeam( int clientNum, int team ) {
idGameLocal::GetMapLoadingGUI
===============
*/
void idGameLocal::GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) { }
void idGameLocal::GetMapLoadingGUI( char gui[ MAX_STRING_CHARS ] ) { }
17 changes: 10 additions & 7 deletions neo/d3xp/Game_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,14 @@ class idEntityPtr {
struct timeState_t {
int time;
int previousTime;
int msec;
float msec;
int framenum;
int realClientTime;

void Set( int t, int pt, int ms, int f, int rct ) { time = t; previousTime = pt; msec = ms; framenum = f; realClientTime = rct; };
void Get( int& t, int& pt, int& ms, int& f, int& rct ) { t = time; pt = previousTime; ms = msec; f = framenum; rct = realClientTime; };
void Save( idSaveGame *savefile ) const { savefile->WriteInt( time ); savefile->WriteInt( previousTime ); savefile->WriteInt( msec ); savefile->WriteInt( framenum ); savefile->WriteInt( realClientTime ); }
void Restore( idRestoreGame *savefile ) { savefile->ReadInt( time ); savefile->ReadInt( previousTime ); savefile->ReadInt( msec ); savefile->ReadInt( framenum ); savefile->ReadInt( realClientTime ); }
void Set( int t, int pt, float ms, int f, int rct ) { time = t; previousTime = pt; msec = ms; framenum = f; realClientTime = rct; };
void Get( int& t, int& pt, float& ms, int& f, int& rct ) { t = time; pt = previousTime; ms = msec; f = framenum; rct = realClientTime; };
void Save( idSaveGame *savefile ) const { savefile->WriteInt( time ); savefile->WriteInt( previousTime ); savefile->WriteFloat( msec ); savefile->WriteInt( framenum ); savefile->WriteInt( realClientTime ); }
void Restore( idRestoreGame *savefile ) { savefile->ReadInt( time ); savefile->ReadInt( previousTime ); savefile->ReadFloat( msec ); savefile->ReadInt( framenum ); savefile->ReadInt( realClientTime ); }
void Increment() { framenum++; previousTime = time; time += msec; realClientTime = time; };
};

Expand Down Expand Up @@ -298,7 +298,10 @@ class idGameLocal : public idGame {
int framenum;
int previousTime; // time in msec of last frame
int time; // in msec
int msec; // time since last update in milliseconds
float msec; // time since last update in milliseconds
float preciseTime; // added by Stradex for cm_gameHz fidelity
int gameFps; //added by Stradex for com_gameHz
float gameMsec; //added by Stradex for com_gameHz (ROE)

int vacuumAreaNum; // -1 if level doesn't have any outside areas

Expand Down Expand Up @@ -483,7 +486,7 @@ class idGameLocal : public idGame {
// added the following to assist licensees with merge issues
int GetFrameNum() const { return framenum; };
int GetTime() const { return time; };
int GetMSec() const { return msec; };
int GetMSec() const { return (int)idMath::Rint(msec); };

int GetNextClientNum( int current ) const;
idPlayer * GetClientByNum( int current ) const;
Expand Down
5 changes: 3 additions & 2 deletions neo/d3xp/Game_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ void idGameLocal::ClientReadSnapshot( int clientNum, int sequence, const int gam
// update the game time
framenum = gameFrame;
time = gameTime;
previousTime = time - msec;
previousTime = time - idMath::Rint(msec);

// so that StartSound/StopSound doesn't risk skipping
isNewFrame = true;
Expand Down Expand Up @@ -1532,7 +1532,8 @@ gameReturn_t idGameLocal::ClientPrediction( int clientNum, const usercmd_t *clie
// update the game time
framenum++;
previousTime = time;
time += msec;
preciseTime += msec;
time = (int)idMath::Rint(preciseTime);

// update the real client time and the new frame flag
if ( time > realClientTime ) {
Expand Down
4 changes: 2 additions & 2 deletions neo/d3xp/Moveable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,14 @@ bool idMoveable::FollowInitialSplinePath( void ) {
if ( initialSpline != NULL ) {
if ( gameLocal.time < initialSpline->GetTime( initialSpline->GetNumValues() - 1 ) ) {
idVec3 splinePos = initialSpline->GetCurrentValue( gameLocal.time );
idVec3 linearVelocity = ( splinePos - physicsObj.GetOrigin() ) * USERCMD_HZ;
idVec3 linearVelocity = ( splinePos - physicsObj.GetOrigin() ) * gameLocal.gameFps;
physicsObj.SetLinearVelocity( linearVelocity );

idVec3 splineDir = initialSpline->GetCurrentFirstDerivative( gameLocal.time );
idVec3 dir = initialSplineDir * physicsObj.GetAxis();
idVec3 angularVelocity = dir.Cross( splineDir );
angularVelocity.Normalize();
angularVelocity *= idMath::ACos16( dir * splineDir / splineDir.Length() ) * USERCMD_HZ;
angularVelocity *= idMath::ACos16( dir * splineDir / splineDir.Length() ) * gameLocal.gameFps;
physicsObj.SetAngularVelocity( angularVelocity );
return true;
} else {
Expand Down
4 changes: 2 additions & 2 deletions neo/d3xp/Mover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2838,9 +2838,9 @@ void idMover_Binary::Use_BinaryMover( idEntity *activator ) {
activatedBy = activator;

if ( moverState == MOVER_POS1 ) {
// FIXME: start moving USERCMD_MSEC later, because if this was player
// FIXME: start moving gameLocal.msec later, because if this was player
// triggered, gameLocal.time hasn't been advanced yet
MatchActivateTeam( MOVER_1TO2, gameLocal.slow.time + USERCMD_MSEC );
MatchActivateTeam( MOVER_1TO2, gameLocal.slow.time + gameLocal.gameMsec );

SetGuiStates( guiBinaryMoverStates[MOVER_1TO2] );
// open areaportal
Expand Down
2 changes: 1 addition & 1 deletion neo/d3xp/PlayerView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef )
if ( blobTime ) {
screenBlob_t* blob = GetScreenBlob();
blob->startFadeTime = gameLocal.slow.time;
blob->finishTime = gameLocal.slow.time + blobTime * g_blobTime.GetFloat() * ( ( float )gameLocal.msec / USERCMD_MSEC );
blob->finishTime = gameLocal.slow.time + blobTime * g_blobTime.GetFloat() * ( ( float )gameLocal.msec / gameLocal.gameMsec );

const char* materialName = damageDef->GetString( "mtr_blob" );
blob->material = declManager->FindMaterial( materialName );
Expand Down
2 changes: 1 addition & 1 deletion neo/d3xp/Projectile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1610,7 +1610,7 @@ void idGuidedProjectile::Launch( const idVec3 &start, const idVec3 &dir, const i
angles = vel.ToAngles();
speed = vel.Length();
rndScale = spawnArgs.GetAngles( "random", "15 15 0" );
turn_max = spawnArgs.GetFloat( "turn_max", "180" ) / ( float )USERCMD_HZ;
turn_max = spawnArgs.GetFloat( "turn_max", "180" ) / ( float )gameLocal.gameFps;
clamp_dist = spawnArgs.GetFloat( "clamp_dist", "256" );
burstMode = spawnArgs.GetBool( "burstMode" );
unGuided = false;
Expand Down
2 changes: 1 addition & 1 deletion neo/d3xp/SmokeParticles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ bool idSmokeParticles::EmitSmoke( const idDeclParticle *smoke, const int systemS
if ( nowCount >= stage->totalParticles ) {
nowCount = stage->totalParticles-1;
}
prevCount = floor( ((float)( deltaMsec - gameLocal.msec /*_D3XP - FIX - was USERCMD_MSEC*/ ) / finalParticleTime) * stage->totalParticles );
prevCount = floor( ((float)( deltaMsec - (int)idMath::Rint(gameLocal.msec) /*_D3XP - FIX - was gameLocal.msec*/ ) / finalParticleTime) * stage->totalParticles );
if ( prevCount < -1 ) {
prevCount = -1;
}
Expand Down
5 changes: 3 additions & 2 deletions neo/d3xp/physics/Force_Drag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ If you have questions concerning this license or the applicable additional terms
#include "sys/platform.h"
#include "framework/UsercmdGen.h"

#include "Game_local.h"
#include "physics/Physics.h"

#include "physics/Force_Drag.h"
Expand Down Expand Up @@ -139,9 +140,9 @@ void idForce_Drag::Evaluate( int time ) {
l2 = dir2.Normalize();

rotation.Set( centerOfMass, dir2.Cross( dir1 ), RAD2DEG( idMath::ACos( dir1 * dir2 ) ) );
physics->SetAngularVelocity( rotation.ToAngularVelocity() / MS2SEC( USERCMD_MSEC ), id );
physics->SetAngularVelocity( rotation.ToAngularVelocity() / MS2SEC( gameLocal.gameMsec ), id );

velocity = physics->GetLinearVelocity( id ) * damping + dir1 * ( ( l1 - l2 ) * ( 1.0f - damping ) / MS2SEC( USERCMD_MSEC ) );
velocity = physics->GetLinearVelocity( id ) * damping + dir1 * ( ( l1 - l2 ) * ( 1.0f - damping ) / MS2SEC( gameLocal.gameMsec ) );
physics->SetLinearVelocity( velocity, id );
}

Expand Down
4 changes: 2 additions & 2 deletions neo/d3xp/physics/Physics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ idPhysics::SnapTimeToPhysicsFrame
*/
int idPhysics::SnapTimeToPhysicsFrame( int t ) {
int s;
s = t + USERCMD_MSEC - 1;
return ( s - s % USERCMD_MSEC );
s = t + (int)idMath::Rint(gameLocal.gameMsec) - 1;
return ( s - s % (int)idMath::Rint(gameLocal.gameMsec) );
}
2 changes: 1 addition & 1 deletion neo/d3xp/physics/Physics_AF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6608,7 +6608,7 @@ idPhysics_AF::idPhysics_AF( void ) {

memset( &current, 0, sizeof( current ) );
current.atRest = -1;
current.lastTimeStep = USERCMD_MSEC;
current.lastTimeStep = gameLocal.gameMsec;
saved = current;

linearFriction = 0.005f;
Expand Down
2 changes: 1 addition & 1 deletion neo/d3xp/physics/Physics_RigidBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ idPhysics_RigidBody::idPhysics_RigidBody( void ) {
memset( &current, 0, sizeof( current ) );

current.atRest = -1;
current.lastTimeStep = USERCMD_MSEC;
current.lastTimeStep = gameLocal.gameMsec;

current.i.position.Zero();
current.i.orientation.Identity();
Expand Down
Loading