Skip to content

Commit 6f4a9b9

Browse files
Merge remote-tracking branch 'dhewm3/master'
2 parents 0d0db88 + 18fc6b9 commit 6f4a9b9

File tree

16 files changed

+93
-45
lines changed

16 files changed

+93
-45
lines changed

.github/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ Note: Numbers starting with a "#" like #330 refer to the bugreport with that num
6767
* Added `fs_gameDllPath` CVar: If set, game DLLs will be searched in that directory before the other
6868
standard places (like next to the executable). Especially useful for developing/debugging mod DLLs
6969
(you can just set `fs_gameDllPath` to the build dir, no need to copy the DLL/.so/.dylib)
70+
* Fixed a crash when using an incomplete cubemap texture (missing one side).
71+
Will now print a warning about the missing side.
72+
* Fix wrong (flipped) labels of Prev./Next Weapon in dhewm3 settings menu (#731)
7073
* Several smaller fixes for all kinds of things incl. build issues
7174

75+
7276
1.5.4 (2024-08-03)
7377
------------------------------------------------------------------------
7478

neo/d3xp/Camera.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ void idCameraAnim::Think( void ) {
514514

515515
if ( frameRate == USERCMD_HZ ) {
516516
frameTime = gameLocal.time - starttime;
517-
frame = frameTime / gameLocal.msec;
517+
frame = frameTime / gameLocal.msecPrecise;
518518
} else {
519519
frameTime = ( gameLocal.time - starttime ) * frameRate;
520520
frame = frameTime / 1000;
@@ -568,7 +568,7 @@ void idCameraAnim::GetViewParms( renderView_t *view ) {
568568

569569
if ( frameRate == USERCMD_HZ ) {
570570
frameTime = gameLocal.time - starttime;
571-
frame = frameTime / gameLocal.msec;
571+
frame = frameTime / gameLocal.msecPrecise;
572572
lerp = 0.0f;
573573
} else {
574574
frameTime = ( gameLocal.time - starttime ) * frameRate;

neo/d3xp/Entity.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,10 +590,10 @@ ID_INLINE void SetTimeState::PushState( int timeGroup ) {
590590

591591
// set correct time
592592
if ( fast ) {
593-
gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
593+
gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime, gameLocal.msecPrecise );
594594
}
595595
else {
596-
gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
596+
gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime, gameLocal.msecPrecise );
597597
}
598598
}
599599
}
@@ -602,10 +602,10 @@ ID_INLINE SetTimeState::~SetTimeState() {
602602
if ( activated && !gameLocal.isMultiplayer ) {
603603
// set previous correct time
604604
if ( previousFast ) {
605-
gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
605+
gameLocal.fast.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime, gameLocal.msecPrecise );
606606
}
607607
else {
608-
gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime );
608+
gameLocal.slow.Get( gameLocal.time, gameLocal.previousTime, gameLocal.msec, gameLocal.framenum, gameLocal.realClientTime, gameLocal.msecPrecise );
609609
}
610610
}
611611
}

neo/d3xp/Game_local.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,14 +1533,21 @@ bool idGameLocal::InitFromSaveGame( const char *mapName, idRenderWorld *renderWo
15331533
if ( gameSoundWorld ) {
15341534
gameSoundWorld->SetSlowmo( false );
15351535
}
1536-
} else {
1536+
// DG: not saving/restoring msecPrecise to avoid breaking savegames
1537+
// if slowmo is off, this is the value msec(Precise) should have
1538+
msecPrecise = USERCMD_MSEC_PRECISE;
1539+
}
1540+
else {
15371541
if ( gameSoundWorld ) {
15381542
gameSoundWorld->SetSlowmo( true );
15391543
}
1544+
// DG: msec(Precise) should be set frequently anyway, so using the approximate msec
1545+
// in the slowmo-case should be good enough (I know, famous last words etc)
1546+
msecPrecise = msec;
15401547
}
15411548

15421549
if ( gameSoundWorld ) {
1543-
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
1550+
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / USERCMD_MSEC_PRECISE ); // DG: slowmoMsec now is precise
15441551
}
15451552
#endif
15461553

