bool Ps2SaveFileManager::removeSavefile(const Common::String &filename) { Common::FSNode savePath(ConfMan.get("savepath")); // TODO: is this fast? Common::FSNode file; if (!savePath.exists() || !savePath.isDirectory()) return false; if (_getDev(savePath) == MC_DEV) { // if (strncmp(savePath.getPath().c_str(), "mc0:", 4) == 0) { char path[32], temp[32]; strcpy(temp, filename.c_str()); // mcSplit(temp, game, ext); char *game = strdup(strtok(temp, ".")); char *ext = strdup(strtok(NULL, "*")); sprintf(path, "mc0:ScummVM/%s", game); // per game path mcCheck(path); sprintf(path, "mc0:ScummVM/%s/%s.sav", game, ext); file = Common::FSNode(path); free(game); free(ext); } else { file = savePath.getChild(filename); } if (!file.exists() || file.isDirectory()) return false; fio.remove(file.getPath().c_str()); return true; }
bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String &themeName) { Common::File stream; bool foundHeader = false; if (node.getName().matchString("*.zip", true) && !node.isDirectory()) { Common::Archive *zipArchive = Common::makeZipArchive(node); if (zipArchive && zipArchive->hasFile("THEMERC")) { // Open THEMERC from the ZIP file. stream.open("THEMERC", *zipArchive); } // Delete the ZIP archive again. Note: This only works because // stream.open() only uses ZipArchive::createReadStreamForMember, // and that in turn happens to read all the data for a given // archive member into a memory block. So there will be no dangling // reference to zipArchive anywhere. This could change if we // ever modify ZipArchive::createReadStreamForMember. delete zipArchive; } else if (node.isDirectory()) { Common::FSNode headerfile = node.getChild("THEMERC"); if (!headerfile.exists() || !headerfile.isReadable() || headerfile.isDirectory()) return false; stream.open(headerfile); } if (stream.isOpen()) { Common::String stxHeader = stream.readLine(); foundHeader = themeConfigParseHeader(stxHeader, themeName); } return foundHeader; }
void DefaultSaveFileManager::checkPath(const Common::FSNode &dir) { clearError(); if (!dir.exists()) { setError(Common::kPathDoesNotExist, "The savepath '"+dir.getPath()+"' does not exist"); } else if (!dir.isDirectory()) { setError(Common::kPathNotDirectory, "The savepath '"+dir.getPath()+"' is not a directory"); } }
bool BaseFileManager::initPaths() { // Removed: Config-based file-path choice. // package files paths const Common::FSNode gameData(ConfMan.get("path")); addPath(PATH_PACKAGE, gameData); Common::FSNode dataSubFolder = gameData.getChild("data"); if (dataSubFolder.exists()) { addPath(PATH_PACKAGE, dataSubFolder); } Common::FSNode languageSubFolder = gameData.getChild("language"); if (languageSubFolder.exists()) { addPath(PATH_PACKAGE, languageSubFolder); } return STATUS_OK; }
void ThemeEngine::listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth) { if (!node.exists() || !node.isReadable() || !node.isDirectory()) return; ThemeDescriptor td; // Check whether we point to a valid theme directory. if (themeConfigUsable(node, td.name)) { td.filename = node.getPath(); td.id = node.getName(); list.push_back(td); // A theme directory should never contain any other themes // thus we just return to the caller here. return; } Common::FSList fileList; // Check all files. We need this to find all themes inside ZIP archives. if (!node.getChildren(fileList, Common::FSNode::kListFilesOnly)) return; for (Common::FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) { // We will only process zip files for now if (!i->getPath().matchString("*.zip", true)) continue; td.name.clear(); if (themeConfigUsable(*i, td.name)) { td.filename = i->getPath(); td.id = i->getName(); // If the name of the node object also contains // the ".zip" suffix, we will strip it. if (td.id.matchString("*.zip", true)) { for (int j = 0; j < 4; ++j) td.id.deleteLastChar(); } list.push_back(td); } } fileList.clear(); // Check if we exceeded the given recursion depth if (depth - 1 == -1) return; // As next step we will search all subdirectories if (!node.getChildren(fileList, Common::FSNode::kListDirectoriesOnly)) return; for (Common::FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) listUsableThemes(*i, list, depth == -1 ? - 1 : depth - 1); }
bool FileSystemUtil::fileExists(const Common::String &filename) { Common::File f; if (f.exists(filename)) return true; // Check if the file exists in the save folder Common::FSNode folder(PersistenceService::getSavegameDirectory()); Common::FSNode fileNode = folder.getChild(getPathFilename(filename)); return fileNode.exists(); }
Common::String PersistenceService::getSavegameDirectory() { Common::FSNode node(FileSystemUtil::getUserdataDirectory()); Common::FSNode childNode = node.getChild(SAVEGAME_DIRECTORY); // Try and return the path using the savegame subfolder. But if doesn't exist, fall back on the data directory if (childNode.exists()) return childNode.getPath(); return node.getPath(); }
FSTestSuite::FSTestSuite() { // FS tests depend on Game Data files. // If those are not found. Disable this testsuite. const Common::String &path = ConfMan.get("path"); Common::FSNode gameRoot(path); Common::FSNode gameIdentificationFile = gameRoot.getChild("TESTBED"); if (!gameIdentificationFile.exists()) { logPrintf("WARNING! : Game Data not found. Skipping FS tests\n"); ConfParams.setGameDataFound(false); Testsuite::enable(false); } addTest("ReadingFile", &FStests::testReadFile, false); addTest("WritingFile", &FStests::testWriteFile, false); }
bool diskFileExists(const Common::String &filename) { // Try directly from SearchMan first Common::ArchiveMemberList files; SearchMan.listMatchingMembers(files, filename); for (Common::ArchiveMemberList::iterator it = files.begin(); it != files.end(); ++it) { if ((*it)->getName() == filename) { return true; } } // File wasn't found in SearchMan, try to parse the path as a relative path. Common::FSNode searchNode = getNodeForRelativePath(filename); if (searchNode.exists() && !searchNode.isDirectory() && searchNode.isReadable()) { return true; } return false; }
bool BaseFileManager::addPath(TPathType type, const Common::FSNode &path) { if (!path.exists()) { return STATUS_FAILED; } switch (type) { case PATH_SINGLE: // _singlePaths.push_back(path); error("TODO: Allow adding single-paths"); break; case PATH_PACKAGE: _packagePaths.push_back(path); break; } return STATUS_OK; }
Common::InSaveFile *DefaultSaveFileManager::openForLoading(const Common::String &filename) { // Ensure that the savepath is valid. If not, generate an appropriate error. Common::String savePathName = getSavePath(); checkPath(Common::FSNode(savePathName)); if (getError().getCode() != Common::kNoError) return 0; // recreate FSNode since checkPath may have changed/created the directory Common::FSNode savePath(savePathName); Common::FSNode file = savePath.getChild(filename); if (!file.exists()) return 0; // Open the file for reading Common::SeekableReadStream *sf = file.createReadStream(); return Common::wrapCompressedReadStream(sf); }
Common::InSaveFile *Ps2SaveFileManager::openForLoading(const Common::String &filename) { Common::FSNode savePath(ConfMan.get("savepath")); // TODO: is this fast? Common::SeekableReadStream *sf; if (!savePath.exists() || !savePath.isDirectory()) return NULL; // _screen->wantAnim(true); if (_getDev(savePath) == MC_DEV) { // if (strncmp(savePath.getPath().c_str(), "mc0:", 4) == 0) { char path[32]; // FIXME : hack for indy4 iq-points if (filename == "iq-points") { mcCheck("mc0:ScummVM/indy4"); sprintf(path, "mc0:ScummVM/indy4/iq-points"); } // FIXME : hack for bs1 saved games else if (filename == "SAVEGAME.INF") { mcCheck("mc0:ScummVM/sword1"); sprintf(path, "mc0:ScummVM/sword1/SAVEGAME.INF"); } else { char temp[32]; printf("MC : filename = %s\n", filename.c_str()); strcpy(temp, filename.c_str()); // mcSplit(temp, game, ext); char *game = strdup(strtok(temp, ".")); char *ext = strdup(strtok(NULL, "*")); sprintf(path, "mc0:ScummVM/%s", game); // per game path // mcCheck(path); // needed on load ? sprintf(path, "mc0:ScummVM/%s/%s.sav", game, ext); free(game); free(ext); } Common::FSNode file(path); if (!file.exists()) return NULL; sf = file.createReadStream(); } else { Common::FSNode file = savePath.getChild(filename); if (!file.exists()) return NULL; sf = file.createReadStream(); } // _screen->wantAnim(false); return Common::wrapCompressedReadStream(sf); }
Common::SeekableReadStream *openDiskFile(const Common::String &filename) { uint32 prefixSize = 0; Common::SeekableReadStream *file = NULL; Common::String fixedFilename = filename; // Absolute path: TODO: Add specific fallbacks here. if (filename.contains(':')) { if (filename.hasPrefix("c:\\windows\\fonts\\")) { // East Side Story refers to "c:\windows\fonts\framd.ttf" fixedFilename = filename.c_str() + 17; } else { error("openDiskFile::Absolute path or invalid filename used in %s", filename.c_str()); } } // Try directly from SearchMan first Common::ArchiveMemberList files; SearchMan.listMatchingMembers(files, fixedFilename); for (Common::ArchiveMemberList::iterator it = files.begin(); it != files.end(); ++it) { if ((*it)->getName() == filename) { file = (*it)->createReadStream(); break; } } // File wasn't found in SearchMan, try to parse the path as a relative path. if (!file) { Common::FSNode searchNode = getNodeForRelativePath(filename); if (searchNode.exists() && !searchNode.isDirectory() && searchNode.isReadable()) { file = searchNode.createReadStream(); } } if (file) { uint32 magic1, magic2; magic1 = file->readUint32LE(); magic2 = file->readUint32LE(); bool compressed = false; if (magic1 == DCGF_MAGIC && magic2 == COMPRESSED_FILE_MAGIC) { compressed = true; } if (compressed) { uint32 dataOffset, compSize, uncompSize; dataOffset = file->readUint32LE(); compSize = file->readUint32LE(); uncompSize = file->readUint32LE(); byte *compBuffer = new byte[compSize]; if (!compBuffer) { error("Error allocating memory for compressed file '%s'", filename.c_str()); delete file; return NULL; } byte *data = new byte[uncompSize]; if (!data) { error("Error allocating buffer for file '%s'", filename.c_str()); delete[] compBuffer; delete file; return NULL; } file->seek(dataOffset + prefixSize, SEEK_SET); file->read(compBuffer, compSize); if (Common::uncompress(data, (unsigned long *)&uncompSize, compBuffer, compSize) != true) { error("Error uncompressing file '%s'", filename.c_str()); delete[] compBuffer; delete file; return NULL; } delete[] compBuffer; delete file; return new Common::MemoryReadStream(data, uncompSize, DisposeAfterUse::YES); } else { file->seek(0, SEEK_SET); return file; } return file; } return NULL; }
bool StyledTTFont::loadFont(const Common::String &fontName, int32 point) { Common::String newFontName; if (fontName.matchString("*times new roman*", true) || fontName.matchString("*times*", true)) { if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC)) newFontName = "timesbi.ttf"; else if (_style & STTF_BOLD) newFontName = "timesbd.ttf"; else if (_style & STTF_ITALIC) newFontName = "timesi.ttf"; else newFontName = "times.ttf"; } else if (fontName.matchString("*courier new*", true) || fontName.matchString("*courier*", true) || fontName.matchString("*ZorkDeath*", true)) { if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC)) newFontName = "courbi.ttf"; else if (_style & STTF_BOLD) newFontName = "courbd.ttf"; else if (_style & STTF_ITALIC) newFontName = "couri.ttf"; else newFontName = "cour.ttf"; } else if (fontName.matchString("*century schoolbook*", true)) { if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC)) newFontName = "censcbkbi.ttf"; else if (_style & STTF_BOLD) newFontName = "censcbkbd.ttf"; else if (_style & STTF_ITALIC) newFontName = "censcbki.ttf"; else newFontName = "censcbk.ttf"; } else if (fontName.matchString("*garamond*", true)) { if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC)) newFontName = "garabi.ttf"; else if (_style & STTF_BOLD) newFontName = "garabd.ttf"; else if (_style & STTF_ITALIC) newFontName = "garai.ttf"; else newFontName = "gara.ttf"; } else if (fontName.matchString("*arial*", true) || fontName.matchString("*ZorkNormal*", true)) { if ((_style & (STTF_BOLD | STTF_ITALIC)) == (STTF_BOLD | STTF_ITALIC)) newFontName = "arialbi.ttf"; else if (_style & STTF_BOLD) newFontName = "arialbd.ttf"; else if (_style & STTF_ITALIC) newFontName = "ariali.ttf"; else newFontName = "arial.ttf"; } else { debug("Could not identify font: %s. Reverting to Arial", fontName.c_str()); newFontName = "arial.ttf"; } bool sharp = (_style & STTF_SHARP) == STTF_SHARP; Common::File *file = _engine->getSearchManager()->openFile(newFontName); if (!file) { Common::SeekableReadStream *themeFile = nullptr; if (ConfMan.hasKey("themepath")) { Common::FSNode themePath(ConfMan.get("themepath")); if (themePath.exists()) { Common::FSNode scummModern = themePath.getChild("scummmodern.zip"); if (scummModern.exists()) { themeFile = scummModern.createReadStream(); } } } if (!themeFile) { // Fallback : Search for ScummModern.zip in SearchMan. themeFile = SearchMan.createReadStreamForMember("scummmodern.zip"); } if (themeFile) { Common::Archive *themeArchive = Common::makeZipArchive(themeFile); if (themeArchive->hasFile("FreeSans.ttf")) { Common::SeekableReadStream *stream = nullptr; stream = themeArchive->createReadStreamForMember("FreeSans.ttf"); Graphics::Font *_newFont = Graphics::loadTTFFont(*stream, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display if (_newFont) { if (!_font) delete _font; _font = _newFont; } if (stream) delete stream; } delete themeArchive; themeArchive = nullptr; } } else { Graphics::Font *_newFont = Graphics::loadTTFFont(*file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display if (_newFont) { if (!_font) delete _font; _font = _newFont; } delete file; } _fntName = fontName; _lineHeight = point; if (_font) return true; return false; }