Пример #1
0
bool CMouseCursor::BuildFromFileNames(const string& name, int lastFrame)
{
	// find the image file type to use
	const char* ext = "";
	const char* exts[] = { "png", "tga", "bmp" };
	const int extCount = sizeof(exts) / sizeof(exts[0]);
	for (int e = 0; e < extCount; e++) {
		ext = exts[e];
		std::ostringstream namebuf;
		namebuf << "anims/" << name << "_0." << ext;
		CFileHandler* f = new CFileHandler(namebuf.str());
		if (f->FileExists()) {
			delete f;
			break;
		}
		delete f;
	}

	while (int(frames.size()) < lastFrame) {
		std::ostringstream namebuf;
		namebuf << "anims/" << name << "_" << frames.size() << "." << ext;
		ImageData image;
		if (!LoadCursorImage(namebuf.str(), image))
			break;
		images.push_back(image);
		FrameData frame(image, defFrameLength);
		frames.push_back(frame);
	}

	hwCursor->Finish();

	return true;
}
Пример #2
0
/** Called by the map-selecting CglList. */
void CPreGame::SelectMap(std::string s)
{
    if (s == "Random map") {
        s = pregame->showList->items[1 + gu->usRandInt() % (pregame->showList->items.size() - 1)];
    }
    stupidGlobalMapname = pregame->mapName = s;
    delete pregame->showList;
    pregame->showList = 0;
    logOutput << "Map: " << s.c_str() << "\n";

    // Determine if the map is inside an archive, and possibly map needed archives
    CFileHandler* f = SAFE_NEW CFileHandler("maps/" + s);
    if (!f->FileExists()) {
        vector<string> ars = archiveScanner->GetArchivesForMap(s);
        if (ars.empty())
            throw content_error("Couldn't find any archives for map '" + s + "'.");
        for (vector<string>::iterator i = ars.begin(); i != ars.end(); ++i) {
            if (!hpiHandler->AddArchive(*i, false))
                throw content_error("Couldn't load archive '" + *i + "' for map '" + s + "'.");
        }
    }
    delete f;

    if (net && net->GetDemoRecorder())
        net->GetDemoRecorder()->SetName(s);
}
Пример #3
0
int CAICallback::GetFileSize (const char *name)
{
	CFileHandler fh (name);

	if (!fh.FileExists ())
		return -1;

	return fh.FileSize();
}
Пример #4
0
int CAICallback::GetFileSize (const char *filename, const char* modes)
{
	CFileHandler fh (filename, modes);

	if (!fh.FileExists ())
		return -1;

	return fh.FileSize();
}
Пример #5
0
bool CAICallback::ReadFile (const char *name, void *buffer, int bufferLength)
{
	CFileHandler fh (name);
	int fs;
	if (!fh.FileExists() || bufferLength < (fs = fh.FileSize()))
		return false;

	fh.Read (buffer, fs);
	return true;
}
Пример #6
0
int CArchiveDir::OpenFile(const std::string& fileName)
{
	CFileHandler* f = SAFE_NEW CFileHandler(archiveName + lcNameToOrigName[StringToLower(fileName)]);

	if (!f || !f->FileExists())
		return 0;

	++curFileHandle;
	fileHandles[curFileHandle] = f;
	return curFileHandle;
}
Пример #7
0
bool CMouseCursor::LoadCursorImage(const string& name, ImageData& image)
{
	CFileHandler* f = new CFileHandler(name);
	if (!f->FileExists()) {
		return false;
	}

	CBitmap b;
	if (!b.Load(name)) {
		logOutput.Print("CMouseCursor: Bad image file: %s", name.c_str());
		return false;
	}

	b.ReverseYAxis();

	CBitmap* final = getAlignedBitmap(b);
	
	// coded bmp transparency mask
	if ((name.size() >= 3) &&
	    (StringToLower(name.substr(name.size() - 3)) == "bmp")) {
		setBitmapTransparency(*final, 84, 84, 252);
	}
Пример #8
0
void CPreGame::LoadMap(const std::string& mapName, const bool forceReload)
{
	static bool alreadyLoaded = false;

	if (!alreadyLoaded || forceReload)
	{
		CFileHandler* f = new CFileHandler("maps/" + mapName);
		if (!f->FileExists()) {
			vector<string> ars = archiveScanner->GetArchivesForMap(mapName);
			if (ars.empty()) {
				throw content_error("Couldn't find any archives for map '" + mapName + "'.");
			}
			for (vector<string>::iterator i = ars.begin(); i != ars.end(); ++i) {
				if (!vfsHandler->AddArchive(*i, false)) {
					throw content_error("Couldn't load archive '" + *i + "' for map '" + mapName + "'.");
				}
			}
		}
		delete f;
		alreadyLoaded = true;
	}
}
Пример #9
0
bool CMouseCursor::BuildFromFileNames(const string& name, int lastFrame)
{
	char namebuf[128];
	if (name.size() > (sizeof(namebuf) - 20)) {
		logOutput.Print("CMouseCursor: Long name %s", name.c_str());
		return false;
	}
	
	// find the image file type to use
	const char* ext = "";
	const char* exts[] = { "png", "tga", "bmp" };
	const int extCount = sizeof(exts) / sizeof(exts[0]);
	for (int e = 0; e < extCount; e++) {
		ext = exts[e];
		SNPRINTF(namebuf, sizeof(namebuf), "anims/%s_%d.%s",
		         name.c_str(), 0, ext);
		CFileHandler* f = new CFileHandler(namebuf);
		if (f->FileExists()) {
			delete f;
			break;
		}
		delete f;
	}

	while (frames.size() < lastFrame) {
		SNPRINTF(namebuf, sizeof(namebuf), "anims/%s_%d.%s",
		         name.c_str(), frames.size(), ext);
		ImageData image;
		if (!LoadCursorImage(namebuf, image)) {
			break;
		}
		images.push_back(image);
		FrameData frame(image, defFrameLength);
		frames.push_back(frame);
	}

	return true;	
}
Пример #10
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;
}
Пример #11
0
bool CGameSetup::Init(char* buf, int size)
{
	for(int a=0;a<MAX_PLAYERS;a++){
		gs->players[a]->team=0;					//needed in case one tries to spec a game with only one team
	}

	gameSetupText=SAFE_NEW char[size];
	memcpy(gameSetupText,buf,size);
	gameSetupTextLength=size;

	file.LoadBuffer(buf,size);

	if(!file.SectionExist("GAME"))
		return false;

	mapname=file.SGetValueDef("","GAME\\mapname");
	scriptName=file.SGetValueDef("Commanders","GAME\\scriptname");
	baseMod=archiveScanner->ModArchiveToModName(file.SGetValueDef(MOD_FILE,"GAME\\Gametype"));
	file.GetDef(hostip,"0","GAME\\HostIP");
	file.GetDef(hostport,"0","GAME\\HostPort");
	file.GetDef(maxUnits,"500","GAME\\MaxUnits");
	file.GetDef(gs->gameMode,"0","GAME\\GameMode");
	file.GetDef(sourceport,"0","GAME\\SourcePort");
	file.GetDef(limitDgun,"0","GAME\\LimitDgun");
	file.GetDef(diminishingMMs,"0","GAME\\DiminishingMMs");
	file.GetDef(disableMapDamage,"0","GAME\\DisableMapDamage");
	demoName=file.SGetValueDef("","GAME\\Demofile");
	if(!demoName.empty())
		hostDemo=true;
	file.GetDef(ghostedBuildings,"1","GAME\\GhostedBuildings");

	file.GetDef(maxSpeed, "3", "GAME\\MaxSpeed");
	file.GetDef(minSpeed, "0.3", "GAME\\MinSpeed");

	// 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);
		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;

	file.GetDef(myPlayer,"0","GAME\\MyPlayerNum");
	gu->myPlayerNum=myPlayer;
	file.GetDef(numPlayers,"2","GAME\\NumPlayers");
	file.GetDef(gs->activeTeams,"2","GAME\\NumTeams");
	file.GetDef(gs->activeAllyTeams,"2","GAME\\NumAllyTeams");

	file.GetDef(startPosType,"0","GAME\\StartPosType");
	if(startPosType==2){
		for(int a=0;a<gs->activeTeams;++a)
			readyTeams[a]=false;
		for(int a=0;a<gs->activeTeams;++a)
			teamStartNum[a]=a;
		SAFE_NEW CStartPosSelecter();
	} else {
		for(int a=0;a<gs->activeTeams;++a)
			readyTeams[a]=true;
		if(startPosType==0){		//in order
			for(int a=0;a<gs->activeTeams;++a)
				teamStartNum[a]=a;
		} else {								//random order
			std::multimap<int,int> startNums;
			for(int a=0;a<gs->activeTeams;++a)
				startNums.insert(pair<int,int>(gu->usRandInt(),a));	//server syncs these later
			int b=0;
			for(std::multimap<int,int>::iterator si=startNums.begin();si!=startNums.end();++si){
				teamStartNum[si->second]=b;
				++b;
			}
		}
	}
	for(int a=0;a<numPlayers;++a){
		char section[50];
		sprintf(section,"GAME\\PLAYER%i\\",a);
		string s(section);

		gs->players[a]->team=atoi(file.SGetValueDef("0",s+"team").c_str());
		gs->players[a]->spectator=!!atoi(file.SGetValueDef("0",s+"spectator").c_str());
		gs->players[a]->playerName=file.SGetValueDef("0",s+"name");

		int fromDemo;
		file.GetDef(fromDemo,"0",s+"IsFromDemo");
		if(fromDemo)
			numDemoPlayers++;
	}
	gu->spectating = gs->players[myPlayer]->spectator;
	gu->spectatingFullView = gu->spectating;

	TdfParser p2;
	CReadMap::OpenTDF (mapname, p2);

	for(int a=0;a<gs->activeTeams;++a){
		char section[50];
		sprintf(section,"GAME\\TEAM%i\\",a);
		string s(section);

		int colorNum=atoi(file.SGetValueDef("0",s+"color").c_str());
		colorNum%=palette.NumTeamColors();
		float3 defaultCol(palette.teamColor[colorNum][0]/255.0f,palette.teamColor[colorNum][1]/255.0f,palette.teamColor[colorNum][2]/255.0f);
		float3 color=file.GetFloat3(defaultCol,s+"rgbcolor");
		for(int b=0;b<3;++b)
			gs->Team(a)->color[b]=int(color[b]*255);
		gs->Team(a)->color[3]=255;

 		gs->Team(a)->handicap=atof(file.SGetValueDef("0",s+"handicap").c_str())/100+1;
 		gs->Team(a)->leader=atoi(file.SGetValueDef("0",s+"teamleader").c_str());
 		gs->Team(a)->side = StringToLower(file.SGetValueDef("arm",s+"side").c_str());
 		gs->SetAllyTeam(a, atoi(file.SGetValueDef("0",s+"allyteam").c_str()));

		if (demoName.empty())
			aiDlls[a]=file.SGetValueDef("",s+"aidll");
		else
			aiDlls[a]="";

		float x,z;
		char teamName[50];
		sprintf(teamName,"TEAM%i",teamStartNum[a]);
		p2.GetDef(x,"1000",string("MAP\\")+teamName+"\\StartPosX");
		p2.GetDef(z,"1000",string("MAP\\")+teamName+"\\StartPosZ");
		gs->Team(a)->startPos=float3(x,100,z);

		if(startPosType==2)
			gs->Team(a)->startPos.y=-500;	//show that we havent selected start pos yet
	}
	gu->myTeam=gs->players[myPlayer]->team;
	gu->myAllyTeam=gs->AllyTeam(gu->myTeam);

	for(int a=0;a<gs->activeAllyTeams;++a){
		char section[50];
		sprintf(section,"GAME\\ALLYTEAM%i\\",a);
		string s(section);

		startRectTop[a]=atof(file.SGetValueDef("0",s+"StartRectTop").c_str());
		startRectBottom[a]=atof(file.SGetValueDef("1",s+"StartRectBottom").c_str());
		startRectLeft[a]=atof(file.SGetValueDef("0",s+"StartRectLeft").c_str());
		startRectRight[a]=atof(file.SGetValueDef("1",s+"StartRectRight").c_str());

		int numAllies=atoi(file.SGetValueDef("0",s+"NumAllies").c_str());
		for(int b=0;b<numAllies;++b){
			char key[100];
			sprintf(key,"GAME\\ALLYTEAM%i\\Ally%i",a,b);
			int other=atoi(file.SGetValueDef("0",key).c_str());
			gs->SetAlly(a,other, true);
		}
	}
	if(startPosType==2){
		for(int a=0;a<gs->activeTeams;++a)
			gs->Team(a)->startPos=float3(startRectLeft[gs->AllyTeam(a)]*gs->mapx*8,-500,startRectTop[gs->AllyTeam(a)]*gs->mapy*8);
	}

	int metal,energy;
	file.GetDef(metal,"1000","GAME\\StartMetal");
	file.GetDef(energy,"1000","GAME\\StartEnergy");
	for(int a=0;a<gs->activeTeams;++a){
		gs->Team(a)->metal=metal;
		gs->Team(a)->metalIncome=metal;	//for the endgame statistics
		gs->Team(a)->metalStorage=metal;

		gs->Team(a)->energy=energy;
		gs->Team(a)->energyIncome=energy;
		gs->Team(a)->energyStorage=energy;
	}

	// Read the unit restrictions
	int numRestrictions;
	file.GetDef(numRestrictions, "0", "GAME\\NumRestrictions");

	for (int i = 0; i < numRestrictions; ++i) {
		char key[100];
		sprintf(key, "GAME\\RESTRICT\\Unit%d", i);
		string resName = file.SGetValueDef("", key);
		sprintf(key, "GAME\\RESTRICT\\Limit%d", i);
		int resLimit;
		file.GetDef(resLimit, "0", key);

		restrictedUnits[resName] = resLimit;
	}

	return true;
}
Пример #12
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;
}
Пример #13
0
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
CglFont::CglFont(const std::string& fontfile, int size, int _outlinewidth, float _outlineweight):
	fontSize(size),
	fontPath(fontfile),
	outlineWidth(_outlinewidth),
	outlineWeight(_outlineweight),
	inBeginEnd(false)
{
	if (size<=0)
		size = 14;

	const float invSize = 1.0f / size;
	const float normScale = invSize / 64.0f;

	FT_Library library;
	FT_Face face;

	//! initialize Freetype2 library
	FT_Error error = FT_Init_FreeType(&library);
	if (error) {
		string msg = "FT_Init_FreeType failed:";
		msg += GetFTError(error);
		throw std::runtime_error(msg);
	}

	//! load font via VFS
	CFileHandler* f = new CFileHandler(fontPath);
	if (!f->FileExists()) {
		//! check in 'fonts/', too
		if (fontPath.substr(0, 6) != "fonts/") {
			delete f;
			fontPath = "fonts/" + fontPath;
			f = new CFileHandler(fontPath);
		}

		if (!f->FileExists()) {
			delete f;
			FT_Done_FreeType(library);
			throw content_error("Couldn't find font '" + fontfile + "'.");
		}
	}
	int filesize = f->FileSize();
	FT_Byte* buf = new FT_Byte[filesize];
	f->Read(buf,filesize);
	delete f;

	//! create face
	error = FT_New_Memory_Face(library, buf, filesize, 0, &face);
	if (error) {
		FT_Done_FreeType(library);
		delete[] buf;
		string msg = fontfile + ": FT_New_Face failed: ";
		msg += GetFTError(error);
		throw content_error(msg);
	}

	//! set render size
	error = FT_Set_Pixel_Sizes(face, 0, size);
	if (error) {
		FT_Done_Face(face);
		FT_Done_FreeType(library);
		delete[] buf;
		string msg = fontfile + ": FT_Set_Pixel_Sizes failed: ";
		msg += GetFTError(error);
		throw content_error(msg);
	}

	//! setup character range
	charstart = 32;
	charend   = 254; //! char 255 = colorcode
	chars     = (charend - charstart) + 1;

	//! get font information
	fontFamily = face->family_name;
	fontStyle  = face->style_name;

	//! font's descender & height (in pixels)
	fontDescender = normScale * FT_MulFix(face->descender, face->size->metrics.y_scale);
	//lineHeight    = invSize * (FT_MulFix(face->height, face->size->metrics.y_scale) / 64.0f);
	//lineHeight    = invSize * math::ceil(FT_MulFix(face->height, face->size->metrics.y_scale) / 64.0f);
	lineHeight = face->height / face->units_per_EM;
	//lineHeight = invSize * face->size->metrics.height / 64.0f;

	if (lineHeight<=0.0f) {
		lineHeight = 1.25 * invSize * (face->bbox.yMax - face->bbox.yMin);
	}

	//! used to create the glyph textureatlas
	CFontTextureRenderer texRenderer(outlineWidth, outlineWeight);

	for (unsigned int i = charstart; i <= charend; i++) {
		GlyphInfo* g = &glyphs[i];

		//! translate WinLatin (codepage-1252) to Unicode (used by freetype)
		int unicode = WinLatinToUnicode(i);

		//! convert to an anti-aliased bitmap
		error = FT_Load_Char(face, unicode, FT_LOAD_RENDER);
		if ( error ) {
			continue;
		}
		FT_GlyphSlot slot = face->glyph;

		//! Keep sign!
		const float ybearing = slot->metrics.horiBearingY * normScale;
		const float xbearing = slot->metrics.horiBearingX * normScale;

		g->advance   = slot->advance.x * normScale;
		g->height    = slot->metrics.height * normScale;
		g->descender = ybearing - g->height;

		g->x0 = xbearing;
		g->y0 = ybearing - fontDescender;
		g->x1 = (xbearing + slot->metrics.width * normScale);
		g->y1 = g->y0 - g->height;

		texRenderer.AddGlyph(i, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.buffer, slot->bitmap.pitch);
	}

	//! create font atlas texture
	fontTexture = texRenderer.CreateTexture();
	texWidth  = texRenderer.texWidth;
	texHeight = texRenderer.texHeight;

	//! get glyph's uv coords in the atlas
	for (unsigned int i = charstart; i <= charend; i++) {
		texRenderer.GetGlyph(i,&glyphs[i]);
	}

	//! generate kerning tables
	for (unsigned int i = charstart; i <= charend; i++) {
		GlyphInfo& g = glyphs[i];
		int unicode = WinLatinToUnicode(i);
		FT_UInt left_glyph = FT_Get_Char_Index(face, unicode);
		for (unsigned int j = 0; j <= 255; j++) {
			unicode = WinLatinToUnicode(j);
			FT_UInt right_glyph = FT_Get_Char_Index(face, unicode);
			FT_Vector kerning;
			kerning.x = kerning.y = 0.0f;
			FT_Get_Kerning(face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning);
			g.kerning[j] = g.advance + normScale * static_cast<float>(kerning.x);
		}
	}

	//! initialize null char
	GlyphInfo& g = glyphs[0];
	g.height = g.descender = g.advance = 0.0f;
	for (unsigned int j = 0; j <= 255; j++) {
		g.kerning[j] = 0.0f;
	}

	FT_Done_Face(face);
	FT_Done_FreeType(library);
	delete[] buf;

	textColor    = white;
	outlineColor = darkOutline;
}
Пример #15
0
bool CGameSetup::Init(char* buf, int size)
{
	for(int a=0;a<gs->activePlayers;a++){
		gs->players[a]->team=0;					//needed in case one tries to spec a game with only one team
	}
	palette.Init();

	gameSetupText=new char[size];
	memcpy(gameSetupText,buf,size);
	gameSetupTextLength=size;

	file=new CSunParser;
	file->LoadBuffer(buf,size);

	if(!file->SectionExist("GAME"))
		return false;

	mapname=file->SGetValueDef("","GAME\\mapname");
	baseMod=file->SGetValueDef("xta_se_060.sdz","GAME\\Gametype");
	file->GetDef(hostip,"0","GAME\\HostIP");
	file->GetDef(hostport,"0","GAME\\HostPort");
	file->GetDef(maxUnits,"500","GAME\\MaxUnits");
	file->GetDef(gs->gameMode,"0","GAME\\GameMode");
	file->GetDef(sourceport,"0","GAME\\SourcePort");
	file->GetDef(limitDgun,"0","GAME\\LimitDgun");
	file->GetDef(diminishingMMs,"0","GAME\\DiminishingMMs");
	demoName=file->SGetValueDef("","GAME\\Demofile");

	// 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;

	file->GetDef(myPlayer,"0","GAME\\MyPlayerNum");
	gu->myPlayerNum=myPlayer;
	file->GetDef(numPlayers,"2","GAME\\NumPlayers");
	gs->activePlayers=numPlayers;
	file->GetDef(gs->activeTeams,"2","GAME\\NumTeams");
	file->GetDef(gs->activeAllyTeams,"2","GAME\\NumAllyTeams");

	file->GetDef(startPosType,"0","GAME\\StartPosType");
	if(startPosType==2){
		for(int a=0;a<gs->activeTeams;++a)
			readyTeams[a]=false;
		for(int a=0;a<gs->activeTeams;++a)
			teamStartNum[a]=a;
		new CStartPosSelecter();
	} else {
		for(int a=0;a<gs->activeTeams;++a)
			readyTeams[a]=true;
		if(startPosType==0){		//in order
			for(int a=0;a<gs->activeTeams;++a)
				teamStartNum[a]=a;
		} else {								//random order
			std::multimap<int,int> startNums;
			for(int a=0;a<gs->activeTeams;++a)
				startNums.insert(pair<int,int>(gu->usRandInt(),a));	//server syncs these later
			int b=0;
			for(std::multimap<int,int>::iterator si=startNums.begin();si!=startNums.end();++si){
				teamStartNum[si->second]=b;
				++b;
			}
		}
	}
	for(int a=0;a<numPlayers;++a){
		char section[50];
		sprintf(section,"GAME\\PLAYER%i\\",a);
		string s(section);

		gs->players[a]->team=atoi(file->SGetValueDef("0",s+"team").c_str());
		gs->players[a]->spectator=!!atoi(file->SGetValueDef("0",s+"spectator").c_str());
		gs->players[a]->playerName=file->SGetValueDef("0",s+"name");

		int fromDemo;
		file->GetDef(fromDemo,"0",s+"IsFromDemo");
		if(fromDemo)
			numDemoPlayers++;
	}
	if(!demoName.empty() && myPlayer==numDemoPlayers){
		hostDemo=true;
	}

	gu->spectating=gs->players[myPlayer]->spectator;

	CSunParser p2;
	p2.LoadFile(string("maps\\")+mapname.substr(0,mapname.find_last_of('.'))+".smd");

	for(int a=0;a<gs->activeTeams;++a){
		char section[50];
		sprintf(section,"GAME\\TEAM%i\\",a);
		string s(section);

		gs->teams[a]->colorNum=atoi(file->SGetValueDef("0",s+"color").c_str());
		for(int b=0;b<4;++b)
			gs->teams[a]->color[b]=palette.teamColor[gs->teams[a]->colorNum][b];

		gs->teams[a]->handicap=atof(file->SGetValueDef("0",s+"handicap").c_str())/100+1;
		gs->teams[a]->leader=atoi(file->SGetValueDef("0",s+"teamleader").c_str());
		gs->teams[a]->side=file->SGetValueDef("arm",s+"side").c_str();
		std::transform(gs->teams[a]->side.begin(), gs->teams[a]->side.end(), gs->teams[a]->side.begin(), (int (*)(int))std::tolower);
		gs->team2allyteam[a]=atoi(file->SGetValueDef("0",s+"allyteam").c_str());
		aiDlls[a]=file->SGetValueDef("",s+"aidll");

		float x,z;
		char teamName[50];
		sprintf(teamName,"TEAM%i",teamStartNum[a]);
		p2.GetDef(x,"1000",string("MAP\\")+teamName+"\\StartPosX");
		p2.GetDef(z,"1000",string("MAP\\")+teamName+"\\StartPosZ");
		gs->teams[a]->startPos=float3(x,100,z);

		if(startPosType==2)
			gs->teams[a]->startPos.y=-500;	//show that we havent selected start pos yet
	}
	gu->myTeam=gs->players[myPlayer]->team;
	gu->myAllyTeam=gs->team2allyteam[gu->myTeam];

	for(int a=0;a<gs->activeAllyTeams;++a){
		char section[50];
		sprintf(section,"GAME\\ALLYTEAM%i\\",a);
		string s(section);

		startRectTop[a]=atof(file->SGetValueDef("0",s+"StartRectTop").c_str());
		startRectBottom[a]=atof(file->SGetValueDef("1",s+"StartRectBottom").c_str());
		startRectLeft[a]=atof(file->SGetValueDef("0",s+"StartRectLeft").c_str());
		startRectRight[a]=atof(file->SGetValueDef("1",s+"StartRectRight").c_str());

		int numAllies=atoi(file->SGetValueDef("0",s+"NumAllies").c_str());
		for(int b=0;b<numAllies;++b){
			char key[100];
			sprintf(key,"GAME\\ALLYTEAM%i\\Ally%i",a,b);
			int other=atoi(file->SGetValueDef("0",key).c_str());
			gs->allies[a][other]=true;
		}
	}

	int metal,energy;
	file->GetDef(metal,"1000","GAME\\StartMetal");
	file->GetDef(energy,"1000","GAME\\StartEnergy");
	for(int a=0;a<gs->activeTeams;++a){
		gs->teams[a]->metal=metal;
		gs->teams[a]->metalStorage=metal;

		gs->teams[a]->energy=energy;
		gs->teams[a]->energyStorage=energy;
	}

	// Read the unit restrictions
	int numRestrictions;
	file->GetDef(numRestrictions, "0", "GAME\\NumRestrictions");

	for (int i = 0; i < numRestrictions; ++i) {
		char key[100];
		sprintf(key, "GAME\\RESTRICT\\Unit%d", i);
		string resName = file->SGetValueDef("", key);
		sprintf(key, "GAME\\RESTRICT\\Limit%d", i);
		int resLimit;
		file->GetDef(resLimit, "0", key);

		restrictedUnits[resName] = resLimit;
	}

	return true;
}
Пример #16
0
S3DModel* CAssParser::Load(const std::string& modelFilePath)
{
	logOutput.Print (LOG_MODEL, "Loading model: %s\n", modelFilePath.c_str() );
	std::string modelPath = modelFilePath.substr(0, modelFilePath.find_last_of('/'));
	std::string modelFileNameNoPath = modelFilePath.substr(modelPath.length()+1, modelFilePath.length());
	std::string modelName = modelFileNameNoPath.substr(0, modelFileNameNoPath.find_last_of('.'));
	std::string modelExt = modelFileNameNoPath.substr(modelFileNameNoPath.find_last_of('.'), modelFilePath.length());

	//! LOAD METADATA
	//! Load the lua metafile. This contains properties unique to Spring models and must return a table
	std::string metaFileName = modelFilePath + ".lua";
	CFileHandler* metaFile = new CFileHandler(metaFileName);
	if (!metaFile->FileExists()) {
		//! Try again without the model file extension
		metaFileName = modelPath + '/' + modelName + ".lua";
		metaFile = new CFileHandler(metaFileName);
	}
	LuaParser metaFileParser(metaFileName, SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP);
	if (!metaFileParser.Execute()) {
		if (!metaFile->FileExists()) {
			logOutput.Print(LOG_MODEL, "No meta-file '%s'. Using defaults.", metaFileName.c_str());
		} else {
			logOutput.Print(LOG_MODEL, "ERROR in '%s': %s. Using defaults.", metaFileName.c_str(), metaFileParser.GetErrorLog().c_str());
		}
	}
	//! Get the (root-level) model table
	const LuaTable& metaTable = metaFileParser.GetRoot();
	if (metaTable.IsValid()) logOutput.Print(LOG_MODEL, "Found valid model metadata in '%s'", metaFileName.c_str());


	//! LOAD MODEL DATA
	//! Create a model importer instance
	Assimp::Importer importer;

	//! Create a logger for debugging model loading issues
	Assimp::DefaultLogger::create("",Assimp::Logger::VERBOSE);
	const unsigned int severity = Assimp::Logger::Debugging|Assimp::Logger::Info|Assimp::Logger::Err|Assimp::Logger::Warn;
	Assimp::DefaultLogger::get()->attachStream( new AssLogStream(), severity );

	//! Give the importer an IO class that handles Spring's VFS
	importer.SetIOHandler( new AssVFSSystem() );

	//! Speed-up processing by skipping things we don't need
	importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_CAMERAS|aiComponent_LIGHTS|aiComponent_TEXTURES|aiComponent_ANIMATIONS);