@@ -2393,7 +2400,7 @@ void idGameLocal::RunTimeGroup2( int msec_fast ) { // dezo2/DG: added argument f
23932400
int num = 0;
23942401

23952402
fast.Increment( msec_fast );
2396-
fast.Get( time, previousTime, msec, framenum, realClientTime );
2403+
fast.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
23972404

23982405
for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() ) {
23992406
if ( ent->timeGroup != TIME_GROUP2 ) {
@@ -2404,7 +2411,7 @@ void idGameLocal::RunTimeGroup2( int msec_fast ) { // dezo2/DG: added argument f
24042411
num++;
24052412
}
24062413

2407-
slow.Get( time, previousTime, msec, framenum, realClientTime );
2414+
slow.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
24082415
}
24092416
#endif
24102417

@@ -2446,8 +2453,9 @@ gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds, int activeEdito
24462453
#ifdef _D3XP
24472454
ComputeSlowMsec();
24482455

2449-
slow.Get( time, previousTime, msec, framenum, realClientTime );
2456+
slow.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
24502457
msec = slowmoMsec;
2458+
msecPrecise = slowmoMsec;
24512459
#endif
24522460

24532461
if ( !isMultiplayer && g_stopTime.GetBool() ) {
@@ -2467,14 +2475,16 @@ gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds, int activeEdito
24672475

24682476
// dezo2/DG: recalculate each frame, see comment at CalcMSec()
24692477
int msec_fast = CalcMSec( framenum );
2470-
if ( slowmoState == SLOWMO_STATE_OFF )
2478+
if ( slowmoState == SLOWMO_STATE_OFF ) {
24712479
msec = msec_fast;
2480+
msecPrecise = USERCMD_MSEC_PRECISE;
2481+
}
24722482

24732483
time += msec;
24742484
realClientTime = time;
24752485

24762486
#ifdef _D3XP
2477-
slow.Set( time, previousTime, msec, framenum, realClientTime );
2487+
slow.Set( time, previousTime, msec, framenum, realClientTime, msecPrecise );
24782488
#endif
24792489

24802490
#ifdef GAME_DLL
@@ -2594,9 +2604,9 @@ gameReturn_t idGameLocal::RunFrame( const usercmd_t *clientCmds, int activeEdito
25942604

25952605
#ifdef _D3XP
25962606
// service pending fast events
2597-
fast.Get( time, previousTime, msec, framenum, realClientTime );
2607+
fast.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
25982608
idEvent::ServiceFastEvents();
2599-
slow.Get( time, previousTime, msec, framenum, realClientTime );
2609+
slow.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
26002610
#endif
26012611

26022612
timer_events.Stop();
@@ -4810,9 +4820,9 @@ idGameLocal::SelectTimeGroup
48104820
*/
48114821
void idGameLocal::SelectTimeGroup( int timeGroup ) {
48124822
if ( timeGroup ) {
4813-
fast.Get( time, previousTime, msec, framenum, realClientTime );
4823+
fast.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
48144824
} else {
4815-
slow.Get( time, previousTime, msec, framenum, realClientTime );
4825+
slow.Get( time, previousTime, msec, framenum, realClientTime, msecPrecise );
48164826
}
48174827
}
48184828

@@ -4862,7 +4872,7 @@ void idGameLocal::ComputeSlowMsec() {
48624872

48634873
// stop the state
48644874
slowmoState = SLOWMO_STATE_OFF;
4865-
slowmoMsec = USERCMD_MSEC;
4875+
slowmoMsec = USERCMD_MSEC_PRECISE; // DG: slowmoMsec now is precise
48664876
}
48674877

48684878
// check the player state
@@ -4880,10 +4890,10 @@ void idGameLocal::ComputeSlowMsec() {
48804890
if ( powerupOn && slowmoState == SLOWMO_STATE_OFF ) {
48814891
slowmoState = SLOWMO_STATE_RAMPUP;
48824892

4883-
slowmoMsec = msec;
4893+
slowmoMsec = msecPrecise;
48844894
if ( gameSoundWorld ) {
48854895
gameSoundWorld->SetSlowmo( true );
4886-
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
4896+
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / USERCMD_MSEC_PRECISE ); // DG: slowmoMsec now is precise
48874897
}
48884898
}
48894899
else if ( !powerupOn && slowmoState == SLOWMO_STATE_ON ) {
@@ -4895,27 +4905,30 @@ void idGameLocal::ComputeSlowMsec() {
48954905
}
48964906
}
48974907

4908+
// DG: for more precision in slowmo timing
4909+
static const float quarterFrameTime = USERCMD_MSEC_PRECISE * 0.25;
4910+
48984911
// do any necessary ramping
48994912
if ( slowmoState == SLOWMO_STATE_RAMPUP ) {
4900-
delta = 4 - slowmoMsec;
4913+
delta = quarterFrameTime - slowmoMsec; // DG: slowmoMsec now is precise
49014914

49024915
if ( fabs( delta ) < g_slowmoStepRate.GetFloat() ) {
4903-
slowmoMsec = 4;
4916+
slowmoMsec = quarterFrameTime; // DG: slowmoMsec now is precise
49044917
slowmoState = SLOWMO_STATE_ON;
49054918
}
49064919
else {
49074920
slowmoMsec += delta * g_slowmoStepRate.GetFloat();
49084921
}
49094922

49104923
if ( gameSoundWorld ) {
4911-
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
4924+
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / USERCMD_MSEC_PRECISE ); // DG: slowmoMsec now is precise
49124925
}
49134926
}
49144927
else if ( slowmoState == SLOWMO_STATE_RAMPDOWN ) {
4915-
delta = 16 - slowmoMsec;
4928+
delta = USERCMD_MSEC_PRECISE - slowmoMsec; // DG: slowmoMsec now is precise
49164929

49174930
if ( fabs( delta ) < g_slowmoStepRate.GetFloat() ) {
4918-
slowmoMsec = 16;
4931+
slowmoMsec = USERCMD_MSEC_PRECISE; // DG: slowmoMsec now is precise
49194932
slowmoState = SLOWMO_STATE_OFF;
49204933
if ( gameSoundWorld ) {
49214934
gameSoundWorld->SetSlowmo( false );
@@ -4926,7 +4939,7 @@ void idGameLocal::ComputeSlowMsec() {
49264939
}
49274940

49284941
if ( gameSoundWorld ) {
4929-
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / (float)USERCMD_MSEC );
4942+
gameSoundWorld->SetSlowmoSpeed( slowmoMsec / USERCMD_MSEC_PRECISE ); // DG: slowmoMsec now is precise
49304943
}
49314944
}
49324945
}
@@ -4938,18 +4951,21 @@ idGameLocal::ResetSlowTimeVars
49384951
*/
49394952
void idGameLocal::ResetSlowTimeVars() {
49404953
msec = USERCMD_MSEC;
4941-
slowmoMsec = USERCMD_MSEC;
4954+
msecPrecise = USERCMD_MSEC_PRECISE;
4955+
slowmoMsec = USERCMD_MSEC_PRECISE; // DG: slowmoMsec now is precise
49424956
slowmoState = SLOWMO_STATE_OFF;
49434957

49444958
fast.framenum = 0;
49454959
fast.previousTime = 0;
49464960
fast.time = 0;
49474961
fast.msec = USERCMD_MSEC;
4962+
fast.msecPrecise = USERCMD_MSEC_PRECISE;
49484963

49494964
slow.framenum = 0;
49504965
slow.previousTime = 0;
49514966
slow.time = 0;
49524967
slow.msec = USERCMD_MSEC;
4968+
fast.msecPrecise = USERCMD_MSEC_PRECISE;
49534969
}
49544970

49554971
/*

neo/d3xp/Game_local.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ void gameError( const char *fmt, ... );
9393

9494
const int NUM_RENDER_PORTAL_BITS = idMath::BitsForInteger( PS_BLOCK_ALL );
9595

96+
// DG: USERCMD_MSEC is 16, USERCMD_MSEC_PRECISE is a float and 16.6666..
97+
const float USERCMD_MSEC_PRECISE = 1000.0f / 60.0f;
98+
9699
typedef struct entityState_s {
97100
int entityNumber;
98101
idBitMsg state;
@@ -223,13 +226,25 @@ struct timeState_t {
223226
int time;
224227
int previousTime;
225228
int msec;
229+
float msecPrecise; // DG: added for smoother timing
226230
int framenum;
227231
int realClientTime;
228232

229-
void Set( int t, int pt, int ms, int f, int rct ) { time = t; previousTime = pt; msec = ms; framenum = f; realClientTime = rct; };
230-
void Get( int& t, int& pt, int& ms, int& f, int& rct ) { t = time; pt = previousTime; ms = msec; f = framenum; rct = realClientTime; };
233+
void Set( int t, int pt, int ms, int f, int rct, float msp ) { time = t; previousTime = pt; msec = ms; framenum = f; realClientTime = rct; msecPrecise = msp; };
234+
void Get( int& t, int& pt, int& ms, int& f, int& rct, float& msp ) { t = time; pt = previousTime; ms = msec; f = framenum; rct = realClientTime; msp = msecPrecise; };
231235
void Save( idSaveGame *savefile ) const { savefile->WriteInt( time ); savefile->WriteInt( previousTime ); savefile->WriteInt( msec ); savefile->WriteInt( framenum ); savefile->WriteInt( realClientTime ); }
232-
void Restore( idRestoreGame *savefile ) { savefile->ReadInt( time ); savefile->ReadInt( previousTime ); savefile->ReadInt( msec ); savefile->ReadInt( framenum ); savefile->ReadInt( realClientTime ); }
236+
void Restore( idRestoreGame *savefile ) { // DG: only functional change to Restore(): setting msecPrecise
237+
savefile->ReadInt( time ); savefile->ReadInt( previousTime );
238+
savefile->ReadInt( msec ); savefile->ReadInt( framenum );
239+
savefile->ReadInt( realClientTime );
240+
if ( msec == 16 || msec == 17 ) {
241+
msecPrecise = USERCMD_MSEC_PRECISE;
242+
} else {
243+
// if we're in some slowmo state, the approximate msec has to suffice,
244+
// it'll be set to the proper value again soon anyway.
245+
msecPrecise = msec;
246+
}
247+
}
233248
void Increment(int _msec) { // dezo2/DG: update msec (sometimes it's 16, sometimes 17)
234249
framenum++;
235250
previousTime = time;
@@ -303,6 +318,12 @@ class idGameLocal : public idGame {
303318
int time; // in msec
304319
int msec; // time since last update in milliseconds
305320

321+
// DG: unlike msec (which is varies by +/-1 each frame, see CalcMSec()),
322+
// msecPrecise remains constant (unless scaled for slowmo) and is not rounded down to an integer,
323+
// so it can be used when the correct time for multiple frames must be calculated,
324+
// or when setting an int-timer for next frame (where it rounds down which is safe for that case)
325+
float msecPrecise;
326+
306327
int vacuumAreaNum; // -1 if level doesn't have any outside areas
307328

308329
gameType_t gameType;

neo/d3xp/Game_network.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,8 +1537,8 @@ gameReturn_t idGameLocal::ClientPrediction( int clientNum, const usercmd_t *clie
15371537
}
15381538

15391539
#ifdef _D3XP
1540-
slow.Set( time, previousTime, msec, framenum, realClientTime );
1541-
fast.Set( time, previousTime, msec, framenum, realClientTime );
1540+
slow.Set( time, previousTime, msec, framenum, realClientTime, msecPrecise );
1541+
fast.Set( time, previousTime, msec, framenum, realClientTime, msecPrecise );
15421542
#endif
15431543

15441544
// set the user commands for this frame

neo/d3xp/Player.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5748,7 +5748,7 @@ void idPlayer::BobCycle( const idVec3 &pushVelocity ) {
57485748

57495749
// check for footstep / splash sounds
57505750
old = bobCycle;
5751-
bobCycle = (int)( old + bobmove * gameLocal.msec ) & 255;
5751+
bobCycle = (int)( old + bobmove * gameLocal.msecPrecise ) & 255;
57525752
bobFoot = ( bobCycle & 128 ) >> 7;
57535753
bobfracsin = idMath::Fabs( sin( ( bobCycle & 127 ) / 127.0 * idMath::PI ) );
57545754
}

neo/d3xp/PlayerView.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ void idPlayerView::DamageImpulse( idVec3 localKickDir, const idDict *damageDef )
303303
if ( blobTime ) {
304304
screenBlob_t* blob = GetScreenBlob();
305305
blob->startFadeTime = gameLocal.slow.time;
306-
blob->finishTime = gameLocal.slow.time + blobTime * g_blobTime.GetFloat() * ( ( float )gameLocal.msec / USERCMD_MSEC );
306+
// DG: use precise timing because gameLocal.msec varies by +/- 1 each frame
307+
blob->finishTime = gameLocal.slow.time + blobTime * g_blobTime.GetFloat() * ( gameLocal.msecPrecise / USERCMD_MSEC_PRECISE );
307308

308309
const char* materialName = damageDef->GetString( "mtr_blob" );
309310
blob->material = declManager->FindMaterial( materialName );

neo/d3xp/script/Script_Thread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ void idThread::WaitFrame( void ) {
929929
// manual control threads don't set waitingUntil so that they can be run again
930930
// that frame if necessary.
931931
if ( !manualControl ) {
932-
waitingUntil = gameLocal.time + gameLocal.msec;
932+
waitingUntil = gameLocal.time + gameLocal.msecPrecise;
933933
}
934934
}
935935

neo/framework/Dhewm3SettingsMenu.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,8 +1117,8 @@ static void InitBindingEntries()
11171117

11181118
{ "_attack", "Attack" , "#str_02112" },
11191119
{ "_impulse13", "Reload" , "#str_02115" },
1120-
{ "_impulse14", "Prev. Weapon" , "#str_02113" },
1121-
{ "_impulse15", "Next Weapon" , "#str_02114" },
1120+
{ "_impulse15", "Prev. Weapon" , "#str_02113" },
1121+
{ "_impulse14", "Next Weapon" , "#str_02114" },
11221122
{ "_zoom", "Zoom View" , "#str_02120" },
11231123
{ "clientDropWeapon", "Drop Weapon", "#str_04071" },
11241124

0 commit comments

Comments
 (0)