diff --git a/src/main.cpp b/src/main.cpp index c0d244271..61f7b2732 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1746,7 +1746,7 @@ void clearGlobalVariables() #ifdef ENABLE_WIIUSE wiimote_manager = NULL; #endif - World::setWorld(NULL); + World::clear(); GUIEngine::resetGlobalVariables(); } // clearGlobalVariables diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 0f98652ab..0848ccfc9 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -87,7 +87,7 @@ #include -World* World::m_world = NULL; +World* World::m_world[PT_COUNT]; /** The main world class is used to handle the track and the karts. * The end of the race is detected in two phases: first the (abstract) @@ -176,17 +176,20 @@ void World::init() main_loop->renderGUI(1100); // Grab the track file Track *track = track_manager->getTrack(RaceManager::get()->getTrackName()); - Scripting::ScriptEngine::getInstance(); - if(!track) + if (m_process_type == PT_MAIN) { - std::ostringstream msg; - msg << "Track '" << RaceManager::get()->getTrackName() - << "' not found.\n"; - throw std::runtime_error(msg.str()); - } + Scripting::ScriptEngine::getInstance(); + if(!track) + { + std::ostringstream msg; + msg << "Track '" << RaceManager::get()->getTrackName() + << "' not found.\n"; + throw std::runtime_error(msg.str()); + } - std::string script_path = track->getTrackFile("scripting.as"); - Scripting::ScriptEngine::getInstance()->loadScript(script_path, true); + std::string script_path = track->getTrackFile("scripting.as"); + Scripting::ScriptEngine::getInstance()->loadScript(script_path, true); + } main_loop->renderGUI(1200); // Create the physics Physics::create(); @@ -254,9 +257,10 @@ void World::init() if (m_race_gui) m_race_gui->init(); - powerup_manager->computeWeightsForRace(RaceManager::get()->getNumberOfKarts()); + if (m_process_type == PT_MAIN) + powerup_manager->computeWeightsForRace(RaceManager::get()->getNumberOfKarts()); main_loop->renderGUI(7200); - if (UserConfigParams::m_particles_effects > 1) + if (m_process_type == PT_MAIN && UserConfigParams::m_particles_effects > 1) { Weather::getInstance(); // create Weather instance } @@ -348,7 +352,7 @@ void World::reset(bool restart) for ( KartList::iterator i = m_karts.begin(); i != m_karts.end() ; ++i ) { (*i)->reset(); - if ((*i)->getController()->canGetAchievements()) + if (m_process_type == PT_MAIN && (*i)->getController()->canGetAchievements()) { updateAchievementModeCounters(true /*start*/); @@ -408,7 +412,8 @@ void World::reset(bool restart) } // Reset all data structures that depend on number of karts. - irr_driver->reset(); + if (m_process_type == PT_MAIN) + irr_driver->reset(); m_unfair_team = false; } // reset @@ -581,10 +586,13 @@ Controller* World::loadAIController(AbstractKart* kart) //----------------------------------------------------------------------------- World::~World() { - material_manager->unloadAllTextures(); + if (m_process_type == PT_MAIN) + material_manager->unloadAllTextures(); + RewindManager::destroy(); - irr_driver->onUnloadWorld(); + if (m_process_type == PT_MAIN) + irr_driver->onUnloadWorld(); ProjectileManager::get()->cleanup(); @@ -607,8 +615,9 @@ World::~World() // gui and this must be deleted. delete m_race_gui; } - - Weather::kill(); + + if (m_process_type == PT_MAIN) + Weather::kill(); m_karts.clear(); if(RaceManager::get()->hasGhostKarts() || RaceManager::get()->isRecordingRace()) @@ -636,11 +645,13 @@ World::~World() // but kill handles this correctly. Physics::destroy(); - Scripting::ScriptEngine::kill(); + if (m_process_type == PT_MAIN) + Scripting::ScriptEngine::kill(); - m_world = NULL; + m_world[m_process_type] = NULL; - irr_driver->getSceneManager()->clear(); + if (m_process_type == PT_MAIN) + irr_driver->getSceneManager()->clear(); #ifdef DEBUG m_magic_number = 0xDEADBEEF; @@ -719,9 +730,11 @@ void World::terminateRace() updateHighscores(&best_highscore_rank); } - updateAchievementDataEndRace(); - - PlayerManager::getCurrentPlayer()->raceFinished(); + if (m_process_type == PT_MAIN) + { + updateAchievementDataEndRace(); + PlayerManager::getCurrentPlayer()->raceFinished(); + } if (m_race_gui) m_race_gui->clearAllMessages(); // we can't delete the race gui here, since it is needed in case of @@ -839,9 +852,12 @@ void World::resetAllKarts() } // Initialise the cameras, now that the correct kart positions are set - for(unsigned int i=0; isetInitialTransform(); + for(unsigned int i=0; isetInitialTransform(); + } } } // resetAllKarts diff --git a/src/modes/world.hpp b/src/modes/world.hpp index e2d37d915..c481c9d76 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -25,6 +25,7 @@ * battle, etc.) */ +#include #include #include #include @@ -37,6 +38,7 @@ #include "states_screens/race_gui_base.hpp" #include "states_screens/state_manager.hpp" #include "utils/random_generator.hpp" +#include "utils/stk_process.hpp" #include "LinearMath/btTransform.h" @@ -88,7 +90,7 @@ public: typedef std::vector > KartList; private: /** A pointer to the global world object for a race. */ - static World *m_world; + static World *m_world[PT_COUNT]; // ------------------------------------------------------------------------ void setAITeam(); // ------------------------------------------------------------------------ @@ -208,16 +210,31 @@ public: // ================================= // ------------------------------------------------------------------------ /** Returns a pointer to the (singleton) world object. */ - static World* getWorld() { return m_world; } + static World* getWorld() + { + ProcessType type = STKProcess::getType(); + return m_world[type]; + } // ------------------------------------------------------------------------ /** Delete the )singleton) world object, if it exists, and sets the * singleton pointer to NULL. It's harmless to call this if the world * has been deleted already. */ - static void deleteWorld() { delete m_world; m_world = NULL; } + static void deleteWorld() + { + ProcessType type = STKProcess::getType(); + delete m_world[type]; + m_world[type] = NULL; + } // ------------------------------------------------------------------------ /** Sets the pointer to the world object. This is only used by * the race_manager.*/ - static void setWorld(World *world) {m_world = world; } + static void setWorld(World *world) + { + ProcessType type = STKProcess::getType(); + m_world[type] = world; + } + // ------------------------------------------------------------------------ + static void clear() { memset(m_world, 0, sizeof(m_world)); } // ------------------------------------------------------------------------ // Pure virtual functions diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 8fbaca5df..e5f1bb11c 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -33,13 +33,15 @@ #include "network/rewind_manager.hpp" #include "network/race_event_manager.hpp" #include "tracks/track.hpp" +#include "utils/stk_process.hpp" #include //----------------------------------------------------------------------------- -WorldStatus::WorldStatus() +WorldStatus::WorldStatus() : m_process_type(STKProcess::getType()) { - main_loop->setFrameBeforeLoadingWorld(); + if (m_process_type == PT_MAIN) + main_loop->setFrameBeforeLoadingWorld(); m_clock_mode = CLOCK_CHRONO; m_phase = SETUP_PHASE; @@ -55,10 +57,14 @@ WorldStatus::WorldStatus() m_play_ready_set_go_sounds = true; m_play_racestart_sounds = true; m_live_join_world = false; - IrrlichtDevice *device = irr_driver->getDevice(); - if (device->getTimer()->isStopped()) - device->getTimer()->start(); + if (m_process_type == PT_MAIN) + { + IrrlichtDevice *device = irr_driver->getDevice(); + + if (device->getTimer()->isStopped()) + device->getTimer()->start(); + } } // WorldStatus //----------------------------------------------------------------------------- @@ -95,13 +101,16 @@ void WorldStatus::reset(bool restart) // Just in case that the game is reset during the intro phase m_track_intro_sound->stop(); - IrrlichtDevice *device = irr_driver->getDevice(); + if (m_process_type == PT_MAIN) + { + IrrlichtDevice *device = irr_driver->getDevice(); - if (device->getTimer()->isStopped()) - device->getTimer()->start(); + if (device->getTimer()->isStopped()) + device->getTimer()->start(); - // Set the right music - Track::getCurrentTrack()->startMusic(); + // Set the right music + Track::getCurrentTrack()->startMusic(); + } } // reset //----------------------------------------------------------------------------- @@ -112,10 +121,14 @@ WorldStatus::~WorldStatus() m_prestart_sound->deleteSFX(); m_start_sound->deleteSFX(); m_track_intro_sound->deleteSFX(); - IrrlichtDevice *device = irr_driver->getDevice(); - if (device->getTimer()->isStopped()) - device->getTimer()->start(); + if (m_process_type == PT_MAIN) + { + IrrlichtDevice *device = irr_driver->getDevice(); + + if (device->getTimer()->isStopped()) + device->getTimer()->start(); + } } // ~WorldStatus //----------------------------------------------------------------------------- @@ -208,7 +221,7 @@ void WorldStatus::updateTime(int ticks) m_track_intro_sound->play(); } - if (Weather::getInstance()) + if (m_process_type == PT_MAIN && Weather::getInstance()) { Weather::getInstance()->playSound(); } @@ -438,7 +451,7 @@ void WorldStatus::updateTime(int ticks) switch (m_clock_mode) { case CLOCK_CHRONO: - if (!device->getTimer()->isStopped()) + if (m_process_type == PT_CHILD || !device->getTimer()->isStopped()) { m_time_ticks++; m_time = stk_config->ticks2Time(m_time_ticks); @@ -452,12 +465,12 @@ void WorldStatus::updateTime(int ticks) m_time_ticks = 0; m_time = 0.0f; // For rescue animation playing (if any) in result screen - if (!device->getTimer()->isStopped()) + if (m_process_type == PT_CHILD || !device->getTimer()->isStopped()) m_count_up_ticks++; break; } - if (!device->getTimer()->isStopped()) + if (m_process_type == PT_CHILD || !device->getTimer()->isStopped()) { m_time_ticks--; m_time = stk_config->ticks2Time(m_time_ticks); @@ -524,6 +537,10 @@ void WorldStatus::pause(Phase phase) m_previous_phase = m_phase; m_phase = phase; + + if (m_process_type != PT_MAIN) + return; + IrrlichtDevice *device = irr_driver->getDevice(); if (!device->getTimer()->isStopped() && @@ -540,6 +557,10 @@ void WorldStatus::unpause() // Set m_previous_phase so that we can use an assert // in pause to detect incorrect pause/unpause sequences. m_previous_phase = UNDEFINED_PHASE; + + if (m_process_type != PT_MAIN) + return; + IrrlichtDevice *device = irr_driver->getDevice(); if (device->getTimer()->isStopped() && diff --git a/src/modes/world_status.hpp b/src/modes/world_status.hpp index 63f989b11..b9a1ed352 100644 --- a/src/modes/world_status.hpp +++ b/src/modes/world_status.hpp @@ -21,6 +21,7 @@ #include "utils/cpp2011.hpp" #include +enum ProcessType : unsigned int; class SFXBase; /** @@ -98,6 +99,9 @@ protected: /** If the start race should be played, disabled in cutscenes. */ bool m_play_racestart_sounds; + /** Process type of this world (main or child). */ + const ProcessType m_process_type; + private: /** Sound to play at the beginning of a race, during which a * a camera intro of the track can be shown. */ diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index f58f3b6b7..5ca54da78 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -507,17 +507,20 @@ void RaceManager::startNew(bool from_overworld) */ void RaceManager::startNextRace() { - + ProcessType type = STKProcess::getType(); main_loop->renderGUI(0); // Uncomment to debug audio leaks // sfx_manager->dump(); - IrrlichtDevice* device = irr_driver->getDevice(); - GUIEngine::clearLoadingTips(); - GUIEngine::renderLoading(true/*clearIcons*/, false/*launching*/, false/*update_tips*/); - device->getVideoDriver()->endScene(); - device->getVideoDriver()->beginScene(true, true, - video::SColor(255,100,101,140)); + if (type == PT_MAIN) + { + IrrlichtDevice* device = irr_driver->getDevice(); + GUIEngine::clearLoadingTips(); + GUIEngine::renderLoading(true/*clearIcons*/, false/*launching*/, false/*update_tips*/); + device->getVideoDriver()->endScene(); + device->getVideoDriver()->beginScene(true, true, + video::SColor(255,100,101,140)); + } m_num_finished_karts = 0; m_num_finished_players = 0; @@ -647,7 +650,8 @@ void RaceManager::startNextRace() } } - irr_driver->onLoadWorld(); + if (type == PT_MAIN) + irr_driver->onLoadWorld(); main_loop->renderGUI(8100); // Save the current score and set last time to zero. This is necessary @@ -670,7 +674,8 @@ void RaceManager::startNextRace() */ void RaceManager::next() { - PropertyAnimator::get()->clear(); + if (STKProcess::getType() == PT_MAIN) + PropertyAnimator::get()->clear(); World::deleteWorld(); m_num_finished_karts = 0; m_num_finished_players = 0; @@ -835,6 +840,7 @@ void RaceManager::exitRace(bool delete_world) // Only display the grand prix result screen if all tracks // were finished, and not when a race is aborted. MessageQueue::discardStatic(); + ProcessType type = STKProcess::getType(); if ( m_major_mode==MAJOR_MODE_GRAND_PRIX && m_track_number==(int)m_tracks.size() ) @@ -890,7 +896,8 @@ void RaceManager::exitRace(bool delete_world) if (delete_world) { - PropertyAnimator::get()->clear(); + if (type == PT_MAIN) + PropertyAnimator::get()->clear(); World::deleteWorld(); } delete_world = false; @@ -933,7 +940,8 @@ void RaceManager::exitRace(bool delete_world) if (delete_world) { - PropertyAnimator::get()->clear(); + if (type == PT_MAIN) + PropertyAnimator::get()->clear(); World::deleteWorld(); }