コード例 #1
0
ファイル: GameSetup.cpp プロジェクト: niavok/spring
void CGameSetup::LoadStartPositions(bool withoutMap)
{
	if (withoutMap && (startPosType == StartPos_Random || startPosType == StartPos_Fixed))
		throw content_error("You need the map to use the map's startpositions");

	if (startPosType == StartPos_Random) {
		// Server syncs these later, so we can use unsynced rng
		UnsyncedRNG rng;
		rng.Seed(gameSetupText.length());
		rng.Seed((size_t)gameSetupText.c_str());
		std::vector<int> teamStartNum(teamStartingData.size());
		for (size_t i = 0; i < teamStartingData.size(); ++i)
			teamStartNum[i] = i;
		std::random_shuffle(teamStartNum.begin(), teamStartNum.end(), rng);
		for (size_t i = 0; i < teamStartingData.size(); ++i)
			teamStartingData[i].teamStartNum = teamStartNum[i];
	}
	else
	{
		for (size_t a = 0; a < teamStartingData.size(); ++a) {
			teamStartingData[a].teamStartNum = (int)a;
		}
	}

	if (startPosType == StartPos_Fixed || startPosType == StartPos_Random)
		LoadStartPositionsFromMap();

	// Show that we havent selected start pos yet
	if (startPosType == StartPos_ChooseInGame) {
		for (size_t a = 0; a < teamStartingData.size(); ++a) {
			teamStartingData[a].startPos.y = -500;
		}
	}
}
コード例 #2
0
void CGameSetup::LoadStartPositions(bool withoutMap)
{
	TdfParser file(gameSetupText.c_str(), gameSetupText.length());

	if (withoutMap && (startPosType == StartPos_Random || startPosType == StartPos_Fixed))
		throw content_error("You need the map to use the map's startpositions");

	if (startPosType == StartPos_Random) {
		// Server syncs these later, so we can use unsynced rng
		UnsyncedRNG rng;
		rng.Seed(gameSetupText.length());
		rng.Seed((size_t)gameSetupText.c_str());
		std::vector<int> teamStartNum(teamStartingData.size());
		for (size_t i = 0; i < teamStartingData.size(); ++i)
			teamStartNum[i] = i;
		std::random_shuffle(teamStartNum.begin(), teamStartNum.end(), rng);
		for (size_t i = 0; i < teamStartingData.size(); ++i)
			teamStartingData[i].teamStartNum = teamStartNum[i];
	}
	else
	{
		for (size_t a = 0; a < teamStartingData.size(); ++a) {
			teamStartingData[a].teamStartNum = (int)a;
		}
	}

	if (!withoutMap)
		LoadStartPositionsFromMap();

	// Show that we havent selected start pos yet
	if (startPosType == StartPos_ChooseInGame) {
		for (size_t a = 0; a < teamStartingData.size(); ++a) {
			teamStartingData[a].startPos.y = -500;
		}
	}

	// Load start position from gameSetup script
	if (startPosType == StartPos_ChooseBeforeGame) {
		for (size_t a = 0; a < teamStartingData.size(); ++a) {
			char section[50];
			sprintf(section, "GAME\\TEAM%i\\", a);
			string s(section);
			std::string xpos = file.SGetValueDef("", s + "StartPosX");
			std::string zpos = file.SGetValueDef("", s + "StartPosZ");
			if (!xpos.empty())
			{
				teamStartingData[a].startPos.x = atoi(xpos.c_str());
			}
			if (!zpos.empty())
			{
				teamStartingData[a].startPos.z = atoi(zpos.c_str());
			}
		}
	}
}
コード例 #3
0
ファイル: TimeProfiler.cpp プロジェクト: Dmytry/spring
void CTimeProfiler::AddTime(const std::string& name, unsigned time)
{
	GML_STDMUTEX_LOCK_NOPROF(time); // AddTime

	std::map<std::string, TimeRecord>::iterator pi;
	if ( (pi = profile.find(name)) != profile.end() )
	{
		pi->second.total+=time;
		pi->second.current+=time;
		pi->second.frames[currentPosition]+=time;
	}
	else
	{
		profile[name].total=time;
		profile[name].current=time;
		profile[name].percent=0;
		memset(profile[name].frames, 0, 128*sizeof(unsigned));
		static UnsyncedRNG rand;
		rand.Seed(SDL_GetTicks());
		profile[name].color.x = rand.RandFloat();
		profile[name].color.y = rand.RandFloat();
		profile[name].color.z = rand.RandFloat();
		profile[name].showGraph=true;
	}
}
コード例 #4
0
ファイル: TimeProfiler.cpp プロジェクト: jamerlan/spring
void CTimeProfiler::AddTime(const std::string& name, const spring_time time, const bool showGraph)
{
	std::map<std::string, TimeRecord>::iterator pi;
	if ( (pi = profile.find(name)) != profile.end() ) {
		// profile already exists
		//FIXME use atomic ints
		pi->second.total   += time;
		pi->second.current += time;
		pi->second.frames[currentPosition] += time;
	} else {
		boost::unique_lock<boost::mutex> ulk(m, boost::defer_lock);
		while (!ulk.try_lock()) {}

		// create a new profile
		auto& p = profile[name];
		p.total   = time;
		p.current = time;
		p.percent = 0;
		memset(p.frames, 0, TimeRecord::frames_size * sizeof(unsigned));
		static UnsyncedRNG rand;
		rand.Seed(spring_tomsecs(spring_gettime()));
		p.color.x = rand.RandFloat();
		p.color.y = rand.RandFloat();
		p.color.z = rand.RandFloat();
		p.showGraph = showGraph;
	}
}
コード例 #5
0
ファイル: TimeProfiler.cpp プロジェクト: BrainDamage/spring
void CTimeProfiler::AddTime(const std::string& name, unsigned time)
{
	GML_STDMUTEX_LOCK_NOPROF(time); // AddTime

	std::map<std::string, TimeRecord>::iterator pi;
	if ( (pi = profile.find(name)) != profile.end() ) {
		// profile already exists
		pi->second.total+=time;
		pi->second.current+=time;
		pi->second.frames[currentPosition]+=time;
	} else {
		// create a new profile
		profile[name].total=time;
		profile[name].current=time;
		profile[name].percent=0;
		memset(profile[name].frames, 0, TimeRecord::frames_size*sizeof(unsigned));
		static UnsyncedRNG rand;
		rand.Seed(SDL_GetTicks());
		profile[name].color.x = rand.RandFloat();
		profile[name].color.y = rand.RandFloat();
		profile[name].color.z = rand.RandFloat();
		// only show "CPU load" by default
		profile[name].showGraph = (name == "CPU load");
	}
}
コード例 #6
0
ファイル: GrassDrawer.cpp プロジェクト: vladmihaisima/spring
void CGrassDrawer::DrawNearBillboards(const std::vector<InviewNearGrass>& inviewNearGrass)
{
	CVertexArray* va = GetVertexArray();
	va->Initialize();
	va->EnlargeArrays(inviewNearGrass.size() * numTurfs * 4, 0, VA_SIZE_TN);

	for (std::vector<InviewNearGrass>::const_iterator gi = inviewNearGrass.begin(); gi != inviewNearGrass.end(); ++gi) {
		const int x = (*gi).x;
		const int y = (*gi).y;

		rng.Seed(y * 1025 + x);

		for (int a = 0; a < numTurfs; a++) {
			const float dx = (x + rng.RandFloat()) * gSSsq;
			const float dy = (y + rng.RandFloat()) * gSSsq;
			const float col = 1.0f;

			float3 pos(dx, CGround::GetHeightReal(dx, dy, false) + 0.5f, dy);
				pos.y -= (CGround::GetSlope(dx, dy, false) * 10.0f + 0.03f);

			va->AddVertexQTN(pos,         0.0f, 0.0f, float3(-partTurfSize, -partTurfSize, col));
			va->AddVertexQTN(pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize, -partTurfSize, col));
			va->AddVertexQTN(pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize,  partTurfSize, col));
			va->AddVertexQTN(pos,         0.0f, 1.0f, float3(-partTurfSize,  partTurfSize, col));
		}
	}

	va->DrawArrayTN(GL_QUADS);
}
コード例 #7
0
void CGrassDrawer::CreateGrassDispList(int listNum)
{
	CVertexArray* va = GetVertexArray();
	va->Initialize();
	rng.Seed(15);

	for (int a = 0; a < strawPerTurf; ++a) {
		// draw a single blade
		const float lngRnd = rng.RandFloat();
		const float length = mapInfo->grass.bladeHeight * (1.0f + lngRnd);
		const float maxAng = mapInfo->grass.bladeAngle * std::max(rng.RandFloat(), 1.f - smoothstep(0.f,1.f,lngRnd));

		float3 sideVect(rng.RandFloat() - 0.5f, 0.0f, rng.RandFloat() - 0.5f);
		sideVect.ANormalize();
		float3 bendVect = sideVect.cross(UpVector); // direction to bend into
		sideVect *= mapInfo->grass.bladeWidth * (-0.15f * lngRnd + 1.0f);
		const float3 basePos = rng.RandVector2D() * (turfSize - (bendVect * std::sin(maxAng) * length).Length2D());

		// select one of the 16 color shadings
		const float xtexCoord = (rng.RandInt() % 16) / 16.0f;
		const int numSections = 2 + int(maxAng * 1.2f + length * 0.2f);

		float3 normalBend = -bendVect;

		// start btm
		va->AddVertexTN(basePos + sideVect - float3(0.0f, 3.0f, 0.0f), xtexCoord              , 0.f, normalBend);
		va->AddVertexTN(basePos - sideVect - float3(0.0f, 3.0f, 0.0f), xtexCoord + (1.0f / 16), 0.f, normalBend);

		for (float h = 0.0f; h < 1.0f; h += (1.0f / numSections)) {
			const float ang = maxAng * h;
			const float3 n = (normalBend * std::cos(ang) + UpVector * std::sin(ang)).ANormalize();
			const float3 edgePos  = (UpVector * std::cos(ang) + bendVect * std::sin(ang)) * length * h;
			const float3 edgePosL = edgePos - sideVect * (1.0f - h);
			const float3 edgePosR = edgePos + sideVect * (1.0f - h);

			va->AddVertexTN(basePos + edgePosR, xtexCoord + (1.0f / 32) * h              , h, (n + sideVect * 0.04f).ANormalize());
			va->AddVertexTN(basePos + edgePosL, xtexCoord - (1.0f / 32) * h + (1.0f / 16), h, (n - sideVect * 0.04f).ANormalize());
		}

		// end top tip (single triangle)
		const float3 edgePos = (UpVector * std::cos(maxAng) + bendVect * std::sin(maxAng)) * length;
		const float3 n = (normalBend * std::cos(maxAng) + UpVector * std::sin(maxAng)).ANormalize();
		va->AddVertexTN(basePos + edgePos, xtexCoord + (1.0f / 32), 1.0f, n);

		// next blade
		va->EndStrip();
	}

	glNewList(listNum, GL_COMPILE);
	va->DrawArrayTN(GL_TRIANGLE_STRIP);
	glEndList();
}
コード例 #8
0
void CGrassDrawer::DrawBillboard(const int x, const int y, const float dist, VA_TYPE_TN* va_tn)
{
	UnsyncedRNG rng; // need our own, cause this function may run threaded
	rng.Seed(y * mapDims.mapx / grassSquareSize + x);
	const float rdist  = 1.0f + rng.RandFloat() * 0.5f;
	float alpha = 1.0f - linearstep(maxGrassDist,  maxGrassDist + 127.f, dist + 128.f);
	alpha = std::min(alpha, linearstep(maxDetailedDist, maxDetailedDist + 128.f * rdist, dist));

	for (int a = 0; a < numTurfs; a++) {
		const STurfParams p = GetTurfParams(rng, x, y);
		float3 pos(p.x, CGround::GetHeightReal(p.x, p.y, false), p.y);
			pos.y -= CGround::GetSlope(p.x, p.y, false) * 30.0f;

		va_tn[a * 4 + 0] = { pos,         0.0f, 1.0f, float3(-partTurfSize, -partTurfSize, alpha) };
		va_tn[a * 4 + 1] = { pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize, -partTurfSize, alpha) };
		va_tn[a * 4 + 2] = { pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize,  partTurfSize, alpha) };
		va_tn[a * 4 + 3] = { pos,         0.0f, 0.0f, float3(-partTurfSize,  partTurfSize, alpha) };
	}
}
コード例 #9
0
ファイル: GrassDrawer.cpp プロジェクト: 304471720/spring
void CGrassBlockDrawer::DrawDetailQuad(const int x, const int y)
{
	const float maxDetailedDist = gd->maxDetailedDist;

	// blocks close to the camera
	for (int y2 = y * grassBlockSize; y2 < (y + 1) * grassBlockSize; ++y2) {
		for (int x2 = x * grassBlockSize; x2 < (x + 1) * grassBlockSize; ++x2) {
			if (!gd->grassMap[y2 * gs->mapx / grassSquareSize + x2]) {
				continue;
			}

			rng.Seed(y2 * gs->mapx / grassSquareSize + x2);
			const float dist  = GetCamDistOfGrassBlock(x2, y2, false);
			const float rdist = 1.0f + rng.RandFloat() * 0.5f;

			//TODO instead of adding grass turfs depending on their distance to the camera,
			//     there should be a fixed sized pool for mesh & billboard turfs
			//     and then we fill these pools with _preference_ for close distance turfs.
			//     So when a map has only less turfs, render them independent of the cam distance as mesh.
			//     -> see Ravaged_2
			if (dist < (maxDetailedDist + 128.f * rdist)) {
				// close grass (render as mesh)
				CGrassDrawer::InviewNearGrass iv;
				iv.dist = dist;
				iv.x = x2;
				iv.y = y2;
				inviewGrass.push_back(iv);
			}

			if (dist > maxDetailedDist) {
				// near but not close, save for later drawing
				CGrassDrawer::InviewNearGrass iv;
				iv.dist = dist;
				iv.x = x2;
				iv.y = y2;
				inviewNearGrass.push_back(iv);
			}
		}
	}
}
コード例 #10
0
void CGrassDrawer::DrawNear(const std::vector<InviewNearGrass>& inviewGrass)
{
	for (const InviewNearGrass& g: inviewGrass) {
		rng.Seed(g.y * mapDims.mapx / grassSquareSize + g.x);
//		const float distSq = GetCamDistOfGrassBlock(g.x, g.y, true);
		const float rdist  = 1.0f + rng.RandFloat() * 0.5f;
		const float alpha  = linearstep(maxDetailedDist, maxDetailedDist + 128.f * rdist, g.dist);

		for (int a = 0; a < numTurfs; a++) {
			const STurfParams& p = GetTurfParams(rng, g.x, g.y);
			float3 pos(p.x, CGround::GetHeightReal(p.x, p.y, false), p.y);
				pos.y -= CGround::GetSlope(p.x, p.y, false) * 30.0f;
				pos.y -= 2.0f * mapInfo->grass.bladeHeight * alpha;

			glPushMatrix();
			glTranslatef3(pos);
			glRotatef(p.rotation, 0.0f, 1.0f, 0.0f);
			glCallList(grassDL);
			glPopMatrix();
		}
	}
}
コード例 #11
0
ファイル: main.cpp プロジェクト: slogic/spring
int main(int argc, char *argv[])
{
#ifdef _WIN32
	try {
#endif
	SDL_Init(SDL_INIT_TIMER);
	std::cout << "If you find any errors, report them to mantis or the forums." << std::endl << std::endl;

	ConfigHandler::Instantiate(); // use the default config file
	FileSystemHandler::Initialize(false);

	CGameServer* server = 0;
	CGameSetup* gameSetup = 0;

	if (argc == 2) {
		const std::string script(argv[1]);
		std::string buf;

		std::cout << "Loading script from file: " << script << std::endl;

		ClientSetup settings;
		CFileHandler fh(argv[1]);

		if (!fh.FileExists())
			throw content_error("script does not exist in given location: " + script);

		if (!fh.LoadStringData(buf))
			throw content_error("script cannot be read: " + script);
		settings.Init(buf);

		gameSetup = new CGameSetup();	// to store the gamedata inside

		if (!gameSetup->Init(buf)) {
			// read the script provided by cmdline
			std::cout << "Failed to load script" << std::endl;
			return 1;
		}

		std::cout << "Starting server..." << std::endl;

		// Create the server, it will run in a separate thread
		GameData data;
		UnsyncedRNG rng;

		rng.Seed(gameSetup->gameSetupText.length());
		rng.Seed(script.length());
		data.SetRandomSeed(rng.RandInt());

		//  Use script provided hashes if they exist
		if (gameSetup->mapHash != 0) {
			data.SetMapChecksum(gameSetup->mapHash);
			gameSetup->LoadStartPositions(false); // reduced mode
		} else {
			data.SetMapChecksum(archiveScanner->GetArchiveCompleteChecksum(gameSetup->mapName));

			CFileHandler f("maps/" + gameSetup->mapName);
			if (!f.FileExists()) {
				vfsHandler->AddArchiveWithDeps(gameSetup->mapName, false);
			}
			gameSetup->LoadStartPositions(); // full mode
		}

		if (gameSetup->modHash != 0) {
			data.SetModChecksum(gameSetup->modHash);
		} else {
			const std::string& modArchive = archiveScanner->ArchiveFromName(gameSetup->modName);
			const unsigned int modCheckSum = archiveScanner->GetArchiveCompleteChecksum(modArchive);
			data.SetModChecksum(modCheckSum);
		}

		data.SetSetup(gameSetup->gameSetupText);
		server = new CGameServer(settings.hostIP, settings.hostPort, &data, gameSetup);

		while (!server->HasFinished()) // check if still running
#ifdef _WIN32
			Sleep(1000);
#else
			sleep(1);	// if so, wait 1  second
#endif
		delete server;	// delete the server after usage
	} else {
		std::cout << "usage: " << argv[0] << " <full_path_to_script>" << std::endl;
	}

	FileSystemHandler::Cleanup();
	ConfigHandler::Deallocate();

#ifdef _WIN32
	} catch (const std::exception& err) {
		std::cout << "Exception raised: " << err.what() << std::endl;
		return 1;
	}
#endif
	return 0;
}
コード例 #12
0
CGrassDrawer::CGrassDrawer()
: CEventClient("[GrassDrawer]", 199992, false)
, grassOff(false)
, blocksX(mapDims.mapx / grassSquareSize / grassBlockSize)
, blocksY(mapDims.mapy / grassSquareSize / grassBlockSize)
, grassDL(0)
, grassBladeTex(0)
, farTex(0)
, farnearVA(nullptr)
, updateBillboards(false)
, grassMap(nullptr)
{
	blockDrawer.ResetState();
	rng.Seed(15);

	const int detail = configHandler->GetInt("GrassDetail");

	// some ATI drivers crash with grass enabled, default to disabled
	if ((detail == 0) || ((detail == 7) && globalRendering->haveATI)) {
		grassOff = true;
		return;
	}

	// needed to create the far tex
	if (!GLEW_EXT_framebuffer_blit) {
		grassOff = true;
		return;
	}

	// load grass density from map
	{
		MapBitmapInfo grassbm;
		unsigned char* grassdata = readMap->GetInfoMap("grass", &grassbm);
		if (!grassdata) {
			grassOff = true;
			return;
		}

		if (grassbm.width != mapDims.mapx / grassSquareSize || grassbm.height != mapDims.mapy / grassSquareSize) {
			char b[128];
			SNPRINTF(b, sizeof(b), "grass-map has wrong size (%dx%d, should be %dx%d)\n",
				grassbm.width, grassbm.height, mapDims.mapx / 4, mapDims.mapy / 4);
			throw std::runtime_error(b);
		}
		const int grassMapSize = mapDims.mapx * mapDims.mapy / (grassSquareSize * grassSquareSize);
		grassMap = new unsigned char[grassMapSize];
		memcpy(grassMap, grassdata, grassMapSize);
		readMap->FreeInfoMap("grass", grassdata);
	}

	// create/load blade texture
	{
		CBitmap grassBladeTexBM;
		if (!grassBladeTexBM.Load(mapInfo->grass.bladeTexName)) {
			// map didn't define a grasstex, so generate one
			grassBladeTexBM.channels = 4;
			grassBladeTexBM.Alloc(256,64);

			for (int a = 0; a < 16; ++a) {
				CreateGrassBladeTex(&grassBladeTexBM.mem[a * 16 * 4]);
			}
		}
		//grassBladeTexBM.Save("blade.png", false);
		grassBladeTex = grassBladeTexBM.CreateTexture(true);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}

	// create shaders * finalize
	grass.resize(blocksX * blocksY);
	farnearVA = new CVertexArray;
	grassDL = glGenLists(1);

	ChangeDetail(detail);
	LoadGrassShaders();
	configHandler->NotifyOnChange(this);

	// eventclient
	autoLinkEvents = true;
	RegisterLinkedEvents(this);
	eventHandler.AddClient(this);
}
コード例 #13
0
ファイル: main.cpp プロジェクト: javaphoon/spring
int main(int argc, char *argv[])
{
#ifdef _WIN32
	try {
#endif
	std::cout << "If you find any errors, report them to mantis or the forums." << std::endl << std::endl;
	ConfigHandler::Instantiate("");
	FileSystemHandler::Cleanup();
	FileSystemHandler::Initialize(false);
	CGameServer* server = 0;
	CGameSetup* gameSetup = 0;

	if (argc > 1)
	{
		const std::string script(argv[1]);
		std::cout << "Loading script from file: " << script << std::endl;

		ClientSetup settings;
		CFileHandler fh(argv[1]);
		if (!fh.FileExists())
			throw content_error("Setupscript doesn't exists in given location: "+script);

		std::string buf;
		if (!fh.LoadStringData(buf))
			throw content_error("Setupscript cannot be read: "+script);
		settings.Init(buf);

		gameSetup = new CGameSetup();	// to store the gamedata inside
		if (!gameSetup->Init(buf))	// read the script provided by cmdline
		{
			std::cout << "Failed to load script" << std::endl;
			return 1;
		}

		std::cout << "Starting server..." << std::endl;
		// Create the server, it will run in a separate thread
		GameData* data = new GameData();
		UnsyncedRNG rng;
		rng.Seed(gameSetup->gameSetupText.length());
		rng.Seed(script.length());
		data->SetRandomSeed(rng.RandInt());

		//  Use script provided hashes if they exist
		if (gameSetup->mapHash != 0)
		{
			data->SetMapChecksum(gameSetup->mapHash);
			gameSetup->LoadStartPositions(false); // reduced mode
		}
		else
		{
			data->SetMapChecksum(archiveScanner->GetMapChecksum(gameSetup->mapName));

			CFileHandler* f = new CFileHandler("maps/" + gameSetup->mapName);
			if (!f->FileExists()) {
				std::vector<std::string> ars = archiveScanner->GetArchivesForMap(gameSetup->mapName);
				if (ars.empty()) {
					throw content_error("Couldn't find any archives for map '" + gameSetup->mapName + "'.");
				}
				for (std::vector<std::string>::iterator i = ars.begin(); i != ars.end(); ++i) {
					if (!vfsHandler->AddArchive(*i, false)) {
						throw content_error("Couldn't load archive '" + *i + "' for map '" + gameSetup->mapName + "'.");
					}
				}
			}
			delete f;
			gameSetup->LoadStartPositions(); // full mode
		}

		if (gameSetup->modHash != 0) {
			data->SetModChecksum(gameSetup->modHash);
		} else {
			const std::string modArchive = archiveScanner->ModNameToModArchive(gameSetup->modName);
			data->SetModChecksum(archiveScanner->GetModChecksum(modArchive));
		}

		data->SetSetup(gameSetup->gameSetupText);
		server = new CGameServer(&settings, false, data, gameSetup);

		while (!server->HasFinished()) // check if still running
#ifdef _WIN32
			Sleep(1000);
#else
			sleep(1);	// if so, wait 1  second
#endif
		delete server;	// delete the server after usage
	}
	else
	{
		std::cout << "usage: spring-dedicated <full_path_to_script>" << std::endl;
	}

	FileSystemHandler::Cleanup();

#ifdef _WIN32
	}
	catch (const std::exception& err)
	{
		std::cout << "Exception raised: " << err.what() << std::endl;
		return 1;
	}
#endif
	return 0;
}
コード例 #14
0
ファイル: main.cpp プロジェクト: GHackAnonymous/spring
int main(int argc, char* argv[])
{
	try {
		spring_clock::PushTickRate();
		// initialize start time (can safely be done before SDL_Init
		// since we are not using SDL_GetTicks as our clock anymore)
		spring_time::setstarttime(spring_time::gettime(true));

		CLogOutput::LogSystemInfo();

		std::string scriptName;
		std::string scriptText;

		ParseCmdLine(argc, argv, &scriptName);

		GlobalConfig::Instantiate();
		FileSystemInitializer::InitializeLogOutput();
		FileSystemInitializer::Initialize();

		// Initialize crash reporting
		CrashHandler::Install();

		LOG("report any errors to Mantis or the forums.");
		LOG("loading script from file: %s", scriptName.c_str());

		CGameServer* server = NULL;

		// server will take ownership of these
		boost::shared_ptr<ClientSetup> dsClientSetup(new ClientSetup());
		boost::shared_ptr<GameData> dsGameData(new GameData());
		boost::shared_ptr<CGameSetup> dsGameSetup(new CGameSetup());

		CFileHandler fh(scriptName);

		if (!fh.FileExists())
			throw content_error("script does not exist in given location: " + scriptName);

		if (!fh.LoadStringData(scriptText))
			throw content_error("script cannot be read: " + scriptName);

		dsClientSetup->LoadFromStartScript(scriptText);

		if (!dsGameSetup->Init(scriptText)) {
			// read the script provided by cmdline
			LOG_L(L_ERROR, "failed to load script %s", scriptName.c_str());
			return 1;
		}

		// Create the server, it will run in a separate thread
		UnsyncedRNG rng;

		const unsigned seed = time(NULL) % ((spring_gettime().toNanoSecsi() + 1) * 9007);
		rng.Seed(seed);

		dsGameData->SetRandomSeed(rng.RandInt());

		//  Use script provided hashes if they exist
		if (dsGameSetup->mapHash != 0) {
			dsGameData->SetMapChecksum(dsGameSetup->mapHash);
			dsGameSetup->LoadStartPositions(false); // reduced mode
		} else {
			dsGameData->SetMapChecksum(archiveScanner->GetArchiveCompleteChecksum(dsGameSetup->mapName));

			CFileHandler f("maps/" + dsGameSetup->mapName);
			if (!f.FileExists()) {
				vfsHandler->AddArchiveWithDeps(dsGameSetup->mapName, false);
			}
			dsGameSetup->LoadStartPositions(); // full mode
		}

		if (dsGameSetup->modHash != 0) {
			dsGameData->SetModChecksum(dsGameSetup->modHash);
		} else {
			const std::string& modArchive = archiveScanner->ArchiveFromName(dsGameSetup->modName);
			const unsigned int modCheckSum = archiveScanner->GetArchiveCompleteChecksum(modArchive);
			dsGameData->SetModChecksum(modCheckSum);
		}

		LOG("starting server...");

		dsGameData->SetSetupText(dsGameSetup->setupText);
		server = new CGameServer(dsClientSetup, dsGameData, dsGameSetup);

		while (!server->HasGameID()) {
			// wait until gameID has been generated or
			// a timeout occurs (if no clients connect)
			if (server->HasFinished()) {
				break;
			}

			spring_secs(1).sleep();
		}

		while (!server->HasFinished()) {
			static bool printData = (server->GetDemoRecorder() != NULL);

			if (printData) {
				printData = false;

				const boost::scoped_ptr<CDemoRecorder>& demoRec = server->GetDemoRecorder();
				const boost::uint8_t* gameID = (demoRec->GetFileHeader()).gameID;

				LOG("recording demo: %s", (demoRec->GetName()).c_str());
				LOG("using mod: %s", (dsGameSetup->modName).c_str());
				LOG("using map: %s", (dsGameSetup->mapName).c_str());
				LOG("GameID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", gameID[0], gameID[1], gameID[2], gameID[3], gameID[4], gameID[5], gameID[6], gameID[7], gameID[8], gameID[9], gameID[10], gameID[11], gameID[12], gameID[13], gameID[14], gameID[15]);
			}

			// wait 1 second between checks
			spring_secs(1).sleep();
		}

		LOG("exiting");

		delete server;

		FileSystemInitializer::Cleanup();
		GlobalConfig::Deallocate();

		spring_clock::PopTickRate();
		LOG("exited");
	}
	CATCH_SPRING_ERRORS

	return GetExitCode();
}
コード例 #15
0
ファイル: GrassDrawer.cpp プロジェクト: vladmihaisima/spring
CGrassDrawer::CGrassDrawer()
: grassOff(false)
, grassDL(0)
, grassBladeTex(0)
, farTex(0)
, grassMap(nullptr)
{
	const int detail = configHandler->GetInt("GrassDetail");

	// some ATI drivers crash with grass enabled, default to disabled
	if ((detail == 0) || ((detail == 7) && globalRendering->haveATI)) {
		grassOff = true;
		return;
	}

	if (!GLEW_EXT_framebuffer_blit) {
		grassOff = true;
		return;
	}

	{
		MapBitmapInfo grassbm;
		unsigned char* grassdata = readMap->GetInfoMap("grass", &grassbm);

		if (!grassdata) {
			grassOff = true;
			return;
		}

		if (grassbm.width != gs->mapx / grassSquareSize || grassbm.height != gs->mapy / grassSquareSize) {
			char b[128];
			SNPRINTF(b, sizeof(b), "grass-map has wrong size (%dx%d, should be %dx%d)\n",
				grassbm.width, grassbm.height, gs->mapx / 4, gs->mapy / 4);
			throw std::runtime_error(b);
		}
		const int grassMapSize = gs->mapx * gs->mapy / (grassSquareSize * grassSquareSize);
		grassMap = new unsigned char[grassMapSize];
		memcpy(grassMap, grassdata, grassMapSize);
		readMap->FreeInfoMap("grass", grassdata);
	}

	ChangeDetail(detail);

	blocksX = gs->mapx / grassSquareSize / grassBlockSize;
	blocksY = gs->mapy / grassSquareSize / grassBlockSize;

	rng.Seed(15);
	grassDL = glGenLists(1);
	CreateGrassDispList(grassDL);

	{
		CBitmap grassBladeTexBM;
		if (!grassBladeTexBM.Load(mapInfo->grass.grassBladeTexName)) {
			//! map didn't define a grasstex, so generate one
			grassBladeTexBM.channels = 4;
			grassBladeTexBM.Alloc(256,64);

			for (int a = 0; a < 16; ++a) {
				CreateGrassBladeTex(&grassBladeTexBM.mem[a * 16 * 4]);
			}
		}

		glGenTextures(1, &grassBladeTex);
		glBindTexture(GL_TEXTURE_2D, grassBladeTex);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
		glBuildMipmaps(GL_TEXTURE_2D, GL_RGBA8, grassBladeTexBM.xsize, grassBladeTexBM.ysize, GL_RGBA, GL_UNSIGNED_BYTE, &grassBladeTexBM.mem[0]);
	}

	CreateFarTex();
	LoadGrassShaders();
	configHandler->NotifyOnChange(this);
}
コード例 #16
0
ファイル: GrassDrawer.cpp プロジェクト: vladmihaisima/spring
void CGrassBlockDrawer::DrawQuad(int x, int y)
{
	const float maxDetailedDist = gd->maxDetailedDist;

	CGrassDrawer::NearGrassStruct* nearGrass = gd->nearGrass;

	if (abs(x - cx) <= gd->detailedBlocks && abs(y - cy) <= gd->detailedBlocks) {
		//! blocks close to the camera
		for (int y2 = y * grassBlockSize; y2 < (y + 1) * grassBlockSize; ++y2) {
			for (int x2 = x * grassBlockSize; x2 < (x + 1) * grassBlockSize; ++x2) {
				if (gd->grassMap[y2 * gs->mapx / grassSquareSize + x2]) {
					float3 squarePos((x2 + 0.5f) * gSSsq, 0.0f, (y2 + 0.5f) * gSSsq);
						squarePos.y = CGround::GetHeightReal(squarePos.x, squarePos.z, false);

					const float sqdist = (camera->GetPos() - squarePos).SqLength();

					CGrassDrawer::NearGrassStruct* ng = &nearGrass[(y2 & 31) * 32 + (x2 & 31)];

					if (sqdist < (maxDetailedDist * maxDetailedDist)) {
						//! close grass, draw directly
						rng.Seed(y2 * 1025 + x2);

						for (int a = 0; a < gd->numTurfs; a++) {
							const float dx = (x2 + rng.RandFloat()) * gSSsq;
							const float dy = (y2 + rng.RandFloat()) * gSSsq;

							float3 pos(dx, CGround::GetHeightReal(dx, dy, false), dy);
								pos.y -= CGround::GetSlope(dx, dy, false) * 10.0f + 0.03f;

							if (ng->square != y2 * 2048 + x2) {
								const float3 v = squarePos - camera->GetPos();
								ng->rotation = GetHeadingFromVector(v.x, v.z) * 180.0f / 32768 + 180; //FIXME make more random
								ng->square = y2 * 2048 + x2;
							}

							glPushMatrix();
							glTranslatef3(pos);
							glRotatef(ng->rotation, 0.0f, 1.0f, 0.0f);
							glCallList(gd->grassDL);
							glPopMatrix();
						}
					} else {
						//! near but not close, save for later drawing
						CGrassDrawer::InviewNearGrass iv;
							iv.dist = sqdist;
							iv.x = x2;
							iv.y = y2;
						inviewNearGrass.push_back(iv);
						ng->square = -1;
					}
				}
			}
		}

		return;
	}

	const float3 dif(camera->GetPos().x - ((x + 0.5f) * bMSsq), 0.0f, camera->GetPos().z - ((y + 0.5f) * bMSsq));
	const float dist = dif.SqLength2D();

	if (dist < Square(gd->maxGrassDist)) {
		const int curSquare = y * gd->blocksX + x;
		const int curModSquare = (y & 31) * 32 + (x & 31);

		CGrassDrawer::GrassStruct* grass = gd->grass + curModSquare;
		grass->lastSeen = globalRendering->drawFrame;

		if (grass->square != curSquare) {
			grass->square = curSquare;

			delete grass->va;
			grass->va = NULL;
		}

		if (!grass->va) {
			grass->va = new CVertexArray;
			grass->pos = float3((x + 0.5f) * bMSsq, CGround::GetHeightReal((x + 0.5f) * bMSsq, (y + 0.5f) * bMSsq, false), (y + 0.5f) * bMSsq);

			CVertexArray* va = grass->va;
			va->Initialize();

			for (int y2 = y * grassBlockSize; y2 < (y + 1) * grassBlockSize; ++y2) {
				for (int x2 = x * grassBlockSize; x2 < (x + 1) * grassBlockSize; ++x2) {
					if (gd->grassMap[y2 * gs->mapx / grassSquareSize + x2]) {
						rng.Seed(y2 * 1025 + x2);

						for (int a = 0; a < gd->numTurfs; a++) {
							const float dx = (x2 + rng.RandFloat()) * gSSsq;
							const float dy = (y2 + rng.RandFloat()) * gSSsq;
							const float col = 1.0f;

							float3 pos(dx, CGround::GetHeightReal(dx, dy, false) + 0.5f, dy);
								pos.y -= (CGround::GetSlope(dx, dy, false) * 10.0f + 0.03f);

							va->AddVertexTN(pos, 0.0f,         0.0f, float3(-partTurfSize, -partTurfSize, col));
							va->AddVertexTN(pos, 1.0f / 16.0f, 0.0f, float3( partTurfSize, -partTurfSize, col));
							va->AddVertexTN(pos, 1.0f / 16.0f, 1.0f, float3( partTurfSize,  partTurfSize, col));
							va->AddVertexTN(pos, 0.0f,         1.0f, float3(-partTurfSize,  partTurfSize, col));
						}
					}
				}
			}
		}

		CGrassDrawer::InviewGrass ig;
			ig.num = curModSquare;
			ig.dist = dif.Length2D();
		inviewGrass.push_back(ig);
	}
}