Beispiel #1
0
//! only used internally, locked in caller's scope
size_t CSound::LoadSoundBuffer(const std::string& path, bool hardFail)
{
	const size_t id = SoundBuffer::GetId(path);
	
	if (id > 0) {
		return id; // file is loaded already
	} else {
		CFileHandler file(path);

		if (!file.FileExists()) {
			if (hardFail)
				handleerror(0, "Couldn't open audio file", path.c_str(),0);
			else
				LogObject(LOG_SOUND) << "Unable to open audio file: " << path;
			return 0;
		}

		std::vector<boost::uint8_t> buf(file.FileSize());
		file.Read(&buf[0], file.FileSize());

		boost::shared_ptr<SoundBuffer> buffer(new SoundBuffer());
		bool success = false;
		const std::string ending = file.GetFileExt();
		if (ending == "wav")
			success = buffer->LoadWAV(path, buf, hardFail);
		else if (ending == "ogg")
			success = buffer->LoadVorbis(path, buf, hardFail);
		else
			LogObject(LOG_SOUND) << "CSound::LoadALBuffer: unknown audio format: " << ending;

		CheckError("CSound::LoadALBuffer");
		if (!success) {
			LogObject(LOG_SOUND) << "Failed to load file: " << path;
			return 0;
		}

		return SoundBuffer::Insert(buffer);
	}
}
Beispiel #2
0
	void SaveStuff()
	{
		FunctionArgs args;
		while (GetTask(args))
		{
			CBitmap b(args.buf, args.x, args.y);
			delete[] args.buf;
			b.ReverseYAxis();
			b.Save(args.filename);
			LogObject() << "Saved: " << args.filename;
		}
		finished = true;
	};
/*
 * stores data and does some top-administration
 */
