diff --git a/source/blood/src/barf.cpp b/source/blood/src/barf.cpp index 6308efc42..04a8e9eb3 100644 --- a/source/blood/src/barf.cpp +++ b/source/blood/src/barf.cpp @@ -61,7 +61,7 @@ struct define_t define_t gCmdDefines[kMaxCmdLineDefines]; -void sub_11DF0(char *pzScriptDir, char *fileName, char flags, int ID); +void sub_11DF0(char *fileName, char flags, int ID); void sub_11C10(char *pzScriptDir, char *fileName, char flags, int ID); struct tag_t { @@ -156,7 +156,7 @@ private: char _fileName[BMAX_PATH]; // [30] public: - void Open(const char *fileName); + int Open(const char *fileName); void Close(); void Increment(); void SkipBeyondValue(char value); @@ -166,28 +166,33 @@ public: void UnsetMark(); }; -void RFS::Open(const char *fileName) +int RFS::Open(const char *fileName) { strcpy(_fileName, fileName); - int hFile = open(_fileName, O_BINARY); - if (hFile == -1) { - ThrowError("Error opening file %s", _fileName); + buildvfs_fd hFile = kopen4loadfrommod(fileName, 0); + if (hFile == buildvfs_fd_invalid) { + initprintf("BARF: Error opening file %s", _fileName); + return 1; } int fileSize = kfilelength(hFile); _ptr = (char*)Resource::Alloc(fileSize); if (_ptr == NULL) { - ThrowError("Not enough memory to read %s", _fileName); + initprintf("BARF: Not enough memory to read %s", _fileName); + kclose(hFile); + return 1; } - read(hFile, _ptr, fileSize); - close(hFile); + kread(hFile, _ptr, fileSize); + kclose(hFile); _curLine = 0; _pUnknown2 = _ptr; _curChar = '\n'; _pEnd = &_ptr[fileSize - 1]; + + return 0; } void RFS::Close() @@ -453,7 +458,7 @@ uint8_t RFS::GetNextTag() // qAssert(1==0); // TODO - what to return here } -void ParseScript(char *scriptFileName) +void ParseScript(const char *scriptFileName) { char text[256]; char char256_1[256]; @@ -462,12 +467,19 @@ void ParseScript(char *scriptFileName) char inp[BMAX_PATH]; char zScriptDirectory[BMAX_PATH], zTemp1[BMAX_PATH], zTemp2[BMAX_PATH]; + int const bakpathsearchmode = pathsearchmode; + pathsearchmode = 1; + SplitPath(scriptFileName, zScriptDirectory, zTemp1, zTemp2); RFS rfs; // AddExtension(name, ".RFS"); - rfs.Open(scriptFileName); + if (rfs.Open(scriptFileName)) + { + pathsearchmode = bakpathsearchmode; + return; + } gParseLevel = 0; dword_44CE0[0] = 0; @@ -489,7 +501,7 @@ void ParseScript(char *scriptFileName) } case kTagEnd: { - parsing = true; + parsing = false; break; } case kTagComment: @@ -870,7 +882,7 @@ void ParseScript(char *scriptFileName) else { if (dword_44CE0[gParseLevel] == 0) { - sub_11DF0(zScriptDirectory, fileName, nFlags, ID); + sub_11DF0(fileName, nFlags, ID); } } break; @@ -880,6 +892,7 @@ void ParseScript(char *scriptFileName) //CreateHeader(); rfs.Close(); + pathsearchmode = bakpathsearchmode; } void sub_11C10(char *pzScriptDir, char *fileName, char flags, int ID) @@ -925,33 +938,19 @@ void sub_11C10(char *pzScriptDir, char *fileName, char flags, int ID) } } -void sub_11DF0(char* pzScriptDir, char *filePath, char flags, int ID) +void sub_11DF0(char *filePath, char flags, int ID) { char zDirectory[BMAX_PATH]; char zFilename[BMAX_PATH]; char zType[BMAX_PATH]; - char zFilePath[BMAX_PATH]; buildvfs_fd handle; - ConcatPath(pzScriptDir, filePath, zFilePath); - - handle = kopen4loadfrommod(zFilePath, 0); - if (handle == buildvfs_fd_invalid) - { - Bstrcpy(zFilePath, filePath); - handle = kopen4loadfrommod(zFilePath, 0); - if (handle == buildvfs_fd_invalid) - return; - } - - kclose(handle); - - SplitPath(zFilePath, zDirectory, zFilename, zType); + SplitPath(filePath, zDirectory, zFilename, zType); if (!Bstrcasecmp(zType, "RAW") || !Bstrcasecmp(zType, "SFX") || !Bstrcasecmp(zType, "MID") || !Bstrcasecmp(zType, "TMB")) - gSoundRes.AddExternalResource(zFilename, zType, ID, flags, zFilePath); + gSoundRes.AddFromBuffer(zFilename, zType, buffer, nBytes, ID, flags); else - gSysRes.AddExternalResource(zFilename, zType, ID, flags, zFilePath); + gSysRes.AddFromBuffer(zFilename, zType, buffer, nBytes, ID, flags); } END_BLD_NS diff --git a/source/blood/src/barf.h b/source/blood/src/barf.h index e93bcc7d3..a86744a1c 100644 --- a/source/blood/src/barf.h +++ b/source/blood/src/barf.h @@ -22,3 +22,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //------------------------------------------------------------------------- #pragma once +void ParseScript(const char* scriptFileName); diff --git a/source/blood/src/db.cpp b/source/blood/src/db.cpp index 84baf093d..fd36ecebd 100644 --- a/source/blood/src/db.cpp +++ b/source/blood/src/db.cpp @@ -720,6 +720,10 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short #ifdef USE_OPENGL Polymost_prepare_loadboard(); #endif + + int const bakpathsearchmode = pathsearchmode; + pathsearchmode = 1; + { char name2[BMAX_PATH]; Bstrncpy(name2, pPath, BMAX_PATH); @@ -738,6 +742,9 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short ChangeExtension(name2, ""); pNode = gSysRes.Lookup(name2, "MAP"); } + + pathsearchmode = bakpathsearchmode; + if (!pNode) { initprintf("Error opening map file %s", pPath); diff --git a/source/blood/src/misc.cpp b/source/blood/src/misc.cpp index 40a7bfd01..d494fc415 100644 --- a/source/blood/src/misc.cpp +++ b/source/blood/src/misc.cpp @@ -154,12 +154,12 @@ void ChangeExtension(char *pzFile, const char *pzExt) void SplitPath(const char *pzPath, char *pzDirectory, char *pzFile, char *pzType) { - int const nLength = Bstrlen(pzFile); - const char *pDirectory = pzFile+nLength; + int const nLength = Bstrlen(pzPath); + const char *pDirectory = pzPath+nLength; const char *pDot = NULL; for (int i = nLength-1; i >= 0; i--) { - if (pzFile[i] == '/' || pzFile[i] == '\\') + if (pzPath[i] == '/' || pzPath[i] == '\\') { Bstrncpy(pzDirectory, pzPath, i); pzDirectory[i] = 0; @@ -171,14 +171,15 @@ void SplitPath(const char *pzPath, char *pzDirectory, char *pzFile, char *pzType else { Bstrncpy(pzFile, pzPath+i+1, pDot-(pzPath+i+1)); + pzFile[pDot-(pzPath+i+1)] = 0; Bstrcpy(pzType, pDot+1); } return; } - else if (pzFile[i] == '.') + else if (pzPath[i] == '.') { - pDot = pzFile+i; + pDot = pzPath+i; } } Bstrcpy(pzDirectory, "/"); @@ -190,6 +191,7 @@ void SplitPath(const char *pzPath, char *pzDirectory, char *pzFile, char *pzType else { Bstrncpy(pzFile, pzPath, pDot-pzPath); + pzFile[pDot-pzPath] = 0; Bstrcpy(pzType, pDot+1); } } @@ -208,7 +210,8 @@ void ConcatPath(const char *pzPath1, const char *pzPath2, char *pzConcatPath) } Bstrncpy(pzConcatPath, pzPath1, i); pzConcatPath[i] = 0; - Bstrcpy(pzConcatPath, pzPath2+j); + Bstrcat(pzConcatPath, "/"); + Bstrcat(pzConcatPath, pzPath2+j); } diff --git a/source/blood/src/resource.cpp b/source/blood/src/resource.cpp index f9752af6c..15d920f1a 100644 --- a/source/blood/src/resource.cpp +++ b/source/blood/src/resource.cpp @@ -159,6 +159,7 @@ void Resource::Init(const char *filename) dict[i].type[nTypeLength] = 0; dict[i].name[nNameLength] = 0; dict[i].id = B_LITTLE32(tdict[i].id); + dict[i].buffer = NULL; } Free(tdict); } @@ -433,7 +434,8 @@ void Resource::AddExternalResource(const char *name, const char *type, int id, i strcpy(node->path, path); } node->size = size; - node->flags |= DICT_EXTERNAL | flags; + node->flags = DICT_EXTERNAL | flags; + node->buffer = NULL; Flush(node); if (id >= 0) { @@ -476,7 +478,103 @@ void Resource::AddExternalResource(const char *name, const char *type, int id, i strcpy(node->path, path); node->id = id; node->size = size; - node->flags |= DICT_EXTERNAL | flags; + node->flags = DICT_EXTERNAL | flags; + node->buffer = NULL; + Flush(node); + } +} + +void Resource::AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags) +{ + char name2[BMAX_PATH], type2[BMAX_PATH]; + + char *pHeapData = (char*)Alloc(size); + if (!pHeapData) + return; + Bmemcpy(pHeapData, data, size); + strcpy(name2, name); + strcpy(type2, type); + Bstrupr(name2); + Bstrupr(type2); + dassert(dict != NULL); + DICTNODE **index = Probe(name2, type2); + dassert(index != NULL); + DICTNODE *node = *index; + if (!node) + { + if (2 * count >= buffSize) + { + Grow(); + } + node = &dict[count++]; + index = Probe(name2, type2); + *index = node; + if (node->type) + { + Free(node->type); + node->type = NULL; + } + if (node->name) + { + Free(node->name); + node->name = NULL; + } + if (node->path) + { + Free(node->path); + node->path = NULL; + } + int nTypeLength = strlen(type2); + int nNameLength = strlen(name2); + node->type = (char*)Alloc(nTypeLength+1); + node->name = (char*)Alloc(nNameLength+1); + strcpy(node->type, type2); + strcpy(node->name, name2); + } + node->size = size; + node->flags = DICT_BUFFER | flags; + node->buffer = pHeapData; + Flush(node); + if (id >= 0) + { + index = Probe(id, type2); + dassert(index != NULL); + DICTNODE *node = *index; + if (!node) + { + if (2 * count >= buffSize) + { + Grow(); + } + node = &dict[count++]; + index = Probe(id, type2); + *index = node; + } + if (node->type) + { + Free(node->type); + node->type = NULL; + } + if (node->name) + { + Free(node->name); + node->name = NULL; + } + if (node->path) + { + Free(node->path); + node->path = NULL; + } + int nTypeLength = strlen(type2); + int nNameLength = strlen(name2); + node->type = (char*)Alloc(nTypeLength+1); + node->name = (char*)Alloc(nNameLength+1); + strcpy(node->type, type2); + strcpy(node->name, name2); + node->id = id; + node->size = size; + node->flags = DICT_BUFFER | flags; + node->buffer = pHeapData; Flush(node); } } @@ -590,6 +688,10 @@ void Resource::Read(DICTNODE *n, void *p) } kclose(fhandle); } + else if (n->flags & DICT_BUFFER) + { + Bmemcpy(p, n->buffer, n->size); + } else { int r = klseek(handle, n->offset, SEEK_SET); diff --git a/source/blood/src/resource.h b/source/blood/src/resource.h index 5d2894aaa..23629eedf 100644 --- a/source/blood/src/resource.h +++ b/source/blood/src/resource.h @@ -35,6 +35,7 @@ enum DICTFLAGS { DICT_LOAD = 4, DICT_LOCK = 8, DICT_CRYPT = 16, + DICT_BUFFER = 32, }; struct RFFHeader @@ -79,6 +80,7 @@ struct DICTNODE : CACHENODE char *type; char *name; char *path; + char *buffer; unsigned int id; }; @@ -96,6 +98,7 @@ public: void Reindex(void); void Grow(void); void AddExternalResource(const char *name, const char *type, int id = 0, int flags = 0, const char* pzDirectory = NULL); + void AddFromBuffer(const char* name, const char* type, char *data, int size, int id = 0, int flags = 0); static void *Alloc(int nSize); static void Free(void *p); DICTNODE *Lookup(const char *name, const char *type);