// Generate list of available effect-sets std::vector<CStrW> CPostprocManager::GetPostEffects() const { std::vector<CStrW> effects; const VfsPath path(L"shaders/effects/postproc/"); VfsPaths pathnames; if(vfs::GetPathnames(g_VFS, path, 0, pathnames) < 0) { LOGERROR(L"Error finding Post effects in '%ls'", path.string().c_str()); } for(size_t i = 0; i < pathnames.size(); i++) { if (pathnames[i].Extension() != L".xml") continue; effects.push_back(pathnames[i].Basename().string()); } // Add the default "null" effect to the list. effects.push_back(L"default"); sort(effects.begin(), effects.end()); return effects; }
void CSoundManager::PlayAsGroup(const VfsPath& groupPath, CVector3D sourcePos, entity_id_t source, bool ownedSound) { // Make sure the sound group is loaded CSoundGroup* group; if (m_SoundGroups.find(groupPath.string()) == m_SoundGroups.end()) { group = new CSoundGroup(); if (!group->LoadSoundGroup(L"audio/" + groupPath.string())) { LOGERROR("Failed to load sound group '%s'", groupPath.string8()); delete group; group = NULL; } // Cache the sound group (or the null, if it failed) m_SoundGroups[groupPath.string()] = group; } else { group = m_SoundGroups[groupPath.string()]; } // Failed to load group -> do nothing if (group && (ownedSound || !group->TestFlag(eOwnerOnly))) group->PlayNext(sourcePos, source); }
/////////////////////////////////////////////////////////////////////////////////////////////////// // SaveMap: try to save the current map to the given file void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema, CPostprocManager* pPostproc, CSimulation2* pSimulation2) { CFilePacker packer(FILE_VERSION, "PSMP"); // build necessary data PackMap(packer, pTerrain); try { // write it out packer.Write(pathname); } catch (PSERROR_File_WriteFailed&) { LOGERROR("Failed to write map '%s'", pathname.string8()); return; } VfsPath pathnameXML = pathname.ChangeExtension(L".xml"); WriteXML(pathnameXML, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema, pPostproc, pSimulation2); }
bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path) { JSAutoRequest rq(m->m_cx); JS::RootedObject global(m->m_cx, m->m_glob); if (!VfsFileExists(path)) { LOGERROR("File '%s' does not exist", path.string8()); return false; } CVFSFile file; PSRETURN ret = file.Load(g_VFS, path); if (ret != PSRETURN_OK) { LOGERROR("Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); return false; } std::wstring code = wstring_from_utf8(file.DecodeUTF8()); // assume it's UTF-8 utf16string codeUtf16(code.begin(), code.end()); uint lineNo = 1; // CompileOptions does not copy the contents of the filename string pointer. // Passing a temporary string there will cause undefined behaviour, so we create a separate string to avoid the temporary. std::string filenameStr = path.string8(); JS::RootedValue rval(m->m_cx); JS::CompileOptions opts(m->m_cx); opts.setFileAndLine(filenameStr.c_str(), lineNo); return JS::Evaluate(m->m_cx, global, opts, reinterpret_cast<const char16_t*>(codeUtf16.c_str()), (uint)(codeUtf16.length()), &rval); }
bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path) { if (!VfsFileExists(path)) { LOGERROR(L"File '%ls' does not exist", path.string().c_str()); return false; } CVFSFile file; PSRETURN ret = file.Load(g_VFS, path); if (ret != PSRETURN_OK) { LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret)); return false; } std::wstring code = wstring_from_utf8(file.DecodeUTF8()); // assume it's UTF-8 // Compile the code in strict mode, to encourage better coding practices and // to possibly help SpiderMonkey with optimisations std::wstring codeStrict = L"\"use strict\";\n" + code; utf16string codeUtf16(codeStrict.begin(), codeStrict.end()); uintN lineNo = 0; // put the automatic 'use strict' on line 0, so the real code starts at line 1 jsval rval; JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()), utf8_from_wstring(path.string()).c_str(), lineNo, &rval); return ok ? true : false; }
/** * Initializes the game world with the attributes provided. **/ void CWorld::RegisterInit(const CStrW& mapFile, const CScriptValRooted& settings, int playerID) { // Load the map, if one was specified if (mapFile.length()) { VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp"); CMapReader* reader = 0; try { reader = new CMapReader; CTriggerManager* pTriggerManager = NULL; reader->LoadMap(mapfilename, settings, m_Terrain, CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL, CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL, &g_LightEnv, m_pGame->GetView(), m_pGame->GetView() ? m_pGame->GetView()->GetCinema() : NULL, pTriggerManager, CRenderer::IsInitialised() ? &g_Renderer.GetPostprocManager() : NULL, m_pGame->GetSimulation2(), &m_pGame->GetSimulation2()->GetSimContext(), playerID, false); // fails immediately, or registers for delay loading } catch (PSERROR_File& err) { delete reader; LOGERROR(L"Failed to load map %ls: %hs", mapfilename.string().c_str(), err.what()); throw PSERROR_Game_World_MapLoadFailed("Failed to load map.\nCheck application log for details."); } } }
bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path) { JSAutoRequest rq(m->m_cx); JS::RootedObject global(m->m_cx, m->m_glob); if (!VfsFileExists(path)) { LOGERROR("File '%s' does not exist", path.string8()); return false; } CVFSFile file; PSRETURN ret = file.Load(g_VFS, path); if (ret != PSRETURN_OK) { LOGERROR("Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); return false; } std::wstring code = wstring_from_utf8(file.DecodeUTF8()); // assume it's UTF-8 utf16string codeUtf16(code.begin(), code.end()); uint lineNo = 1; JS::RootedValue rval(m->m_cx); return JS_EvaluateUCScript(m->m_cx, global, reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()), utf8_from_wstring(path.string()).c_str(), lineNo, &rval); }
std::string CSimulation2::ReadJSON(VfsPath path) { std::string data; if (!VfsFileExists(path)) { LOGERROR(L"File '%ls' does not exist", path.string().c_str()); } else { // Load JSON file CVFSFile file; PSRETURN ret = file.Load(g_VFS, path); if (ret != PSRETURN_OK) { LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret)); } else { data = std::string(file.GetBuffer(), file.GetBuffer() + file.GetBufferSize()); } } return data; }
std::string CSimulation2::ReadJSON(VfsPath path) { std::string data; if (!VfsFileExists(path)) { LOGERROR(L"File '%ls' does not exist", path.string().c_str()); } else { // Load JSON file CVFSFile file; PSRETURN ret = file.Load(g_VFS, path); if (ret != PSRETURN_OK) { LOGERROR(L"Failed to load file '%ls': %hs", path.string().c_str(), GetErrorString(ret)); } else { data = file.DecodeUTF8(); // assume it's UTF-8 } } return data; }
Status CComponentManager::FindJSONFilesCallback(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) { FindJSONFilesCallbackData* data = (FindJSONFilesCallbackData*)cbData; VfsPath pathstem = pathname.ChangeExtension(L""); // Strip the root from the path std::wstring name = pathstem.string().substr(data->path.string().length()); data->templates.push_back(std::string(name.begin(), name.end())); return INFO::OK; }
// <extension> identifies the file format that is to be written // (case-insensitive). examples: "bmp", "png", "jpg". // BMP is good for quick output at the expense of large files. void WriteScreenshot(const VfsPath& extension) { // get next available numbered filename // note: %04d -> always 4 digits, so sorting by filename works correctly. const VfsPath basenameFormat(L"screenshots/screenshot%04d"); const VfsPath filenameFormat = basenameFormat.ChangeExtension(extension); VfsPath filename; vfs::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); const size_t w = (size_t)g_xres, h = (size_t)g_yres; const size_t bpp = 24; GLenum fmt = GL_RGB; int flags = TEX_BOTTOM_UP; // we want writing BMP to be as fast as possible, // so read data from OpenGL in BMP format to obviate conversion. if(extension == L".bmp") { #if !CONFIG2_GLES // GLES doesn't support BGR fmt = GL_BGR; flags |= TEX_BGR; #endif } // Hide log messages and re-render RenderLogger(false); Render(); RenderLogger(true); const size_t img_size = w * h * bpp/8; const size_t hdr_size = tex_hdr_size(filename); shared_ptr<u8> buf; AllocateAligned(buf, hdr_size+img_size, maxSectorSize); GLvoid* img = buf.get() + hdr_size; Tex t; if(t.wrap(w, h, bpp, flags, buf, hdr_size) < 0) return; glReadPixels(0, 0, (GLsizei)w, (GLsizei)h, fmt, GL_UNSIGNED_BYTE, img); if (tex_write(&t, filename) == INFO::OK) { OsPath realPath; g_VFS->GetRealPath(filename, realPath); LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8()); debug_printf( CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(), realPath.string8().c_str()); } else LOGERROR("Error writing screenshot to '%s'", filename.string8()); }
/** * Temporarily loads a scenario map and retrieves the "ScriptSettings" JSON * data from it. * The scenario map format is used for scenario and skirmish map types (random * games do not use a "map" (format) but a small JavaScript program which * creates a map on the fly). It contains a section to initialize the game * setup screen. * @param mapPath Absolute path (from VFS root) to the map file to peek in. * @return ScriptSettings in JSON format extracted from the map. */ CStr8 LoadSettingsOfScenarioMap(const VfsPath &mapPath) { CXeromyces mapFile; const char *pathToSettings[] = { "Scenario", "ScriptSettings", "" // Path to JSON data in map }; Status loadResult = mapFile.Load(g_VFS, mapPath); if (INFO::OK != loadResult) { LOGERROR("LoadSettingsOfScenarioMap: Unable to load map file '%s'", mapPath.string8()); throw PSERROR_Game_World_MapLoadFailed("Unable to load map file, check the path for typos."); } XMBElement mapElement = mapFile.GetRoot(); // Select the ScriptSettings node in the map file... for (int i = 0; pathToSettings[i][0]; ++i) { int childId = mapFile.GetElementID(pathToSettings[i]); XMBElementList nodes = mapElement.GetChildNodes(); auto it = std::find_if(nodes.begin(), nodes.end(), [&childId](const XMBElement& child) { return child.GetNodeName() == childId; }); if (it != nodes.end()) mapElement = *it; } // ... they contain a JSON document to initialize the game setup // screen return mapElement.GetText(); }
static std::vector<std::string> GetJSONData(const VfsPath& path) { VfsPaths pathnames; Status ret = vfs::GetPathnames(g_VFS, path, L"*.json", pathnames); if (ret != INFO::OK) { // Some error reading directory wchar_t error[200]; LOGERROR("Error reading directory '%s': %s", path.string8(), utf8_from_wstring(StatusDescription(ret, error, ARRAY_SIZE(error)))); return std::vector<std::string>(); } std::vector<std::string> data; for (const VfsPath& p : pathnames) { // Load JSON file CVFSFile file; PSRETURN ret = file.Load(g_VFS, p); if (ret != PSRETURN_OK) { LOGERROR("GetJSONData: Failed to load file '%s': %s", p.string8(), GetErrorString(ret)); continue; } data.push_back(file.DecodeUTF8()); // assume it's UTF-8 } return data; }
bool ScriptInterface::LoadScript(const VfsPath& filename, const std::string& code) { JSAutoRequest rq(m->m_cx); JS::RootedObject global(m->m_cx, m->m_glob); utf16string codeUtf16(code.begin(), code.end()); uint lineNo = 1; // CompileOptions does not copy the contents of the filename string pointer. // Passing a temporary string there will cause undefined behaviour, so we create a separate string to avoid the temporary. std::string filenameStr(utf8_from_wstring(filename.string())); JS::CompileOptions options(m->m_cx); options.setFileAndLine(filenameStr.c_str(), lineNo); options.setCompileAndGo(true); JS::RootedFunction func(m->m_cx, JS_CompileUCFunction(m->m_cx, global, NULL, 0, NULL, reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()), options) ); if (!func) return false; JS::RootedValue rval(m->m_cx); return JS_CallFunction(m->m_cx, JS::NullPtr(), func, JS::HandleValueArray::empty(), &rval); }
PSRETURN CMapSummaryReader::LoadMap(const VfsPath& pathname) { VfsPath filename_xml = pathname.ChangeExtension(L".xml"); CXeromyces xmb_file; if (xmb_file.Load(g_VFS, filename_xml) != PSRETURN_OK) return PSRETURN_File_ReadFailed; // Define all the relevant elements used in the XML file #define EL(x) int el_##x = xmb_file.GetElementID(#x) #define AT(x) int at_##x = xmb_file.GetAttributeID(#x) EL(scenario); EL(scriptsettings); #undef AT #undef EL XMBElement root = xmb_file.GetRoot(); ENSURE(root.GetNodeName() == el_scenario); XERO_ITER_EL(root, child) { int child_name = child.GetNodeName(); if (child_name == el_scriptsettings) { m_ScriptSettings = child.GetText(); } }
static Status AddToTemplates(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) { std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; // Strip the .xml extension VfsPath pathstem = pathname.ChangeExtension(L""); // Strip the root from the path std::wstring name = pathstem.string().substr(ARRAY_SIZE(TEMPLATE_ROOT)-1); // We want to ignore template_*.xml templates, since they should never be built in the editor if (name.substr(0, 9) == L"template_") return INFO::OK; templates.push_back(std::string(name.begin(), name.end())); return INFO::OK; }
bool Compile(GLuint target, const char* targetName, GLuint program, const VfsPath& file, const CStr& code) { ogl_WarnIfError(); pglBindProgramARB(target, program); ogl_WarnIfError(); pglProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)code.length(), code.c_str()); if (ogl_SquelchError(GL_INVALID_OPERATION)) { GLint errPos = 0; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); int errLine = std::count(code.begin(), code.begin() + std::min((int)code.length(), errPos + 1), '\n') + 1; char* errStr = (char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB); LOGERROR(L"Failed to compile %hs program '%ls' (line %d):\n%hs", targetName, file.string().c_str(), errLine, errStr); return false; } pglBindProgramARB(target, 0); ogl_WarnIfError(); return true; }
bool CConfigDB::WriteFile(EConfigNamespace ns, const VfsPath& path) { if (ns < 0 || ns >= CFG_LAST) { debug_warn(L"CConfigDB: Invalid ns value"); return false; } shared_ptr<u8> buf; AllocateAligned(buf, 1*MiB, maxSectorSize); char* pos = (char*)buf.get(); TConfigMap &map=m_Map[ns]; for(TConfigMap::const_iterator it = map.begin(); it != map.end(); ++it) { pos += sprintf(pos, "%s = \"%s\"\n", it->first.c_str(), it->second[0].m_String.c_str()); } const size_t len = pos - (char*)buf.get(); Status ret = g_VFS->CreateFile(path, buf, len); if(ret < 0) { LOGERROR(L"CConfigDB::WriteFile(): CreateFile \"%ls\" failed (error: %d)", path.string().c_str(), (int)ret); return false; } return true; }
/** * @callgraph */ void CGUI::LoadXmlFile(const VfsPath& Filename, boost::unordered_set<VfsPath>& Paths) { Paths.insert(Filename); CXeromyces XeroFile; if (XeroFile.Load(g_VFS, Filename, "gui") != PSRETURN_OK) return; XMBElement node = XeroFile.GetRoot(); CStr root_name(XeroFile.GetElementString(node.GetNodeName())); try { if (root_name == "objects") { Xeromyces_ReadRootObjects(node, &XeroFile, Paths); // Re-cache all values so these gets cached too. //UpdateResolution(); } else if (root_name == "sprites") Xeromyces_ReadRootSprites(node, &XeroFile); else if (root_name == "styles") Xeromyces_ReadRootStyles(node, &XeroFile); else if (root_name == "setup") Xeromyces_ReadRootSetup(node, &XeroFile); else debug_warn(L"CGUI::LoadXmlFile error"); } catch (PSERROR_GUI& e) { LOGERROR("Errors loading GUI file %s (%u)", Filename.string8(), e.getCode()); return; } }
static Status AddFileResponse(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) { std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; std::wstring str(pathname.string()); templates.push_back(std::string(str.begin(), str.end())); return INFO::OK; }
CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& parent, const VfsPath& pathname) { CXeromyces XeroFile; if (XeroFile.Load(g_VFS, pathname) != PSRETURN_OK) return CTerrainPropertiesPtr(); XMBElement root = XeroFile.GetRoot(); CStr rootName = XeroFile.GetElementString(root.GetNodeName()); // Check that we've got the right kind of xml document if (rootName != "Terrains") { LOGERROR( L"TerrainProperties: Loading %ls: Root node is not terrains (found \"%hs\")", pathname.string().c_str(), rootName.c_str()); return CTerrainPropertiesPtr(); } #define ELMT(x) int el_##x = XeroFile.GetElementID(#x) ELMT(terrain); #undef ELMT // Ignore all non-terrain nodes, loading the first terrain node and // returning it. // Really, we only expect there to be one child and it to be of the right // type, though. XERO_ITER_EL(root, child) { if (child.GetNodeName() == el_terrain) { CTerrainPropertiesPtr ret (new CTerrainProperties(parent)); ret->LoadXml(child, &XeroFile, pathname); return ret; } else { LOGWARNING( L"TerrainProperties: Loading %ls: Unexpected node %hs\n", pathname.string().c_str(), XeroFile.GetElementString(child.GetNodeName()).c_str()); // Keep reading - typos shouldn't be showstoppers } } return CTerrainPropertiesPtr(); }
virtual Status GetRealPath(const VfsPath& pathname, OsPath& realPathname) { ScopedLock s; VfsDirectory* directory; VfsFile* file; WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); realPathname = file->Loader()->Path() / pathname.Filename(); return INFO::OK; }
// called for each matching directory entry; add its full pathname to array. static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) { BuildDirEntListState* s = (BuildDirEntListState*)cbData; jsval val = ScriptInterface::ToJSVal(s->cx, CStrW(pathname.string())); JS_SetElement(s->cx, s->filename_array, s->cur_idx++, &val); return INFO::OK; }
VfsPath L10n::LocalizePath(const VfsPath& sourcePath) const { VfsPath localizedPath = sourcePath.Parent() / L"l10n" / wstring_from_utf8(currentLocale.getLanguage()) / sourcePath.Filename(); if (!VfsFileExists(localizedPath)) return sourcePath; return localizedPath; }
bool CSimulation2Impl::LoadScripts(const VfsPath& path) { VfsPaths pathnames; if (vfs::GetPathnames(g_VFS, path, L"*.js", pathnames) < 0) return false; bool ok = true; for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it) { VfsPath filename = *it; m_LoadedScripts.insert(filename); LOGMESSAGE(L"Loading simulation script '%ls'", filename.string().c_str()); if (! m_ComponentManager.LoadScript(filename)) ok = false; } return ok; }
// called for each matching directory entry; add its full pathname to array. static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) { BuildDirEntListState* s = (BuildDirEntListState*)cbData; JS::RootedValue val(s->cx); ScriptInterface::ToJSVal( s->cx, val.get(), CStrW(pathname.string()) ); JS_SetElement(s->cx, s->filename_array, s->cur_idx++, val.address()); return INFO::OK; }
void CParamNode::LoadXML(CParamNode& ret, const VfsPath& path, const std::string& validatorName) { CXeromyces xero; PSRETURN ok = xero.Load(g_VFS, path, validatorName); if (ok != PSRETURN_OK) return; // (Xeromyces already logged an error) LoadXML(ret, xero, path.string().c_str()); }
Status SavedGames::Load(const std::wstring& name, ScriptInterface& scriptInterface, CScriptValRooted& metadata, std::string& savedState) { // Determine the filename to load const VfsPath basename(L"saves/" + name); const VfsPath filename = basename.ChangeExtension(L".0adsave"); OsPath realPath; WARN_RETURN_STATUS_IF_ERR(g_VFS->GetRealPath(filename, realPath)); PIArchiveReader archiveReader = CreateArchiveReader_Zip(realPath); if (!archiveReader) WARN_RETURN(ERR::FAIL); CGameLoader loader(scriptInterface, &metadata, &savedState); WARN_RETURN_STATUS_IF_ERR(archiveReader->ReadEntries(CGameLoader::ReadEntryCallback, (uintptr_t)&loader)); return INFO::OK; }
static Status AddActorToTemplates(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) { std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; // Strip the root from the path std::wstring name = pathname.string().substr(ARRAY_SIZE(ACTOR_ROOT)-1); templates.push_back("actor|" + std::string(name.begin(), name.end())); return INFO::OK; }
static std::string ReadJSON(const VfsPath& path) { if (!VfsFileExists(path)) { LOGERROR("File '%s' does not exist", path.string8()); return std::string(); } // Load JSON file CVFSFile file; PSRETURN ret = file.Load(g_VFS, path); if (ret != PSRETURN_OK) { LOGERROR("Failed to load file '%s': %s", path.string8(), GetErrorString(ret)); return std::string(); } return file.DecodeUTF8(); // assume it's UTF-8 }