#ifndef BITMAP_NO_OPENGL
	//! Optimize VBO-Mesh sizes/ranges
	GLint maxIndices  = 1024;
	GLint maxVertices = 1024;
	glGetIntegerv(GL_MAX_ELEMENTS_INDICES,  &maxIndices);
	glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices); //FIXME returns not optimal data, at best compute it ourself! (pre-TL cache size!)
	importer.SetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,   maxVertices);
	importer.SetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices/3);
#endif

	//! Read the model file to build a scene object
	logOutput.Print(LOG_MODEL, "Importing model file: %s\n", modelFilePath.c_str() );
	const aiScene* scene = importer.ReadFile( modelFilePath, ASS_POSTPROCESS_OPTIONS );
	if (scene != NULL) {
		logOutput.Print(LOG_MODEL, "Processing scene for model: %s (%d meshes / %d materials / %d textures)", modelFilePath.c_str(), scene->mNumMeshes, scene->mNumMaterials, scene->mNumTextures );
	} else {
		logOutput.Print (LOG_MODEL, "Model Import Error: %s\n",  importer.GetErrorString());
	}

	SAssModel* model = new SAssModel;
	model->name = modelFilePath;
	model->type = MODELTYPE_ASS;
	model->scene = scene;
	//model->meta = &metaTable;

	//! Gather per mesh info
	CalculatePerMeshMinMax(model);

	//! Assign textures
	//! The S3O texture handler uses two textures.
	//! The first contains diffuse color (RGB) and teamcolor (A)
	//! The second contains glow (R), reflectivity (G) and 1-bit Alpha (A).
	if (metaTable.KeyExists("tex1")) {
		model->tex1 = metaTable.GetString("tex1", "default.png");
	} else {
		//! Search for a texture
		std::vector<std::string> files = CFileHandler::FindFiles("unittextures/", modelName + ".*");
		for(std::vector<std::string>::iterator fi = files.begin(); fi != files.end(); ++fi) {
			std::string texPath = std::string(*fi);
			model->tex1 = texPath.substr(texPath.find('/')+1, texPath.length());
			break; //! there can be only one!
		}
	}
	if (metaTable.KeyExists("tex2")) {
		model->tex2 = metaTable.GetString("tex2", "");
	} else {
		//! Search for a texture
		std::vector<std::string> files = CFileHandler::FindFiles("unittextures/", modelName + "2.*");
		for(std::vector<std::string>::iterator fi = files.begin(); fi != files.end(); ++fi) {
			std::string texPath = std::string(*fi);
			model->tex2 = texPath.substr(texPath.find('/')+1, texPath.length());
			break; //! there can be only one!
		}
	}
	model->flipTexY = metaTable.GetBool("fliptextures", true); //! Flip texture upside down
	model->invertTexAlpha = metaTable.GetBool("invertteamcolor", true); //! Reverse teamcolor levels

	//! Load textures
	logOutput.Print(LOG_MODEL, "Loading textures. Tex1: '%s' Tex2: '%s'", model->tex1.c_str(), model->tex2.c_str());
	texturehandlerS3O->LoadS3OTexture(model);

	//! Load all pieces in the model
	logOutput.Print(LOG_MODEL, "Loading pieces from root node '%s'", scene->mRootNode->mName.data);
	LoadPiece(model, scene->mRootNode, metaTable);

	//! Update piece hierarchy based on metadata
	BuildPieceHierarchy( model );

	//! Simplified dimensions used for rough calculations
	model->radius = metaTable.GetFloat("radius", model->radius);
	model->height = metaTable.GetFloat("height", model->height);
	model->relMidPos = metaTable.GetFloat3("midpos", model->relMidPos);
	model->mins = metaTable.GetFloat3("mins", model->mins);
	model->maxs = metaTable.GetFloat3("maxs", model->maxs);

	//! Calculate model dimensions if not set
	if (!metaTable.KeyExists("mins") || !metaTable.KeyExists("maxs")) CalculateMinMax( model->rootPiece );
	if (model->radius < 0.0001f) CalculateRadius( model );
	if (model->height < 0.0001f) CalculateHeight( model );

	//! Verbose logging of model properties
	logOutput.Print(LOG_MODEL_DETAIL, "model->name: %s", model->name.c_str());
	logOutput.Print(LOG_MODEL_DETAIL, "model->numobjects: %d", model->numPieces);
	logOutput.Print(LOG_MODEL_DETAIL, "model->radius: %f", model->radius);
	logOutput.Print(LOG_MODEL_DETAIL, "model->height: %f", model->height);
	logOutput.Print(LOG_MODEL_DETAIL, "model->mins: (%f,%f,%f)", model->mins[0], model->mins[1], model->mins[2]);
	logOutput.Print(LOG_MODEL_DETAIL, "model->maxs: (%f,%f,%f)", model->maxs[0], model->maxs[1], model->maxs[2]);

	logOutput.Print (LOG_MODEL, "Model %s Imported.", model->name.c_str());
	return model;
}