Avoid doing extra game state updates if the game state updates are somehow slower than graphical updates.
parent
a5ad6ef0e9
commit
ceb339939e
|
@ -149,7 +149,7 @@ UDWORD getModularScaledRealTime(UDWORD timePeriod, UDWORD requiredRange)
|
|||
}
|
||||
|
||||
/* Call this each loop to update the game timer */
|
||||
void gameTimeUpdate()
|
||||
void gameTimeUpdate(unsigned renderAverage, unsigned stateAverage)
|
||||
{
|
||||
deltaGameTime = 0;
|
||||
deltaGraphicsTime = 0;
|
||||
|
@ -171,8 +171,13 @@ void gameTimeUpdate()
|
|||
return;
|
||||
}
|
||||
|
||||
(void)stateAverage; // Don't need to know the average state update time.
|
||||
// A bit arbitrary formula, but if the average time to render a frame is high compared to the time to update the
|
||||
// state, then update multiple times per frame. Otherwise, update at least once per frame.
|
||||
unsigned maximumTicksPerFrame = renderAverage*2 + GAME_TICKS_PER_UPDATE*modifier.d/std::max<int>(modifier.n, 1) + 1;
|
||||
|
||||
// Make sure graphics updates fast enough.
|
||||
prevRealTime = std::max(prevRealTime + MAXIMUM_TICKS_PER_FRAME, currTime) - MAXIMUM_TICKS_PER_FRAME; // Written this way to avoid unsigned underflow.
|
||||
prevRealTime = std::max(prevRealTime + maximumTicksPerFrame, currTime) - maximumTicksPerFrame; // Written this way to avoid unsigned underflow.
|
||||
|
||||
// Calculate the new game time
|
||||
int newDeltaGraphicsTime = quantiseFraction(modifier.n, modifier.d, currTime, prevRealTime);
|
||||
|
|
|
@ -71,7 +71,7 @@ extern void setGameTime(uint32_t newGameTime);
|
|||
* The game time increases in GAME_UNITS_PER_TICK increments, and deltaGameTime is either 0 or GAME_UNITS_PER_TICK.
|
||||
* @returns true iff the game time ticked.
|
||||
*/
|
||||
extern void gameTimeUpdate(void);
|
||||
void gameTimeUpdate(unsigned renderAverage, unsigned stateAverage);
|
||||
/// Call after updating the state, and before processing any net messages that use deltaGameTime. (Sets deltaGameTime = 0.)
|
||||
void gameTimeUpdateEnd(void);
|
||||
|
||||
|
|
26
src/loop.cpp
26
src/loop.cpp
|
@ -93,6 +93,9 @@
|
|||
#include "objmem.h"
|
||||
#endif
|
||||
|
||||
#include <numeric>
|
||||
|
||||
|
||||
static void fireWaitingCallbacks(void);
|
||||
|
||||
/*
|
||||
|
@ -663,6 +666,10 @@ static void gameStateUpdate()
|
|||
GAMECODE gameLoop(void)
|
||||
{
|
||||
static uint32_t lastFlushTime = 0;
|
||||
static unsigned stateTimes[8];
|
||||
static unsigned renderTimes[8];
|
||||
static int stateTimeIndex = 0;
|
||||
static int renderTimeIndex = 0;
|
||||
|
||||
bool didTick = false;
|
||||
while (true)
|
||||
|
@ -671,8 +678,11 @@ GAMECODE gameLoop(void)
|
|||
// Receive GAME_BLAH messages, and if it's time, process exactly as many GAME_BLAH messages as required to be able to tick the gameTime.
|
||||
recvMessage();
|
||||
|
||||
unsigned renderAverage = std::accumulate(renderTimes, renderTimes + ARRAY_SIZE(renderTimes), 0) / ARRAY_SIZE(renderTimes);
|
||||
unsigned stateAverage = std::accumulate(stateTimes, stateTimes + ARRAY_SIZE(stateTimes), 0) / ARRAY_SIZE(stateTimes);
|
||||
|
||||
// Update gameTime and graphicsTime, and corresponding deltas. Note that gameTime and graphicsTime pause, if we aren't getting our GAME_GAME_TIME messages.
|
||||
gameTimeUpdate();
|
||||
gameTimeUpdate(renderAverage, stateAverage);
|
||||
|
||||
if (deltaGameTime == 0)
|
||||
{
|
||||
|
@ -682,9 +692,14 @@ GAMECODE gameLoop(void)
|
|||
|
||||
ASSERT(!paused && !gameUpdatePaused() && !editPaused(), "Nonsensical pause values.");
|
||||
|
||||
unsigned before = wzGetTicks();
|
||||
syncDebug("Begin game state update, gameTime = %d", gameTime);
|
||||
gameStateUpdate();
|
||||
syncDebug("End game state update, gameTime = %d", gameTime);
|
||||
unsigned after = wzGetTicks();
|
||||
|
||||
stateTimes[stateTimeIndex] = after - before;
|
||||
stateTimeIndex = (stateTimeIndex + 1)%ARRAY_SIZE(stateTimes);
|
||||
|
||||
ASSERT(deltaGraphicsTime == 0, "Shouldn't update graphics and game state at once.");
|
||||
}
|
||||
|
@ -695,7 +710,14 @@ GAMECODE gameLoop(void)
|
|||
NETflush(); // Make sure the game time tick message is really sent over the network, and that we aren't waiting too long to send data.
|
||||
}
|
||||
|
||||
return renderLoop();
|
||||
unsigned before = wzGetTicks();
|
||||
GAMECODE renderReturn = renderLoop();
|
||||
unsigned after = wzGetTicks();
|
||||
|
||||
renderTimes[renderTimeIndex] = after - before;
|
||||
renderTimeIndex = (renderTimeIndex + 1)%ARRAY_SIZE(renderTimes);
|
||||
|
||||
return renderReturn;
|
||||
}
|
||||
|
||||
/* The video playback loop */
|
||||
|
|
Loading…
Reference in New Issue