IPath::SearchResult CPathEstimator::GetPath(const MoveData& moveData, float3 start, const CPathFinderDef& peDef, Path& path, unsigned int maxSearchedBlocks) {
	start.CheckInBounds();
	// clear the path
	path.path.clear();
	path.pathCost = PATHCOST_INFINITY;

	// initial calculations
	maxBlocksToBeSearched = std::min(maxSearchedBlocks, (unsigned int) MAX_SEARCHED_BLOCKS);
	startBlock.x = (int)(start.x / BLOCK_PIXEL_SIZE);
	startBlock.y = (int)(start.z / BLOCK_PIXEL_SIZE);
	startBlocknr = startBlock.y * nbrOfBlocksX + startBlock.x;
	int2 goalBlock;
	goalBlock.x = peDef.goalSquareX / BLOCK_SIZE;
	goalBlock.y = peDef.goalSquareZ / BLOCK_SIZE;

	CPathCache::CacheItem* ci = pathCache->GetCachedPath(startBlock, goalBlock, peDef.sqGoalRadius, moveData.pathType);
	if (ci) {
		// use a cached path if we have one
		path = ci->path;
		return ci->result;
	}

	// oterhwise search
	SearchResult result = InitSearch(moveData, peDef);

	// if search successful, generate new path
	if (result == Ok || result == GoalOutOfRange) {
		FinishSearch(moveData, path);
		// only add succesful paths to the cache
		pathCache->AddPath(&path, result, startBlock, goalBlock, peDef.sqGoalRadius, moveData.pathType);

		if (PATHDEBUG) {
			LogObject() << "PE: Search completed.\n";
			LogObject() << "Tested blocks: " << testedBlocks << "\n";
			LogObject() << "Open blocks: " << (float)(openBlockBufferPointer - openBlockBuffer) << "\n";
			LogObject() << "Path length: " << (int)(path.path.size()) << "\n";
			LogObject() << "Path cost: " << path.pathCost << "\n";
		}
	} else {
		if (PATHDEBUG) {
			LogObject() << "PE: Search failed!\n";
			LogObject() << "Tested blocks: " << testedBlocks << "\n";
			LogObject() << "Open blocks: " << (float)(openBlockBufferPointer - openBlockBuffer) << "\n";
		}
	}

	return result;
}
Beispiel #4
0
size_t CSound::GetSoundId(const std::string& name, bool hardFail)
{
	GML_RECMUTEX_LOCK(sound); // GetSoundId

	if (sources.empty())
		return 0;

	soundMapT::const_iterator it = soundMap.find(name);
	if (it != soundMap.end())
	{
		// sounditem found
		return it->second;
	}
	else
	{
		size_t newid = sounds.size();

		soundItemDefMap::iterator itemDefIt = soundItemDefs.find(name);
		if (itemDefIt != soundItemDefs.end())
		{
			//logOutput.Print("CSound::GetSoundId: %s points to %s", name.c_str(), it->second.c_str());
			sounds.push_back(new SoundItem(GetWaveBuffer(itemDefIt->second["file"], hardFail), itemDefIt->second));
			soundMap[name] = newid;
			return newid;
		}
		else
		{
			if (GetWaveId(name, hardFail) > 0) // maybe raw filename?
			{
				soundItemDef temp = defaultItem;
				temp["name"] = name;
				sounds.push_back(new SoundItem(GetWaveBuffer(name, hardFail), temp)); // use raw file with default values
				soundMap[name] = newid;
				return newid;
			}
			else
			{
				if (hardFail)
					ErrorMessageBox("Couldn't open wav file", name, 0);
				else
				{
					LogObject(LOG_SOUND) << "CSound::GetSoundId: could not find sound: " << name;
					return 0;
				}
			}
		}
	}

	return 0;
}
bool CSound::LoadSoundDefs(const std::string& filename)
{
	//! can be called from LuaUnsyncedCtrl too
	boost::mutex::scoped_lock lck(soundMutex);

	LuaParser parser(filename, SPRING_VFS_MOD, SPRING_VFS_ZIP);
	parser.SetLowerKeys(false);
	parser.SetLowerCppKeys(false);
	parser.Execute();
	if (!parser.IsValid())
	{
		LogObject(LOG_SOUND) << "Could not load " << filename << ": " << parser.GetErrorLog();
		return false;
	}
	else
	{
		const LuaTable soundRoot = parser.GetRoot();
		const LuaTable soundItemTable = soundRoot.SubTable("SoundItems");
		if (!soundItemTable.IsValid())
		{
			LogObject(LOG_SOUND) << "CSound(): could not parse SoundItems table in " << filename;
			return false;
		}
		else
		{
			std::vector<std::string> keys;
			soundItemTable.GetKeys(keys);
			for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it)
			{
				const std::string name(*it);
				soundItemDef bufmap;
				const LuaTable buf(soundItemTable.SubTable(*it));
				buf.GetMap(bufmap);
				bufmap["name"] = name;
				soundItemDefMap::const_iterator sit = soundItemDefs.find(name);
				if (sit != soundItemDefs.end())
					LogObject(LOG_SOUND) << "CSound(): two SoundItems have the same name: " << name;

				soundItemDef::const_iterator inspec = bufmap.find("file");
				if (inspec == bufmap.end())	// no file, drop
					LogObject(LOG_SOUND) << "CSound(): SoundItem has no file tag: " << name;
				else
					soundItemDefs[name] = bufmap;

				if (buf.KeyExists("preload"))
				{
					LogObject(LOG_SOUND) << "CSound(): preloading " << name;
					const size_t newid = sounds.size();
					sounds.push_back(new SoundItem(GetWaveBuffer(bufmap["file"], true), bufmap));
					soundMap[name] = newid;
				}
			}
			LogObject(LOG_SOUND) << "CSound(): Sucessfully parsed " << keys.size() << " SoundItems from " << filename;
		}
	}
	return true;
}
Beispiel #6
0
void Gui::Draw()
{
	for (ElList::iterator it = toBeAdded.begin(); it != toBeAdded.end(); ++it)
	{
		bool duplicate = false;
		for (ElList::iterator elIt = elements.begin(); elIt != elements.end(); ++elIt)
		{
			if (it->element == elIt->element)
			{
				LogObject() << "Gui::AddElement: skipping duplicated object";
				duplicate = true;
				break;
			}
		}
		if (!duplicate)
		{
			if (it->asBackground)
				elements.push_back(*it);
			else
				elements.push_front(*it);
		}
	}
	toBeAdded.clear();

	for (ElList::iterator it = toBeRemoved.begin(); it != toBeRemoved.end(); ++it)
	{
		for (ElList::iterator elIt = elements.begin(); elIt != elements.end(); ++elIt)
		{
			if (it->element == elIt->element)
			{
				delete (elIt->element);
				elements.erase(elIt);
				break;
			}
		}
	}
	toBeRemoved.clear();

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
	glEnable(GL_BLEND);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	for (ElList::reverse_iterator it = elements.rbegin(); it != elements.rend(); ++it)
		(*it).element->Draw();
}
Beispiel #7
0
void CSound::PrintDebugInfo()
{
	boost::recursive_mutex::scoped_lock lck(soundMutex);

	LogObject(LOG_SOUND) << "OpenAL Sound System:";
	LogObject(LOG_SOUND) << "# SoundSources: " << sources.size();
	LogObject(LOG_SOUND) << "# SoundBuffers: " << SoundBuffer::Count();

	LogObject(LOG_SOUND) << "# reserved for buffers: " << (SoundBuffer::AllocedSize()/1024) << " kB";
	LogObject(LOG_SOUND) << "# PlayRequests for empty sound: " << numEmptyPlayRequests;
	LogObject(LOG_SOUND) << "# Samples disrupted: " << numAbortedPlays;
	LogObject(LOG_SOUND) << "# SoundItems: " << sounds.size();
}
Beispiel #8
0
void Picture::Load(const std::string& _file)
{
	file = _file;
	
	CBitmap bmp;
	if (bmp.Load(file))
	{
		texture = bmp.CreateTexture(false);
	}
	else
	{
		LogObject() << "Failed to load: " << file;
		texture = 0;
	}
}
Beispiel #9
0
bool CheckError(const char* msg)
{
	ALenum e = alGetError();
	if (e != AL_NO_ERROR)
	{
		char *alerr = (char*)alGetString(e);
		std::string err = msg;
		err += ": ";
		err += (alerr != NULL) ? alerr : "Unknown error";

		LogObject(LOG_SOUND) << err.c_str();
		return false;
	}
	return true;
}
Beispiel #10
0
void CSound::PlaySample(size_t id, const float3& p, const float3& velocity, float volume, bool relative)
{
	GML_RECMUTEX_LOCK(sound); // PlaySample

	if (sources.empty() || volume == 0.0f)
		return;

	if (id == 0)
	{
		numEmptyPlayRequests++;
		return;
	}

	if (p.distance(myPos) > sounds[id].MaxDistance())
	{
		if (!relative)
			return;
		else
			LogObject(LOG_SOUND) << "CSound::PlaySample: maxdist ignored for relative payback: " << sounds[id].Name();
	}

	bool found1Free = false;
	int minPriority = 1;
	size_t minPos = 0;

	for (size_t pos = 0; pos != sources.size(); ++pos)
	{
		if (!sources[pos].IsPlaying())
		{
			minPos = pos;
			found1Free = true;
			break;
		}
		else
		{
			if (sources[pos].GetCurrentPriority() < minPriority && sources[pos].GetCurrentPriority() <=  sounds[id].GetPriority())
			{
				found1Free = true;
				minPriority = sources[pos].GetCurrentPriority();
				minPos = pos;
			}
		}
	}

	if (found1Free)
		sources[minPos].Play(&sounds[id], p, velocity, volume, relative);
	CheckError("CSound::PlaySample");
}
Beispiel #11
0
void CSound::PrintDebugInfo()
{
	LogObject(LOG_SOUND) << "OpenAL Sound System:";
	LogObject(LOG_SOUND) << "# SoundSources: " << sources.size();
	LogObject(LOG_SOUND) << "# SoundBuffers: " << SoundBuffer::Count();

	LogObject(LOG_SOUND) << "# reserved for buffers: " << (SoundBuffer::AllocedSize()/1024) << " kB";
	LogObject(LOG_SOUND) << "# PlayRequests for empty sound: " << numEmptyPlayRequests;
	LogObject(LOG_SOUND) << "# SoundItems: " << sounds.size();
}
Beispiel #12
0
void AudioChannel::FindSourceAndPlay(size_t id, const float3& pos, const float3& velocity, float volume, bool relative)
{
	if (!enabled)
		return;

	if (volume <= 0.0f)
		return;

	boost::recursive_mutex::scoped_lock slck(soundMutex);

	SoundItem* sndItem = sound->GetSoundItem(id);
	if (!sndItem)
	{
		sound->numEmptyPlayRequests++;
		return;
	}

	if (pos.distance(sound->GetListenerPos()) > sndItem->MaxDistance())
	{
		if (!relative)
			return;
		else
			LogObject(LOG_SOUND) << "CSound::PlaySample: maxdist ignored for relative payback: " << sndItem->Name();
	}

	if (emmitsThisFrame >= emmitsPerFrame)
		return;
	emmitsThisFrame++;
	
	CSoundSource* sndSource = sound->GetNextBestSource();
	if (!sndSource)
		return;

	if (sndSource->GetCurrentPriority() < sndItem->GetPriority())
	{
		if (sndSource->IsPlaying())
			sound->numAbortedPlays++;

		sndSource->Play(this, sndItem, pos, velocity, volume, relative);
		CheckError("CSound::FindSourceAndPlay");

		boost::recursive_mutex::scoped_lock lck(chanMutex);

		cur_sources[sndSource] = true;
	}
}
Beispiel #13
0
size_t CSound::GetSoundId(const std::string& name, bool hardFail)
{
	boost::recursive_mutex::scoped_lock lck(soundMutex);

	if (sources.empty())
		return 0;

	soundMapT::const_iterator it = soundMap.find(name);
	if (it != soundMap.end())
	{
		// sounditem found
		return it->second;
	}
	else
	{
		soundItemDefMap::const_iterator itemDefIt = soundItemDefs.find(name);
		if (itemDefIt != soundItemDefs.end())
		{
			return MakeItemFromDef(itemDefIt->second);
		}
		else
		{
			if (LoadSoundBuffer(name, hardFail) > 0) // maybe raw filename?
			{
				soundItemDef temp = defaultItem;
				temp["file"] = name;
				return MakeItemFromDef(temp);
			}
			else
			{
				if (hardFail)
				{
					ErrorMessageBox("Couldn't open wav file", name, 0);
					return 0;
				}
				else
				{
					LogObject(LOG_SOUND) << "CSound::GetSoundId: could not find sound: " << name;
					return 0;
				}
			}
		}
	}
}
Beispiel #14
0
bool Button::HandleEventSelf(const SDL_Event& ev)
{
	switch (ev.type) {
		case SDL_MOUSEBUTTONDOWN: {
			if ((ev.button.button == SDL_BUTTON_LEFT) && MouseOver(ev.button.x, ev.button.y) && gui->MouseOverElement(GetRoot(), ev.motion.x, ev.motion.y))
			{
				clicked = true;
			};
			break;
		}
		case SDL_MOUSEBUTTONUP: {
			if ((ev.button.button == SDL_BUTTON_LEFT) && MouseOver(ev.button.x, ev.button.y) && clicked)
			{
				if (!Clicked.empty())
				{
					Clicked();
				}
				else
				{
					LogObject() << "Button " << label << " clicked without callback";
				}
				clicked = false;
				return true;
			}
		}
		case SDL_MOUSEMOTION: {
			if (MouseOver(ev.motion.x, ev.motion.y) && gui->MouseOverElement(GetRoot(), ev.motion.x, ev.motion.y))
			{
				hovered = true;
			}
			else
			{
				hovered = false;
				clicked = false;
			}
			break;
		}
	}
	return false;
}
Beispiel #15
0
CArchiveZip::CArchiveZip(const std::string& name):
	CArchiveBuffered(name),
	curSearchHandle(1)
{
#ifdef USEWIN32IOAPI
	zlib_filefunc_def ffunc;
	fill_win32_filefunc(&ffunc);
	zip = unzOpen2(name.c_str(),&ffunc);
#else
	zip = unzOpen(name.c_str());
#endif
	if (!zip) {
		LogObject() << "Error opening " << name;
		return;
	}

	// We need to map file positions to speed up opening later
	for (int ret = unzGoToFirstFile(zip); ret == UNZ_OK; ret = unzGoToNextFile(zip)) {
		unz_file_info info;
		char fname[512];

		unzGetCurrentFileInfo(zip, &info, fname, 512, NULL, 0, NULL, 0);

		const std::string name = StringToLower(fname);
		if (name.empty()) {
			continue;
		}
		const char last = name[name.length() - 1];
		if ((last == '/') || (last == '\\')) {
			continue; // exclude directory names
		}

		FileData fd;
		unzGetFilePos(zip, &fd.fp);
		fd.size = info.uncompressed_size;
		fd.origName = fname;
		fd.crc = info.crc;
		fileData[name] = fd;
	}
}
void CSound::StartThread(int maxSounds)
{
	{
		boost::mutex::scoped_lock lck(soundMutex);

		// Generate sound sources
		for (int i = 0; i < maxSounds; i++)
		{
			SoundSource* thenewone = new SoundSource();
			if (thenewone->IsValid())
			{
				sources.push_back(thenewone);
			}
			else
			{
				maxSounds = i-1;
				LogObject(LOG_SOUND) << "Your hardware/driver can not handle more than " << maxSounds << " soundsources";
				delete thenewone;
				break;
			}
		}

		// Set distance model (sound attenuation)
		alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
		//alDopplerFactor(1.0);

		alListenerf(AL_GAIN, masterVolume);
	}

	while (true) {
		boost::this_thread::sleep(boost::posix_time::millisec(50));
		boost::this_thread::interruption_point();

		boost::mutex::scoped_lock lck(soundMutex);

		Update();
	}
}
Beispiel #17
0
int CommonDefHandler::LoadSoundFile(const std::string& fileName)
{
	const std::string extension = filesystem.GetExtension(fileName);
	bool hasFile = false;
	if (extension == "wav" || extension == "ogg")
	{
		CFileHandler raw(fileName);
		if (raw.FileExists())
			hasFile = true;
	}

	if (!sound->HasSoundItem(fileName) && !hasFile)
	{
		std::string soundFile = "sounds/" + fileName;

		if (extension.empty()) {
			// extension missing, try wav
			soundFile += ".wav";
		}
		CFileHandler fh(soundFile);
		if (fh.FileExists()) {
			// we have a valid soundfile: store name, ID, and default volume
			const int id = sound->GetSoundId(soundFile);
			return id;
		}
		else
		{
			LogObject() << "Could not load sound from def: " << fileName;
			return 0;
		}
	}
	else
	{
		const int id = sound->GetSoundId(fileName);
		return id;
	}
}
Beispiel #18
0
// FOR SYNCED MESSAGES
void CGame::ActionReceived(const Action& action, int playernum)
{
	if (action.command == "cheat") {
		SetBoolArg(gs->cheatEnabled, action.extra);
		if (gs->cheatEnabled)
			logOutput.Print("Cheating!");
		else
			logOutput.Print("No more cheating");
	}
	else if (action.command == "nohelp") {
		SetBoolArg(gs->noHelperAIs, action.extra);
		selectedUnits.PossibleCommandChange(NULL);
		logOutput.Print("LuaUI control is %s", gs->noHelperAIs ? "disabled" : "enabled");
	}
	else if (action.command == "nospecdraw") {
		bool buf;
		SetBoolArg(buf, action.extra);
		inMapDrawer->SetSpecMapDrawingAllowed(buf);
	}
	else if (action.command == "godmode") {
		if (!gs->cheatEnabled)
			logOutput.Print("godmode requires /cheat");
		else {
			SetBoolArg(gs->godMode, action.extra);
			CLuaUI::UpdateTeams();
			if (gs->godMode) {
				logOutput.Print("God Mode Enabled");
			} else {
				logOutput.Print("God Mode Disabled");
			}
			CPlayer::UpdateControlledTeams();
		}
	}
	else if (action.command == "globallos") {
		if (!gs->cheatEnabled) {
			logOutput.Print("globallos requires /cheat");
		} else {
			SetBoolArg(gs->globalLOS, action.extra);
			if (gs->globalLOS) {
				logOutput.Print("Global LOS Enabled");
			} else {
				logOutput.Print("Global LOS Disabled");
			}
		}
	}
	else if (action.command == "nocost" && gs->cheatEnabled) {
		if (unitDefHandler->ToggleNoCost()) {
			logOutput.Print("Everything is for free!");
		} else {
			logOutput.Print("Everything costs resources again!");
		}
	}
	else if (action.command == "give" && gs->cheatEnabled) {
		std::string s = "give "; //FIXME lazyness
		s += action.extra;

		// .give [amount] <unitName> [team] <@x,y,z>
		const vector<string> &args = CSimpleParser::Tokenize(s, 0);

		if (args.size() < 3) {
			logOutput.Print("Someone is spoofing invalid .give messages!");
			return;
		}

		float3 pos;
		if (sscanf(args[args.size() - 1].c_str(), "@%f,%f,%f", &pos.x, &pos.y, &pos.z) != 3) {
			logOutput.Print("Someone is spoofing invalid .give messages!");
			return;
		}

		int amount = 1;
		int team = playerHandler->Player(playernum)->team;

		int amountArgIdx = -1;
		int teamArgIdx = -1;

		if (args.size() == 5) {
			amountArgIdx = 1;
			teamArgIdx = 3;
		}
		else if (args.size() == 4) {
			if (args[1].find_first_not_of("0123456789") == string::npos) {
				amountArgIdx = 1;
			} else {
				teamArgIdx = 2;
			}
		}

		if (amountArgIdx >= 0) {
			const string& amountStr = args[amountArgIdx];
			amount = atoi(amountStr.c_str());
			if ((amount < 0) || (amountStr.find_first_not_of("0123456789") != string::npos)) {
				logOutput.Print("Bad give amount: %s", amountStr.c_str());
				return;
			}
		}

		if (teamArgIdx >= 0) {
			const string& teamStr = args[teamArgIdx];
			team = atoi(teamStr.c_str());
			if ((!teamHandler->IsValidTeam(team)) || (teamStr.find_first_not_of("0123456789") != string::npos)) {
				logOutput.Print("Bad give team: %s", teamStr.c_str());
				return;
			}
		}

		const string unitName = (amountArgIdx >= 0) ? args[2] : args[1];

		if (unitName == "all") {
			// player entered ".give all"
			int numRequestedUnits = unitDefHandler->unitDefs.size() - 1; /// defid=0 is not valid
			int currentNumUnits = teamHandler->Team(team)->units.size();
			int sqSize = (int) streflop::ceil(streflop::sqrt((float) numRequestedUnits));

			// make sure team unit-limit not exceeded
			if ((currentNumUnits + numRequestedUnits) > uh->MaxUnitsPerTeam()) {
				numRequestedUnits = uh->MaxUnitsPerTeam() - currentNumUnits;
			}

			// make sure square is entirely on the map
			float sqHalfMapSize = sqSize / 2 * 10 * SQUARE_SIZE;
			pos.x = std::max(sqHalfMapSize, std::min(pos.x, float3::maxxpos - sqHalfMapSize - 1));
			pos.z = std::max(sqHalfMapSize, std::min(pos.z, float3::maxzpos - sqHalfMapSize - 1));

			for (int a = 1; a <= numRequestedUnits; ++a) {
				float posx = pos.x + (a % sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
				float posz = pos.z + (a / sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
				float3 pos2 = float3(posx, pos.y, posz);
				const UnitDef* ud = unitDefHandler->GetUnitDefByID(a);
				if (ud) {
					const CUnit* unit = unitLoader->LoadUnit(ud, pos2, team, false, 0, NULL);
					if (unit) {
						unitLoader->FlattenGround(unit);
					}
				}
			}
		}
		else if (!unitName.empty()) {
			int numRequestedUnits = amount;
			int currentNumUnits = teamHandler->Team(team)->units.size();

			if (currentNumUnits >= uh->MaxUnitsPerTeam()) {
				LogObject() << "Unable to give any more units to team " << team << "(current: " << currentNumUnits << ", max: " << uh->MaxUnits() << ")";
				return;
			}

			// make sure team unit-limit is not exceeded
			if ((currentNumUnits + numRequestedUnits) > uh->MaxUnitsPerTeam()) {
				numRequestedUnits = uh->MaxUnitsPerTeam() - currentNumUnits;
			}

			const UnitDef* unitDef = unitDefHandler->GetUnitDefByName(unitName);

			if (unitDef != NULL) {
				int xsize = unitDef->xsize;
				int zsize = unitDef->zsize;
				int squareSize = (int) streflop::ceil(streflop::sqrt((float) numRequestedUnits));
				int total = numRequestedUnits;

				float3 minpos = pos;
				minpos.x -= ((squareSize - 1) * xsize * SQUARE_SIZE) / 2;
				minpos.z -= ((squareSize - 1) * zsize * SQUARE_SIZE) / 2;

				for (int z = 0; z < squareSize; ++z) {
					for (int x = 0; x < squareSize && total > 0; ++x) {
						float minposx = minpos.x + x * xsize * SQUARE_SIZE;
						float minposz = minpos.z + z * zsize * SQUARE_SIZE;
						const float3 upos(minposx, minpos.y, minposz);
						const CUnit* unit = unitLoader->LoadUnit(unitDef, upos, team, false, 0, NULL);

						if (unit) {
							unitLoader->FlattenGround(unit);
						}
						--total;
					}
				}

				logOutput.Print("Giving %i %s to team %i", numRequestedUnits, unitName.c_str(), team);
			} else {
				int allyteam = -1;
				if (teamArgIdx < 0) {
					team = -1; // default to world features
					allyteam = -1;
				} else {
					allyteam = teamHandler->AllyTeam(team);
				}

				const FeatureDef* featureDef = featureHandler->GetFeatureDef(unitName);
				if (featureDef) {
					int xsize = featureDef->xsize;
					int zsize = featureDef->zsize;
					int squareSize = (int) streflop::ceil(streflop::sqrt((float) numRequestedUnits));
					int total = amount; // FIXME -- feature count limit?

					float3 minpos = pos;
					minpos.x -= ((squareSize - 1) * xsize * SQUARE_SIZE) / 2;
					minpos.z -= ((squareSize - 1) * zsize * SQUARE_SIZE) / 2;

					for (int z = 0; z < squareSize; ++z) {
						for (int x = 0; x < squareSize && total > 0; ++x) {
							float minposx = minpos.x + x * xsize * SQUARE_SIZE;
							float minposz = minpos.z + z * zsize * SQUARE_SIZE;
							float minposy = ground->GetHeightReal(minposx, minposz);
							const float3 upos(minposx, minposy, minposz);

							CFeature* feature = new CFeature();
							// Initialize() adds the feature to the FeatureHandler -> no memory-leak
							feature->Initialize(upos, featureDef, 0, 0, team, allyteam, "");
							--total;
						}
					}

					logOutput.Print("Giving %i %s (feature) to team %i",
									numRequestedUnits, unitName.c_str(), team);
				}
				else {
					logOutput.Print(unitName + " is not a valid unitname");
				}
			}
		}
	}
	else if (action.command == "destroy" && gs->cheatEnabled) {
		std::stringstream ss(action.extra);
		logOutput.Print("Killing units: %s", action.extra.c_str());
		do {
			unsigned id;
			ss >> id;
			if (!ss)
				break;
			if (id >= uh->units.size())
				continue;
			if (uh->units[id] == NULL)
				continue;
			uh->units[id]->KillUnit(false, false, 0);
		} while (true);
	}
Beispiel #19
0
bool SoundBuffer::LoadWAV(const std::string& file, std::vector<boost::uint8_t> buffer, bool strict)
{
	WAVHeader* header = (WAVHeader*)(&buffer[0]);

	if (memcmp(header->riff, "RIFF", 4) || memcmp(header->wavefmt, "WAVEfmt", 7)) {
		if (strict) {
			ErrorMessageBox("ReadWAV: invalid header.", file, 0);
		}
		return false;
	}

#define hswabword(c) header->c = swabword(header->c)
#define hswabdword(c) header->c = swabdword(header->c)
	hswabword(format_tag);
	hswabword(channels);
	hswabword(BlockAlign);
	hswabword(BitsPerSample);

	hswabdword(totalLength);
	hswabdword(length);
	hswabdword(SamplesPerSec);
	hswabdword(AvgBytesPerSec);
	hswabdword(datalen);
#undef hswabword
#undef hswabdword

	if (header->format_tag != 1) { // Microsoft PCM format?
		if (strict) {
			ErrorMessageBox("ReadWAV: invalid format tag.", file, 0);
		}
		return false;
	}

	ALenum format;
	if (header->channels == 1) {
		if (header->BitsPerSample == 8) format = AL_FORMAT_MONO8;
		else if (header->BitsPerSample == 16) format = AL_FORMAT_MONO16;
		else {
			if (strict) {
				ErrorMessageBox("ReadWAV: invalid number of bits per sample (mono).", file, 0);
			}
			return false;
		}
	}
	else if (header->channels == 2) {
		if (header->BitsPerSample == 8) format = AL_FORMAT_STEREO8;
		else if (header->BitsPerSample == 16) format = AL_FORMAT_STEREO16;
		else {
			if (strict) {
				ErrorMessageBox("ReadWAV: invalid number of bits per sample (stereo).", file, 0);
			}
			return false;
		}
	}
	else {
		if (strict) {
			ErrorMessageBox("ReadWAV (%s): invalid number of channels.", file, 0);
		}
		return false;
	}

	if (static_cast<unsigned>(header->datalen) > buffer.size() - sizeof(WAVHeader)) {
		LogObject(LOG_SOUND) << "WAV file " << file << " has data length " << header->datalen << " greater than actual data length " << buffer.size() - sizeof(WAVHeader);

//		logOutput.Print("OpenAL: size %d\n", size);
//		logOutput.Print("OpenAL: sizeof(WAVHeader) %d\n", sizeof(WAVHeader));
//		logOutput.Print("OpenAL: format_tag %d\n", header->format_tag);
//		logOutput.Print("OpenAL: channels %d\n", header->channels);
//		logOutput.Print("OpenAL: BlockAlign %d\n", header->BlockAlign);
//		logOutput.Print("OpenAL: BitsPerSample %d\n", header->BitsPerSample);
//		logOutput.Print("OpenAL: totalLength %d\n", header->totalLength);
//		logOutput.Print("OpenAL: length %d\n", header->length);
//		logOutput.Print("OpenAL: SamplesPerSec %d\n", header->SamplesPerSec);
//		logOutput.Print("OpenAL: AvgBytesPerSec %d\n", header->AvgBytesPerSec);

		header->datalen = boost::uint32_t(buffer.size() - sizeof(WAVHeader))&(~boost::uint32_t((header->BitsPerSample*header->channels)/8 -1));
	}

	if (!AlGenBuffer(file, format, &buffer[sizeof(WAVHeader)], header->datalen, header->SamplesPerSec))
		LogObject(LOG_SOUND) << "Loading audio failed for " << file;
	return true;
}
Beispiel #20
0
bool SoundBuffer::LoadVorbis(const std::string& file, std::vector<boost::uint8_t> buffer, bool strict)
{
	VorbisInputBuffer buf;
	buf.data = &buffer[0];
	buf.pos = 0;
	buf.size = buffer.size();
	
	ov_callbacks vorbisCallbacks;
	vorbisCallbacks.read_func  = VorbisRead;
	vorbisCallbacks.close_func = VorbisClose;
	vorbisCallbacks.seek_func  = NULL;
	vorbisCallbacks.tell_func  = NULL;

	OggVorbis_File oggStream;
	int result = 0;
	if ((result = ov_open_callbacks(&buf, &oggStream, NULL, 0, vorbisCallbacks)) < 0)
	{
		logOutput.Print("Could not open Ogg stream (reason: %s).", ErrorString(result).c_str());
		return false;
	}
	
	vorbis_info* vorbisInfo = ov_info(&oggStream, -1);
	// vorbis_comment* vorbisComment = ov_comment(&oggStream, -1);

	ALenum format;
	if (vorbisInfo->channels == 1)
	{
		format = AL_FORMAT_MONO16;
	}
	else if (vorbisInfo->channels == 2)
	{
		format = AL_FORMAT_STEREO16;
	}
	else
	{
		if (strict)
			ErrorMessageBox("SoundBuffer::LoadVorbis (%s): invalid number of channels.", file, 0);
		else
			LogObject(LOG_SOUND) << "File  " << file << ": invalid number of channels: " << vorbisInfo->channels;
		return false;
	}

	size_t pos = 0;
	std::vector<boost::uint8_t> decodeBuffer(512*1024); // 512kb read buffer
	int section = 0;
	long read = 0;
	do
	{
		if (4*pos > 3*decodeBuffer.size()) // enlarge buffer so ov_read has enough space
			decodeBuffer.resize(decodeBuffer.size()*2);
		read = ov_read(&oggStream, (char*)&decodeBuffer[pos], decodeBuffer.size() - pos, 0, 2, 1, &section);
		switch(read)
		{
			case OV_HOLE:
				LogObject(LOG_SOUND) << file << ": garbage or corrupt page in stream (non-fatal)";
				continue; // read next
			case OV_EBADLINK:
				LogObject(LOG_SOUND) << file << ": corrupted stream";
				return false; // abort
			case OV_EINVAL:
				LogObject(LOG_SOUND) << file << ": corrupted headers";
				return false; // abort
			default:
				break; // all good
		};
		pos += read;
	} while (read > 0); // read == 0 indicated EOF, read < 0 is error

	AlGenBuffer(file, format, &decodeBuffer[0], pos, vorbisInfo->rate);
	return true;
}
Beispiel #21
0
CUnit* CUnitLoader::LoadUnit(const UnitDef* ud, float3 pos, int team,
                             bool build, int facing, const CUnit* builder)
{
	GML_RECMUTEX_LOCK(sel); // LoadUnit - for anti deadlock purposes.
	GML_RECMUTEX_LOCK(quad); // LoadUnit - make sure other threads cannot access an incomplete unit

	SCOPED_TIMER("Unit loader");

	CUnit* unit;

	std::string type = ud->type;

	// clamp to map
	if (pos.x < 0)
		pos.x = 0;
	if (pos.x >= gs->mapx * SQUARE_SIZE)
		pos.x = gs->mapx-1;
	if (pos.z < 0)
		pos.z = 0;
	if (pos.z >= gs->mapy * SQUARE_SIZE)
		pos.z = gs->mapy-1;

	if (!build) {
		pos.y = ground->GetHeight2(pos.x, pos.z);
		if (ud->floater && pos.y < 0.0f) {
			// adjust to waterline iif we are submerged
 			pos.y = -ud->waterline;
		}
	}

	if (team < 0) {
		team = teamHandler->GaiaTeamID(); // FIXME use gs->gaiaTeamID ?  (once it is always enabled)
		if (team < 0)
			throw content_error("Invalid team and no gaia team to put unit in");
	}

	if (type == "GroundUnit") {
		unit = new CUnit;
	} else if (type == "Transport") {
		unit = new CTransportUnit;
	} else if (type == "Building") {
		unit = new CBuilding;
	} else if (type == "Factory") {
		unit = new CFactory;
	} else if (type == "Builder") {
		unit = new CBuilder;
	} else if (type == "Bomber" || type == "Fighter") {
		unit = new CUnit;
	} else if (type == "MetalExtractor") {
		unit = new CExtractorBuilding;
	} else {
		LogObject() << "Unknown unit type " << type.c_str() << "\n";
		return NULL;
	}

	unit->UnitInit(ud, team, pos);
	unit->beingBuilt = build;

	unit->buildFacing = abs(facing) % 4;
	unit->xsize = ((unit->buildFacing & 1) == 0) ? ud->xsize : ud->zsize;
	unit->zsize = ((unit->buildFacing & 1) == 1) ? ud->xsize : ud->zsize;

	unit->power = ud->power;
	unit->maxHealth = ud->health;
	unit->health = ud->health;
	//unit->metalUpkeep = ud->metalUpkeep*16.0f/GAME_SPEED;
	//unit->energyUpkeep = ud->energyUpkeep*16.0f/GAME_SPEED;
	unit->controlRadius = (int)(ud->controlRadius / SQUARE_SIZE);
	unit->losHeight = ud->losHeight;
	unit->metalCost = ud->metalCost;
	unit->energyCost = ud->energyCost;
	unit->buildTime = ud->buildTime;
	unit->aihint = ud->aihint;
	unit->tooltip = ud->humanName + " - " + ud->tooltip;
	unit->armoredMultiple = std::max(0.0001f, ud->armoredMultiple);		//armored multiple of 0 will crash spring
	unit->wreckName = ud->wreckName;

	unit->realLosRadius = (int) (ud->losRadius);
	unit->realAirLosRadius = (int) (ud->airLosRadius);
	unit->upright = ud->upright;
	unit->radarRadius      = ud->radarRadius    / (SQUARE_SIZE * 8);
	unit->sonarRadius      = ud->sonarRadius    / (SQUARE_SIZE * 8);
	unit->jammerRadius     = ud->jammerRadius   / (SQUARE_SIZE * 8);
	unit->sonarJamRadius   = ud->sonarJamRadius / (SQUARE_SIZE * 8);
	unit->seismicRadius    = ud->seismicRadius  / (SQUARE_SIZE * 8);
	unit->seismicSignature = ud->seismicSignature;
	unit->hasRadarCapacity = unit->radarRadius  || unit->sonarRadius    ||
	                         unit->jammerRadius || unit->sonarJamRadius ||
	                         unit->seismicRadius;
	unit->stealth = ud->stealth;
	unit->sonarStealth = ud->sonarStealth;
	unit->category = ud->category;
	unit->armorType = ud->armorType;
	unit->floatOnWater =
		ud->floater || (ud->movedata && ((ud->movedata->moveType == MoveData::Hover_Move) ||
		                                 (ud->movedata->moveType == MoveData::Ship_Move)));
	unit->maxSpeed = ud->speed / GAME_SPEED;
	unit->decloakDistance = ud->decloakDistance;

	unit->flankingBonusMode        = ud->flankingBonusMode;
	unit->flankingBonusDir         = ud->flankingBonusDir;
	unit->flankingBonusMobility    = ud->flankingBonusMobilityAdd * 1000;
	unit->flankingBonusMobilityAdd = ud->flankingBonusMobilityAdd;
	unit->flankingBonusAvgDamage = (ud->flankingBonusMax + ud->flankingBonusMin) * 0.5f;
	unit->flankingBonusDifDamage = (ud->flankingBonusMax - ud->flankingBonusMin) * 0.5f;


	if(ud->highTrajectoryType==1)
		unit->useHighTrajectory=true;

	if(ud->fireState >= 0)
		unit->fireState = ud->fireState;

	if(build){
		unit->ChangeLos(1,1);
		unit->health=0.1f;
	} else {
		unit->ChangeLos((int)(ud->losRadius),(int)(ud->airLosRadius));
	}

	if (type == "GroundUnit") {
		new CMobileCAI(unit);
	}
	else if (type == "Transport") {
		new CTransportCAI(unit);
	}
	else if (type == "Factory") {
		new CFactoryCAI(unit);
	}
	else if (type == "Builder") {
		new CBuilderCAI(unit);
	}
	else if (type == "Bomber") {
		if (ud->hoverAttack) {
			new CMobileCAI(unit);
		} else {
			new CAirCAI(unit);
		}
	}
	else if(type == "Fighter"){
		if (ud->hoverAttack) {
			new CMobileCAI(unit);
		} else {
			new CAirCAI(unit);
		}
	}
	else {
		new CCommandAI(unit);
	}

	if (ud->canmove && !ud->canfly && (type != "Factory")) {
		CGroundMoveType* mt = new CGroundMoveType(unit);
		mt->maxSpeed = ud->speed / GAME_SPEED;
		mt->maxWantedSpeed = ud->speed / GAME_SPEED;
		mt->turnRate = ud->turnRate;
		mt->baseTurnRate = ud->turnRate;

		if (mt->accRate <= 0.0f) {
			LogObject() << "acceleration of unit-type " << ud->name.c_str() << " is zero or negative!\n";
			mt->accRate = 0.01f;
		}

		mt->accRate = ud->maxAcc;
		mt->decRate = ud->maxDec;
		mt->floatOnWater = (ud->movedata->moveType == MoveData::Hover_Move ||
		                    ud->movedata->moveType == MoveData::Ship_Move);

		if (!unit->beingBuilt) {
			// otherwise set this when finished building instead
			unit->mass = ud->mass;
		}
		unit->moveType = mt;

		// Ground-mobility
		unit->mobility = new MoveData(ud->movedata);

	} else if (ud->canfly) {
		// Air-mobility
		unit->mobility = new MoveData(ud->movedata);

		if (!unit->beingBuilt) {
			// otherwise set this when finished building instead
			unit->mass = ud->mass;
		}

		if ((type == "Builder") || ud->hoverAttack || ud->transportCapacity) {
			CTAAirMoveType* mt = new CTAAirMoveType(unit);

			mt->turnRate = ud->turnRate;
			mt->maxSpeed = ud->speed / GAME_SPEED;
			mt->accRate = ud->maxAcc;
			mt->decRate = ud->maxDec;
			mt->wantedHeight = ud->wantedHeight + gs->randFloat() * 5;
			mt->orgWantedHeight = mt->wantedHeight;
			mt->dontLand = ud->DontLand();
			mt->collide = ud->collide;
			mt->altitudeRate = ud->verticalSpeed;
			mt->bankingAllowed = ud->bankingAllowed;

			unit->moveType = mt;
		}
		else {
			CAirMoveType *mt = new CAirMoveType(unit);

			if(type=="Fighter")
				mt->isFighter=true;

			mt->collide = ud->collide;

			mt->wingAngle = ud->wingAngle;
			mt->crashDrag = 1 - ud->crashDrag;
			mt->invDrag = 1 - ud->drag;
			mt->frontToSpeed = ud->frontToSpeed;
			mt->speedToFront = ud->speedToFront;
			mt->myGravity = ud->myGravity;

			mt->maxBank = ud->maxBank;
			mt->maxPitch = ud->maxPitch;
			mt->turnRadius = ud->turnRadius;
			mt->wantedHeight = (ud->wantedHeight * 1.5f) +
			                   ((gs->randFloat() - 0.3f) * 15 * (mt->isFighter ? 2 : 1));

			mt->maxAcc = ud->maxAcc;
			mt->maxAileron = ud->maxAileron;
			mt->maxElevator = ud->maxElevator;
			mt->maxRudder = ud->maxRudder;

			unit->moveType = mt;
		}
	} else {
		unit->moveType = new CMoveType(unit);
		unit->upright = true;
	}

	unit->energyTickMake = ud->energyMake;

	if (ud->tidalGenerator > 0)
		unit->energyTickMake += ud->tidalGenerator * mapInfo->map.tidalStrength;


	unit->model = ud->LoadModel();
	unit->SetRadius(unit->model->radius);

	modelParser->CreateLocalModel(unit);


	// copy the UnitDef volume instance
	//
	// aircraft still get half-size spheres for coldet purposes
	// iif no custom volume is defined (unit->model->radius and
	// unit->radius themselves are no longer altered)
	unit->collisionVolume = new CollisionVolume(ud->collisionVolume, unit->model->radius * ((ud->canfly)? 0.5f: 1.0f));

	if (unit->model->radius <= 60.0f) {
		// the interval-based method fails too easily for units
		// with small default volumes, force use of raytracing
		unit->collisionVolume->SetTestType(COLVOL_TEST_CONT);
	}


	if (ud->floater) {
		// restrict our depth to our waterline
		unit->pos.y = std::max(-ud->waterline, ground->GetHeight2(unit->pos.x, unit->pos.z));
	} else {
		unit->pos.y = ground->GetHeight2(unit->pos.x, unit->pos.z);
	}

	unit->script = CUnitScriptFactory::CreateScript(ud->scriptPath, unit);

	unit->weapons.reserve(ud->weapons.size());
	for (unsigned int i = 0; i < ud->weapons.size(); i++) {
		unit->weapons.push_back(LoadWeapon(ud->weapons[i].def, unit, &ud->weapons[i]));
	}

	// Call initializing script functions
	unit->script->Create();

	unit->heading = GetHeadingFromFacing(facing);
	unit->frontdir = GetVectorFromHeading(unit->heading);
	unit->updir = UpVector;
	unit->rightdir = unit->frontdir.cross(unit->updir);

	unit->yardMap = ud->yardmaps[facing];

	unit->Init(builder);

	if (!build) {
		unit->FinishedBuilding();
	}
	return unit;
}
Beispiel #22
0
CWeapon* CUnitLoader::LoadWeapon(const WeaponDef *weapondef, CUnit* owner, const UnitDef::UnitDefWeapon* udw)
{
	CWeapon* weapon;

	if (!weapondef) {
		logOutput.Print("Error: No weapon def?");
	}

	if (udw->name == "NOWEAPON") {
		weapon = new CNoWeapon(owner);
	} else if (weapondef->type == "Cannon") {
		weapon = new CCannon(owner);
		((CCannon*)weapon)->selfExplode = weapondef->selfExplode;
	} else if (weapondef->type == "Rifle") {
		weapon = new CRifle(owner);
	} else if (weapondef->type == "Melee") {
		weapon = new CMeleeWeapon(owner);
	} else if (weapondef->type == "AircraftBomb") {
		weapon = new CBombDropper(owner, false);
	} else if (weapondef->type == "Shield") {
		weapon = new CPlasmaRepulser(owner);
	} else if (weapondef->type == "Flame") {
		weapon = new CFlameThrower(owner);
	} else if (weapondef->type == "MissileLauncher") {
		weapon = new CMissileLauncher(owner);
	} else if (weapondef->type == "TorpedoLauncher") {
		if (owner->unitDef->canfly && !weapondef->submissile) {
			weapon = new CBombDropper(owner, true);
			if (weapondef->tracks)
				((CBombDropper*) weapon)->tracking = weapondef->turnrate;
			((CBombDropper*) weapon)->bombMoveRange = weapondef->range;
		} else {
			weapon = new CTorpedoLauncher(owner);
			if (weapondef->tracks)
				((CTorpedoLauncher*) weapon)->tracking = weapondef->turnrate;
		}
	} else if (weapondef->type == "LaserCannon") {
		weapon = new CLaserCannon(owner);
		((CLaserCannon*) weapon)->color = weapondef->visuals.color;
	} else if (weapondef->type == "BeamLaser") {
		weapon = new CBeamLaser(owner);
		((CBeamLaser*) weapon)->color = weapondef->visuals.color;
	} else if (weapondef->type == "LightningCannon") {
		weapon = new CLightningCannon(owner);
		((CLightningCannon*) weapon)->color = weapondef->visuals.color;
	} else if (weapondef->type == "EmgCannon") {
		weapon = new CEmgCannon(owner);
	} else if (weapondef->type == "DGun") {
		weapon = new CDGunWeapon(owner);
	} else if (weapondef->type == "StarburstLauncher"){
		weapon = new CStarburstLauncher(owner);
		if (weapondef->tracks)
			((CStarburstLauncher*) weapon)->tracking = weapondef->turnrate;
		else
			((CStarburstLauncher*) weapon)->tracking = 0;
		((CStarburstLauncher*) weapon)->uptime = weapondef->uptime * GAME_SPEED;
	} else {
		LogObject() << "Unknown weapon type " << weapondef->type.c_str() << "\n";
		return 0;
	}
	weapon->weaponDef = weapondef;

	weapon->reloadTime = (int) (weapondef->reload * GAME_SPEED);
	if (weapon->reloadTime == 0)
		weapon->reloadTime = 1;
	weapon->range = weapondef->range;
//	weapon->baseRange = weapondef->range;
	weapon->heightMod = weapondef->heightmod;
	weapon->projectileSpeed = weapondef->projectilespeed;
//	weapon->baseProjectileSpeed = weapondef->projectilespeed / GAME_SPEED;

	weapon->areaOfEffect = weapondef->areaOfEffect;
	weapon->accuracy = weapondef->accuracy;
	weapon->sprayAngle = weapondef->sprayAngle;

	weapon->stockpileTime = (int) (weapondef->stockpileTime * GAME_SPEED);

	weapon->salvoSize = weapondef->salvosize;
	weapon->salvoDelay = (int) (weapondef->salvodelay * GAME_SPEED);
	weapon->projectilesPerShot = weapondef->projectilespershot;

	weapon->metalFireCost = weapondef->metalcost;
	weapon->energyFireCost = weapondef->energycost;

	weapon->fireSoundId = weapondef->firesound.getID(0);
	weapon->fireSoundVolume = weapondef->firesound.getVolume(0);

	weapon->onlyForward = weapondef->onlyForward;
	if (owner->unitDef->type == "Fighter" && !owner->unitDef->hoverAttack) {
		// fighter aircraft have too big tolerance in TA
		weapon->maxAngleDif = cos(weapondef->maxAngle * 0.4f / 180 * PI);
	} else {
		weapon->maxAngleDif = cos(weapondef->maxAngle / 180 * PI);
	}

	weapon->SetWeaponNum(owner->weapons.size());

	weapon->badTargetCategory = udw->badTargetCat;
	weapon->onlyTargetCategory = weapondef->onlyTargetCategory & udw->onlyTargetCat;

	if (udw->slavedTo) {
		const int index = (udw->slavedTo - 1);
		if ((index < 0) || (static_cast<size_t>(index) >= owner->weapons.size())) {
			throw content_error("Bad weapon slave in " + owner->unitDef->name);
		}
		weapon->slavedTo = owner->weapons[index];
	}

	weapon->mainDir = udw->mainDir;
	weapon->maxMainDirAngleDif = udw->maxAngleDif;

	weapon->fuelUsage = udw->fuelUsage;
	weapon->avoidFriendly = weapondef->avoidFriendly;
	weapon->avoidFeature = weapondef->avoidFeature;
	weapon->avoidNeutral = weapondef->avoidNeutral;
	weapon->targetBorder = weapondef->targetBorder;
	weapon->cylinderTargetting = weapondef->cylinderTargetting;
	weapon->minIntensity = weapondef->minIntensity;
	weapon->heightBoostFactor = weapondef->heightBoostFactor;
	weapon->collisionFlags = weapondef->collisionFlags;
	weapon->Init();

	return weapon;
}
Beispiel #23
0
/**
 * Search with several start positions
 */
IPath::SearchResult CPathFinder::GetPath(
	const MoveData& moveData,
	const std::vector<float3>& startPos,
	const CPathFinderDef& pfDef,
	IPath::Path& path,
	int ownerId,
	bool synced
) {
	// Clear the given path.
	path.path.clear();
	path.squares.clear();
	path.pathCost = PATHCOST_INFINITY;

	// Store som basic data.
	maxSquaresToBeSearched = MAX_SEARCHED_NODES_PF - 8U;
	testMobile = false;
	exactPath = true;
	needPath = true;

	// If exact path is reqired and the goal is blocked, then no search is needed.
	if (exactPath && pfDef.GoalIsBlocked(moveData, (CMoveMath::BLOCK_STRUCTURE | CMoveMath::BLOCK_TERRAIN)))
		return IPath::CantGetCloser;

	// If the starting position is a goal position, then no search need to be performed.
	if (pfDef.IsGoal(startxSqr, startzSqr))
		return IPath::CantGetCloser;

	// Clearing the system from last search.
	ResetSearch();

	openSquareBuffer.SetSize(0);

	for (std::vector<float3>::const_iterator si = startPos.begin(); si != startPos.end(); ++si) {
		start = *si;
		startxSqr = (int(start.x) / SQUARE_SIZE) | 1;
		startzSqr = (int(start.z) / SQUARE_SIZE) | 1;
		startSquare = startxSqr + startzSqr * gs->mapx;
		goalSquare = startSquare;

		squareStates[startSquare].nodeMask = (PATHOPT_START | PATHOPT_OPEN);
		squareStates[startSquare].fCost = 0.0f;
		squareStates[startSquare].gCost = 0.0f;
		dirtySquares.push_back(startSquare);

		if (openSquareBuffer.GetSize() >= MAX_SEARCHED_NODES_PF) {
			continue;
		}

		PathNode* os = openSquareBuffer.GetNode(openSquareBuffer.GetSize());
			os->fCost     = 0.0f;
			os->gCost     = 0.0f;
			os->nodePos.x = startxSqr;
			os->nodePos.y = startzSqr;
			os->nodeNum   = startSquare;
		openSquareBuffer.SetSize(openSquareBuffer.GetSize() + 1);
		openSquares.push(os);
	}

	// note: DoSearch, not InitSearch
	IPath::SearchResult result = DoSearch(moveData, pfDef, ownerId, synced);

	// Respond to the success of the search.
	if (result == IPath::Ok) {
		FinishSearch(moveData, path);
		if (PATHDEBUG) {
			LogObject() << "Path found.\n";
			LogObject() << "Nodes tested: " << testedNodes << "\n";
			LogObject() << "Open squares: " << openSquareBuffer.GetSize() << "\n";
			LogObject() << "Path nodes: " << path.path.size() << "\n";
			LogObject() << "Path cost: " << path.pathCost << "\n";
		}
	} else {
		if (PATHDEBUG) {
			LogObject() << "No path found!\n";
			LogObject() << "Nodes tested: " << testedNodes << "\n";
			LogObject() << "Open squares: " << openSquareBuffer.GetSize() << "\n";
		}
	}
	return result;
}
Beispiel #24
0
void CGame::ClientReadNet()
{
	if (gu->gameTime - lastCpuUsageTime >= 1) {
		lastCpuUsageTime = gu->gameTime;

		if (playing) {
			net->Send(CBaseNetProtocol::Get().SendCPUUsage(profiler.GetPercent("CPU load")));
#if defined(USE_GML) && GML_ENABLE_SIM
			net->Send(CBaseNetProtocol::Get().SendLuaDrawTime(gu->myPlayerNum, luaDrawTime));
#endif
		} else {
			// the CPU-load percentage is undefined prior to SimFrame()
			net->Send(CBaseNetProtocol::Get().SendCPUUsage(0.0f));
		}
	}

	boost::shared_ptr<const netcode::RawPacket> packet;

	// compute new timeLeft to "smooth" out SimFrame() calls
	if (!gameServer) {
		const unsigned int currentFrame = SDL_GetTicks();

		if (timeLeft > 1.0f)
			timeLeft -= 1.0f;
		timeLeft += consumeSpeed * ((float)(currentFrame - lastframe) / 1000.f);
		if (skipping)
			timeLeft = 0.01f;
		lastframe = currentFrame;

		// read ahead to calculate the number of NETMSG_NEWFRAMES
		// we still have to process (in variable "que")
		int que = 0; // Number of NETMSG_NEWFRAMEs waiting to be processed.
		unsigned ahead = 0;
		while ((packet = net->Peek(ahead))) {
			if (packet->data[0] == NETMSG_NEWFRAME || packet->data[0] == NETMSG_KEYFRAME)
				++que;
			++ahead;
		}

		if(que < leastQue)
			leastQue = que;
	}
	else
	{
		// make sure ClientReadNet returns at least every 15 game frames
		// so CGame can process keyboard input, and render etc.
		timeLeft = (float)MAX_CONSECUTIVE_SIMFRAMES * gs->userSpeedFactor;
	}

	// always render at least 2FPS (will otherwise be highly unresponsive when catching up after a reconnection)
	unsigned procstarttime = SDL_GetTicks();
	// really process the messages
	while (timeLeft > 0.0f && (SDL_GetTicks() - procstarttime) < 500 && (packet = net->GetData(gs->frameNum)))
	{
		const unsigned char* inbuf = packet->data;
		const unsigned dataLength = packet->length;
		const unsigned char packetCode = inbuf[0];

		switch (packetCode) {
			case NETMSG_QUIT: {
				try {
					netcode::UnpackPacket pckt(packet, 3);
					std::string message;
					pckt >> message;
					logOutput.Print(message);
					if (!gameOver) {
						GameEnd(std::vector<unsigned char>());
					}
					AddTraffic(-1, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid QuitMessage: %s", e.err.c_str());
				}
				break;
			}

			case NETMSG_PLAYERLEFT: {
				const unsigned char player = inbuf[1];
				if (!playerHandler->IsValidPlayer(player)) {
					logOutput.Print("Got invalid player num (%i) in NETMSG_PLAYERLEFT", player);
					break;
				}
				playerHandler->PlayerLeft(player, inbuf[2]);
				eventHandler.PlayerRemoved(player, (int) inbuf[2]);

				AddTraffic(player, packetCode, dataLength);
				break;
			}

			case NETMSG_MEMDUMP: {
				MakeMemDump();
#ifdef TRACE_SYNC
				tracefile.Commit();
#endif
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_STARTPLAYING: {
				unsigned timeToStart = *(unsigned*)(inbuf+1);
				if (timeToStart > 0) {
					GameSetupDrawer::StartCountdown(timeToStart);
				} else {
					StartPlaying();
				}
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_SENDPLAYERSTAT: {
				//logOutput.Print("Game over");
			// Warning: using CPlayer::Statistics here may cause endianness problems
			// once net->SendData is endian aware!
				net->Send(CBaseNetProtocol::Get().SendPlayerStat(gu->myPlayerNum, playerHandler->Player(gu->myPlayerNum)->currentStats));
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_PLAYERSTAT: {
				const unsigned char player = inbuf[1];
				if (!playerHandler->IsValidPlayer(player)) {
					logOutput.Print("Got invalid player num %i in playerstat msg",player);
					break;
				}
				playerHandler->Player(player)->currentStats = *(CPlayer::Statistics*)&inbuf[2];
				if (gameOver) {
					CDemoRecorder* record = net->GetDemoRecorder();
					if (record != NULL) {
						record->SetPlayerStats(player, playerHandler->Player(player)->currentStats);
					}
				}
				AddTraffic(player, packetCode, dataLength);
				break;
			}

			case NETMSG_PAUSE: {
				const unsigned char player = inbuf[1];
				if (!playerHandler->IsValidPlayer(player)) {
					logOutput.Print("Got invalid player num %i in pause msg",player);
					break;
				}
				gs->paused=!!inbuf[2];
				logOutput.Print(gs->paused ? "%s paused the game" : "%s unpaused the game" ,
											playerHandler->Player(player)->name.c_str());
				eventHandler.GamePaused(player, gs->paused);
				lastframe = SDL_GetTicks();
				AddTraffic(player, packetCode, dataLength);
				break;
			}

			case NETMSG_INTERNAL_SPEED: {
				gs->speedFactor = *((float*) &inbuf[1]);
				sound->PitchAdjust(sqrt(gs->speedFactor));
				//	logOutput.Print("Internal speed set to %.2f",gs->speedFactor);
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_USER_SPEED: {
				gs->userSpeedFactor = *((float*) &inbuf[2]);

				const unsigned char player = inbuf[1];
				if (!playerHandler->IsValidPlayer(player) && player != SERVER_PLAYER) {
					logOutput.Print("Got invalid player num %i in user speed msg", player);
					break;
				}
				const char* pName = (player == SERVER_PLAYER)? "server": playerHandler->Player(player)->name.c_str();

				logOutput.Print("Speed set to %.1f [%s]", gs->userSpeedFactor, pName);
				AddTraffic(player, packetCode, dataLength);
				break;
			}

			case NETMSG_CPU_USAGE: {
				logOutput.Print("Game clients shouldn't get cpu usage msgs?");
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_PLAYERINFO: {
				const unsigned char player = inbuf[1];
				if (!playerHandler->IsValidPlayer(player)) {
					logOutput.Print("Got invalid player num %i in playerinfo msg", player);
					break;
				}
				playerHandler->Player(player)->cpuUsage = *(float*) &inbuf[2];
				playerHandler->Player(player)->ping = *(boost::uint32_t*) &inbuf[6];

				AddTraffic(player, packetCode, dataLength);
				break;
			}

			case NETMSG_PLAYERNAME: {
				try {
					netcode::UnpackPacket pckt(packet, 2);
					unsigned char player;
					pckt >> player;
					if (!playerHandler->IsValidPlayer(player))
						throw netcode::UnpackPacketException("Invalid player number");

					pckt >> playerHandler->Player(player)->name;
					playerHandler->Player(player)->readyToStart=(gameSetup->startPosType != CGameSetup::StartPos_ChooseInGame);
					playerHandler->Player(player)->active=true;
					wordCompletion->AddWord(playerHandler->Player(player)->name, false, false, false); // required?
					AddTraffic(player, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid PlayerName: %s", e.err.c_str());
				}
				break;
			}

			case NETMSG_CHAT: {
				try {
					ChatMessage msg(packet);

					HandleChatMsg(msg);
					AddTraffic(msg.fromPlayer, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid ChatMessage: %s", e.err.c_str());
				}
				break;
			}

			case NETMSG_SYSTEMMSG:{
				try {
					netcode::UnpackPacket pckt(packet, 4);
					string s;
					pckt >> s;
					logOutput.Print(s);
					AddTraffic(-1, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid SystemMessage: %s", e.err.c_str());
				}
				break;
			}

			case NETMSG_STARTPOS:{
				const unsigned char player = inbuf[1];
				if (!playerHandler->IsValidPlayer(player) && player != SERVER_PLAYER) {
					logOutput.Print("Got invalid player num %i in start pos msg", player);
					break;
				}
				const int team = inbuf[2];
				if (!teamHandler->IsValidTeam(team)) {
					logOutput.Print("Got invalid team num %i in startpos msg", team);
				} else {
					float3 pos(*(float*)&inbuf[4],
					           *(float*)&inbuf[8],
					           *(float*)&inbuf[12]);
					if (!luaRules || luaRules->AllowStartPosition(player, pos)) {
						teamHandler->Team(team)->StartposMessage(pos);
						if (inbuf[3] != 2 && player != SERVER_PLAYER)
						{
							playerHandler->Player(player)->readyToStart = !!inbuf[3];
						}
						if (pos.y != -500) // no marker marker when no pos set yet
						{
							char label[128];
							SNPRINTF(label, sizeof(label), "Start %i", team);
							inMapDrawer->LocalPoint(pos, label, player);
							// FIXME - erase old pos ?
						}
					}
				}
				AddTraffic(player, packetCode, dataLength);
				break;
			}

			case NETMSG_RANDSEED: {
				gs->SetRandSeed(*((unsigned int*)&inbuf[1]), true);
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_GAMEID: {
				const unsigned char* p = &inbuf[1];
				CDemoRecorder* record = net->GetDemoRecorder();
				if (record != NULL) {
					record->SetGameID(p);
				}
				memcpy(gameID, p, sizeof(gameID));
				logOutput.Print(
				  "GameID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
				  p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
				  p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]);
				AddTraffic(-1, packetCode, dataLength);
				break;
			}

			case NETMSG_PATH_CHECKSUM: {
				const unsigned char playerNum = inbuf[1];
				if (!playerHandler->IsValidPlayer(playerNum)) {
					logOutput.Print("Got invalid player num %i in path checksum msg", playerNum);
					break;
				}

				const boost::uint32_t playerCheckSum = *(boost::uint32_t*) &inbuf[2];
				const boost::uint32_t localCheckSum = pathManager->GetPathCheckSum();
				const CPlayer* player = playerHandler->Player(playerNum);

				if (playerCheckSum == 0) {
					logOutput.Print(
						"[DESYNC WARNING] path-checksum for player %d (%s) is 0; non-writable cache?",
						playerNum, player->name.c_str()
					);
				} else {
					if (playerCheckSum != localCheckSum) {
						logOutput.Print(
							"[DESYNC WARNING] path-checksum %08x for player %d (%s) does not match local checksum %08x",
							playerCheckSum, playerNum, player->name.c_str(), localCheckSum
						);
					}
				}
			} break;

			case NETMSG_KEYFRAME: {
				int serverframenum = *(int*)(inbuf+1);
				net->Send(CBaseNetProtocol::Get().SendKeyFrame(serverframenum));
				if (gs->frameNum == (serverframenum - 1)) {
				} else {
					// error
					LogObject() << "Error: Keyframe difference: " << gs->frameNum - (serverframenum - 1);
				}
				/* Fall through */
			}
			case NETMSG_NEWFRAME: {
				timeLeft -= 1.0f;
				SimFrame();
				// both NETMSG_SYNCRESPONSE and NETMSG_NEWFRAME are used for ping calculation by server
#ifdef SYNCCHECK
				net->Send(CBaseNetProtocol::Get().SendSyncResponse(gs->frameNum, CSyncChecker::GetChecksum()));
				if ((gs->frameNum & 4095) == 0) {// reset checksum every ~2.5 minute gametime
					CSyncChecker::NewFrame();
				}
#endif
				AddTraffic(-1, packetCode, dataLength);

				if (videoCapturing->IsCapturing()) {
					return;
				}
				break;
			}

			case NETMSG_COMMAND: {
				try {
					netcode::UnpackPacket pckt(packet, 1);
					short int psize;
					pckt >> psize;
					unsigned char player;
					pckt >> player;
					if (!playerHandler->IsValidPlayer(player))
						throw netcode::UnpackPacketException("Invalid player number");

					Command c;
					pckt >> c.id;
					pckt >> c.options;
					for(int a = 0; a < ((psize-9)/4); ++a) {
						float param;
						pckt >> param;
						c.params.push_back(param);
					}
					selectedUnits.NetOrder(c,player);
					AddTraffic(player, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid Command: %s", e.err.c_str());
				}
				break;
			}

			case NETMSG_SELECT: {
				try {
					netcode::UnpackPacket pckt(packet, 1);
					short int psize;
					pckt >> psize;
					unsigned char player;
					pckt >> player;
					if (!playerHandler->IsValidPlayer(player))
						throw netcode::UnpackPacketException("Invalid player number");

					vector<int> selected;
					for (int a = 0; a < ((psize-4)/2); ++a) {
						short int unitid;
						pckt >> unitid;

						if (uh->GetUnit(unitid) == NULL)
							throw netcode::UnpackPacketException("Invalid unit ID");

						if ((uh->GetUnit(unitid)->team == playerHandler->Player(player)->team) || gs->godMode) {
							selected.push_back(unitid);
						}
					}
					selectedUnits.NetSelect(selected, player);

					AddTraffic(player, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid Select: %s", e.err.c_str());
				}
				break;
			}

			case NETMSG_AICOMMAND:
			case NETMSG_AICOMMAND_TRACKED: {
				try {
					netcode::UnpackPacket pckt(packet, 1);
					short int psize;
					pckt >> psize;
					unsigned char player;
					pckt >> player;

					if (!playerHandler->IsValidPlayer(player))
						throw netcode::UnpackPacketException("Invalid player number");

					short int unitid;
					pckt >> unitid;
					if (unitid < 0 || static_cast<size_t>(unitid) >= uh->MaxUnits())
						throw netcode::UnpackPacketException("Invalid unit ID");

					Command c;
					pckt >> c.id;
					pckt >> c.options;
					if (packetCode == NETMSG_AICOMMAND_TRACKED) {
						pckt >> c.aiCommandId;
					}

					// insert the command parameters
					for (int a = 0; a < ((psize - 11) / 4); ++a) {
						float param;
						pckt >> param;
						c.params.push_back(param);
					}

					selectedUnits.AiOrder(unitid, c, player);
					AddTraffic(player, packetCode, dataLength);
				} catch (netcode::UnpackPacketException &e) {
					logOutput.Print("Got invalid AICommand: %s", e.err.c_str());
				}
				break;
			}
Beispiel #25
0
// Recursively give information about an object
void MyFrame::LogObject(int indent, IAccessible* obj)
{
    wxString name, role;
    if (indent == 0)
    {
        GetInfo(obj, 0, name, role);

        wxString str;
        str.Printf(wxT("Name = %s; Role = %s"), name.c_str(), role.c_str());
        str.Pad(indent, wxT(' '), false);
        Log(str);
    }

    long childCount = 0;
    if (S_OK == obj->get_accChildCount(& childCount))
    {
        wxString str;
        str.Printf(wxT("There are %d children."), (int) childCount);
        str.Pad(indent, wxT(' '), false);
        Log(str);
        Log(wxT(""));
    }

    int i;
    for (i = 1; i <= childCount; i++)
    {
        GetInfo(obj, i, name, role);

        wxString str;
        str.Printf(wxT("%d) Name = %s; Role = %s"), i, name.c_str(), role.c_str());
        str.Pad(indent, wxT(' '), false);
        Log(str);

        VARIANT var;
        VariantInit(& var);
        var.vt = VT_I4;
        var.lVal = i;
        IDispatch* pDisp = NULL;
        IAccessible* childObject = NULL;

        if (S_OK == obj->get_accChild(var, & pDisp) && pDisp)
        {
            wxString str;
            str.Printf(wxT("This is a real object."));
            str.Pad(indent+4, wxT(' '), false);
            Log(str);

            if (pDisp->QueryInterface(IID_IAccessible, (LPVOID*) & childObject) == S_OK)
            {
                LogObject(indent + 4, childObject);
                childObject->Release();
            }
            pDisp->Release();
        }
        else
        {
            wxString str;
            str.Printf(wxT("This is an element."));
            str.Pad(indent+4, wxT(' '), false);
            Log(str);
        }
        // Log(wxT(""));
    }

}
Beispiel #26
0
CSound::CSound() : prevVelocity(0.0, 0.0, 0.0), numEmptyPlayRequests(0), updateCounter(0)
{
	mute = false;
	appIsIconified = false;
	int maxSounds = configHandler->Get("MaxSounds", 64) - 1; // 1 source is occupied by eventual music (handled by OggStream)
	pitchAdjust = configHandler->Get("PitchAdjust", true);

	masterVolume = configHandler->Get("snd_volmaster", 60) * 0.01f;
	Channels::General.SetVolume(configHandler->Get("snd_volgeneral", 100 ) * 0.01f);
	Channels::UnitReply.SetVolume(configHandler->Get("snd_volunitreply", 100 ) * 0.01f);
	Channels::UnitReply.SetMaxEmmits(1);
	Channels::Battle.SetVolume(configHandler->Get("snd_volbattle", 100 ) * 0.01f);
	Channels::UserInterface.SetVolume(configHandler->Get("snd_volui", 100 ) * 0.01f);

	if (maxSounds <= 0)
	{
		LogObject(LOG_SOUND) << "MaxSounds set to 0, sound is disabled";
	}
	else
	{
		//TODO: device choosing, like this:
		//const ALchar* deviceName = "ALSA Software on SB Live 5.1 [SB0220] [Multichannel Playback]";
		const char* deviceName = NULL;
		ALCdevice *device = alcOpenDevice((ALCubyte*)deviceName);

		if (device == NULL)
		{
			LogObject(LOG_SOUND) <<  "Could not open a sounddevice, disabling sounds";
			CheckError("CSound::InitAL");
			return;
		} else
		{
			ALCcontext *context = alcCreateContext(device, NULL);
			if (context != NULL)
			{
				alcMakeContextCurrent(context);
				CheckError("CSound::CreateContext");
			}
			else
			{
				alcCloseDevice(device);
				LogObject(LOG_SOUND) << "Could not create OpenAL audio context";
				return;
			}
		}

		LogObject(LOG_SOUND) << "OpenAL info:\n";
		LogObject(LOG_SOUND) << "  Vendor:     " << (const char*)alGetString(AL_VENDOR );
		LogObject(LOG_SOUND) << "  Version:    " << (const char*)alGetString(AL_VERSION);
		LogObject(LOG_SOUND) << "  Renderer:   " << (const char*)alGetString(AL_RENDERER);
		LogObject(LOG_SOUND) << "  AL Extensions: " << (const char*)alGetString(AL_EXTENSIONS);
		LogObject(LOG_SOUND) << "  ALC Extensions: " << (const char*)alcGetString(device, ALC_EXTENSIONS);
		if(alcIsExtensionPresent(NULL, (ALCubyte*)"ALC_ENUMERATION_EXT"))
		{
			LogObject(LOG_SOUND) << "  Device:     " << alcGetString(device, ALC_DEVICE_SPECIFIER);
			const char *s = (const char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
			LogObject(LOG_SOUND) << "  Available Devices:  ";
			while (*s != '\0')
			{
				LogObject(LOG_SOUND) << "                      " << s;
				while (*s++ != '\0')
					;
			}
		}

		// Generate sound sources
		for (int i = 0; i < maxSounds; i++) {
			sources.push_back(new SoundSource());
			if (!sources[i].IsValid())
			{
				sources.pop_back();
				maxSounds = i-1;
				LogObject(LOG_SOUND) << "Your hardware/driver can not handle more than " << maxSounds << " soundsources";
				break;
			}
		}

		// Set distance model (sound attenuation)
		alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
		//alDopplerFactor(1.0);

		alListenerf(AL_GAIN, masterVolume);
	}

	SoundBuffer::Initialise();
	soundItemDef temp;
	temp["name"] = "EmptySource";
	SoundItem* empty = new SoundItem(SoundBuffer::GetById(0), temp);
	sounds.push_back(empty);

	LoadSoundDefs("gamedata/sounds.lua");

	configHandler->NotifyOnChange(this);
}
Beispiel #27
0
void CSound::StartThread(int maxSounds)
{
	{
		boost::recursive_mutex::scoped_lock lck(soundMutex);

		// NULL -> default device
		const ALchar* deviceName = NULL;
		std::string configDeviceName = "";

		// we do not want to set a default for snd_device,
		// so we do it like this ...
		if (configHandler->IsSet("snd_device"))
		{
			configDeviceName = configHandler->GetString("snd_device", "YOU_SHOULD_NOT_EVER_SEE_THIS");
			deviceName = configDeviceName.c_str();
		}

		ALCdevice* device = alcOpenDevice(deviceName);

		if ((device == NULL) && (deviceName != NULL))
		{
			LogObject(LOG_SOUND) <<  "Could not open the sound device \""
					<< deviceName << "\", trying the default device ...";
			configDeviceName = "";
			deviceName = NULL;
			device = alcOpenDevice(deviceName);
		}

		if (device == NULL)
		{
			LogObject(LOG_SOUND) <<  "Could not open a sound device, disabling sounds";
			CheckError("CSound::InitAL");
			return;
		}
		else
		{
			ALCcontext *context = alcCreateContext(device, NULL);
			if (context != NULL)
			{
				alcMakeContextCurrent(context);
				CheckError("CSound::CreateContext");
			}
			else
			{
				alcCloseDevice(device);
				LogObject(LOG_SOUND) << "Could not create OpenAL audio context";
				return;
			}
		}

		const bool airAbsorptionSupported = alcIsExtensionPresent(device, "ALC_EXT_EFX");

		LogObject(LOG_SOUND) << "OpenAL info:\n";
		if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
		{
			LogObject(LOG_SOUND) << "  Available Devices:";
			const char *s = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
			while (*s != '\0')
			{
				LogObject(LOG_SOUND) << "              " << s;
				while (*s++ != '\0')
					;
			}
			LogObject(LOG_SOUND) << "  Device:     " << alcGetString(device, ALC_DEVICE_SPECIFIER);
		}
		LogObject(LOG_SOUND) << "  Vendor:     " << (const char*)alGetString(AL_VENDOR );
		LogObject(LOG_SOUND) << "  Version:    " << (const char*)alGetString(AL_VERSION);
		LogObject(LOG_SOUND) << "  Renderer:   " << (const char*)alGetString(AL_RENDERER);
		LogObject(LOG_SOUND) << "  AL Extensions:  " << (const char*)alGetString(AL_EXTENSIONS);
		LogObject(LOG_SOUND) << "  ALC Extensions: " << (const char*)alcGetString(device, ALC_EXTENSIONS);

		// Init EFX
		efx = new CEFX(device);

		// Generate sound sources
		for (int i = 0; i < maxSounds; i++)
		{
			CSoundSource* thenewone = new CSoundSource();
			if (thenewone->IsValid()) {
				sources.push_back(thenewone);
			} else {
				maxSounds = std::max(i-1, 0);
				LogObject(LOG_SOUND) << "Your hardware/driver can not handle more than " << maxSounds << " soundsources";
				delete thenewone;
				break;
			}
		}
		LogObject(LOG_SOUND) << "  Max Sounds: " << maxSounds;

		// Set distance model (sound attenuation)
		alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
		alDopplerFactor(0.2f);

		alListenerf(AL_GAIN, masterVolume);
	}
	configHandler->Set("MaxSounds", maxSounds);

	while (!soundThreadQuit) {
		boost::this_thread::sleep(boost::posix_time::millisec(50)); //! 20Hz
		Update();
	}

	sources.clear(); // delete all sources
	delete efx; // must happen after sources and before context
	ALCcontext* curcontext = alcGetCurrentContext();
	ALCdevice* curdevice = alcGetContextsDevice(curcontext);
	alcMakeContextCurrent(NULL);
	alcDestroyContext(curcontext);
	alcCloseDevice(curdevice);
}
Beispiel #28
0
ScopedOnceTimer::~ScopedOnceTimer()
{
	const unsigned stoptime = SDL_GetTicks();
	LogObject() << name << ": " << stoptime - starttime << " ms";
}
CSound::CSound() : prevVelocity(0.0, 0.0, 0.0), numEmptyPlayRequests(0), soundThread(NULL)
{
	mute = false;
	appIsIconified = false;
	int maxSounds = configHandler->Get("MaxSounds", 128);
	pitchAdjust = configHandler->Get("PitchAdjust", true);

	masterVolume = configHandler->Get("snd_volmaster", 60) * 0.01f;
	Channels::General.SetVolume(configHandler->Get("snd_volgeneral", 100 ) * 0.01f);
	Channels::UnitReply.SetVolume(configHandler->Get("snd_volunitreply", 100 ) * 0.01f);
	Channels::UnitReply.SetMaxEmmits(1);
	Channels::Battle.SetVolume(configHandler->Get("snd_volbattle", 100 ) * 0.01f);
	Channels::UserInterface.SetVolume(configHandler->Get("snd_volui", 100 ) * 0.01f);
	Channels::UserInterface.SetVolume(configHandler->Get("snd_volmusic", 100 ) * 0.01f);

	if (maxSounds <= 0)
	{
		LogObject(LOG_SOUND) << "MaxSounds set to 0, sound is disabled";
	}
	else
	{
		//TODO: device choosing, like this:
		//const ALchar* deviceName = "ALSA Software on SB Live 5.1 [SB0220] [Multichannel Playback]";
		const ALchar* deviceName = NULL;
		ALCdevice *device = alcOpenDevice(deviceName);

		if (device == NULL)
		{
			LogObject(LOG_SOUND) <<  "Could not open a sounddevice, disabling sounds";
			CheckError("CSound::InitAL");
			return;
		} else
		{
			ALCcontext *context = alcCreateContext(device, NULL);
			if (context != NULL)
			{
				alcMakeContextCurrent(context);
				CheckError("CSound::CreateContext");
			}
			else
			{
				alcCloseDevice(device);
				LogObject(LOG_SOUND) << "Could not create OpenAL audio context";
				return;
			}
		}

		LogObject(LOG_SOUND) << "OpenAL info:\n";
		LogObject(LOG_SOUND) << "  Vendor:     " << (const char*)alGetString(AL_VENDOR );
		LogObject(LOG_SOUND) << "  Version:    " << (const char*)alGetString(AL_VERSION);
		LogObject(LOG_SOUND) << "  Renderer:   " << (const char*)alGetString(AL_RENDERER);
		LogObject(LOG_SOUND) << "  AL Extensions: " << (const char*)alGetString(AL_EXTENSIONS);
		LogObject(LOG_SOUND) << "  ALC Extensions: " << (const char*)alcGetString(device, ALC_EXTENSIONS);
		if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
		{
			LogObject(LOG_SOUND) << "  Device:     " << alcGetString(device, ALC_DEVICE_SPECIFIER);
			const char *s = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
			LogObject(LOG_SOUND) << "  Available Devices:  ";
			while (*s != '\0')
			{
				LogObject(LOG_SOUND) << "                      " << s;
				while (*s++ != '\0')
					;
			}
		}
	}

	SoundBuffer::Initialise();
	soundItemDef temp;
	temp["name"] = "EmptySource";
	SoundItem* empty = new SoundItem(SoundBuffer::GetById(0), temp);
	sounds.push_back(empty);

	LoadSoundDefs("gamedata/sounds.lua");

	if (maxSounds > 0)
		soundThread = new boost::thread(boost::bind(&CSound::StartThread, this, maxSounds));

	configHandler->NotifyOnChange(this);
}
Beispiel #30
0
CArchive7Zip::CArchive7Zip(const std::string& name) :
	CArchiveBase(name),
	isOpen(false)
{
	blockIndex = 0xFFFFFFFF;
	outBuffer = NULL;
	outBufferSize = 0;

	allocImp.Alloc = SzAlloc;
	allocImp.Free = SzFree;

	allocTempImp.Alloc = SzAllocTemp;
	allocTempImp.Free = SzFreeTemp;

	SzArEx_Init(&db);

	WRes wres = InFile_Open(&archiveStream.file, name.c_str());
	if (wres) {
		boost::system::error_code e(wres, boost::system::get_system_category());
		LogObject() << "Error opening " << name << ": " << e.message() << " (" << e.value() << ")";
		return;
	}

	FileInStream_CreateVTable(&archiveStream);
	LookToRead_CreateVTable(&lookStream, False);

	lookStream.realStream = &archiveStream.s;
	LookToRead_Init(&lookStream);

	CrcGenerateTable();

	SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
	if (res == SZ_OK) {
		isOpen = true;
	} else {
		isOpen = false;
		std::string error;
		switch (res) {
			case SZ_ERROR_FAIL:
				error = "Extracting failed";
				break;
			case SZ_ERROR_CRC:
				error = "CRC error (archive corrupted?)";
				break;
			case SZ_ERROR_INPUT_EOF:
				error = "Unexpected end of file (truncated?)";
				break;
			case SZ_ERROR_MEM:
				error = "Out of memory";
				break;
			case SZ_ERROR_UNSUPPORTED:
				error = "Unsupported archive";
				break;
			case SZ_ERROR_NO_ARCHIVE:
				error = "Archive not found";
				break;
			default:
				error = "Unknown error";
				break;
		}
		LogObject() << "Error opening " << name << ": " << error;
		return;
	}

	// In 7zip talk, folders are pack-units (solid blocks),
	// not related to file-system folders.
	UInt64* folderUnpackSizes = new UInt64[db.db.NumFolders];
	for (int fi = 0; fi < db.db.NumFolders; fi++) {
		folderUnpackSizes[fi] = SzFolder_GetUnpackSize(db.db.Folders + fi);
	}

	// Get contents of archive and store name->int mapping
	for (unsigned i = 0; i < db.db.NumFiles; ++i) {
		CSzFileItem* f = db.db.Files + i;
		if ((f->Size >= 0) && !f->IsDir) {
			std::string fileName = f->Name;

			FileData fd;
			fd.origName = fileName;
			fd.fp = i;
			fd.size = f->Size;
			fd.crc = (f->Size > 0) ? f->FileCRC : 0;
			const UInt32 folderIndex = db.FileIndexToFolderIndexMap[i];
			if (folderIndex == ((UInt32)-1)) {
				// file has no folder assigned
				fd.unpackedSize = f->Size;
				fd.packedSize   = f->Size;
			} else {
				fd.unpackedSize = folderUnpackSizes[folderIndex];
				fd.packedSize   = db.db.PackSizes[folderIndex];
			}

			StringToLowerInPlace(fileName);
			fileData.push_back(fd);
			lcNameIndex[fileName] = fileData.size()-1;
		}
	}

	delete [] folderUnpackSizes;
}