/* The main game loop */ GAMECODE gameLoop() { static uint32_t lastFlushTime = 0; static int renderBudget = 0; // Scaled time spent rendering minus scaled time spent updating. static bool previousUpdateWasRender = false; const Rational renderFraction(2, 5); // Minimum fraction of time spent rendering. const Rational updateFraction = Rational(1) - renderFraction; countUpdate(false); // kick off with correct counts 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(renderBudget > 0 || previousUpdateWasRender); if (deltaGameTime == 0) { break; // Not doing a game state update. } ASSERT(!paused && !gameUpdatePaused(), "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(); renderBudget -= (after - before) * renderFraction.n; renderBudget = std::max(renderBudget, (-updateFraction * 500).floor()); previousUpdateWasRender = false; ASSERT(deltaGraphicsTime == 0, "Shouldn't update graphics and game state at once."); } if (realTime - lastFlushTime >= 400u) { lastFlushTime = realTime; NETflush(); // Make sure that we aren't waiting too long to send data. } unsigned before = wzGetTicks(); GAMECODE renderReturn = renderLoop(); unsigned after = wzGetTicks(); renderBudget += (after - before) * updateFraction.n; renderBudget = std::min(renderBudget, (renderFraction * 500).floor()); previousUpdateWasRender = true; return renderReturn; }
/* The main game loop */ GAMECODE gameLoop(void) { static uint32_t lastFlushTime = 0; 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 (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. } return renderLoop(); }