From c1f473940c4c357cdc46a00fbba739598eaf0cdd Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 9 Jan 2012 07:00:15 +0000 Subject: [PATCH] Refactor: Moved path property out of LumpInfo Now that derivatives of AbstractFile store all their lump records in their own PathDirectory instances, it is no longer necessary for LumpInfo to store a copy of the absolute path. WadFile, ZipFile and LumpFile can now dynamically compose the full vfs path to a lump they contain, should it be needed. Todo: It should not be necessary to compose an absolute path when instantiating LumpFile, or when pruning duplicates from the zip LumpDirectory, or when resolving resource searches. Todo: LumpInfo::name is now redundant, it can be refactored away. --- .../engine/portable/include/abstractfile.h | 6 +- doomsday/engine/portable/include/fs_main.h | 26 ++- doomsday/engine/portable/include/lumpfile.h | 4 +- doomsday/engine/portable/include/lumpinfo.h | 1 - doomsday/engine/portable/include/wadfile.h | 8 +- doomsday/engine/portable/include/zipfile.h | 4 +- doomsday/engine/portable/src/abstractfile.c | 6 +- doomsday/engine/portable/src/dd_main.c | 4 +- doomsday/engine/portable/src/dd_wad.c | 6 +- doomsday/engine/portable/src/dfile.c | 10 +- doomsday/engine/portable/src/fs_main.c | 199 +++++++++++------- doomsday/engine/portable/src/gl_texmanager.c | 22 +- doomsday/engine/portable/src/lumpdirectory.c | 72 +++++-- doomsday/engine/portable/src/lumpfile.c | 44 ++-- doomsday/engine/portable/src/r_data.c | 43 ++-- doomsday/engine/portable/src/s_mus.c | 3 +- doomsday/engine/portable/src/wadfile.c | 50 +++-- doomsday/engine/portable/src/zipfile.c | 38 ++-- 18 files changed, 329 insertions(+), 217 deletions(-) diff --git a/doomsday/engine/portable/include/abstractfile.h b/doomsday/engine/portable/include/abstractfile.h index c981d2d887..937dbf0f53 100644 --- a/doomsday/engine/portable/include/abstractfile.h +++ b/doomsday/engine/portable/include/abstractfile.h @@ -57,6 +57,9 @@ typedef struct abstractfile_s { /// protected: File stream handle/wrapper. DFile* _file; + /// Absolute variable-length path in the vfs. + ddstring_t _path; + /// Info descriptor (file metadata). LumpInfo _info; @@ -68,12 +71,13 @@ typedef struct abstractfile_s { * Initialize this resource. * * @param type File type identifier. + * @param path Path to this file in the virtual file system. * @param file Handle to the file. AbstractFile takes ownership of the handle. * @param info Lump info descriptor for the file. A copy is made. * @return Same as @a af for convenience (chaining). */ abstractfile_t* AbstractFile_Init(abstractfile_t* af, filetype_t type, - DFile* file, const LumpInfo* info); + const char* path, DFile* file, const LumpInfo* info); /** * Release all memory acquired for objects linked with this resource. diff --git a/doomsday/engine/portable/include/fs_main.h b/doomsday/engine/portable/include/fs_main.h index b4dceb0971..e192f89c82 100644 --- a/doomsday/engine/portable/include/fs_main.h +++ b/doomsday/engine/portable/include/fs_main.h @@ -208,6 +208,16 @@ DFile* F_Open(const char* path, const char* mode); /* baseOffset = 0 */ */ DFile* F_OpenLump(lumpnum_t lumpNum); +/** + * Write the data associated with the specified lump index to @a fileName. + * + * @param lumpNum Absolute index of the lump to open. + * @param fileName If not @c NULL write the associated data to this path. + * Can be @c NULL in which case the fileName will be chosen automatically. + * @return @c true iff successful. + */ +boolean F_DumpLump(lumpnum_t lumpNum, const char* fileName); + /** * @return The time when the file was last modified, as seconds since * the Epoch else zero if the file is not found. @@ -256,6 +266,12 @@ void F_Close(DFile* file); /// Completely destroy this file; close if open, clear references and any acquired identifiers. void F_Delete(DFile* file); +/// @return Must be free'd with Str_Delete +ddstring_t* F_ComposeLumpPath2(abstractfile_t* fsObject, int lumpIdx, char delimiter); +ddstring_t* F_ComposeLumpPath(abstractfile_t* fsObject, int lumpIdx); /*delimiter='/'*/ + +struct pathdirectorynode_s* F_LumpDirectoryNode(const LumpInfo* lumpInfo); + const LumpInfo* F_LumpInfo(abstractfile_t* file, int lumpIdx); size_t F_ReadLumpSection(abstractfile_t* file, int lumpIdx, uint8_t* buffer, @@ -265,16 +281,6 @@ const uint8_t* F_CacheLump(abstractfile_t* file, int lumpIdx, int tag); void F_CacheChangeTag(abstractfile_t* file, int lumpIdx, int tag); -/** - * Write the data associated with the specified lump index to @a fileName. - * - * @param lumpIdx Index of the lump data being dumped. - * @param fileName If not @c NULL write the associated data to this path. - * Can be @c NULL in which case the fileName will be chosen automatically. - * @return @c true iff successful. - */ -boolean F_DumpLump(abstractfile_t* file, int lumpIdx, const char* fileName); - /** * Parm is passed on to the callback, which is called for each file * matching the filespec. Absolute path names are given to the callback. diff --git a/doomsday/engine/portable/include/lumpfile.h b/doomsday/engine/portable/include/lumpfile.h index aa04af3dc6..ba5e733b6e 100644 --- a/doomsday/engine/portable/include/lumpfile.h +++ b/doomsday/engine/portable/include/lumpfile.h @@ -41,11 +41,13 @@ typedef struct lumpfile_s { void** _cacheData; } LumpFile; -LumpFile* LumpFile_New(DFile* file, const LumpInfo* info); +LumpFile* LumpFile_New(DFile* file, const char* path, const LumpInfo* info); void LumpFile_Delete(LumpFile* lump); int LumpFile_PublishLumpsToDirectory(LumpFile* lump, struct lumpdirectory_s* directory); +ddstring_t* LumpFile_ComposeLumpPath(LumpFile* lump, int lumpIdx, char delimiter); + const LumpInfo* LumpFile_LumpInfo(LumpFile* lump, int lumpIdx); /** diff --git a/doomsday/engine/portable/include/lumpinfo.h b/doomsday/engine/portable/include/lumpinfo.h index 81ee4bb5e1..4de3c2b0ad 100644 --- a/doomsday/engine/portable/include/lumpinfo.h +++ b/doomsday/engine/portable/include/lumpinfo.h @@ -40,7 +40,6 @@ typedef struct { size_t compressedSize; /// Size of the original file compressed. struct abstractfile_s* container; /// Owning package else @c NULL. lumpname_t name; /// Ends in '\0'. Used with WAD lumps. - ddstring_t path; /// Absolute variable-length path in the vfs. } LumpInfo; void F_InitLumpInfo(LumpInfo* info); diff --git a/doomsday/engine/portable/include/wadfile.h b/doomsday/engine/portable/include/wadfile.h index ba5595ecc7..62d9625405 100644 --- a/doomsday/engine/portable/include/wadfile.h +++ b/doomsday/engine/portable/include/wadfile.h @@ -39,14 +39,16 @@ struct pathdirectorynode_s; struct wadfile_s; // The wadfile instance (opaque) typedef struct wadfile_s WadFile; -WadFile* WadFile_New(DFile* file, const LumpInfo* info); +WadFile* WadFile_New(DFile* file, const char* path, const LumpInfo* info); void WadFile_Delete(WadFile* wad); -int WadFile_PublishLumpsToDirectory(WadFile* file, struct lumpdirectory_s* directory); +int WadFile_PublishLumpsToDirectory(WadFile* wad, struct lumpdirectory_s* directory); struct pathdirectorynode_s* WadFile_DirectoryNodeForLump(WadFile* wad, int lumpIdx); -const LumpInfo* WadFile_LumpInfo(WadFile* file, int lumpIdx); +ddstring_t* WadFile_ComposeLumpPath(WadFile* wad, int lumpIdx, char delimiter); + +const LumpInfo* WadFile_LumpInfo(WadFile* wad, int lumpIdx); /** * Read the data associated with the specified lump index into @a buffer. diff --git a/doomsday/engine/portable/include/zipfile.h b/doomsday/engine/portable/include/zipfile.h index 2f07368320..538b5a9581 100644 --- a/doomsday/engine/portable/include/zipfile.h +++ b/doomsday/engine/portable/include/zipfile.h @@ -41,13 +41,15 @@ struct pathdirectorynode_s; struct zipfile_s; // The zipfile instance (opaque) typedef struct zipfile_s ZipFile; -ZipFile* ZipFile_New(DFile* file, const LumpInfo* info); +ZipFile* ZipFile_New(DFile* file, const char* path, const LumpInfo* info); void ZipFile_Delete(ZipFile* zip); int ZipFile_PublishLumpsToDirectory(ZipFile* zip, struct lumpdirectory_s* directory); struct pathdirectorynode_s* ZipFile_DirectoryNodeForLump(ZipFile* zip, int lumpIdx); +ddstring_t* ZipFile_ComposeLumpPath(ZipFile* zip, int lumpIdx, char delimiter); + const LumpInfo* ZipFile_LumpInfo(ZipFile* zip, int lumpIdx); /** diff --git a/doomsday/engine/portable/src/abstractfile.c b/doomsday/engine/portable/src/abstractfile.c index 126c53e162..245778cd07 100644 --- a/doomsday/engine/portable/src/abstractfile.c +++ b/doomsday/engine/portable/src/abstractfile.c @@ -28,7 +28,7 @@ #include "abstractfile.h" abstractfile_t* AbstractFile_Init(abstractfile_t* af, filetype_t type, - DFile* file, const LumpInfo* info) + const char* path, DFile* file, const LumpInfo* info) { // Used to favor newer files when duplicates are pruned. static uint fileCounter = 0; @@ -39,6 +39,7 @@ abstractfile_t* AbstractFile_Init(abstractfile_t* af, filetype_t type, af->_file = file; af->_flags.startup = false; af->_flags.iwad = false; + Str_Init(&af->_path); Str_Set(&af->_path, path); F_CopyLumpInfo(&af->_info, info); return af; @@ -47,6 +48,7 @@ abstractfile_t* AbstractFile_Init(abstractfile_t* af, filetype_t type, void AbstractFile_Destroy(abstractfile_t* af) { assert(af); + Str_Free(&af->_path); F_DestroyLumpInfo(&af->_info); if(af->_file) DFile_Delete(af->_file, true); @@ -85,7 +87,7 @@ DFile* AbstractFile_Handle(abstractfile_t* af) const ddstring_t* AbstractFile_Path(const abstractfile_t* af) { assert(af); - return &af->_info.path; + return &af->_path; } uint AbstractFile_LoadOrderIndex(const abstractfile_t* af) diff --git a/doomsday/engine/portable/src/dd_main.c b/doomsday/engine/portable/src/dd_main.c index c695e29ee9..0439fc8986 100644 --- a/doomsday/engine/portable/src/dd_main.c +++ b/doomsday/engine/portable/src/dd_main.c @@ -1556,9 +1556,7 @@ int DD_Main(void) lumpnum_t absoluteLumpNum = F_CheckLumpNumForName(name); if(absoluteLumpNum >= 0) { - int lumpIdx; - abstractfile_t* fsObject = F_FindFileForLumpNum2(absoluteLumpNum, &lumpIdx); - F_DumpLump(fsObject, lumpIdx, NULL); + F_DumpLump(absoluteLumpNum, NULL); } } diff --git a/doomsday/engine/portable/src/dd_wad.c b/doomsday/engine/portable/src/dd_wad.c index ef96971c39..f1f8f2748b 100644 --- a/doomsday/engine/portable/src/dd_wad.c +++ b/doomsday/engine/portable/src/dd_wad.c @@ -48,13 +48,13 @@ size_t W_LumpLength(lumpnum_t absoluteLumpNum) const char* W_LumpName(lumpnum_t absoluteLumpNum) { - const LumpInfo* info = F_FindInfoForLumpNum(absoluteLumpNum); - if(!info) + const char* lumpName = F_LumpName(absoluteLumpNum); + if(!lumpName[0]) { W_Error("W_LumpName: Invalid lumpnum %i.", absoluteLumpNum); return NULL; } - return info->name; + return lumpName; } uint W_LumpLastModified(lumpnum_t absoluteLumpNum) diff --git a/doomsday/engine/portable/src/dfile.c b/doomsday/engine/portable/src/dfile.c index e64f2df870..f604024e1e 100644 --- a/doomsday/engine/portable/src/dfile.c +++ b/doomsday/engine/portable/src/dfile.c @@ -120,9 +120,13 @@ DFile* DFileBuilder_NewFromAbstractFileLump(abstractfile_t* container, int lumpI Con_Error("DFileBuilder::NewFromAbstractFileLump: Failed on allocation of %lu bytes for data buffer.", (unsigned long) file->_size); #if _DEBUG - VERBOSE2( Con_Printf("DFile [%p] buffering \"%s:%s\"...\n", (void*)file, - F_PrettyPath(Str_Text(AbstractFile_Path(container))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path)))) ) + VERBOSE2( + ddstring_t* path = F_ComposeLumpPath(container, lumpIdx); + Con_Printf("DFile [%p] buffering \"%s:%s\"...\n", (void*)file, + F_PrettyPath(Str_Text(AbstractFile_Path(container))), + F_PrettyPath(Str_Text(path))); + Str_Delete(path); + ) #endif F_ReadLumpSection(container, lumpIdx, (uint8_t*)file->_data, 0, info->size); } diff --git a/doomsday/engine/portable/src/fs_main.c b/doomsday/engine/portable/src/fs_main.c index 14f5600dfc..6a3c7f74b2 100644 --- a/doomsday/engine/portable/src/fs_main.c +++ b/doomsday/engine/portable/src/fs_main.c @@ -168,27 +168,27 @@ static int findFileNodeIndexForPath(FileList* list, const char* path_) return found; } -static abstractfile_t* newUnknownFile(DFile* file, const LumpInfo* info) +static abstractfile_t* newUnknownFile(DFile* file, const char* path, const LumpInfo* info) { abstractfile_t* af = (abstractfile_t*)malloc(sizeof *af); if(!af) Con_Error("newUnknownFile: Failed on allocation of %lu bytes for new abstractfile_t.", (unsigned long) sizeof *af); - return AbstractFile_Init(af, FT_UNKNOWNFILE, file, info); + return AbstractFile_Init(af, FT_UNKNOWNFILE, path, file, info); } -static abstractfile_t* newZipFile(DFile* file, const LumpInfo* info) +static abstractfile_t* newZipFile(DFile* file, const char* path, const LumpInfo* info) { - return (abstractfile_t*)ZipFile_New(file, info); + return (abstractfile_t*)ZipFile_New(file, path, info); } -static abstractfile_t* newWadFile(DFile* file, const LumpInfo* info) +static abstractfile_t* newWadFile(DFile* file, const char* path, const LumpInfo* info) { - return (abstractfile_t*)WadFile_New(file, info); + return (abstractfile_t*)WadFile_New(file, path, info); } -static abstractfile_t* newLumpFile(DFile* file, const LumpInfo* info) +static abstractfile_t* newLumpFile(DFile* file, const char* path, const LumpInfo* info) { - return (abstractfile_t*)LumpFile_New(file, info); + return (abstractfile_t*)LumpFile_New(file, path, info); } static int pruneLumpsFromDirectorysByFile(abstractfile_t* af) @@ -444,7 +444,6 @@ void F_InitLumpInfo(LumpInfo* info) { assert(info); memset(info->name, 0, sizeof info->name); - Str_Init(&info->path); info->lumpIdx = 0; info->size = 0; info->compressedSize = 0; @@ -456,9 +455,6 @@ void F_CopyLumpInfo(LumpInfo* dst, const LumpInfo* src) { assert(dst && src); memcpy(dst->name, src->name, sizeof dst->name); - Str_Init(&dst->path); - if(!Str_IsEmpty(&src->path)) - Str_Set(&dst->path, Str_Text(&src->path)); dst->lumpIdx = src->lumpIdx; dst->size = src->size; dst->compressedSize = src->compressedSize; @@ -468,8 +464,7 @@ void F_CopyLumpInfo(LumpInfo* dst, const LumpInfo* src) void F_DestroyLumpInfo(LumpInfo* info) { - assert(info); - Str_Free(&info->path); + // Nothing to do. } void F_Init(void) @@ -751,16 +746,15 @@ lumpnum_t F_OpenAuxiliary3(const char* path, size_t baseOffset, boolean silent) // Prepare the temporary info descriptor. F_InitLumpInfo(&info); - Str_Set(&info.path, Str_Text(foundPath)); info.lastModified = F_LastModified(Str_Text(foundPath)); - Str_Delete(foundPath); - - dfile = DFileBuilder_NewFromAbstractFile(newWadFile(dfile, &info)); + dfile = DFileBuilder_NewFromAbstractFile(newWadFile(dfile, Str_Text(foundPath), &info)); FileList_AddBack(openFiles, dfile); FileList_AddBack(loadedFiles, DFileBuilder_NewCopy(dfile)); WadFile_PublishLumpsToDirectory((WadFile*)DFile_File(dfile), ActiveWadLumpDirectory); + Str_Delete(foundPath); + // We're done with the descriptor. F_DestroyLumpInfo(&info); return AUXILIARY_BASE; @@ -856,6 +850,36 @@ const LumpInfo* F_LumpInfo(abstractfile_t* fsObject, int lumpIdx) } } +PathDirectoryNode* F_LumpDirectoryNode(const LumpInfo* lumpInfo) +{ + if(!lumpInfo || !lumpInfo->container) return NULL; + switch(AbstractFile_Type(lumpInfo->container)) + { + case FT_ZIPFILE: return ZipFile_DirectoryNodeForLump((ZipFile*)lumpInfo->container, lumpInfo->lumpIdx); + case FT_WADFILE: return WadFile_DirectoryNodeForLump((WadFile*)lumpInfo->container, lumpInfo->lumpIdx); + default: return NULL; + } +} + +ddstring_t* F_ComposeLumpPath2(abstractfile_t* fsObject, int lumpIdx, char delimiter) +{ + assert(fsObject); + switch(AbstractFile_Type(fsObject)) + { + case FT_ZIPFILE: return ZipFile_ComposeLumpPath( (ZipFile*)fsObject, lumpIdx, delimiter); + case FT_WADFILE: return WadFile_ComposeLumpPath( (WadFile*)fsObject, lumpIdx, delimiter); + case FT_LUMPFILE: return LumpFile_ComposeLumpPath((LumpFile*)fsObject, lumpIdx, delimiter); + default: + Con_Error("F_ComposeLumpPath: Invalid file type %i.", AbstractFile_Type(fsObject)); + exit(1); // Unreachable. + } +} + +ddstring_t* F_ComposeLumpPath(abstractfile_t* fsObject, int lumpIdx) +{ + return F_ComposeLumpPath2(fsObject, lumpIdx, '/'); +} + size_t F_ReadLumpSection(abstractfile_t* fsObject, int lumpIdx, uint8_t* buffer, size_t startOffset, size_t length) { @@ -899,16 +923,24 @@ void F_CacheChangeTag(abstractfile_t* fsObject, int lumpIdx, int tag) } } -boolean F_DumpLump(abstractfile_t* fsObject, int lumpIdx, const char* path) +boolean F_DumpLump(lumpnum_t absoluteLumpNum, const char* path) { char buf[LUMPNAME_T_LASTINDEX + 4/*.ext*/ + 1]; - const LumpInfo* info = F_LumpInfo(fsObject, lumpIdx); + const LumpInfo* info; + abstractfile_t* fsObject; ddstring_t nativePath; + const char* lumpName; const char* fname; + int lumpIdx; FILE* outFile; + fsObject = F_FindFileForLumpNum2(absoluteLumpNum, &lumpIdx); + if(!fsObject) return false; + + info = F_LumpInfo(fsObject, lumpIdx); if(!info) return false; + lumpName = F_LumpName(absoluteLumpNum); if(path && path[0]) { fname = path; @@ -916,7 +948,7 @@ boolean F_DumpLump(abstractfile_t* fsObject, int lumpIdx, const char* path) else { memset(buf, 0, sizeof buf); - dd_snprintf(buf, 13, "%s.lmp", info->name); + dd_snprintf(buf, 13, "%s.lmp", lumpName); fname = buf; } @@ -935,7 +967,7 @@ boolean F_DumpLump(abstractfile_t* fsObject, int lumpIdx, const char* path) fclose(outFile); F_CacheChangeTag(fsObject, lumpIdx, PU_CACHE); - Con_Printf("%s dumped to \"%s\"\n", F_PrettyPath(info->name), F_PrettyPath(Str_Text(&nativePath))); + Con_Printf("%s dumped to \"%s\"\n", lumpName, F_PrettyPath(Str_Text(&nativePath))); Str_Free(&nativePath); return true; } @@ -1136,17 +1168,6 @@ static int iterateLocalPaths(const ddstring_t* searchDirectory, const ddstring_t return result; } -static PathDirectoryNode* directoryNodeForLump(const LumpInfo* lumpInfo) -{ - if(!lumpInfo || !lumpInfo->container) return NULL; - switch(AbstractFile_Type(lumpInfo->container)) - { - case FT_ZIPFILE: return ZipFile_DirectoryNodeForLump((ZipFile*)lumpInfo->container, lumpInfo->lumpIdx); - case FT_WADFILE: return WadFile_DirectoryNodeForLump((WadFile*)lumpInfo->container, lumpInfo->lumpIdx); - default: return NULL; - } -} - typedef struct { /// Callback to make for each processed file. int (*callback) (const ddstring_t* path, pathdirectorynode_type_t type, void* paramaters); @@ -1164,25 +1185,35 @@ typedef struct { static int findLumpWorker(const LumpInfo* lumpInfo, void* paramaters) { findlumpworker_paramaters_t* p = (findlumpworker_paramaters_t*)paramaters; - PathDirectoryNode* node = directoryNodeForLump(lumpInfo); + PathDirectoryNode* node = F_LumpDirectoryNode(lumpInfo); + ddstring_t* filePath = NULL; boolean patternMatched; + int result = 0; // Continue iteration. assert(lumpInfo && p); - if(!node || !(p->flags & SPF_NO_DECEND)) + if(!node) return 0; // Most irregular... + + if(!(p->flags & SPF_NO_DECEND)) { - patternMatched = F_MatchFileName(Str_Text(&lumpInfo->path), Str_Text(&p->pattern)); + filePath = F_ComposeLumpPath(lumpInfo->container, lumpInfo->lumpIdx); + patternMatched = F_MatchFileName(Str_Text(filePath), Str_Text(&p->pattern)); } else { patternMatched = PathDirectoryNode_MatchDirectory(node, PCF_MATCH_FULL, &p->patternMap, NULL); + if(patternMatched) + { + filePath = F_ComposeLumpPath(lumpInfo->container, lumpInfo->lumpIdx); + } } if(patternMatched) { - int result = p->callback(&lumpInfo->path, PT_LEAF, p->paramaters); - if(result) return result; + result = p->callback(filePath, PT_LEAF, p->paramaters); } - return 0; // Continue iteration. + + if(filePath) Str_Delete(filePath); + return result; } int F_AllResourcePaths2(const char* rawSearchPattern, int flags, @@ -1380,17 +1411,19 @@ abstractfile_t* F_FindLumpFile(const char* path, int* lumpIdx) } static DFile* openAsLumpFile(abstractfile_t* container, int lumpIdx, - const char* absolutePath, boolean isDehackedPatch, boolean dontBuffer) + const char* _absPath, boolean isDehackedPatch, boolean dontBuffer) { + ddstring_t absPath; LumpInfo info; DFile* file; + Str_Init(&absPath); Str_Set(&absPath, _absPath); + Str_Strip(&absPath); + F_FixSlashes(&absPath, &absPath); + // Prepare the temporary info descriptor. F_InitLumpInfo(&info); F_CopyLumpInfo(&info, F_LumpInfo(container, lumpIdx)); - Str_Set(&info.path, absolutePath); - Str_Strip(&info.path); - F_FixSlashes(&info.path, &info.path); // Prepare the name of this single-lump file. if(isDehackedPatch) @@ -1400,10 +1433,10 @@ static DFile* openAsLumpFile(abstractfile_t* container, int lumpIdx, else { // Is there a prefix to be omitted in the name? - char* slash = strrchr(absolutePath, '/'); + char* slash = strrchr(Str_Text(&absPath), '/'); int offset = 0; // The slash must not be too early in the string. - if(slash && slash >= absolutePath + 2) + if(slash && slash >= Str_Text(&absPath) + 2) { // Good old negative indices. if(slash[-2] == '.' && slash[-1] >= '1' && slash[-1] <= '9') @@ -1411,80 +1444,83 @@ static DFile* openAsLumpFile(abstractfile_t* container, int lumpIdx, offset = slash[-1] - '1' + 1; } } - F_ExtractFileBase2(info.name, Str_Text(&info.path), LUMPNAME_T_LASTINDEX, offset); + F_ExtractFileBase2(info.name, Str_Text(&absPath), LUMPNAME_T_LASTINDEX, offset); info.name[LUMPNAME_T_LASTINDEX] = '\0'; } file = DFileBuilder_NewFromAbstractFile( - newLumpFile(DFileBuilder_NewFromAbstractFileLump(container, lumpIdx, dontBuffer), &info)); + newLumpFile(DFileBuilder_NewFromAbstractFileLump(container, lumpIdx, dontBuffer), + Str_Text(&absPath), &info)); + Str_Free(&absPath); // We're done with the descriptor. F_DestroyLumpInfo(&info); return file; } -static DFile* tryOpenAsZipFile(DFile* file, const LumpInfo* info) +static DFile* tryOpenAsZipFile(DFile* file, const char* path, const LumpInfo* info) { if(inited && ZipFile_Recognise(file)) { - return DFileBuilder_NewFromAbstractFile(newZipFile(file, info)); + return DFileBuilder_NewFromAbstractFile(newZipFile(file, path, info)); } return NULL; } -static DFile* tryOpenAsWadFile(DFile* file, const LumpInfo* info) +static DFile* tryOpenAsWadFile(DFile* file, const char* path, const LumpInfo* info) { if(inited && WadFile_Recognise(file)) { - return DFileBuilder_NewFromAbstractFile(newWadFile(file, info)); + return DFileBuilder_NewFromAbstractFile(newWadFile(file, path, info)); } return NULL; } -static DFile* tryOpenFile3(DFile* file, const LumpInfo* info) +static DFile* tryOpenFile3(DFile* file, const char* path, const LumpInfo* info) { - assert(file && info); - { static const struct filehandler_s { resourcetype_t resourceType; - DFile* (*tryOpenFile)(DFile* file, const LumpInfo* info); + DFile* (*tryOpenFile)(DFile* file, const char* path, const LumpInfo* info); } handlers[] = { { RT_ZIP, tryOpenAsZipFile }, { RT_WAD, tryOpenAsWadFile }, { RT_NONE, NULL } }, *hdlr = NULL; - resourcetype_t resourceType = F_GuessResourceTypeByName(Str_Text(&info->path)); + resourcetype_t resourceType; DFile* hndl = NULL; + int n = 0; + assert(file && path && path[0] && info); + + resourceType = F_GuessResourceTypeByName(path); // Firstly try the expected format given the file name. - for(hdlr = handlers; NULL != hdlr->tryOpenFile; hdlr++) + for(hdlr = handlers; hdlr->tryOpenFile; hdlr++) { if(hdlr->resourceType != resourceType) continue; - hndl = hdlr->tryOpenFile(file, info); + hndl = hdlr->tryOpenFile(file, path, info); break; } // If not yet loaded; try each recognisable format. /// \todo Order here should be determined by the resource locator. - { int n = 0; - while(NULL == hndl && NULL != handlers[n].tryOpenFile) + while(!hndl && handlers[n].tryOpenFile) { if(hdlr != &handlers[n]) // We already know its not in this format. { - hndl = handlers[n].tryOpenFile(file, info); + hndl = handlers[n].tryOpenFile(file, path, info); } ++n; - }} + } // If still not loaded; this an unknown format. if(!hndl) { - hndl = DFileBuilder_NewFromAbstractFile(newUnknownFile(file, info)); + hndl = DFileBuilder_NewFromAbstractFile(newUnknownFile(file, path, info)); } + assert(hndl); return hndl; - } } /** @@ -1557,19 +1593,17 @@ static DFile* tryOpenFile2(const char* path, const char* mode, size_t baseOffset } // Prepare the temporary info descriptor. - // Search path is used here rather than found path as the latter may have - // been mapped to another location. We want the file to be attributed with - // the path it is to be known by throughout the virtual file system. F_InitLumpInfo(&info); - Str_Set(&info.path, Str_Text(&searchPath)); - Str_Strip(&info.path); info.lastModified = F_LastModified(Str_Text(foundPath)); - Str_Free(&searchPath); - Str_Delete(foundPath); + // Search path is used here rather than found path as the latter may have + // been mapped to another location. We want the file to be attributed with + // the path it is to be known by throughout the virtual file system. - dfile = tryOpenFile3(DFileBuilder_NewFromFile(file, baseOffset), &info); + dfile = tryOpenFile3(DFileBuilder_NewFromFile(file, baseOffset), Str_Text(&searchPath), &info); + Str_Delete(foundPath); + Str_Free(&searchPath); // We're done with the descriptor. F_DestroyLumpInfo(&info); return dfile; @@ -1714,17 +1748,20 @@ boolean F_RemoveFile(const char* path) boolean F_RemoveFiles(const char* const* filenames, size_t num) { boolean succeeded = false; - { size_t i; + size_t i; + for(i = 0; i < num; ++i) { if(unloadFile(filenames[i])) { - VERBOSE2( Con_Message("Done unloading %s\n", F_PrettyPath(filenames[i])) ); + VERBOSE2( Con_Message("Done unloading %s\n", F_PrettyPath(filenames[i])) ) succeeded = true; // At least one has been unloaded. } else + { Con_Message("Warning: Errors occured while unloading %s\n", filenames[i]); - }} + } + } // A changed file list may alter the main lump directory. if(succeeded) @@ -1740,8 +1777,12 @@ DFile* F_OpenLump(lumpnum_t absoluteLumpNum) abstractfile_t* container = F_FindFileForLumpNum2(absoluteLumpNum, &lumpIdx); if(container) { - /// \todo All lumps should be attributed with an absolute file path not just those from Zips. - abstractfile_t* fsObject = newLumpFile(DFileBuilder_NewFromAbstractFileLump(container, lumpIdx, false), F_LumpInfo(container, lumpIdx)); + ddstring_t* path = F_ComposeLumpPath(container, lumpIdx); + abstractfile_t* fsObject = newLumpFile( + DFileBuilder_NewFromAbstractFileLump(container, lumpIdx, false), + Str_Text(path), F_LumpInfo(container, lumpIdx)); + + Str_Delete(path); if(fsObject) { return FileList_AddBack(openFiles, DFileBuilder_NewFromAbstractFile(fsObject)); @@ -2158,9 +2199,7 @@ D_CMD(DumpLump) lumpnum_t absoluteLumpNum = F_CheckLumpNumForName2(argv[1], true); if(absoluteLumpNum >= 0) { - int lumpIdx; - abstractfile_t* fsObject = F_FindFileForLumpNum2(absoluteLumpNum, &lumpIdx); - return F_DumpLump(fsObject, lumpIdx, NULL); + return F_DumpLump(absoluteLumpNum, NULL); } Con_Printf("No such lump.\n"); return false; diff --git a/doomsday/engine/portable/src/gl_texmanager.c b/doomsday/engine/portable/src/gl_texmanager.c index 20f3a5cddb..88140c7d54 100644 --- a/doomsday/engine/portable/src/gl_texmanager.c +++ b/doomsday/engine/portable/src/gl_texmanager.c @@ -1453,24 +1453,13 @@ uint8_t* GL_LoadImageFromFile(image_t* img, DFile* file) { const imagehandler_t* hdlr; const char* fileName; - int n = 0; assert(img && file); GL_InitImage(img); - // Firstly try the expected format given the file name. - switch(AbstractFile_Type(DFile_File_Const(file))) - { - case FT_LUMPFILE: { - const LumpInfo* info = AbstractFile_Info(DFile_File_Const(file)); - fileName = (char*)info->name; - break; - } - default: - fileName = Str_Text(AbstractFile_Path(DFile_File_Const(file))); - break; - } + fileName = Str_Text(AbstractFile_Path(DFile_File_Const(file))); + // Firstly try the expected format given the file name. hdlr = findHandlerFromFileName(fileName); if(hdlr) { @@ -1481,10 +1470,11 @@ uint8_t* GL_LoadImageFromFile(image_t* img, DFile* file) { // Try each recognisable format instead. /// \todo Order here should be determined by the resource locator. - for(n = 0; handlers[n].name && !img->pixels; ++n) + int i; + for(i = 0; handlers[i].name && !img->pixels; ++i) { - if(&handlers[n] == hdlr) continue; // We already know its not in this format. - handlers[n].loadFunc(img, file); + if(&handlers[i] == hdlr) continue; // We already know its not in this format. + handlers[i].loadFunc(img, file); } } diff --git a/doomsday/engine/portable/src/lumpdirectory.c b/doomsday/engine/portable/src/lumpdirectory.c index 72b05e51f8..bbd548c306 100644 --- a/doomsday/engine/portable/src/lumpdirectory.c +++ b/doomsday/engine/portable/src/lumpdirectory.c @@ -311,6 +311,7 @@ static lumpnum_t LumpDirectory_IndexForName2(lumpdirectory_t* ld, const char* na assert(ld); if(!(!name || !name[0]) && ld->_numRecords != 0) { + PathMap searchPattern; register int idx; // Do we need to rebuild the name hash chains? @@ -327,20 +328,20 @@ static lumpnum_t LumpDirectory_IndexForName2(lumpdirectory_t* ld, const char* na } /// \todo Do not resort to a linear search. - for(idx = ld->_numRecords; idx-- > 0 ; ) + PathMap_Initialize(&searchPattern, name); + for(idx = ld->_numRecords; idx-- > 0; ) { - const LumpInfo* info = F_LumpInfo(ld->_records[idx].fsObject, ld->_records[idx].fsLumpIdx); - if(matchLumpName) - { - if(!strnicmp(name, info->name, LUMPNAME_T_LASTINDEX)) - return idx; - } - else + const lumpdirectory_lumprecord_t* rec = ld->_records + idx; + const LumpInfo* info = F_LumpInfo(rec->fsObject, rec->fsLumpIdx); + PathDirectoryNode* node = F_LumpDirectoryNode(info); + + if(PathDirectoryNode_MatchDirectory(node, 0, &searchPattern, NULL/*no paramaters*/)) { - if(!stricmp(name, Str_Text(&info->path))) - return idx; + // This is the lump we are looking for. + break; } } + PathMap_Destroy(&searchPattern); return idx; } return -1; @@ -364,9 +365,11 @@ int C_DECL LumpDirectory_CompareRecordName(const void* a, const void* b) const LumpInfo* infoB = F_LumpInfo(recordB->fsObject, recordB->fsLumpIdx); int result = strnicmp(infoA->name, infoB->name, LUMPNAME_T_LASTINDEX); if(0 != result) return result; + // Still matched; try the file load order indexes. result = (AbstractFile_LoadOrderIndex(recordA->fsObject) - AbstractFile_LoadOrderIndex(recordB->fsObject)); if(0 != result) return result; + // Still matched (i.e., present in the same package); use the pre-sort indexes. return (recordB->presortIndex > recordA->presortIndex); } @@ -375,17 +378,47 @@ int C_DECL LumpDirectory_CompareRecordPath(const void* a, const void* b) { const lumpdirectory_lumprecord_t* recordA = (const lumpdirectory_lumprecord_t*)a; const lumpdirectory_lumprecord_t* recordB = (const lumpdirectory_lumprecord_t*)b; - const LumpInfo* infoA = F_LumpInfo(recordA->fsObject, recordA->fsLumpIdx); - const LumpInfo* infoB = F_LumpInfo(recordB->fsObject, recordB->fsLumpIdx); - int result = Str_CompareIgnoreCase(&infoA->path, Str_Text(&infoB->path)); + ddstring_t* pathA = F_ComposeLumpPath(recordA->fsObject, recordA->fsLumpIdx); + ddstring_t* pathB = F_ComposeLumpPath(recordB->fsObject, recordB->fsLumpIdx); + int result; + + result = Str_CompareIgnoreCase(pathA, Str_Text(pathB)); + + Str_Delete(pathA); + Str_Delete(pathB); if(0 != result) return result; + // Still matched; try the file load order indexes. result = (AbstractFile_LoadOrderIndex(recordA->fsObject) - AbstractFile_LoadOrderIndex(recordB->fsObject)); if(0 != result) return result; + // Still matched (i.e., present in the same package); use the pre-sort indexes. return (recordB->presortIndex > recordA->presortIndex); } +static int LumpDirectory_CompareRecords(const lumpdirectory_lumprecord_t* recordA, + const lumpdirectory_lumprecord_t* recordB, boolean matchLumpName) +{ + ddstring_t* pathA, *pathB; + int result; + assert(recordA && recordB); + + if(matchLumpName) + { + return strnicmp(F_LumpInfo(recordA->fsObject, recordA->fsLumpIdx)->name, + F_LumpInfo(recordB->fsObject, recordB->fsLumpIdx)->name, LUMPNAME_T_MAXLEN); + } + + pathA = F_ComposeLumpPath(recordA->fsObject, recordA->fsLumpIdx); + pathB = F_ComposeLumpPath(recordB->fsObject, recordB->fsLumpIdx); + + result = Str_CompareIgnoreCase(pathA, Str_Text(pathB)); + + Str_Delete(pathA); + Str_Delete(pathB); + return result; +} + void LumpDirectory_PruneDuplicateRecords(lumpdirectory_t* ld, boolean matchLumpName) { int i, j, sortedNumRecords; @@ -409,10 +442,8 @@ void LumpDirectory_PruneDuplicateRecords(lumpdirectory_t* ld, boolean matchLumpN // Is this entry equal to one or more of the next? j = i; while(j < sortedNumRecords && - (matchLumpName? !strnicmp(F_LumpInfo(ld->_records[j-1].fsObject, ld->_records[j-1].fsLumpIdx)->name, - F_LumpInfo(ld->_records[j ].fsObject, ld->_records[j ].fsLumpIdx)->name, LUMPNAME_T_MAXLEN) : - !Str_CompareIgnoreCase( &F_LumpInfo(ld->_records[j-1].fsObject, ld->_records[j-1].fsLumpIdx)->path, - Str_Text(&F_LumpInfo(ld->_records[j ].fsObject, ld->_records[j ].fsLumpIdx)->path)))) + !LumpDirectory_CompareRecords(ld->_records + (j-1), + ld->_records + (j), matchLumpName)) { ++j; } if(j == i) continue; // No. @@ -456,10 +487,9 @@ void LumpDirectory_Print(lumpdirectory_t* ld) { lumpdirectory_lumprecord_t* rec = ld->_records + i; const LumpInfo* info = F_LumpInfo(rec->fsObject, rec->fsLumpIdx); - printf("%04i - \"%s:(%-8s | %s)\" (size: %lu bytes%s)\n", i, - F_PrettyPath(Str_Text(AbstractFile_Path(rec->fsObject))), - (info->name[0]? info->name : "N/A"), F_PrettyPath(Str_Text(&info->path)), - (unsigned long) info->size, (info->compressedSize != info->size? " compressed" : "")); + printf("%04i - \"%s\" (size: %lu bytes%s)\n", i, + F_PrettyPath(Str_Text(AbstractFile_Path(rec->fsObject))), + (unsigned long) info->size, (info->compressedSize != info->size? " compressed" : "")); } printf("---End of lumps---\n"); } diff --git a/doomsday/engine/portable/src/lumpfile.c b/doomsday/engine/portable/src/lumpfile.c index beb54e56b7..263a19b656 100644 --- a/doomsday/engine/portable/src/lumpfile.c +++ b/doomsday/engine/portable/src/lumpfile.c @@ -29,13 +29,13 @@ #include "lumpdirectory.h" #include "lumpfile.h" -LumpFile* LumpFile_New(DFile* file, const LumpInfo* info) +LumpFile* LumpFile_New(DFile* file, const char* path, const LumpInfo* info) { LumpFile* lump = (LumpFile*)malloc(sizeof *lump); if(!lump) Con_Error("LumpFile::Construct: Failed on allocation of %lu bytes for new LumpFile.", (unsigned long) sizeof *lump); - AbstractFile_Init((abstractfile_t*)lump, FT_LUMPFILE, file, info); + AbstractFile_Init((abstractfile_t*)lump, FT_LUMPFILE, path, file, info); lump->_cacheData = NULL; return lump; } @@ -57,6 +57,13 @@ int LumpFile_PublishLumpsToDirectory(LumpFile* lump, lumpdirectory_t* directory) return 1; } +ddstring_t* LumpFile_ComposeLumpPath(LumpFile* lump, int lumpIdx, char delimiter) +{ + const LumpInfo* info = AbstractFile_Info((abstractfile_t*)lump); + // Our container knows our path. + return F_ComposeLumpPath2(info->container, info->lumpIdx, delimiter); +} + const LumpInfo* LumpFile_LumpInfo(LumpFile* lump, int lumpIdx) { assert(lump); @@ -80,17 +87,16 @@ void LumpFile_ClearLumpCache(LumpFile* lump) size_t LumpFile_ReadLumpSection2(LumpFile* lump, int lumpIdx, uint8_t* buffer, size_t startOffset, size_t length, boolean tryCache) { - assert(lump); - { const LumpInfo* info = LumpFile_LumpInfo(lump, lumpIdx); size_t readBytes; VERBOSE2( - Con_Printf("LumpFile::ReadLumpSection: \"%s:%s\" (%lu bytes%s) [%lu +%lu]", + Con_Printf("LumpFile::ReadLumpSection: \"%s\" (%lu bytes%s) [%lu +%lu]", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)lump))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path))), (unsigned long) info->size, + (unsigned long) info->size, (info->compressedSize != info->size? ", compressed" : ""), - (unsigned long) startOffset, (unsigned long)length) ) + (unsigned long) startOffset, (unsigned long)length) + ) // Try to avoid a file system read by checking for a cached copy. if(tryCache && lump->_cacheData) @@ -116,7 +122,6 @@ size_t LumpFile_ReadLumpSection2(LumpFile* lump, int lumpIdx, uint8_t* buffer, (unsigned long) readBytes, (unsigned long) length, lumpIdx); } return readBytes; - } } size_t LumpFile_ReadLumpSection(LumpFile* lump, int lumpIdx, uint8_t* buffer, @@ -139,25 +144,23 @@ size_t LumpFile_ReadLump(LumpFile* lump, int lumpIdx, uint8_t* buffer) const uint8_t* LumpFile_CacheLump(LumpFile* lump, int lumpIdx, int tag) { - assert(lump); - { const LumpInfo* info = LumpFile_LumpInfo(lump, lumpIdx); boolean isCached = (NULL != lump->_cacheData); void** cachePtr = (void**)&lump->_cacheData; VERBOSE2( - Con_Printf("LumpFile::CacheLump: \"%s:%s\" (%lu bytes%s) %s\n", + Con_Printf("LumpFile::CacheLump: \"%s\" (%lu bytes%s) %s\n", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)lump))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path))), (unsigned long) info->size, (info->compressedSize != info->size? ", compressed" : ""), - isCached? "hit":"miss") ) + isCached? "hit":"miss") + ) if(!isCached) { uint8_t* ptr; - assert(NULL != info); + assert(info); ptr = (uint8_t*)Z_Malloc(info->size, tag, cachePtr); - if(NULL == ptr) + if(!ptr) Con_Error("LumpFile::CacheLump: Failed on allocation of %lu bytes for " "cache copy of lump #%i.", (unsigned long) info->size, lumpIdx); LumpFile_ReadLump2(lump, lumpIdx, ptr, false); @@ -168,26 +171,23 @@ const uint8_t* LumpFile_CacheLump(LumpFile* lump, int lumpIdx, int tag) } return (uint8_t*)(*cachePtr); - } } void LumpFile_ChangeLumpCacheTag(LumpFile* lump, int lumpIdx, int tag) { - assert(lump); - { boolean isCached = (NULL != lump->_cacheData); void** cachePtr = (void**)&lump->_cacheData; + if(isCached) { VERBOSE2( const LumpInfo* info = LumpFile_LumpInfo(lump, lumpIdx); - Con_Printf("LumpFile::ChangeLumpCacheTag: \"%s:%s\" tag=%i\n", - F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)lump))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path))), tag) ) + Con_Printf("LumpFile::ChangeLumpCacheTag: \"%s\" tag=%i\n", + F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)lump))), tag) + ) Z_ChangeTag2(*cachePtr, tag); } - } } int LumpFile_LumpCount(LumpFile* lump) diff --git a/doomsday/engine/portable/src/r_data.c b/doomsday/engine/portable/src/r_data.c index d6b90d1e4b..96f3c18945 100644 --- a/doomsday/engine/portable/src/r_data.c +++ b/doomsday/engine/portable/src/r_data.c @@ -1804,14 +1804,13 @@ static patchcompositetex_t** loadPatchCompositeDefs(int* numDefs) numLumps = F_LumpCount(); for(i = 0; i < numLumps; ++i) { - const LumpInfo* info; + const char* lumpName; // Will this be processed anyway? if(i == firstTexLump || i == secondTexLump) continue; - info = F_FindInfoForLumpNum(i); - assert(info); - if(strnicmp(info->name, "TEXTURE1", 8) && strnicmp(info->name, "TEXTURE2", 8)) continue; + lumpName = F_LumpName(i); + if(strnicmp(lumpName, "TEXTURE1", 8) && strnicmp(lumpName, "TEXTURE2", 8)) continue; defLumps = (lumpnum_t*)realloc(defLumps, sizeof *defLumps * ++defLumpsSize); if(!defLumps) @@ -2063,7 +2062,6 @@ void R_InitPatchComposites(void) static texture_t* createFlatForLump(lumpnum_t lumpNum, int uniqueId) { - const LumpInfo* info = F_FindInfoForLumpNum(lumpNum); Uri* uri, *resourcePath; textureid_t texId; texture_t* tex; @@ -2072,11 +2070,11 @@ static texture_t* createFlatForLump(lumpnum_t lumpNum, int uniqueId) int flags; // We can only perform some basic filtering of lumps at this time. - if(!info || info->size == 0) return NULL; + if(F_LumpLength(lumpNum) == 0) return NULL; // Compose the resource name. uri = Uri_NewWithPath2(TN_FLATS_NAME":", RC_NULL); - Uri_SetPath(uri, info->name); + Uri_SetPath(uri, F_LumpName(lumpNum)); // Compose the path to the data resource. // Note that we do not use the lump name and instead use the logical lump index @@ -2156,20 +2154,19 @@ void R_InitFlatTextures(void) numLumps = F_LumpCount(); for(i = 0; i < numLumps; ++i) { - const LumpInfo* info = F_FindInfoForLumpNum(i); - assert(info); + const char* lumpName = F_LumpName(i); - if(info->name[0] == 'F') + if(lumpName[0] == 'F') { - if(!strnicmp(info->name + 1, "_START", 6) || - !strnicmp(info->name + 2, "_START", 6)) + if(!strnicmp(lumpName + 1, "_START", 6) || + !strnicmp(lumpName + 2, "_START", 6)) { // We've arrived at *a* sprite block. Stack_Push(stack, NULL); continue; } - else if(!strnicmp(info->name + 1, "_END", 4) || - !strnicmp(info->name + 2, "_END", 4)) + else if(!strnicmp(lumpName + 1, "_END", 4) || + !strnicmp(lumpName + 2, "_END", 4)) { // The sprite block ends. Stack_Pop(stack); @@ -2226,23 +2223,23 @@ void R_InitSpriteTextures(void) /// \fixme Load order here does not respect id tech1 logic. for(i = 0; i < numLumps; ++i) { - const LumpInfo* info = F_FindInfoForLumpNum((lumpnum_t)i); + const char* lumpName = F_LumpName((lumpnum_t)i); patchtex_t* pTex; textureid_t texId; texture_t* tex; int flags; - if(info->name[0] == 'S') + if(lumpName[0] == 'S') { - if(!strnicmp(info->name + 1, "_START", 6) || - !strnicmp(info->name + 2, "_START", 6)) + if(!strnicmp(lumpName + 1, "_START", 6) || + !strnicmp(lumpName + 2, "_START", 6)) { // We've arrived at *a* sprite block. Stack_Push(stack, NULL); continue; } - else if(!strnicmp(info->name + 1, "_END", 4) || - !strnicmp(info->name + 2, "_END", 4)) + else if(!strnicmp(lumpName + 1, "_END", 4) || + !strnicmp(lumpName + 2, "_END", 4)) { // The sprite block ends. Stack_Pop(stack); @@ -2251,13 +2248,13 @@ void R_InitSpriteTextures(void) } if(!Stack_Height(stack)) continue; - if(!validSpriteName(info->name)) continue; + if(!validSpriteName(lumpName)) continue; // Compose the resource name. - Uri_SetPath(uri, info->name); + Uri_SetPath(uri, lumpName); // Compose the data resource path. - Uri_SetPath(resourcePath, info->name); + Uri_SetPath(resourcePath, lumpName); texId = Textures_Declare(uri, uniqueId, resourcePath); if(texId == NOTEXTUREID) continue; // Invalid uri? diff --git a/doomsday/engine/portable/src/s_mus.c b/doomsday/engine/portable/src/s_mus.c index 1880800478..a24bab3946 100644 --- a/doomsday/engine/portable/src/s_mus.c +++ b/doomsday/engine/portable/src/s_mus.c @@ -426,9 +426,8 @@ int Mus_StartLump(lumpnum_t lump, boolean looped, boolean canPlayMUS) { // Music interface does not offer buffer playback. // Write this lump to disk and play from there. - fsObject = F_FindFileForLumpNum2(lump, &lumpIdx); srcFile = composeBufferedMusicFilename(currentBufFile ^= 1, 0); - if(!F_DumpLump(fsObject, lumpIdx, Str_Text(srcFile))) + if(!F_DumpLump(lump, Str_Text(srcFile))) { Str_Delete(srcFile); return 0; diff --git a/doomsday/engine/portable/src/wadfile.c b/doomsday/engine/portable/src/wadfile.c index 2522f38067..7d283c8687 100644 --- a/doomsday/engine/portable/src/wadfile.c +++ b/doomsday/engine/portable/src/wadfile.c @@ -104,6 +104,7 @@ static void WadFile_ReadLumpDirectory(WadFile* wad) wadfile_lumprecord_t* record; const wadlumprecord_t* src; PathDirectoryNode* node; + ddstring_t absPath; int i, j; assert(wad); @@ -123,6 +124,8 @@ static void WadFile_ReadLumpDirectory(WadFile* wad) if(!wad->lumpRecords) Con_Error("WadFile::readLumpDirectory: Failed on allocation of %lu bytes for new lump record vector.", (unsigned long) (wad->lumpRecordsCount * sizeof(*wad->lumpRecords))); + Str_Init(&absPath); + src = lumpDir; record = wad->lumpRecords; for(i = 0; i < wad->lumpRecordsCount; ++i, src++, record++) @@ -149,10 +152,9 @@ static void WadFile_ReadLumpDirectory(WadFile* wad) if(!record->info.name[0]) strcpy(record->info.name, "________"); - Str_Init(&record->info.path); Str_Set(&record->info.path, record->info.name); - // Make it absolute. - F_PrependBasePath(&record->info.path, &record->info.path); + Str_Set(&absPath, record->info.name); + F_PrependBasePath(&absPath, &absPath); record->info.size = record->info.compressedSize = (size_t)LONG(src->size); record->info.container = (abstractfile_t*)wad; @@ -165,9 +167,12 @@ static void WadFile_ReadLumpDirectory(WadFile* wad) { wad->lumpDirectory = PathDirectory_NewWithFlags(PDF_ALLOW_DUPLICATE_LEAF); } - node = PathDirectory_Insert(wad->lumpDirectory, Str_Text(&record->info.path), '/'); + node = PathDirectory_Insert(wad->lumpDirectory, Str_Text(&absPath), '/'); PathDirectoryNode_AttachUserData(node, record); } + + Str_Free(&absPath); + // We are finished with the temporary lump records. free(lumpDir); } @@ -206,7 +211,7 @@ static wadfile_lumprecord_t* WadFile_LumpRecord(WadFile* wad, int lumpIdx) return (wadfile_lumprecord_t*)PathDirectoryNode_UserData(wad->lumpDirectoryMap[lumpIdx]); } -WadFile* WadFile_New(DFile* file, const LumpInfo* info) +WadFile* WadFile_New(DFile* file, const char* path, const LumpInfo* info) { WadFile* wad; wadheader_t hdr; @@ -216,13 +221,13 @@ WadFile* WadFile_New(DFile* file, const LumpInfo* info) if(!WadFile_ReadArchiveHeader(file, &hdr)) Con_Error("WadFile::New: File %s does not appear to be of WAD format." - " Missing a call to WadFile::Recognise?", Str_Text(&info->path)); + " Missing a call to WadFile::Recognise?", path); wad = (WadFile*)malloc(sizeof *wad); if(!wad) Con_Error("WadFile::Construct:: Failed on allocation of %lu bytes for new WadFile.", (unsigned long) sizeof *wad); - AbstractFile_Init((abstractfile_t*)wad, FT_WADFILE, file, info); + AbstractFile_Init((abstractfile_t*)wad, FT_WADFILE, path, file, info); wad->lumpRecordsCount = hdr.lumpRecordsCount; wad->lumpRecordsOffset = hdr.lumpRecordsOffset; wad->lumpRecords = NULL; @@ -261,6 +266,16 @@ PathDirectoryNode* WadFile_DirectoryNodeForLump(WadFile* wad, int lumpIdx) return wad->lumpDirectoryMap[lumpIdx]; } +ddstring_t* WadFile_ComposeLumpPath(WadFile* wad, int lumpIdx, char delimiter) +{ + PathDirectoryNode* node = WadFile_DirectoryNodeForLump(wad, lumpIdx); + if(node) + { + return PathDirectory_ComposePath(PathDirectoryNode_Directory(node), node, Str_New(), NULL, delimiter); + } + return Str_New(); +} + const LumpInfo* WadFile_LumpInfo(WadFile* wad, int lumpIdx) { wadfile_lumprecord_t* lumpRecord = WadFile_LumpRecord(wad, lumpIdx); @@ -366,11 +381,15 @@ size_t WadFile_ReadLumpSection2(WadFile* wad, int lumpIdx, uint8_t* buffer, if(!lumpRecord) return 0; VERBOSE2( + ddstring_t* path = WadFile_ComposeLumpPath(wad, lumpIdx, '/'); Con_Printf("WadFile::ReadLumpSection: \"%s:%s\" (%lu bytes%s) [%lu +%lu]", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)wad))), - (lumpRecord->info.name[0]? lumpRecord->info.name : F_PrettyPath(Str_Text(&lumpRecord->info.path))), (unsigned long) lumpRecord->info.size, + F_PrettyPath(Str_Text(path)), + (unsigned long) lumpRecord->info.size, (lumpRecord->info.compressedSize != lumpRecord->info.size? ", compressed" : ""), - (unsigned long) startOffset, (unsigned long)length) ) + (unsigned long) startOffset, (unsigned long)length); + Str_Delete(path) + ) // Try to avoid a file system read by checking for a cached copy. if(tryCache && wad->lumpCache) @@ -437,10 +456,13 @@ const uint8_t* WadFile_CacheLump(WadFile* wad, int lumpIdx, int tag) void** cachePtr; VERBOSE2( + ddstring_t* path = WadFile_ComposeLumpPath(wad, lumpIdx, '/'); Con_Printf("WadFile::CacheLump: \"%s:%s\" (%lu bytes%s)", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)wad))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path))), (unsigned long) info->size, - (info->compressedSize != info->size? ", compressed" : "")) ) + F_PrettyPath(Str_Text(path)), (unsigned long) info->size, + (info->compressedSize != info->size? ", compressed" : "")); + Str_Delete(path) + ) if(WadFile_LumpCount(wad) > 1) { @@ -497,10 +519,12 @@ void WadFile_ChangeLumpCacheTag(WadFile* wad, int lumpIdx, int tag) if(isCached) { VERBOSE2( - const LumpInfo* info = WadFile_LumpInfo(wad, lumpIdx); + ddstring_t* path = WadFile_ComposeLumpPath(wad, lumpIdx, '/'); Con_Printf("WadFile::ChangeLumpCacheTag: \"%s:%s\" tag=%i\n", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)wad))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path))), tag) ) + F_PrettyPath(Str_Text(path)), tag); + Str_Delete(path) + ) Z_ChangeTag2(*cachePtr, tag); } diff --git a/doomsday/engine/portable/src/zipfile.c b/doomsday/engine/portable/src/zipfile.c index 03a8f6709f..1d18e57460 100644 --- a/doomsday/engine/portable/src/zipfile.c +++ b/doomsday/engine/portable/src/zipfile.c @@ -410,10 +410,6 @@ static void ZipFile_ReadLumpDirectory(ZipFile* zip) PathDirectoryNode_AttachUserData(node, record); record->info.lumpIdx = lumpIdx++; - - // Take a copy of the name. - Str_Init(&record->info.path); Str_Set(&record->info.path, Str_Text(&entryPath)); - record->info.size = ULONG(header->size); if(USHORT(header->compression) == ZFC_DEFLATED) { @@ -479,7 +475,7 @@ static zipfile_lumprecord_t* ZipFile_LumpRecord(ZipFile* zip, int lumpIdx) return (zipfile_lumprecord_t*)PathDirectoryNode_UserData(zip->lumpDirectoryMap[lumpIdx]); } -ZipFile* ZipFile_New(DFile* file, const LumpInfo* info) +ZipFile* ZipFile_New(DFile* file, const char* path, const LumpInfo* info) { ZipFile* zip; @@ -489,7 +485,7 @@ ZipFile* ZipFile_New(DFile* file, const LumpInfo* info) if(!zip) Con_Error("ZipFile::New: Failed on allocation of %lu bytes for new ZipFile.", (unsigned long) sizeof *zip); - AbstractFile_Init((abstractfile_t*)zip, FT_ZIPFILE, file, info); + AbstractFile_Init((abstractfile_t*)zip, FT_ZIPFILE, path, file, info); zip->lumpDirectory = NULL; zip->lumpDirectoryMap = NULL; zip->lumpRecords = NULL; @@ -523,6 +519,16 @@ PathDirectoryNode* ZipFile_DirectoryNodeForLump(ZipFile* zip, int lumpIdx) return zip->lumpDirectoryMap[lumpIdx]; } +ddstring_t* ZipFile_ComposeLumpPath(ZipFile* zip, int lumpIdx, char delimiter) +{ + PathDirectoryNode* node = ZipFile_DirectoryNodeForLump(zip, lumpIdx); + if(node) + { + return PathDirectory_ComposePath(PathDirectoryNode_Directory(node), node, Str_New(), NULL, delimiter); + } + return Str_New(); +} + const LumpInfo* ZipFile_LumpInfo(ZipFile* zip, int lumpIdx) { zipfile_lumprecord_t* lumpRecord = ZipFile_LumpRecord(zip, lumpIdx); @@ -671,11 +677,14 @@ size_t ZipFile_ReadLumpSection2(ZipFile* zip, int lumpIdx, uint8_t* buffer, if(!lumpRecord) return 0; VERBOSE2( + ddstring_t* path = ZipFile_ComposeLumpPath(zip, lumpIdx, '/'); Con_Printf("ZipFile::ReadLumpSection: \"%s:%s\" (%lu bytes%s) [%lu +%lu]", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)zip))), - F_PrettyPath(Str_Text(&lumpRecord->info.path)), (unsigned long) lumpRecord->info.size, + F_PrettyPath(Str_Text(path)), (unsigned long) lumpRecord->info.size, (lumpRecord->info.compressedSize != lumpRecord->info.size? ", compressed" : ""), - (unsigned long) startOffset, (unsigned long)length) ) + (unsigned long) startOffset, (unsigned long)length); + Str_Delete(path); + ) // Try to avoid a file system read by checking for a cached copy. if(tryCache && zip->lumpCache) @@ -735,10 +744,13 @@ const uint8_t* ZipFile_CacheLump(ZipFile* zip, int lumpIdx, int tag) void** cachePtr; VERBOSE2( + ddstring_t* path = ZipFile_ComposeLumpPath(zip, lumpIdx, '/'); Con_Printf("ZipFile::CacheLump: \"%s:%s\" (%lu bytes%s)", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)zip))), - F_PrettyPath(Str_Text(&info->path)), (unsigned long) info->size, - (info->compressedSize != info->size? ", compressed" : "")) ) + F_PrettyPath(Str_Text(path)), (unsigned long) info->size, + (info->compressedSize != info->size? ", compressed" : "")); + Str_Delete(path); + ) if(ZipFile_LumpCount(zip) > 1) { @@ -795,10 +807,12 @@ void ZipFile_ChangeLumpCacheTag(ZipFile* zip, int lumpIdx, int tag) if(isCached) { VERBOSE2( - const LumpInfo* info = ZipFile_LumpInfo(zip, lumpIdx); + ddstring_t* path = ZipFile_ComposeLumpPath(zip, lumpIdx, '/'); Con_Printf("ZipFile::ChangeLumpCacheTag: \"%s:%s\" tag=%i\n", F_PrettyPath(Str_Text(AbstractFile_Path((abstractfile_t*)zip))), - (info->name[0]? info->name : F_PrettyPath(Str_Text(&info->path))), tag) ) + F_PrettyPath(Str_Text(path)), tag); + Str_Delete(path); + ) Z_ChangeTag2(*cachePtr, tag); }