Added Doom 3 BFG timestep code.

This commit is contained in:
Justin Marshall
2020-07-22 16:07:54 -07:00
parent 3f697a2509
commit fb51ac1a1f
3 changed files with 145 additions and 51 deletions
+3 -3
View File
@@ -49,16 +49,16 @@ class CCPtr
CCPtr(NoInitClass const & ) {};
CCPtr(T * ptr);
operator T * (void) const {
__forceinline operator T * (void) const {
if (ID == -1) return(NULL);
assert(Heap != NULL && ID < Heap->Length());
return((T*) (*Heap)[ID]);
}
T & operator * (void) const {
__forceinline T & operator * (void) const {
assert(Heap != NULL && ID < Heap->Length());
return(*(T*)(*Heap)[ID]);
}
T * operator -> (void) const {
__forceinline T * operator -> (void) const {
if (ID == -1) return(NULL);
assert(Heap != NULL && ID < Heap->Length());
return((T*) (*Heap)[ID]);
+109 -48
View File
@@ -146,6 +146,13 @@ bool bNoMovies = false;
KeyNumType g_globalKeyNumType = KN_NONE;
int g_globalKeyFlags = 0;
int gameFrame = 0;
int gameTimeResidual = 0;
float com_engineHz_latched = 90.0f; // Latched version of cvar, updated between map loads
int64_t com_engineHz_numerator = 100LL * 1000LL;
int64_t com_engineHz_denominator = 100LL * 60LL;
/****************************************
** Function prototypes for this module **
*****************************************/
@@ -2101,59 +2108,109 @@ FacingType KN_To_Facing(int input)
return(FACING_NONE);
}
/***********************************************************************************************
* Sync_Delay -- Forces the game into a 15 FPS rate. *
* *
* This routine will wait until the timer for the current frame has expired before *
* returning. It is called at the end of every game loop in order to force the game loop *
* to run at a fixed rate. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine will delay an amount of time according to the game speed setting. *
* *
* HISTORY: *
* 01/04/1995 JLB : Created. *
* 03/06/1995 JLB : Fixed. *
*=============================================================================================*/
static void Sync_Delay(void)
void Main_Delay()
{
/*
** Accumulate the number of 'spare' ticks that are frittered away here.
*/
SpareTicks += FrameTimer;
//--------------------------------------------
// Determine how many game tics we are going to run,
// now that the previous frame is completely finished.
//
// It is important that any waiting on the GPU be done
// before this, or there will be a bad stuttering when
// dropping frames for performance management.
//--------------------------------------------
/*
** Delay until the frame timer expires. This forces the game loop to be regulated to a
** speed controlled by the game options slider.
*/
while (FrameTimer) {
Color_Cycle();
Call_Back();
// input:
// thisFrameTime
// com_noSleep
// com_engineHz
// com_fixedTic
// com_deltaTimeClamp
// IsMultiplayer
//
// in/out state:
// gameFrame
// gameTimeResidual
// lastFrameTime
// syncNextFrame
//
// Output:
// numGameFrames
if (SpecialDialog == SDLG_NONE) {
#ifdef WIN32
WWMouse->Erase_Mouse(&HidPage, TRUE);
#endif //WIN32
KeyNumType input = KN_NONE;
int x, y;
Map.Input(input, x, y);
if (input) {
Keyboard_Process(input);
}
Map.Render();
}
}
animFrameNum+=0.5f; // This is garbage and needs to be fixed with proper delta time bits!!!
if (!FrameTimer) {
Color_Cycle();
Call_Back();
// How many game frames to run
int numGameFrames = 0;
const int deltaTimeClamp = 50;
for (;;) {
const int thisFrameTime = Sys_Milliseconds();
static int lastFrameTime = thisFrameTime; // initialized only the first time
const int deltaMilliseconds = thisFrameTime - lastFrameTime;
lastFrameTime = thisFrameTime;
// if there was a large gap in time since the last frame, or the frame
// rate is very very low, limit the number of frames we will run
const int clampedDeltaMilliseconds = min(deltaMilliseconds, deltaTimeClamp);
gameTimeResidual += clampedDeltaMilliseconds; // *timescale.GetFloat();
// don't run any frames when paused
//if (pauseGame) {
// gameFrame++;
// gameTimeResidual = 0;
// break;
//}
// debug cvar to force multiple game tics
//if (com_fixedTic.GetInteger() > 0) {
// numGameFrames = com_fixedTic.GetInteger();
// gameFrame += numGameFrames;
// gameTimeResidual = 0;
// break;
//}
//if (syncNextGameFrame) {
// // don't sleep at all
// syncNextGameFrame = false;
// gameFrame++;
// numGameFrames++;
// gameTimeResidual = 0;
// break;
//}
for (;; ) {
// How much time to wait before running the next frame,
// based on com_engineHz
const int frameDelay = FRAME_TO_MSEC(gameFrame + 1) - FRAME_TO_MSEC(gameFrame);
if (gameTimeResidual < frameDelay) {
break;
}
gameTimeResidual -= frameDelay;
gameFrame++;
numGameFrames++;
// if there is enough residual left, we may run additional frames
}
if (numGameFrames > 0) {
// ready to actually run them
break;
}
// if we are vsyncing, we always want to run at least one game
// frame and never sleep, which might happen due to scheduling issues
// if we were just looking at real time.
//if (com_noSleep.GetBool()) {
// numGameFrames = 1;
// gameFrame += numGameFrames;
// gameTimeResidual = 0;
// break;
//}
// not enough time has passed to run a frame, as might happen if
// we don't have vsync on, or the monitor is running at 120hz while
// com_engineHz is 60, so sleep a bit and check again
Sleep(0);
}
}
/***********************************************************************************************
* Main_Loop -- This is the main game loop (as a single loop). *
@@ -2483,7 +2540,11 @@ Mono_Set_Cursor(0,0);
Scenario_MapScriptFrame();
Sync_Delay();
Main_Delay();
SpareTicks += FrameTimer;
animFrameNum += 0.5f; // This is garbage and needs to be fixed with proper delta time bits!!!
Call_Back();
return(!GameActive);
}
+33
View File
@@ -1207,4 +1207,37 @@ extern int g_globalKeyFlags;
extern float animFrameNum;
extern bool g_loadingPlague;
extern float com_engineHz_latched;
extern int64_t com_engineHz_numerator;
extern int64_t com_engineHz_denominator;
__forceinline float Get_com_engineHz_latched(void) {
return com_engineHz_latched;
}
__forceinline int64_t Get_com_engineHz_numerator(void) {
return com_engineHz_numerator;
}
__forceinline int64_t Get_com_engineHz_denominator(void) {
return com_engineHz_denominator;
}
// Returns the msec the frame starts on
__forceinline int FRAME_TO_MSEC(int64_t frame) {
return (int)((frame * Get_com_engineHz_numerator()) / Get_com_engineHz_denominator());
}
// Rounds DOWN to the nearest frame
__forceinline int MSEC_TO_FRAME_FLOOR(int msec) {
return (int)((((int64_t)msec * Get_com_engineHz_denominator()) + (Get_com_engineHz_denominator() - 1)) / Get_com_engineHz_numerator());
}
// Rounds UP to the nearest frame
__forceinline int MSEC_TO_FRAME_CEIL(int msec) {
return (int)((((int64_t)msec * Get_com_engineHz_denominator()) + (Get_com_engineHz_numerator() - 1)) / Get_com_engineHz_numerator());
}
// Aligns msec so it starts on a frame bondary
__forceinline int MSEC_ALIGN_TO_FRAME(int msec) {
return FRAME_TO_MSEC(MSEC_TO_FRAME_CEIL(msec));
}
#endif