Allow multiple logical updates per rendered frame.
Allows maintaining game speed when the GPU can't keep up.master
parent
74261ad652
commit
e50368114d
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include <time.h>
|
||||
|
||||
// Maximum seconds per frame.
|
||||
// If not reaching the goal, force graphics updates, even if we aren't doing enough game state updates to maintain game speed.
|
||||
#define MAXIMUM_SPF 1/4
|
||||
|
||||
/* See header file for documentation */
|
||||
UDWORD gameTime = 0, deltaGameTime = 0, graphicsTime = 0, deltaGraphicsTime = 0, realTime = 0, deltaRealTime = 0;
|
||||
float graphicsTimeFraction = 0.0, realTimeFraction = 0.0;
|
||||
|
@ -188,10 +192,10 @@ void gameTimeUpdate()
|
|||
{
|
||||
unsigned player;
|
||||
|
||||
// Pause time, since we are waiting GAME_GAME_TIME from other players.
|
||||
scaledCurrTime = graphicsTime;
|
||||
// Pause time at current game time, since we are waiting GAME_GAME_TIME from other players.
|
||||
scaledCurrTime = gameTime;
|
||||
baseTime = currTime;
|
||||
timeOffset = graphicsTime;
|
||||
timeOffset = gameTime;
|
||||
|
||||
debug(LOG_SYNC, "Waiting for other players. gameTime = %u, player times are {%s}", gameTime, listToString("%u", ", ", gameQueueTime, gameQueueTime + game.maxPlayers).c_str());
|
||||
mayUpdate = false;
|
||||
|
@ -212,10 +216,10 @@ void gameTimeUpdate()
|
|||
// Adjust deltas.
|
||||
if (scaledCurrTime >= gameTime && mayUpdate)
|
||||
{
|
||||
if (scaledCurrTime > gameTime + GAME_TICKS_PER_UPDATE)
|
||||
if (scaledCurrTime > gameTime + GAME_TICKS_PER_SEC*MAXIMUM_SPF)
|
||||
{
|
||||
// Game isn't updating fast enough...
|
||||
uint32_t slideBack = deltaGraphicsTime - GAME_TICKS_PER_UPDATE;
|
||||
uint32_t slideBack = deltaGraphicsTime - GAME_TICKS_PER_SEC*MAXIMUM_SPF;
|
||||
baseTime += slideBack / modifier; // adjust the addition to base time
|
||||
deltaGraphicsTime -= slideBack;
|
||||
}
|
||||
|
@ -235,6 +239,11 @@ void gameTimeUpdate()
|
|||
deltaGameTime = 0;
|
||||
}
|
||||
|
||||
if (deltaGameTime != 0)
|
||||
{
|
||||
deltaGraphicsTime = 0; // Don't update graphics until game state is updated.
|
||||
}
|
||||
|
||||
// Store the game and graphics times
|
||||
gameTime += deltaGameTime;
|
||||
graphicsTime += deltaGraphicsTime;
|
||||
|
|
|
@ -2575,9 +2575,12 @@ float available_speed[] = {
|
|||
5.f / 2.f, // n
|
||||
3.f / 1.f, // n
|
||||
10.f / 1.f, // n
|
||||
20.f / 1.f // n
|
||||
20.f / 1.f, // n
|
||||
30.f / 1.f, // n
|
||||
60.f / 1.f, // n
|
||||
100.f / 1.f, // n
|
||||
};
|
||||
unsigned int nb_available_speeds = 12;
|
||||
unsigned int nb_available_speeds = ARRAY_SIZE(available_speed);
|
||||
|
||||
void kf_SpeedUp( void )
|
||||
{
|
||||
|
|
31
src/loop.cpp
31
src/loop.cpp
|
@ -671,25 +671,34 @@ static void gameStateUpdate()
|
|||
/* The main game loop */
|
||||
GAMECODE gameLoop(void)
|
||||
{
|
||||
bool gameTicked; // true iff we are doing a logical update.
|
||||
static uint32_t lastFlushTime = 0;
|
||||
|
||||
// Receive NET_BLAH messages.
|
||||
// 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();
|
||||
|
||||
// Update gameTime and graphicsTime, and corresponding deltas. Note that gameTime and graphicsTime pause, if we aren't getting our GAME_GAME_TIME messages.
|
||||
gameTimeUpdate();
|
||||
gameTicked = deltaGameTime != 0;
|
||||
|
||||
if (gameTicked)
|
||||
bool didTick = false;
|
||||
while (true)
|
||||
{
|
||||
// Receive NET_BLAH messages.
|
||||
// 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();
|
||||
|
||||
// Update gameTime and graphicsTime, and corresponding deltas. Note that gameTime and graphicsTime pause, if we aren't getting our GAME_GAME_TIME messages.
|
||||
gameTimeUpdate();
|
||||
|
||||
if (deltaGameTime == 0)
|
||||
{
|
||||
break; // Not doing a game state update.
|
||||
}
|
||||
didTick = true;
|
||||
|
||||
ASSERT(!paused && !gameUpdatePaused() && !editPaused(), "Nonsensical pause values.");
|
||||
|
||||
syncDebug("Begin game state update, gameTime = %d", gameTime);
|
||||
gameStateUpdate();
|
||||
syncDebug("End game state update, gameTime = %d", gameTime);
|
||||
|
||||
ASSERT(deltaGraphicsTime == 0, "Shouldn't update graphics and game state at once.");
|
||||
}
|
||||
|
||||
if (gameTicked || realTime - lastFlushTime < 400u)
|
||||
if (didTick || realTime - lastFlushTime < 400u)
|
||||
{
|
||||
lastFlushTime = realTime;
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue