Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Avoid doing extra game state updates if the game state updates are so…

…mehow slower than graphical updates.
  • Loading branch information...
commit ceb339939edfd494974820a9e036421c8a53e742 1 parent a5ad6ef
@Cyp Cyp authored
Showing with 32 additions and 5 deletions.
  1. +7 −2 lib/gamelib/gtime.cpp
  2. +1 −1  lib/gamelib/gtime.h
  3. +24 −2 src/loop.cpp
View
9 lib/gamelib/gtime.cpp
@@ -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);
View
2  lib/gamelib/gtime.h
@@ -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);
View
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 */
Please sign in to comment.
Something went wrong with that request. Please try again.