Exemple #1
0
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();
}
Exemple #2
0
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;
}
Exemple #5
0
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;
}
Exemple #8
0
/**
 * @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;
}
Exemple #10
0
/**
 * @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;
}