Try to synchronize timer independent of music

This commit is contained in:
Benau 2018-04-24 01:01:47 +08:00
parent b919c82da5
commit 62ea07ecc8
5 changed files with 47 additions and 39 deletions

View File

@ -30,7 +30,6 @@
#include "modes/profile_world.hpp"
#include "modes/world.hpp"
#include "network/network_config.hpp"
#include "network/protocols/lobby_protocol.hpp"
#include "network/protocol_manager.hpp"
#include "network/race_event_manager.hpp"
#include "network/rewind_manager.hpp"
@ -55,6 +54,7 @@ MainLoop::MainLoop(unsigned parent_pid)
m_prev_time = 0;
m_throttle_fps = true;
m_is_last_substep = false;
m_frame_before_loading_world = false;
#ifdef WIN32
if (parent_pid != 0)
{
@ -302,23 +302,6 @@ void MainLoop::run()
while (!m_abort)
{
bool loading_shutdown = false;
auto lb = LobbyProtocol::get<LobbyProtocol>();
if (World::getWorld() && lb &&
STKHost::existHost() && !STKHost::get()->requestedShutdown())
{
while (!lb->allPlayersReady())
{
if (STKHost::existHost() && STKHost::get()->requestedShutdown())
{
loading_shutdown = true;
break;
}
StkTime::sleep(1);
m_curr_time = irr_driver->getDevice()->getTimer()->getRealTime();
}
}
#ifdef WIN32
if (parent != 0 && parent != INVALID_HANDLE_VALUE)
{
@ -349,8 +332,7 @@ void MainLoop::run()
// Shutdown next frame if shutdown request is sent while loading the
// world
if (!loading_shutdown && STKHost::existHost() &&
STKHost::get()->requestedShutdown())
if (STKHost::existHost() && STKHost::get()->requestedShutdown())
{
SFXManager::get()->quickSound("anvil");
core::stringw msg = _("Server connection timed out.");
@ -428,7 +410,21 @@ void MainLoop::run()
}
PROFILER_POP_CPU_MARKER();
if (World::getWorld()) World::getWorld()->updateTime(1);
if (m_frame_before_loading_world)
{
m_frame_before_loading_world = false;
break;
}
if (World::getWorld())
{
if (World::getWorld()->getPhase() == WorldStatus::SETUP_PHASE)
{
// Skip the large num steps contributed by loading time
World::getWorld()->updateTime(1);
break;
}
World::getWorld()->updateTime(1);
}
} // for i < num_steps
m_is_last_substep = false;

View File

@ -34,6 +34,7 @@ private:
/** True if the frame rate should be throttled. */
bool m_throttle_fps;
bool m_frame_before_loading_world;
/** True during the last substep of the inner main loop (where world
* is updated). Used to reduce amount of updates (e.g. sfx positions
* etc). */
@ -56,6 +57,8 @@ public:
/** Returns if this is the last substep. Used to reduce the amount
* of updates (e.g. to sfx position) to once per rendered frame. */
bool isLastSubstep() const { return m_is_last_substep; }
// ------------------------------------------------------------------------
void setFrameBeforeLoadingWorld() { m_frame_before_loading_world = true; }
}; // MainLoop
extern MainLoop* main_loop;

View File

@ -38,6 +38,7 @@
//-----------------------------------------------------------------------------
WorldStatus::WorldStatus()
{
main_loop->setFrameBeforeLoadingWorld();
m_clock_mode = CLOCK_CHRONO;
m_prestart_sound = SFXManager::get()->createSoundSource("pre_start_race");
@ -246,24 +247,42 @@ void WorldStatus::updateTime(int ticks)
m_auxiliary_ticks = 0;
if (m_play_ready_set_go_sounds)
m_prestart_sound->play();
// In a networked game the client needs to wait for a notification
// from the server that all clients and the server are ready to
// start the game. The server will actually wait for all clients
// to confirm that they have started the race before starting
// itself. In a normal race, this phase is skipped and the race
// starts immediately.
m_phase = NetworkConfig::get()->isNetworking() ? WAIT_FOR_SERVER_PHASE
: READY_PHASE;
if (NetworkConfig::get()->isNetworking())
{
m_phase = WAIT_FOR_SERVER_PHASE;
// In networked races, inform the start game protocol that
// the world has been setup
auto lobby = LobbyProtocol::get<LobbyProtocol>();
assert(lobby);
lobby->finishedLoadingWorld();
}
else
{
if (m_play_ready_set_go_sounds)
m_prestart_sound->play();
m_phase = READY_PHASE;
}
return; // Don't increase time
case WAIT_FOR_SERVER_PHASE:
{
// Wait for all players to finish loading world
auto lobby = LobbyProtocol::get<LobbyProtocol>();
assert(lobby);
if (!lobby->allPlayersReady())
return;
// This stage is only reached in case of a networked game.
// The server waits for a confirmation from
// each client that they have started (to guarantee that the
// server is running with a local time behind all clients).
if (m_play_ready_set_go_sounds)
m_prestart_sound->play();
if (NetworkConfig::get()->isServer() &&
m_server_is_ready.load() == false) return;

View File

@ -1276,8 +1276,8 @@ void ServerLobby::finishedLoadingWorldClient(Event *event)
{
std::shared_ptr<STKPeer> peer = event->getPeerSP();
m_peers_ready.at(peer) = true;
Log::info("ServerLobby", "Peer %d has finished loading world",
peer->getHostId());
Log::info("ServerLobby", "Peer %d has finished loading world at %lf",
peer->getHostId(), StkTime::getRealTime());
} // finishedLoadingWorldClient
//-----------------------------------------------------------------------------

View File

@ -46,7 +46,6 @@
#include "network/protocol_manager.hpp"
#include "network/network_config.hpp"
#include "network/network_string.hpp"
#include "network/protocols/lobby_protocol.hpp"
#include "network/race_event_manager.hpp"
#include "replay/replay_play.hpp"
#include "scriptengine/property_animator.hpp"
@ -561,15 +560,6 @@ void RaceManager::startNextRace()
m_kart_status[i].m_last_score = m_kart_status[i].m_score;
m_kart_status[i].m_last_time = 0;
}
// In networked races, inform the start game protocol that
// the world has been setup
if(NetworkConfig::get()->isNetworking())
{
auto lobby = LobbyProtocol::get<LobbyProtocol>();
assert(lobby);
lobby->finishedLoadingWorld();
}
} // startNextRace
//-----------------------------------------------------------------------------