mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-11 18:50:46 +00:00
- rework of the file system code.
Made more efficient by basing the lookup on names, not strings and some additions for acting as a stand-in for Blood's resource manager.
This commit is contained in:
parent
693095bffb
commit
261af9e401
10 changed files with 260 additions and 242 deletions
|
@ -171,7 +171,7 @@ struct F7ZLump : public FResourceLump
|
|||
{
|
||||
int Position;
|
||||
|
||||
virtual int FillCache();
|
||||
int ValidateCache() override;
|
||||
|
||||
};
|
||||
|
||||
|
@ -344,11 +344,10 @@ F7ZFile::~F7ZFile()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int F7ZLump::FillCache()
|
||||
int F7ZLump::ValidateCache()
|
||||
{
|
||||
Cache.Resize(LumpSize);
|
||||
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, (char*)Cache.Data());
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
struct FDirectoryLump : public FResourceLump
|
||||
{
|
||||
virtual FileReader NewReader();
|
||||
virtual int FillCache();
|
||||
int ValidateCache() override;
|
||||
|
||||
FString mFullPath;
|
||||
};
|
||||
|
@ -300,7 +300,7 @@ FileReader FDirectoryLump::NewReader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FDirectoryLump::FillCache()
|
||||
int FDirectoryLump::ValidateCache()
|
||||
{
|
||||
FileReader fr;
|
||||
if (!fr.OpenFile(mFullPath))
|
||||
|
@ -311,7 +311,6 @@ int FDirectoryLump::FillCache()
|
|||
LumpSize = fr.GetLength(); // keep this updated
|
||||
Cache.Resize(LumpSize);
|
||||
fr.Read(Cache.Data(), LumpSize);
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,18 +73,9 @@ bool FLumpFile::Open(bool quiet)
|
|||
Lumps[0].Position = 0;
|
||||
Lumps[0].LumpSize = (int)Reader.GetLength();
|
||||
Lumps[0].Flags = 0;
|
||||
Lumps[0].FullName = FileName;
|
||||
auto p = FileName.LastIndexOf('/');
|
||||
Lumps[0].PathLen = FileName.LastIndexOf('/') + 1;
|
||||
Lumps[0].ExtStart = FileName.LastIndexOf('.');
|
||||
Lumps[0].LumpNameSetup(FileName.GetChars() + p);
|
||||
NumLumps = 1;
|
||||
if (Lumps[0].ExtStart < Lumps[0].PathLen) Lumps[0].ExtStart = -1;
|
||||
/*
|
||||
if (!quiet)
|
||||
{
|
||||
Printf("\n");
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ struct RFFLump
|
|||
uint8_t Flags;
|
||||
char Extension[3];
|
||||
char Name[8];
|
||||
uint32_t IndexNum; // Used by .sfx, possibly others
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -72,11 +71,9 @@ struct RFFLump
|
|||
struct FRFFLump : public FUncompressedLump
|
||||
{
|
||||
virtual FileReader *GetReader();
|
||||
virtual int FillCache();
|
||||
int ValidataCache() override;
|
||||
|
||||
uint32_t IndexNum;
|
||||
|
||||
int GetIndexNum() const { return IndexNum; }
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -159,7 +156,7 @@ bool FRFFFile::Open(bool quiet)
|
|||
{
|
||||
Lump.Flags |= LUMPF_BLOODCRYPT;
|
||||
}
|
||||
Lump.IndexNum = LittleLong(lumps[i].IndexNum);
|
||||
Lump.ResourceId = LittleLong(lumps[i].ResourceId);
|
||||
// Rearrange the name and extension to construct the fullname.
|
||||
char name[13];
|
||||
strncpy(name, lumps[i].Name, 8);
|
||||
|
@ -172,14 +169,6 @@ bool FRFFFile::Open(bool quiet)
|
|||
name[len+3] = lumps[i].Extension[2];
|
||||
name[len+4] = 0;
|
||||
Lump.LumpNameSetup(name);
|
||||
if (Lump.IndexNum > 0)
|
||||
{
|
||||
// Create a second entry for looking up by index.
|
||||
Lumps.Reserve(1);
|
||||
auto& l = Lumps.Last();
|
||||
l = Lumps[Lumps.Size() - 2];
|
||||
snprintf(name, 13, "{%d}.%c%c%c", l.IndexNum, lumps[i].Extension[0], lumps[i].Extension[1], lumps[i].Extension[2]);
|
||||
}
|
||||
}
|
||||
delete[] lumps;
|
||||
return true;
|
||||
|
@ -212,11 +201,11 @@ FileReader *FRFFLump::GetReader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FRFFLump::FillCache()
|
||||
int FRFFLump::ValidateCache()
|
||||
{
|
||||
int res = FUncompressedLump::FillCache();
|
||||
int res = FUncompressedLump::ValidateCache();
|
||||
|
||||
if (Flags & LUMPF_BLOODCRYPT)
|
||||
if (res && )(Flags & LUMPF_BLOODCRYPT))
|
||||
{
|
||||
int cryptlen = std::min<int> (LumpSize, 256);
|
||||
uint8_t *data = Cache.Data();
|
||||
|
|
|
@ -356,14 +356,13 @@ FileReader *FZipLump::GetReader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FZipLump::FillCache()
|
||||
int FZipLump::ValidataCache()
|
||||
{
|
||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
||||
|
||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||
Cache.Resize(LumpSize);
|
||||
UncompressZipLump((char*)Cache.Data(), Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ struct FZipLump : public FResourceLump
|
|||
unsigned CRC32;
|
||||
|
||||
virtual FileReader *GetReader();
|
||||
virtual int FillCache();
|
||||
virtual int ValidateCache() override;
|
||||
|
||||
private:
|
||||
void SetLumpAddress();
|
||||
|
@ -50,4 +50,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "m_argv.h"
|
||||
#include "cmdlib.h"
|
||||
#include "printf.h"
|
||||
#include "name.h"
|
||||
//#include "c_dispatch.h"
|
||||
#include "filesystem.h"
|
||||
#include "superfasthash.h"
|
||||
|
@ -120,15 +121,12 @@ int FileSystem::InitMultipleFiles (TArray<FString> &filenames, const TArray<FStr
|
|||
}
|
||||
|
||||
// [RH] Set up hash table
|
||||
Hashes.Resize(8 * NumEntries);
|
||||
FirstFileIndex_BaseName = &Hashes[0];
|
||||
NextFileIndex_BaseName = &Hashes[NumEntries];
|
||||
FirstFileIndex_FullName = &Hashes[NumEntries*2];
|
||||
NextFileIndex_FullName = &Hashes[NumEntries*3];
|
||||
FirstFileIndex_NoExt = &Hashes[NumEntries*4];
|
||||
NextFileIndex_NoExt = &Hashes[NumEntries*5];
|
||||
FirstFileIndex_BaseExt = &Hashes[NumEntries*6];
|
||||
NextFileIndex_BaseExt = &Hashes[NumEntries*7];
|
||||
Hashes.Resize(NumLookupModes * 2 * NumEntries);
|
||||
for (int i = 0; i < NumLookupModes; i++)
|
||||
{
|
||||
FirstFileIndex[i] = &Hashes[i * 2 * NumEntries];
|
||||
NextFileIndex[i] = &Hashes[(i+1) * 2 * NumEntries];
|
||||
}
|
||||
InitHashChains ();
|
||||
FileInfo.ShrinkToFit();
|
||||
Files.ShrinkToFit();
|
||||
|
@ -199,12 +197,12 @@ void FileSystem::AddFile (const char *filename, FileReader *filer)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordCheckIfWadLoaded
|
||||
// CheckIfResourceFileLoaded
|
||||
//
|
||||
// Returns true if the specified wad is loaded, false otherwise.
|
||||
// If a fully-qualified path is specified, then the wad must match exactly.
|
||||
// Otherwise, any wad with that name will work, whatever its path.
|
||||
// Returns the wads index if found, or -1 if not.
|
||||
// Returns true if the specified file is loaded, false otherwise.
|
||||
// If a fully-qualified path is specified, then the file must match exactly.
|
||||
// Otherwise, any file with that name will work, whatever its path.
|
||||
// Returns the file's index if found, or -1 if not.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -237,11 +235,9 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordFindFile
|
||||
// FindFile
|
||||
//
|
||||
// Same as above but looks for a fully qualified name from a .zip
|
||||
// These don't care about namespaces though because those are part
|
||||
// of the path.
|
||||
// Looks up a file by name, either eith or without path and extension
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -253,62 +249,28 @@ int FileSystem::FindFile (const char *name, ELookupMode lookupmode, int filenum)
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
uint32_t* fli;
|
||||
uint32_t* nli;
|
||||
FName lname(name, true);
|
||||
if (lname == NAME_None) return -1;
|
||||
|
||||
switch (lookupmode)
|
||||
{
|
||||
case ELookupMode::FullName:
|
||||
fli = FirstFileIndex_FullName;
|
||||
nli = NextFileIndex_FullName;
|
||||
break;
|
||||
|
||||
case ELookupMode::NoExtension:
|
||||
fli = FirstFileIndex_NoExt;
|
||||
nli = NextFileIndex_NoExt;
|
||||
break;
|
||||
|
||||
case ELookupMode::BaseName:
|
||||
fli = FirstFileIndex_BaseName;
|
||||
nli = NextFileIndex_BaseName;
|
||||
break;
|
||||
|
||||
case ELookupMode::BaseWithExtension:
|
||||
fli = FirstFileIndex_BaseExt;
|
||||
nli = NextFileIndex_BaseExt;
|
||||
break;
|
||||
|
||||
}
|
||||
auto len = strlen(name);
|
||||
|
||||
for (i = fli[MakeKey(name) % NumEntries]; i != NULL_INDEX; i = nli[i])
|
||||
if (lookupmode == ELookupMode::IdWithType) return -1;
|
||||
int lookupindex = (int)lookupmode;
|
||||
uint32_t* fli = FirstFileIndex[lookupindex];
|
||||
uint32_t* nli = NextFileIndex[lookupindex];
|
||||
|
||||
for (i = fli[int(lname) % NumEntries]; i != NULL_INDEX; i = nli[i])
|
||||
{
|
||||
if (filenum > 0 && FileInfo[i].rfnum != filenum) continue;
|
||||
auto lump = FileInfo[i].lump;
|
||||
if (FileInfo[i].rfnum != filenum) continue;
|
||||
const char* fn = lump->FullName.GetChars();
|
||||
const char* fnstart, * fnend;
|
||||
if (lookupmode == ELookupMode::BaseName || lookupmode == ELookupMode::BaseWithExtension) fnstart = fn + lump->PathLen;
|
||||
else fnstart = fn;
|
||||
|
||||
if ((lookupmode == ELookupMode::NoExtension || lookupmode == ELookupMode::BaseName) && lump->ExtStart >= 0) fnend = fn + lump->ExtStart;
|
||||
else fnend = fn + lump->FullName.Len();
|
||||
|
||||
if ((fnend - fnstart) == (ptrdiff_t)len)
|
||||
{
|
||||
if (!strnicmp(name, fnstart, len))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (lump->LumpName[lookupindex] == lname) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordGetFile
|
||||
// GetFile
|
||||
//
|
||||
// Calls GetFileRecordFindFile, but bombs out if not found.
|
||||
// Calls FindFile, but bombs out if not found.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -328,7 +290,61 @@ int FileSystem::GetFile (const char *name, ELookupMode lookupmode, int filenum)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordLumpLength
|
||||
// FindResource
|
||||
//
|
||||
// Looks for content based on Blood resource IDs.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FileSystem::FindResource (int resid, const char *type, int filenum) const noexcept
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (type == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
FName lname(type, true);
|
||||
if (lname == NAME_None) return -1;
|
||||
|
||||
const int lookuptype = (int)ELookupMode::IdWithType
|
||||
uint32_t* fli = FirstFileIndex[lookuptype];
|
||||
uint32_t* nli = NextFileIndex[lookuptype];
|
||||
|
||||
for (i = fli[int(resid) % NumEntries]; i != NULL_INDEX; i = nli[i])
|
||||
{
|
||||
if (filenum > 0 && FileInfo[i].rfnum != filenum) continue;
|
||||
auto lump = FileInfo[i].lump;
|
||||
if (lump->LumpName[lookuptype] == lname) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetResource
|
||||
//
|
||||
// Calls GetResource, but bombs out if not found.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FileSystem::GetResource (int resid, const char *type, int filenum) const
|
||||
{
|
||||
int i;
|
||||
|
||||
i = FindResource (resid, type, lookupmode, filenum);
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
FStringf error("GetResource: %d of type %s not found!", resid, type);
|
||||
throw FileSystemError(error.GetChars());
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// LumpLength
|
||||
//
|
||||
// Returns the buffer size needed to load the given lump.
|
||||
//
|
||||
|
@ -379,7 +395,7 @@ int FileSystem::GetFileFlags (int lump)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordInitHashChains
|
||||
// InitHashChains
|
||||
//
|
||||
// Prepares the lumpinfos for hashing.
|
||||
// (Hey! This looks suspiciously like something from Boom! :-)
|
||||
|
@ -388,68 +404,26 @@ int FileSystem::GetFileFlags (int lump)
|
|||
|
||||
void FileSystem::InitHashChains (void)
|
||||
{
|
||||
char name[8];
|
||||
unsigned int i, j;
|
||||
|
||||
// Mark all buckets as empty
|
||||
memset(FirstFileIndex_BaseExt, 255, NumEntries * sizeof(FirstFileIndex_BaseExt[0]));
|
||||
memset(NextFileIndex_BaseExt, 255, NumEntries * sizeof(NextFileIndex_BaseExt[0]));
|
||||
memset (FirstFileIndex_BaseName, 255, NumEntries*sizeof(FirstFileIndex_BaseName[0]));
|
||||
memset (NextFileIndex_BaseName, 255, NumEntries*sizeof(NextFileIndex_BaseName[0]));
|
||||
memset (FirstFileIndex_FullName, 255, NumEntries*sizeof(FirstFileIndex_FullName[0]));
|
||||
memset (NextFileIndex_FullName, 255, NumEntries*sizeof(NextFileIndex_FullName[0]));
|
||||
memset(FirstFileIndex_NoExt, 255, NumEntries * sizeof(FirstFileIndex_NoExt[0]));
|
||||
memset(NextFileIndex_NoExt, 255, NumEntries * sizeof(NextFileIndex_NoExt[0]));
|
||||
memset(Hashes.Data(), 255, Hashes.Size() * sizeof(Hashes[0]));
|
||||
|
||||
// Now set up the chains
|
||||
for (i = 0; i < (unsigned)NumEntries; i++)
|
||||
for (int i = 0; i < (unsigned)NumEntries; i++)
|
||||
{
|
||||
|
||||
// Do the same for the full paths
|
||||
auto lump = FileInfo[i].lump;
|
||||
auto& Name = lump->FullName;
|
||||
if (Name.IsNotEmpty())
|
||||
for (int l = 0; l < NumLookupModes; l++)
|
||||
{
|
||||
j = MakeKey(Name) % NumEntries;
|
||||
NextFileIndex_FullName[i] = FirstFileIndex_FullName[j];
|
||||
FirstFileIndex_FullName[j] = i;
|
||||
|
||||
j = MakeKey(Name + lump->PathLen) % NumEntries;
|
||||
NextFileIndex_BaseExt[i] = FirstFileIndex_BaseExt[j];
|
||||
FirstFileIndex_BaseExt[j] = i;
|
||||
|
||||
j = MakeKey(Name, lump->ExtStart) % NumEntries;
|
||||
NextFileIndex_NoExt[i] = FirstFileIndex_NoExt[j];
|
||||
FirstFileIndex_NoExt[j] = i;
|
||||
|
||||
if (lump->ExtStart > lump->PathLen)
|
||||
int hash;
|
||||
if (l != (int)ELookupMode::IdWithType && lump->LumpName[l] != NAME_None)
|
||||
{
|
||||
j = MakeKey(Name, lump->ExtStart) % NumEntries;
|
||||
NextFileIndex_NoExt[i] = FirstFileIndex_NoExt[j];
|
||||
FirstFileIndex_NoExt[j] = i;
|
||||
|
||||
j = MakeKey(Name + lump->PathLen, lump->ExtStart - lump->PathLen) % NumEntries;
|
||||
NextFileIndex_BaseName[i] = FirstFileIndex_BaseName[j];
|
||||
FirstFileIndex_BaseName[j] = i;
|
||||
hash = int(lump->LumpName[l]) % NumEntries;
|
||||
}
|
||||
else
|
||||
else if (lump->ResourceId > 0)
|
||||
{
|
||||
NextFileIndex_NoExt[i] = NextFileIndex_FullName[i];
|
||||
FirstFileIndex_NoExt[i] = FirstFileIndex_FullName[i];
|
||||
|
||||
NextFileIndex_BaseName[i] = NextFileIndex_BaseExt[i];
|
||||
FirstFileIndex_BaseName[j] = FirstFileIndex_BaseExt[i];
|
||||
hash = int(lump->ResourceId) % NumEntries;
|
||||
}
|
||||
|
||||
FString nameNoExt = Name;
|
||||
auto dot = nameNoExt.LastIndexOf('.');
|
||||
auto slash = nameNoExt.LastIndexOf('/');
|
||||
if (dot > slash) nameNoExt.Truncate(dot);
|
||||
|
||||
j = MakeKey(nameNoExt) % NumEntries;
|
||||
NextFileIndex_NoExt[i] = FirstFileIndex_NoExt[j];
|
||||
FirstFileIndex_NoExt[j] = i;
|
||||
|
||||
NextFileIndex[l][hash] = FirstFileIndex[l][hash];
|
||||
FirstFileIndex[l][hash] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,36 +440,26 @@ void FileSystem::InitHashChains (void)
|
|||
|
||||
int FileSystem::Iterate (const char *name, int *lastlump, ELookupMode lookupmode)
|
||||
{
|
||||
union
|
||||
{
|
||||
char name8[8];
|
||||
uint64_t qname;
|
||||
};
|
||||
FileRecord *lump_p;
|
||||
|
||||
|
||||
int lookupindex = static_cast<int>(lookupmode);
|
||||
FName lname(name, true);
|
||||
assert(lastlump != NULL && *lastlump >= 0);
|
||||
if (lname == NAME_None)
|
||||
{
|
||||
*lastlump = NumEntries;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lump_p = &FileInfo[*lastlump];
|
||||
auto len = strlen(name);
|
||||
while (lump_p < &FileInfo[NumEntries])
|
||||
{
|
||||
auto lump = lump_p->lump;
|
||||
const char* fn = lump->FullName.GetChars();
|
||||
const char* fnstart, * fnend;
|
||||
if (lookupmode == ELookupMode::BaseName || lookupmode == ELookupMode::BaseWithExtension) fnstart = fn + lump->PathLen;
|
||||
else fnstart = fn;
|
||||
|
||||
if ((lookupmode == ELookupMode::NoExtension || lookupmode == ELookupMode::BaseName) && lump->ExtStart >= 0) fnend = fn + lump->ExtStart;
|
||||
else fnend = fn + lump->FullName.Len();
|
||||
|
||||
if ((fnend - fnstart) == (ptrdiff_t)len)
|
||||
if (lump->LumpName[lookupindex] == lname)
|
||||
{
|
||||
if (!strnicmp(name, fnstart, len))
|
||||
{
|
||||
int lump = int(lump_p - &FileInfo[0]);
|
||||
*lastlump = lump + 1;
|
||||
return lump;
|
||||
}
|
||||
int lump = int(lump_p - &FileInfo[0]);
|
||||
*lastlump = lump + 1;
|
||||
return lump;
|
||||
}
|
||||
lump_p++;
|
||||
}
|
||||
|
@ -505,7 +469,7 @@ int FileSystem::Iterate (const char *name, int *lastlump, ELookupMode lookupmode
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordGetLumpName
|
||||
// GetLumpName
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -514,12 +478,12 @@ const char *FileSystem::GetFileName (int lump) const
|
|||
if ((size_t)lump >= NumEntries)
|
||||
return nullptr;
|
||||
else
|
||||
return FileInfo[lump].lump->FullName;
|
||||
return FileInfo[lump].lump->FullName();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FileSystem :: GetLumpFullPath
|
||||
// FileSystem :: GetFilrFullPath
|
||||
//
|
||||
// Returns the name of the lump's wad prefixed to the lump's full name.
|
||||
//
|
||||
|
@ -542,21 +506,21 @@ FString FileSystem::GetFileFullPath(int lump) const
|
|||
//
|
||||
// Returns the index number for this lump. This is *not* the lump's position
|
||||
// in the lump directory, but rather a special value that RFF can associate
|
||||
// with files. Other archive types will return 0, since they don't have it.
|
||||
// with files. Other archive types will return -1, since they don't have it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FileSystem::GetRFFIndexNum(int lump) const
|
||||
int FileSystem::GetResourceId(int lump) const
|
||||
{
|
||||
if ((size_t)lump >= NumEntries)
|
||||
return 0;
|
||||
return -1;
|
||||
else
|
||||
return FileInfo[lump].lump->GetIndexNum();
|
||||
return FileInfo[lump].lump->ResourceId;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordGetLumpFile
|
||||
// GetLumpFile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -599,12 +563,12 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray<FolderEntry> &r
|
|||
result.Clear();
|
||||
for (unsigned i = 0; i < FileInfo.Size(); i++)
|
||||
{
|
||||
if (FileInfo[i].lump->FullName.IndexOf(path) == 0)
|
||||
if (!strncmp(FileInfo[i].lump->FullName(), path, path.Len()))
|
||||
{
|
||||
// Only if it hasn't been replaced.
|
||||
if ((unsigned)FindFile(FileInfo[i].lump->FullName) == i)
|
||||
if ((unsigned)FindFile(FileInfo[i].lump->FullName()) == i)
|
||||
{
|
||||
result.Push({ FileInfo[i].lump->FullName.GetChars(), i });
|
||||
result.Push({ FileInfo[i].lump->FullName(), i });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -633,7 +597,7 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray<FolderEntry> &r
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordReadFile
|
||||
// ReadFile
|
||||
//
|
||||
// Loads the lump into a TArray and returns it.
|
||||
//
|
||||
|
@ -641,6 +605,9 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray<FolderEntry> &r
|
|||
|
||||
TArray<uint8_t> FileSystem::GetFileData(int lump, int pad)
|
||||
{
|
||||
if ((size_t)lump >= FileInfo.Size())
|
||||
return TArray<<uint8_t>();
|
||||
|
||||
auto lumpr = OpenFileReader(lump);
|
||||
auto size = lumpr.GetLength();
|
||||
TArray<uint8_t> data(size + pad, true);
|
||||
|
@ -655,6 +622,33 @@ TArray<uint8_t> FileSystem::GetFileData(int lump, int pad)
|
|||
return data;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Interface to the lump cache
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const void *FileSystem::Lock(int lump)
|
||||
{
|
||||
if ((size_t)lump >= FileInfo.Size()) return nullptr;
|
||||
auto lump = FileInfo[lump].lump;
|
||||
return lump->Lock();
|
||||
}
|
||||
|
||||
void FileSystem::Unlock(bool mayfree)
|
||||
{
|
||||
if ((size_t)lump >= FileInfo.Size()) return;
|
||||
auto lump = FileInfo[lump].lump;
|
||||
lump->Unlock(maxfree);
|
||||
}
|
||||
|
||||
const void *FileSystem::Get(int lump)
|
||||
{
|
||||
if ((size_t)lump >= FileInfo.Size()) return nullptr;
|
||||
auto lump = FileInfo[lump].lump;
|
||||
return lump->Get();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ReadFile - variant 2
|
||||
|
@ -723,7 +717,7 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordGetResourceFileName
|
||||
// GetResourceFileName
|
||||
//
|
||||
// Returns the name of the given wad.
|
||||
//
|
||||
|
@ -791,7 +785,7 @@ int FileSystem::GetEntryCount (int rfnum) const noexcept
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFileRecordGetResourceFileFullName
|
||||
// GetResourceFileFullName
|
||||
//
|
||||
// Returns the name of the given wad, including any path
|
||||
//
|
||||
|
|
|
@ -49,14 +49,22 @@ struct FolderEntry
|
|||
unsigned lumpnum;
|
||||
};
|
||||
|
||||
enum class ELookupMode
|
||||
enum class ELookupMode // Todo: Merge with FResourceLump::ENameType
|
||||
{
|
||||
FullName = 0,
|
||||
NoExtension = 1,
|
||||
BaseName = 2,
|
||||
BaseWithExtension = 3
|
||||
FullName,
|
||||
NoExtension,
|
||||
BaseName,
|
||||
BaseWithExtension,
|
||||
IdWithType,
|
||||
NumLookupModes
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NumLookupModes = (int)ELookupMode::NumLookupModes + 1
|
||||
};
|
||||
|
||||
|
||||
class FileSystem
|
||||
{
|
||||
public:
|
||||
|
@ -83,9 +91,17 @@ public:
|
|||
int FindFile (const std::string &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept { return FindFile(name.c_str(), lookupmode, filenum); }
|
||||
int GetFile (const std::string &name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const { return GetFile(name.c_str(), lookupmode, filenum); }
|
||||
|
||||
int FindResource (int resid, const char *type, int filenum = -1) const noexcept;
|
||||
int GetResource (int resid, const char *type, int filenum = -1) const; // Like FindFile, but throws an exception when it cannot find what it looks for.
|
||||
|
||||
|
||||
TArray<uint8_t> GetFileData(int file, int pad = 0); // reads file into a writable buffer and optionally adds some padding at the end. (FileData isn't writable!)
|
||||
FileData ReadFile (int file);
|
||||
FileData ReadFile (const char *name) { return ReadFile (GetFile (name)); }
|
||||
|
||||
const void *Lock(int lump);
|
||||
void Unlock(bool mayfree = false);
|
||||
void *Get(int lump);
|
||||
|
||||
FileReader OpenFileReader(int file); // opens a reader that redirects to the containing file's one.
|
||||
FileReader ReopenFileReader(int file, bool alwayscache = false); // opens an independent reader.
|
||||
|
@ -105,6 +121,7 @@ public:
|
|||
unsigned GetFilesInFolder(const char *path, TArray<FolderEntry> &result, bool atomic) const;
|
||||
|
||||
bool IsEncryptedFile(int file) const noexcept;
|
||||
int GetResourceId(int file) const;
|
||||
|
||||
int GetNumResourceFiles() const { return NumFiles; }
|
||||
int GetNumEntries () const { return NumEntries; }
|
||||
|
@ -117,17 +134,8 @@ protected:
|
|||
TArray<FileRecord> FileInfo;
|
||||
|
||||
TArray<uint32_t> Hashes; // one allocation for all hash lists.
|
||||
uint32_t *FirstFileIndex_BaseName; // Hash information for the base name (no path and no extension)
|
||||
uint32_t *NextFileIndex_BaseName;
|
||||
|
||||
uint32_t* FirstFileIndex_BaseExt; // Hash information for the base name (no path and no extension)
|
||||
uint32_t* NextFileIndex_BaseExt;
|
||||
|
||||
uint32_t *FirstFileIndex_FullName; // The same information for fully qualified paths
|
||||
uint32_t *NextFileIndex_FullName;
|
||||
|
||||
uint32_t *FirstFileIndex_NoExt; // The same information for fully qualified paths but without the extension
|
||||
uint32_t *NextFileIndex_NoExt;
|
||||
uint32_t *FirstFileIndex[NumLookupModes]; // Hash information for the base name (no path and no extension)
|
||||
uint32_t *NextFileIndex[NumLookupModes];
|
||||
|
||||
uint32_t NumFiles = 0; // Not necessarily the same as FileInfo.Size()
|
||||
uint32_t NumEntries;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <zlib.h>
|
||||
#include "resourcefile.h"
|
||||
#include "name.h"
|
||||
|
||||
extern FString LumpFilter;
|
||||
|
||||
|
@ -78,16 +79,26 @@ FResourceLump::~FResourceLump()
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the lump name information for anything not coming from a WAD file.
|
||||
// Sets up the file name information
|
||||
// This is stored as FNames for various formats.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FResourceLump::LumpNameSetup(FString iname)
|
||||
{
|
||||
PathLen = iname.LastIndexOf('/') + 1;
|
||||
ExtStart = iname.LastIndexOf('.');
|
||||
if (ExtStart <= PathLen) ExtStart = -1;
|
||||
FullName = iname;
|
||||
auto pathLen = iname.LastIndexOf('/') + 1;
|
||||
LumpName[FullNameType] = iname.GetChars();
|
||||
LumpName[BaseNameType] = iname.GetChars() + pathLen;
|
||||
|
||||
auto extStart = iname.LastIndexOf('.');
|
||||
if (extStart <= pathLen) extStart = -1;
|
||||
if (extStart > 0)
|
||||
{
|
||||
LumpName[ExtensionType] = iname.GetChars() + extStart + 1;
|
||||
iname.Truncate(extStart);
|
||||
}
|
||||
LumpName[FullNameNoExtType] = iname.GetChars();
|
||||
LumpName[BaseNameNoExtType] = iname.GetChars() + pathLen;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -100,9 +111,9 @@ void FResourceLump::LumpNameSetup(FString iname)
|
|||
FCompressedBuffer FResourceLump::GetRawData()
|
||||
{
|
||||
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)LumpSize, METHOD_STORED, 0, 0, new char[LumpSize] };
|
||||
memcpy(cbuf.mBuffer, CacheLump(), LumpSize);
|
||||
memcpy(cbuf.mBuffer, Lock(), LumpSize);
|
||||
cbuf.mCRC32 = crc32(0, (uint8_t*)cbuf.mBuffer, LumpSize);
|
||||
ReleaseCache();
|
||||
Unlock(true);
|
||||
return cbuf;
|
||||
}
|
||||
|
||||
|
@ -135,7 +146,7 @@ FileReader FResourceLump::NewReader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void *FResourceLump::CacheLump()
|
||||
void *FResourceLump::Lock()
|
||||
{
|
||||
if (Cache.Size())
|
||||
{
|
||||
|
@ -143,7 +154,23 @@ void *FResourceLump::CacheLump()
|
|||
}
|
||||
else if (LumpSize > 0)
|
||||
{
|
||||
FillCache();
|
||||
ValidateCache()
|
||||
RefCount++;
|
||||
}
|
||||
return Cache.Data();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Caches a lump's content without increasing the reference counter
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void *FResourceLump::Get()
|
||||
{
|
||||
if (Cache.Size() == 0)
|
||||
{
|
||||
ValidateCache()
|
||||
}
|
||||
return Cache.Data();
|
||||
}
|
||||
|
@ -154,13 +181,13 @@ void *FResourceLump::CacheLump()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FResourceLump::ReleaseCache()
|
||||
int FResourceLump::Unlock(bool mayfree)
|
||||
{
|
||||
if (LumpSize > 0 && RefCount > 0)
|
||||
{
|
||||
if (--RefCount == 0)
|
||||
{
|
||||
Cache.Reset();
|
||||
if (mayfree) Cache.Reset();
|
||||
}
|
||||
}
|
||||
return RefCount;
|
||||
|
@ -246,8 +273,7 @@ int lumpcmp(const void * a, const void * b)
|
|||
{
|
||||
FResourceLump * rec1 = (FResourceLump *)a;
|
||||
FResourceLump * rec2 = (FResourceLump *)b;
|
||||
|
||||
return rec1->FullName.CompareNoCase(rec2->FullName);
|
||||
return stricmp(rec1->LumpName[FResourceLump::FullNameType].GetChars(), rec2->LumpName[FResourceLump::FullNameType].GetChars());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -323,8 +349,8 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize,
|
|||
for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize)
|
||||
{
|
||||
FResourceLump *lump = (FResourceLump *)lump_p;
|
||||
assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0);
|
||||
lump->LumpNameSetup(lump->FullName.Mid(filter.Len()));
|
||||
assert(filter.CompareNoCase(lump->FullName(), (int)filter.Len()) == 0);
|
||||
lump->LumpNameSetup(lump->FullName() + filter.Len());
|
||||
}
|
||||
|
||||
// Move filtered lumps to the end of the lump list.
|
||||
|
@ -370,7 +396,8 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m
|
|||
for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize)
|
||||
{
|
||||
FResourceLump *lump = (FResourceLump *)p;
|
||||
lump->FullName = "";
|
||||
for (auto &ln : lump->LumpName)
|
||||
ln = NAME_None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,10 +430,11 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
|||
{
|
||||
mid = min + (max - min) / 2;
|
||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
||||
cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len());
|
||||
cmp = filter.CompareNoCase(lump->FullName(), (int)filter.Len());
|
||||
|
||||
if (cmp == 0)
|
||||
break;
|
||||
else if (cmp < 0)
|
||||
else if (cmp > 0)
|
||||
min = mid + 1;
|
||||
else
|
||||
max = mid - 1;
|
||||
|
@ -423,7 +451,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
|||
{
|
||||
mid = min + (max - min) / 2;
|
||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
||||
cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len());
|
||||
cmp = filter.CompareNoCase(lump->FullName(), (int)filter.Len());
|
||||
// Go left on matches and right on misses.
|
||||
if (cmp == 0)
|
||||
max = mid - 1;
|
||||
|
@ -438,7 +466,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
|||
{
|
||||
mid = min + (max - min) / 2;
|
||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
||||
cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len());
|
||||
cmp = filter.CompareNoCase(lump->FullName(), (int)filter.Len());
|
||||
// Go right on matches and left on misses.
|
||||
if (cmp == 0)
|
||||
min = mid + 1;
|
||||
|
@ -457,10 +485,12 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
|||
|
||||
FResourceLump *FResourceFile::FindLump(const char *name)
|
||||
{
|
||||
FName lname(name, true);
|
||||
if (lname == NAME_None) return nullptr;
|
||||
for (unsigned i = 0; i < NumLumps; i++)
|
||||
{
|
||||
FResourceLump *lump = GetLump(i);
|
||||
if (!stricmp(name, lump->FullName))
|
||||
if (lump->LumpName[FResourceLump::FullNameType] == lname)
|
||||
{
|
||||
return lump;
|
||||
}
|
||||
|
@ -486,12 +516,11 @@ FileReader *FUncompressedLump::GetReader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FUncompressedLump::FillCache()
|
||||
int FUncompressedLump::ValidateCache()
|
||||
{
|
||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||
Cache.Resize(LumpSize);
|
||||
Owner->Reader.Read(Cache.Data(), LumpSize);
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -546,7 +575,7 @@ FExternalLump::FExternalLump(const char *_filename, int filesize)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FExternalLump::FillCache()
|
||||
int FExternalLump::ValidateCache()
|
||||
{
|
||||
Cache.Resize(LumpSize);
|
||||
FileReader f;
|
||||
|
@ -559,6 +588,5 @@ int FExternalLump::FillCache()
|
|||
{
|
||||
memset(Cache.Data(), 0, LumpSize);
|
||||
}
|
||||
RefCount = 1;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -42,17 +42,26 @@ struct FCompressedBuffer
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct FResourceLump
|
||||
{
|
||||
enum ENameType
|
||||
{
|
||||
FullNameType,
|
||||
FullNameNoExtType,
|
||||
BaseNameType,
|
||||
BaseNameNoExtType,
|
||||
ExtensionType,
|
||||
NUMNAMETYPES
|
||||
};
|
||||
|
||||
friend class FResourceFile;
|
||||
|
||||
unsigned LumpSize = 0;
|
||||
int RefCount = 0;
|
||||
int Flags = 0;
|
||||
int PathLen = 0;
|
||||
int ExtStart = -1;
|
||||
int ResourceId = -1;
|
||||
FString FullName; // Name with extension and path
|
||||
FName LumpName[NUMNAMETYPES] = {};
|
||||
FResourceFile * Owner = nullptr;
|
||||
TArray<uint8_t> Cache;
|
||||
|
||||
|
@ -62,20 +71,22 @@ struct FResourceLump
|
|||
virtual FileReader *GetReader();
|
||||
virtual FileReader NewReader();
|
||||
virtual int GetFileOffset() { return -1; }
|
||||
virtual int GetIndexNum() const { return 0; }
|
||||
void LumpNameSetup(FString iname);
|
||||
virtual FCompressedBuffer GetRawData();
|
||||
|
||||
void *CacheLump();
|
||||
int ReleaseCache();
|
||||
void *Lock(); // validates the cache and increases the refcount.
|
||||
void Unlock(bool freeunrefd = false); // recreases the refcount and optionally frees the buffer
|
||||
void *Get(); // validates the cache and returns a pointer without locking
|
||||
|
||||
// Wrappers for emulating Blood's resource system
|
||||
unsigned Size() const{ return LumpSize; }
|
||||
int LockCount() const { return RefCount; }
|
||||
FString BaseName(); // don't know if these will be needed
|
||||
FString Type();
|
||||
const char *ResName() const { return LumpName[BaseNameNoExtType]; } needed
|
||||
const char *ResType() { return LumpName[ExtensionType]; }
|
||||
const char *FullName() const { return LumpName[FullNameType]; } needed
|
||||
|
||||
protected:
|
||||
virtual int FillCache() { return -1; }
|
||||
virtual int ValidateCache() { return -1; }
|
||||
|
||||
};
|
||||
|
||||
|
@ -127,7 +138,7 @@ struct FUncompressedLump : public FResourceLump
|
|||
int Position;
|
||||
|
||||
virtual FileReader *GetReader();
|
||||
virtual int FillCache();
|
||||
int ValidateCache() override;
|
||||
virtual int GetFileOffset() { return Position; }
|
||||
|
||||
};
|
||||
|
@ -150,7 +161,7 @@ struct FExternalLump : public FResourceLump
|
|||
FString Filename;
|
||||
|
||||
FExternalLump(const char *_filename, int filesize = -1);
|
||||
virtual int FillCache();
|
||||
virtual int ValidateCache() override;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue