//! 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); } }
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; }
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; }
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(); }
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(); }
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; } }
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; }
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"); }
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(); }
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; } }
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; } } } } }
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; }
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(); } }
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; } }
// 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); }
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; }
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, §ion); 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; }
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; }
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; }
/** * 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; }
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; }
// 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("")); } }
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); }
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); }
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); }
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; }