//this should be called on frame 0 when the game has started
void CLoadSaveHandler::LoadGame()
{
	LoadStartPicture(teamHandler->Team(gu->myTeam)->side);
	PrintLoadMsg("Loading game");
	creg::CInputStreamSerializer inputStream;
	void *pGSC = 0;
	creg::Class* gsccls = 0;
	inputStream.LoadPackage(ifs, pGSC, gsccls);

	assert (pGSC && gsccls == CGameStateCollector::StaticClass());

	CGameStateCollector *gsc = (CGameStateCollector *)pGSC;
	delete gsc; // only job of gsc is to collect gamestate data
	for (int a=0;a<MAX_TEAMS;a++)
		grouphandlers[a]->Load(ifs);
	globalAI->Load(ifs);
	delete ifs;
	for (int a=0;a<MAX_TEAMS;a++) {//For old savegames
		if (teamHandler->Team(a)->isDead && globalAI->ais[a]) {
			delete globalAI->ais[a];
			globalAI->ais[a] = 0;
		}
	}
	gs->paused = false;
	if (gameServer) {
		gameServer->isPaused = false;
		gameServer->syncErrorFrame = 0;
	}
	UnloadStartPicture();
}
示例#2
0
/// this should be called on frame 0 when the game has started
void CLoadSaveHandler::LoadGame()
{
	LoadStartPicture(teamHandler->Team(gu->myTeam)->side);
	PrintLoadMsg("Loading game");
	creg::CInputStreamSerializer inputStream;
	void *pGSC = 0;
	creg::Class* gsccls = 0;
	inputStream.LoadPackage(ifs, pGSC, gsccls);

	assert (pGSC && gsccls == CGameStateCollector::StaticClass());

	CGameStateCollector *gsc = (CGameStateCollector *)pGSC;
	delete gsc; // the only job of gsc is to collect gamestate data
	for (int a=0; a < teamHandler->ActiveTeams();a++)
		grouphandlers[a]->Load(ifs);
	eoh->Load(ifs);
	delete ifs;
	//for (int a=0; a < teamHandler->ActiveTeams(); a++) { // For old savegames
	//	if (teamHandler->Team(a)->isDead && eoh->IsSkirmishAI(a)) {
	//		eoh->DestroySkirmishAI(skirmishAIId(a), 2 /* = team died */);
	//	}
	//}
	gs->paused = false;
	if (gameServer) {
		gameServer->isPaused = false;
		gameServer->syncErrorFrame = 0;
	}
	UnloadStartPicture();
}
void CLoadScreen::Init()
{
	activeController = this;

	//! hide the cursor until we are ingame
	SDL_ShowCursor(SDL_DISABLE);

	//! When calling this function, mod archives have to be loaded
	//! and gu->myPlayerNum has to be set.
	skirmishAIHandler.LoadPreGame();

#ifdef HEADLESS
	mt_loading = false;
#else
	const int mtCfg = configHandler->GetInt("LoadingMT");
	// user override
	mt_loading = (mtCfg > 0);
	// runtime detect. disable for intel/mesa drivers, they crash at multithreaded OpenGL (date: Nov. 2011)
	mt_loading |= (mtCfg < 0) && !globalRendering->haveMesa && !globalRendering->haveIntel;
#endif

	//! Create a thread during the loading that pings the host/server, so it knows that this client is still alive/loading
	netHeartbeatThread = new boost::thread(boost::bind<void, CNetProtocol, CNetProtocol*>(&CNetProtocol::UpdateLoop, net));

	game = new CGame(mapName, modName, saveFile);

	//FIXME: remove when LuaLoadScreen was added
	{
		const CTeam* team = teamHandler->Team(gu->myTeam);
		assert(team);
		const std::string mapStartPic(mapInfo->GetStringValue("Startpic"));

		if (mapStartPic.empty())
			RandomStartPicture(team->side);
		else
			LoadStartPicture(mapStartPic);

		const std::string mapStartMusic(mapInfo->GetStringValue("Startmusic"));
		if (!mapStartMusic.empty())
			Channels::BGMusic.StreamPlay(mapStartMusic);
	}

	try {
		//! Create the Game Loading Thread
		if (mt_loading)
			gameLoadThread = new COffscreenGLThread( boost::bind(&CGame::LoadGame, game, mapName) );

	} catch (const opengl_error& gle) {
		LOG_L(L_WARNING, "Offscreen GL Context creation failed, "
				"falling back to single-threaded loading. The problem was: %s",
				gle.what());
		mt_loading = false;
	}

	if (!mt_loading) {
		LOG("LoadingScreen: single-threaded");
		game->LoadGame(mapName);
	}
}
示例#4
0
void CLoadScreen::Init()
{
	activeController = this;

	//! hide the cursor until we are ingame
	SDL_ShowCursor(SDL_DISABLE);

	//! When calling this function, mod archives have to be loaded
	//! and gu->myPlayerNum has to be set.
	skirmishAIHandler.LoadPreGame();

#ifdef HEADLESS
	mt_loading = false;
#else
	mt_loading = configHandler->Get("LoadingMT", true);
#endif

	//! Create a thread during the loading that pings the host/server, so it knows that this client is still alive/loading
	netHeartbeatThread = new boost::thread(boost::bind<void, CNetProtocol, CNetProtocol*>(&CNetProtocol::UpdateLoop, net));

	game = new CGame(mapName, modName, saveFile);

	//FIXME: remove when LuaLoadScreen was added
	{
		const CTeam* team = teamHandler->Team(gu->myTeam);
		assert(team);
		const std::string mapStartPic(mapInfo->GetStringValue("Startpic"));

		if (mapStartPic.empty())
			RandomStartPicture(team->side);
		else
			LoadStartPicture(mapStartPic);

		const std::string mapStartMusic(mapInfo->GetStringValue("Startmusic"));
		if (!mapStartMusic.empty())
			Channels::BGMusic.StreamPlay(mapStartMusic);
	}

	try {
		//! Create the Game Loading Thread
		if (mt_loading)
			gameLoadThread = new COffscreenGLThread( boost::bind(&CGame::LoadGame, game, mapName) );

	} catch (opengl_error& gle) {
		//! Offscreen GL Context creation failed,
		//! fallback to singlethreaded loading.
		logOutput.Print(std::string(gle.what()));
		logOutput.Print("Fallback to singlethreaded loading.");
		mt_loading = false;
	}

	if (!mt_loading) {
		Draw();
		game->LoadGame(mapName);
	}
}
示例#5
0
void CLoadScreen::RandomStartPicture(const std::string& sidePref)
{
	if (startupTexture)
		return;

	const std::string picDir = "bitmaps/loadpictures/";

	std::string name = "";
	if (!sidePref.empty()) {
		name = SelectPicture(picDir, sidePref + "_");
	}
	if (name.empty()) {
		name = SelectPicture(picDir, "");
	}
	if (name.empty() || (name.rfind(".db") == name.size() - 3)) {
		return; // no valid pictures
	}
	LoadStartPicture(name);
}
void CLoadSaveHandler::SaveGame(std::string file)
{
	LoadStartPicture(teamHandler->Team(gu->myTeam)->side);
	PrintLoadMsg("Saving game");
	try {
		std::ofstream ofs(filesystem.LocateFile(file, FileSystem::WRITE).c_str(), std::ios::out|std::ios::binary);
		if (ofs.bad() || !ofs.is_open()) {
			handleerror(0,"Couldnt save game to file",file.c_str(),0);
			return;
		}

		std::string scriptText;
		if (gameSetup) {
			scriptText = gameSetup->gameSetupText;
		}

		WriteString(ofs, scriptText);

		WriteString(ofs, modName);
		WriteString(ofs, mapName);

		CGameStateCollector *gsc = new CGameStateCollector();

		creg::COutputStreamSerializer os;
		os.SavePackage(&ofs, gsc, gsc->GetClass());
		PrintSize("Game",ofs.tellp());
		int aistart = ofs.tellp();
		for (int a=0;a<MAX_TEAMS;a++)
			grouphandlers[a]->Save(&ofs);
		globalAI->Save(&ofs);
		PrintSize("AIs",((int)ofs.tellp())-aistart);
	} catch (content_error &e) {
		logOutput.Print("Save faild(content error): %s",e.what());
	} catch (std::exception &e) {
		logOutput.Print("Save faild: %s",e.what());
	} catch (char* &e) {
		logOutput.Print("Save faild: %s",e);
	} catch (...) {
		logOutput.Print("Save faild(unknwon error)");
	}
	UnloadStartPicture();
}
示例#7
0
bool CPreGame::Update(void)
{
	if(waitOnAddress && !userWriting){
		waitOnAddress=false;
		if (saveAddress)
			configHandler.SetString("address",userInput);
		if(net->InitClient(userInput.c_str(),8452,0)==-1){
			info->AddLine("Client couldnt connect");
			return false;
		}
		userWriting=false;
	}

	if(!server && !waitOnAddress){
		net->Update();
		UpdateClientNet();
	}

	if(waitOnScript && !showList){
		waitOnScript=false;

		mapName=CScriptHandler::Instance().chosenScript->GetMapName();

		if(mapName==""){
			ShowMapList();
			waitOnMap=true;
		} else {
			allReady=true;
		}
	}

	if(allReady){
		ENTER_MIXED;

		// Map all required archives depending on selected mod(s)
		stupidGlobalModName = MOD_FILE;
		if (gameSetup)
			stupidGlobalModName = gameSetup->baseMod;
		vector<string> ars = archiveScanner->GetArchives(stupidGlobalModName);
		for (vector<string>::iterator i = ars.begin(); i != ars.end(); ++i) {
			hpiHandler->AddArchive(*i, false);
		}

		// Determine if the map is inside an archive, and possibly map needed archives
		CFileHandler* f = new CFileHandler("maps/" + mapName);
		if (!f->FileExists()) {
			vector<string> ars = archiveScanner->GetArchivesForMap(mapName);
			for (vector<string>::iterator i = ars.begin(); i != ars.end(); ++i) {
				hpiHandler->AddArchive(*i, false);
			}
		}
		delete f;

		LoadStartPicture();

		game=new CGame(server,mapName);
		ENTER_UNSYNCED;
		game->Update();
		pregame=0;
		delete this;
		return true;
	}
	return true;
}
示例#8
0
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;
}
示例#9
0
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;
}