void CLoadScreen::SetLoadMessage(const std::string& text, bool replace_lastline) { Watchdog::ClearTimer("main"); boost::recursive_mutex::scoped_lock lck(mutex); if (!replace_lastline) { if (oldLoadMessages.empty()) { oldLoadMessages = curLoadMessage; } else { oldLoadMessages += "\n" + curLoadMessage; } } curLoadMessage = text; logOutput.Print(text); logOutput.Flush(); //! Check the FPU state (needed for synced computations), //! some external libraries which get linked during loading might reset those. //! Here it is done for the loading thread, for the mainthread it is done in CLoadScreen::Update() good_fpu_control_registers(curLoadMessage.c_str()); if (!mt_loading) Draw(); }
void CLoadScreen::SetLoadMessage(const std::string& text, bool replace_lastline) { Watchdog::ClearTimer(WDT_LOAD); boost::recursive_mutex::scoped_lock lck(mutex); if (!replace_lastline) { if (oldLoadMessages.empty()) { oldLoadMessages = curLoadMessage; } else { oldLoadMessages += "\n" + curLoadMessage; } } curLoadMessage = text; LOG("%s", text.c_str()); LOG_CLEANUP(); if (LuaIntro) LuaIntro->LoadProgress(text, replace_lastline); //! Check the FPU state (needed for synced computations), //! some external libraries which get linked during loading might reset those. //! Here it is done for the loading thread, for the mainthread it is done in CLoadScreen::Update() good_fpu_control_registers(curLoadMessage.c_str()); if (!mtLoading) { Update(); Draw(); } }
// On msvc main() is declared as a non-throwing function. // Moving the catch clause to a seperate function makes it possible to re-throw the exception for the installed crash reporter int Run(int argc, char *argv[]) { #ifdef __MINGW32__ // For the MinGW backtrace() implementation we need to know the stack end. { extern void* stack_end; char here; stack_end = (void*) &here; } #endif #ifdef STREFLOP_H // Set single precision floating point math. streflop_init<streflop::Simple>(); #endif good_fpu_control_registers("::Run"); // It's nice to be able to disable catching when you're debugging #ifndef NO_CATCH_EXCEPTIONS try { SpringApp app; return app.Run (argc,argv); } catch (const content_error& e) { SDL_Quit(); logOutput.RemoveAllSubscribers(); logOutput.Print ("Content error: %s\n", e.what()); handleerror(NULL, e.what(), "Incorrect/Missing content:", MBF_OK | MBF_EXCL); return -1; } catch (const std::exception& e) { SDL_Quit(); #ifdef _MSC_VER logOutput.Print ("Fatal error: %s\n", e.what()); logOutput.RemoveAllSubscribers(); throw; // let the error handler catch it #else logOutput.RemoveAllSubscribers(); handleerror(NULL, e.what(), "Fatal Error", MBF_OK | MBF_EXCL); return -1; #endif } catch (const char* e) { SDL_Quit(); #ifdef _MSC_VER logOutput.Print ("Fatal error: %s\n", e); logOutput.RemoveAllSubscribers(); throw; // let the error handler catch it #else logOutput.RemoveAllSubscribers(); handleerror(NULL, e, "Fatal Error", MBF_OK | MBF_EXCL); return -1; #endif } #else SpringApp app; return app.Run (argc, argv); #endif }
bool CLoadScreen::Update() { { //! cause of `curLoadMessage` boost::recursive_mutex::scoped_lock lck(mutex); //! Stuff that needs to be done regularly while loading. good_fpu_control_registers(curLoadMessage.c_str()); } if (game->finishedLoading) { CLoadScreen::DeleteInstance(); } return true; }
bool CLoadScreen::Update() { { //! cause of `curLoadMessage` boost::recursive_mutex::scoped_lock lck(mutex); //! Stuff that needs to be done regularly while loading. good_fpu_control_registers(curLoadMessage.c_str()); } if (game->IsFinishedLoading()) { CLoadScreen::DeleteInstance(); return true; } if (!mtLoading) { // without this call the window manager would think the window is unresponsive and thus asks for hard kill SDL_PollEvent(nullptr); } CNamedTextures::Update(); return true; }
CPreGame::CPreGame(bool server, const string& demo): showList(0), server(server), state(UNKNOWN), saveAddress(true) { CommandDescription::Init(); infoConsole = SAFE_NEW CInfoConsole; pregame = this; // prevent crashes if Select* is called from ctor net = SAFE_NEW CNet; if (server) { assert(good_fpu_control_registers()); gameServer = SAFE_NEW CGameServer; assert(good_fpu_control_registers()); } //hpiHandler=SAFE_NEW CHpiHandler(); activeController=this; inbufpos=0; inbuflength=0; if(!gameSetup){ for(int a=0;a<gs->activeTeams;a++){ for(int b=0;b<4;++b) gs->Team(a)->color[b]=palette.teamColor[a][b]; } } if(server){ if(gameSetup){ CScriptHandler::SelectScript(gameSetup->scriptName); SelectMap(gameSetup->mapname); SelectMod(gameSetup->baseMod); state = ALL_READY; } else { ShowScriptList(); state = WAIT_ON_SCRIPT; } } else { if(gameSetup){ PrintLoadMsg("Connecting to server"); if(net->InitClient(gameSetup->hostip.c_str(),gameSetup->hostport,gameSetup->sourceport)==-1){ handleerror(0,"Client couldn't connect","PreGame error",0); exit(-1); } CScriptHandler::SelectScript(gameSetup->scriptName); SelectMap(gameSetup->mapname); SelectMod(gameSetup->baseMod); state = ALL_READY; } else { if (demo != "") { userInput = demo; state = WAIT_ON_ADDRESS; userWriting = false; saveAddress = false; } else { userInput=configHandler.GetString("address",""); userPrompt = "Enter server address: "; state = WAIT_ON_ADDRESS; userWriting = true; } } } assert(state != UNKNOWN); }
bool CPreGame::Update() { assert(good_fpu_control_registers("CPreGame::Update")); switch (state) { case UNKNOWN: logOutput.Print("Internal error in CPreGame"); return false; case WAIT_ON_ADDRESS: if (userWriting) break; if (saveAddress) configHandler.SetString("address",userInput); if(net->InitClient(userInput.c_str(),8452,0)==-1){ logOutput.Print("Client couldn't connect"); return false; } // State is never WAIT_ON_ADDRESS if gameSetup was true in our constructor, // so if it's true here, it means net->InitClient() just loaded a demo // with gameSetup. // If so, don't wait indefinitely on a script/map/mod name, but load // everything from gameSetup and switch to ALL_READY state. if(gameSetup) { CScriptHandler::SelectScript("Commanders"); SelectMap(gameSetup->mapname); SelectMod(gameSetup->baseMod); state = ALL_READY; break; } else { state = WAIT_ON_SCRIPT; // fall trough } case WAIT_ON_SCRIPT: if (showList || !server) break; mapName = CScriptHandler::Instance().chosenScript->GetMapName(); if (mapName == "") ShowMapList(); state = WAIT_ON_MAP; // fall through case WAIT_ON_MAP: if (showList || !server) break; modName = CScriptHandler::Instance().chosenScript->GetModName(); if (modName == "") ShowModList(); state = WAIT_ON_MOD; // fall through case WAIT_ON_MOD: if (showList || !server) break; state = ALL_READY; // fall through case ALL_READY: ENTER_MIXED; // Map all required archives depending on selected mod(s) vector<string> ars = archiveScanner->GetArchives(modName); if (ars.empty()) logOutput.Print("Warning: mod archive \"%s\" is missing?\n", modName.c_str()); for (vector<string>::iterator i = ars.begin(); i != ars.end(); ++i) if (!hpiHandler->AddArchive(*i, false)) logOutput.Print("Warning: Couldn't load archive '%s'.", i->c_str()); // Determine if the map is inside an archive, and possibly map needed archives CFileHandler* f = SAFE_NEW CFileHandler("maps/" + mapName); if (!f->FileExists()) { vector<string> ars = archiveScanner->GetArchivesForMap(mapName); if (ars.empty()) logOutput.Print("Warning: map archive \"%s\" is missing?\n", mapName.c_str()); for (vector<string>::iterator i = ars.begin(); i != ars.end(); ++i) { if (!hpiHandler->AddArchive(*i, false)) logOutput.Print("Warning: Couldn't load archive '%s'.", i->c_str()); } } delete f; // always load springcontent.sdz hpiHandler->AddArchive("base/springcontent.sdz", false); LoadStartPicture(); game = SAFE_NEW CGame(server, mapName, modName, infoConsole); infoConsole = 0; ENTER_UNSYNCED; pregame=0; delete this; return true; } if(!server && state != WAIT_ON_ADDRESS){ net->Update(); UpdateClientNet(); } return true; }
/** * @brief Initializes the SpringApp instance * @return whether initialization was successful */ bool SpringApp::Initialize() { #if !(defined(WIN32) || defined(__APPLE__) || defined(HEADLESS)) //! this MUST run before any other X11 call (esp. those by SDL!) //! we need it to make calls to X11 threadsafe if (!XInitThreads()) { LOG_L(L_FATAL, "Xlib is not thread safe"); return false; } #endif #if defined(_WIN32) && defined(__GNUC__) // load QTCreator's gdb helper dll; a variant of this should also work on other OSes { // don't display a dialog box if gdb helpers aren't found UINT olderrors = SetErrorMode(SEM_FAILCRITICALERRORS); if (LoadLibrary("gdbmacros.dll")) { LOG("QT Creator's gdbmacros.dll loaded"); } SetErrorMode(olderrors); } #endif // Initialize class system creg::System::InitializeClasses(); // Initialize crash reporting CrashHandler::Install(); globalRendering = new CGlobalRendering(); ParseCmdLine(); CMyMath::Init(); good_fpu_control_registers("::Run"); Watchdog::Install(); //! register (this) mainthread Watchdog::RegisterThread(WDT_MAIN, true); // log OS version LOG("OS: %s", Platform::GetOS().c_str()); if (Platform::Is64Bit()) LOG("OS: 64bit native mode"); else if (Platform::Is32BitEmulation()) LOG("OS: emulated 32bit mode"); else LOG("OS: 32bit native mode"); FileSystemInitializer::Initialize(); UpdateOldConfigs(); if (!InitWindow(("Spring " + SpringVersion::GetSync()).c_str())) { SDL_Quit(); return false; } mouseInput = IMouseInput::GetInstance(); keyInput = KeyInput::GetInstance(); input.AddHandler(boost::bind(&SpringApp::MainEventHandler, this, _1)); // Global structures gs = new CGlobalSynced(); gu = new CGlobalUnsynced(); // Initialize GLEW LoadExtensions(); //! check if FSAA init worked fine if (globalRendering->FSAA && !MultisampleVerify()) globalRendering->FSAA = 0; InitOpenGL(); agui::InitGui(); LoadFonts(); globalRendering->PostInit(); // Initialize named texture handler CNamedTextures::Init(); // Initialize Lua GL LuaOpenGL::Init(); // Sound ISound::Initialize(); InitJoystick(); SetProcessAffinity(configHandler->GetInt("SetCoreAffinity")); // Create CGameSetup and CPreGame objects Startup(); return true; }
/** * @brief Initializes the SpringApp instance * @return whether initialization was successful */ bool SpringApp::Initialize() { assert(cmdline != NULL); assert(configHandler != NULL); // list user's config LOG("============== <User Config> =============="); const std::map<std::string, std::string> settings = configHandler->GetDataWithoutDefaults(); for (auto& it: settings) { // exclude non-engine configtags if (ConfigVariable::GetMetaData(it.first) == nullptr) continue; LOG("%s = %s", it.first.c_str(), it.second.c_str()); } LOG("============== </User Config> =============="); FileSystemInitializer::InitializeLogOutput(); CLogOutput::LogSystemInfo(); LOG(" CPU Clock: %s", spring_clock::GetName()); LOG("Physical CPU Cores: %d", Threading::GetPhysicalCpuCores()); LOG(" Logical CPU Cores: %d", Threading::GetLogicalCpuCores()); CMyMath::Init(); globalRendering = new CGlobalRendering(); globalRendering->SetFullScreen(configHandler->GetBool("Fullscreen"), cmdline->IsSet("window"), cmdline->IsSet("fullscreen")); #if !(defined(WIN32) || defined(__APPLE__) || defined(HEADLESS)) // this MUST run before any other X11 call (esp. those by SDL!) // we need it to make calls to X11 threadsafe if (!XInitThreads()) { LOG_L(L_FATAL, "Xlib is not thread safe"); return false; } #endif #if defined(WIN32) && defined(__GNUC__) // load QTCreator's gdb helper dll; a variant of this should also work on other OSes { // don't display a dialog box if gdb helpers aren't found UINT olderrors = SetErrorMode(SEM_FAILCRITICALERRORS); if (LoadLibrary("gdbmacros.dll")) { LOG_L(L_DEBUG, "QT Creator's gdbmacros.dll loaded"); } SetErrorMode(olderrors); } #endif // Initialize crash reporting CrashHandler::Install(); good_fpu_control_registers(__FUNCTION__); // CREG & GlobalConfig creg::System::InitializeClasses(); GlobalConfig::Instantiate(); // Create Window if (!InitWindow(("Spring " + SpringVersion::GetSync()).c_str())) { SDL_Quit(); return false; } // Init OpenGL LoadExtensions(); // Initialize GLEW globalRendering->PostInit(); InitOpenGL(); // Install Watchdog (must happen after time epoch is set) Watchdog::Install(); Watchdog::RegisterThread(WDT_MAIN, true); // ArchiveScanner uses for_mt --> needs thread-count set // (use all threads available, later switch to less) ThreadPool::SetThreadCount(ThreadPool::GetMaxThreads()); FileSystemInitializer::Initialize(); mouseInput = IMouseInput::GetInstance(); input.AddHandler(boost::bind(&SpringApp::MainEventHandler, this, _1)); // Global structures gs = new CGlobalSynced(); gu = new CGlobalUnsynced(); // GUIs agui::InitGui(); LoadFonts(); CNamedTextures::Init(); LuaOpenGL::Init(); ISound::Initialize(); InitJoystick(); // Lua socket restrictions luaSocketRestrictions = new CLuaSocketRestrictions(); // Multithreading & Affinity Threading::SetThreadName("unknown"); // set default threadname Threading::InitThreadPool(); Threading::SetThreadScheduler(); battery = new CBattery(); // Create CGameSetup and CPreGame objects Startup(); return true; }
/** * @brief Initializes the SpringApp instance * @return whether initialization was successful */ bool SpringApp::Initialize() { #if !(defined(WIN32) || defined(__APPLE__) || defined(HEADLESS)) //! this MUST run before any other X11 call (esp. those by SDL!) //! we need it to make calls to X11 threadsafe if (!XInitThreads()) { LOG_L(L_FATAL, "Xlib is not thread safe"); return false; } #endif #if defined(_WIN32) && defined(__GNUC__) // load QTCreator's gdb helper dll; a variant of this should also work on other OSes { // don't display a dialog box if gdb helpers aren't found UINT olderrors = SetErrorMode(SEM_FAILCRITICALERRORS); if (LoadLibrary("gdbmacros.dll")) { LOG("QT Creator's gdbmacros.dll loaded"); } SetErrorMode(olderrors); } #endif // Initialize class system creg::System::InitializeClasses(); // Initialize crash reporting CrashHandler::Install(); globalRendering = new CGlobalRendering(); ParseCmdLine(); CMyMath::Init(); good_fpu_control_registers("::Run"); // log OS version LOG("OS: %s", Platform::GetOS().c_str()); if (Platform::Is64Bit()) LOG("OS: 64bit native mode"); else if (Platform::Is32BitEmulation()) LOG("OS: emulated 32bit mode"); else LOG("OS: 32bit native mode"); // Rename Threads // We give the process itself the name `unknown`, htop & co. will still show the binary's name. // But all child threads copy by default the name of their parent, so all threads that don't set // their name themselves will show up as 'unknown'. Threading::SetThreadName("unknown"); #ifdef _OPENMP #pragma omp parallel { int i = omp_get_thread_num(); if (i != 0) { // 0 is the source thread std::ostringstream buf; buf << "omp" << i; Threading::SetThreadName(buf.str().c_str()); } } #endif // Install Watchdog Watchdog::Install(); Watchdog::RegisterThread(WDT_MAIN, true); FileSystemInitializer::Initialize(); // Create Window if (!InitWindow(("Spring " + SpringVersion::GetSync()).c_str())) { SDL_Quit(); return false; } mouseInput = IMouseInput::GetInstance(); keyInput = KeyInput::GetInstance(); input.AddHandler(boost::bind(&SpringApp::MainEventHandler, this, _1)); // Global structures gs = new CGlobalSynced(); gu = new CGlobalUnsynced(); // Initialize GLEW LoadExtensions(); //! check if FSAA init worked fine if (globalRendering->FSAA && !MultisampleVerify()) globalRendering->FSAA = 0; InitOpenGL(); agui::InitGui(); LoadFonts(); globalRendering->PostInit(); // Initialize named texture handler CNamedTextures::Init(); // Initialize Lua GL LuaOpenGL::Init(); // Sound & Input ISound::Initialize(); InitJoystick(); // Multithreading & Affinity LOG("CPU Cores: %d", Threading::GetAvailableCores()); const uint32_t affinity = configHandler->GetUnsigned("SetCoreAffinity"); const uint32_t cpuMask = Threading::SetAffinity(affinity); if (cpuMask == 0xFFFFFF) { LOG("CPU affinity not set"); } else if (cpuMask != affinity) { LOG("CPU affinity mask set: %d (config is %d)", cpuMask, affinity); } else if (cpuMask == 0) { LOG_L(L_ERROR, "Failed to CPU affinity mask <%d>", affinity); } else { LOG("CPU affinity mask set: %d", cpuMask); } // Create CGameSetup and CPreGame objects Startup(); return true; }
bool CPreGame::Update() { good_fpu_control_registers("CPreGame::Update"); switch (state) { case UNKNOWN: logOutput.Print("Internal error in CPreGame"); return false; case WAIT_ON_ADDRESS: { if (userWriting) break; if (saveAddress) configHandler.SetString("address",userInput); net->InitClient(userInput.c_str(),8452,0, 0); state = WAIT_ON_SCRIPT; // fall trough } case WAIT_ON_SCRIPT: if (showList || !server) break; mapName = CScriptHandler::Instance().chosenScript->GetMapName(); if (mapName == "") ShowMapList(); else SelectMap(mapName); state = WAIT_ON_MAP; // fall through case WAIT_ON_MAP: if (showList || !server) break; modName = CScriptHandler::Instance().chosenScript->GetModName(); if (modName == "") ShowModList(); else SelectMod(modName); state = WAIT_ON_MOD; // fall through case WAIT_ON_MOD: if (showList || !server) break; state = WAIT_CONNECTING; // fall through case WAIT_CONNECTING: if ((server || hasDemo) && !gameServer) { good_fpu_control_registers("before CGameServer creation"); gameServer = new CGameServer(gameSetup? gameSetup->hostport : 8452, mapName, modArchive, scriptName, demoFile); gameServer->AddLocalClient(gameSetup? gameSetup->myPlayerNum : 0); good_fpu_control_registers("after CGameServer creation"); } if (net->Connected()) state = ALL_READY; // fall through else break; // abort case ALL_READY: { ENTER_MIXED; const int teamID = gs->players[gu->myPlayerNum]->team; const CTeam* team = gs->Team(teamID); if (net->localDemoPlayback) gs->players[gu->myPlayerNum]->spectator = true; LoadStartPicture(team->side); game = SAFE_NEW CGame(mapName, modArchive, infoConsole); if (savefile) { savefile->LoadGame(); } infoConsole = 0; ENTER_UNSYNCED; pregame=0; delete this; return true; } default: assert(false); break; } if(state > WAIT_ON_ADDRESS) { net->Update(); UpdateClientNet(); } return true; }