static size_t file_write(const void * const p, size_t len, stream_t *stream) { PHYSFS_sint64 count; int error; PHYSFS_File *file; if (file_check_context(stream)) return 0; file = stream->context.pfs.file; count = PHYSFS_writeBytes(file, p, len); if (count < len && (error = PHYSFS_getLastErrorCode())) { s_log_error("Error writing to file stream (pfs: %s). (File: %s)", PHYSFS_getErrorByCode(error), stream->context.pfs.file_path); stream->error = STREAM_ERROR_FAILURE; if (count == -1) return 0; } return (size_t)count; }
void FS_Init(const char *argv0) { int err = PHYSFS_init(argv0); if (err == 0) { Con_Errorf(ERR_FATAL, "Error in PHYSFS_init: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); return; } const char *baseDir = PHYSFS_getBaseDir(); fs_basepath = Con_GetVarDefault("fs.basepath", baseDir, CONVAR_STARTUP); fs_basegame = Con_GetVarDefault("fs.basegame", "base", CONVAR_STARTUP); fs_game = Con_GetVarDefault("fs.game", DEFAULT_GAME, CONVAR_STARTUP); bool modLoaded = fs_game->string[0] != '\0'; char **baseFiles, **gameFiles; // get the file listing for the basegame dir, then immediately unmount const char *fullBasePath = tempstr("%s/%s", fs_basepath->string, fs_basegame->string); PHYSFS_mount(fullBasePath, "/", 1); baseFiles = PHYSFS_enumerateFiles("/"); PHYSFS_removeFromSearchPath(fullBasePath); // if fs_game is set, do the same thing for the fs_game dir if (modLoaded) { const char *fullGamePath = tempstr("%s/%s", fs_basepath->string, fs_game->string); PHYSFS_mount(fullGamePath, "/", 1); gameFiles = PHYSFS_enumerateFiles("/"); PHYSFS_removeFromSearchPath(fullGamePath); // mount the mod dir first, then mount mod PK3s PHYSFS_mount(tempstr("%s/%s", fs_basepath->string, fs_game->string), "/", 1); FS_AddPaksFromList(gameFiles, fs_basepath->string, fs_game->string); PHYSFS_freeList(gameFiles); } // then mount the base game dir, then the mount base game PK3s PHYSFS_mount(tempstr("%s/%s", fs_basepath->string, fs_basegame->string), "/", 1); FS_AddPaksFromList(baseFiles, fs_basepath->string, fs_basegame->string); PHYSFS_freeList(baseFiles); // print all the files we've found in order of priority Con_Printf("Current filesystem search path:\n"); PHYSFS_getSearchPathCallback(printSearchPath, NULL); Con_Printf("\n"); // add command handler for dir to view virtual filesystem Con_AddCommand("dir", Cmd_Dir_f); }
FileSystem::FileSystem(std::vector<UString> paths) { // FIXME: Is this the right thing to do that? LogInfo("Registering external archivers..."); PHYSFS_registerArchiver(getCueArchiver()); // Paths are supplied in inverse-search order (IE the last in 'paths' should be the first // searched) for (auto &p : paths) { if (!PHYSFS_mount(p.cStr(), "/", 0)) { LogInfo("Failed to add resource dir \"%s\", error: %s", p, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); continue; } else LogInfo("Resource dir \"%s\" mounted to \"%s\"", p, PHYSFS_getMountPoint(p.cStr())); } this->writeDir = PHYSFS_getPrefDir(PROGRAM_ORGANISATION, PROGRAM_NAME); LogInfo("Setting write directory to \"%s\"", this->writeDir); PHYSFS_setWriteDir(this->writeDir.cStr()); // Finally, the write directory trumps all PHYSFS_mount(this->writeDir.cStr(), "/", 0); }