mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-26 00:40:56 +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;
|
int Position;
|
||||||
|
|
||||||
virtual int FillCache();
|
int ValidateCache() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -344,11 +344,10 @@ F7ZFile::~F7ZFile()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int F7ZLump::FillCache()
|
int F7ZLump::ValidateCache()
|
||||||
{
|
{
|
||||||
Cache.Resize(LumpSize);
|
Cache.Resize(LumpSize);
|
||||||
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, (char*)Cache.Data());
|
static_cast<F7ZFile*>(Owner)->Archive->Extract(Position, (char*)Cache.Data());
|
||||||
RefCount = 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
struct FDirectoryLump : public FResourceLump
|
struct FDirectoryLump : public FResourceLump
|
||||||
{
|
{
|
||||||
virtual FileReader NewReader();
|
virtual FileReader NewReader();
|
||||||
virtual int FillCache();
|
int ValidateCache() override;
|
||||||
|
|
||||||
FString mFullPath;
|
FString mFullPath;
|
||||||
};
|
};
|
||||||
|
@ -300,7 +300,7 @@ FileReader FDirectoryLump::NewReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FDirectoryLump::FillCache()
|
int FDirectoryLump::ValidateCache()
|
||||||
{
|
{
|
||||||
FileReader fr;
|
FileReader fr;
|
||||||
if (!fr.OpenFile(mFullPath))
|
if (!fr.OpenFile(mFullPath))
|
||||||
|
@ -311,7 +311,6 @@ int FDirectoryLump::FillCache()
|
||||||
LumpSize = fr.GetLength(); // keep this updated
|
LumpSize = fr.GetLength(); // keep this updated
|
||||||
Cache.Resize(LumpSize);
|
Cache.Resize(LumpSize);
|
||||||
fr.Read(Cache.Data(), LumpSize);
|
fr.Read(Cache.Data(), LumpSize);
|
||||||
RefCount = 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,18 +73,9 @@ bool FLumpFile::Open(bool quiet)
|
||||||
Lumps[0].Position = 0;
|
Lumps[0].Position = 0;
|
||||||
Lumps[0].LumpSize = (int)Reader.GetLength();
|
Lumps[0].LumpSize = (int)Reader.GetLength();
|
||||||
Lumps[0].Flags = 0;
|
Lumps[0].Flags = 0;
|
||||||
Lumps[0].FullName = FileName;
|
|
||||||
auto p = FileName.LastIndexOf('/');
|
auto p = FileName.LastIndexOf('/');
|
||||||
Lumps[0].PathLen = FileName.LastIndexOf('/') + 1;
|
Lumps[0].LumpNameSetup(FileName.GetChars() + p);
|
||||||
Lumps[0].ExtStart = FileName.LastIndexOf('.');
|
|
||||||
NumLumps = 1;
|
NumLumps = 1;
|
||||||
if (Lumps[0].ExtStart < Lumps[0].PathLen) Lumps[0].ExtStart = -1;
|
|
||||||
/*
|
|
||||||
if (!quiet)
|
|
||||||
{
|
|
||||||
Printf("\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ struct RFFLump
|
||||||
uint8_t Flags;
|
uint8_t Flags;
|
||||||
char Extension[3];
|
char Extension[3];
|
||||||
char Name[8];
|
char Name[8];
|
||||||
uint32_t IndexNum; // Used by .sfx, possibly others
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -72,11 +71,9 @@ struct RFFLump
|
||||||
struct FRFFLump : public FUncompressedLump
|
struct FRFFLump : public FUncompressedLump
|
||||||
{
|
{
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual int FillCache();
|
int ValidataCache() override;
|
||||||
|
|
||||||
uint32_t IndexNum;
|
uint32_t IndexNum;
|
||||||
|
|
||||||
int GetIndexNum() const { return IndexNum; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -159,7 +156,7 @@ bool FRFFFile::Open(bool quiet)
|
||||||
{
|
{
|
||||||
Lump.Flags |= LUMPF_BLOODCRYPT;
|
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.
|
// Rearrange the name and extension to construct the fullname.
|
||||||
char name[13];
|
char name[13];
|
||||||
strncpy(name, lumps[i].Name, 8);
|
strncpy(name, lumps[i].Name, 8);
|
||||||
|
@ -172,14 +169,6 @@ bool FRFFFile::Open(bool quiet)
|
||||||
name[len+3] = lumps[i].Extension[2];
|
name[len+3] = lumps[i].Extension[2];
|
||||||
name[len+4] = 0;
|
name[len+4] = 0;
|
||||||
Lump.LumpNameSetup(name);
|
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;
|
delete[] lumps;
|
||||||
return true;
|
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);
|
int cryptlen = std::min<int> (LumpSize, 256);
|
||||||
uint8_t *data = Cache.Data();
|
uint8_t *data = Cache.Data();
|
||||||
|
|
|
@ -356,14 +356,13 @@ FileReader *FZipLump::GetReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FZipLump::FillCache()
|
int FZipLump::ValidataCache()
|
||||||
{
|
{
|
||||||
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
if (Flags & LUMPFZIP_NEEDFILESTART) SetLumpAddress();
|
||||||
|
|
||||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
Cache.Resize(LumpSize);
|
Cache.Resize(LumpSize);
|
||||||
UncompressZipLump((char*)Cache.Data(), Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
|
UncompressZipLump((char*)Cache.Data(), Owner->Reader, Method, LumpSize, CompressedSize, GPFlags);
|
||||||
RefCount = 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct FZipLump : public FResourceLump
|
||||||
unsigned CRC32;
|
unsigned CRC32;
|
||||||
|
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual int FillCache();
|
virtual int ValidateCache() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetLumpAddress();
|
void SetLumpAddress();
|
||||||
|
@ -50,4 +50,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
#include "name.h"
|
||||||
//#include "c_dispatch.h"
|
//#include "c_dispatch.h"
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "superfasthash.h"
|
#include "superfasthash.h"
|
||||||
|
@ -120,15 +121,12 @@ int FileSystem::InitMultipleFiles (TArray<FString> &filenames, const TArray<FStr
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Set up hash table
|
// [RH] Set up hash table
|
||||||
Hashes.Resize(8 * NumEntries);
|
Hashes.Resize(NumLookupModes * 2 * NumEntries);
|
||||||
FirstFileIndex_BaseName = &Hashes[0];
|
for (int i = 0; i < NumLookupModes; i++)
|
||||||
NextFileIndex_BaseName = &Hashes[NumEntries];
|
{
|
||||||
FirstFileIndex_FullName = &Hashes[NumEntries*2];
|
FirstFileIndex[i] = &Hashes[i * 2 * NumEntries];
|
||||||
NextFileIndex_FullName = &Hashes[NumEntries*3];
|
NextFileIndex[i] = &Hashes[(i+1) * 2 * NumEntries];
|
||||||
FirstFileIndex_NoExt = &Hashes[NumEntries*4];
|
}
|
||||||
NextFileIndex_NoExt = &Hashes[NumEntries*5];
|
|
||||||
FirstFileIndex_BaseExt = &Hashes[NumEntries*6];
|
|
||||||
NextFileIndex_BaseExt = &Hashes[NumEntries*7];
|
|
||||||
InitHashChains ();
|
InitHashChains ();
|
||||||
FileInfo.ShrinkToFit();
|
FileInfo.ShrinkToFit();
|
||||||
Files.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.
|
// Returns true if the specified file is loaded, false otherwise.
|
||||||
// If a fully-qualified path is specified, then the wad must match exactly.
|
// If a fully-qualified path is specified, then the file must match exactly.
|
||||||
// Otherwise, any wad with that name will work, whatever its path.
|
// Otherwise, any file with that name will work, whatever its path.
|
||||||
// Returns the wads index if found, or -1 if not.
|
// 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
|
// Looks up a file by name, either eith or without path and extension
|
||||||
// These don't care about namespaces though because those are part
|
|
||||||
// of the path.
|
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
@ -253,62 +249,28 @@ int FileSystem::FindFile (const char *name, ELookupMode lookupmode, int filenum)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint32_t* fli;
|
FName lname(name, true);
|
||||||
uint32_t* nli;
|
if (lname == NAME_None) return -1;
|
||||||
|
|
||||||
switch (lookupmode)
|
if (lookupmode == ELookupMode::IdWithType) return -1;
|
||||||
{
|
int lookupindex = (int)lookupmode;
|
||||||
case ELookupMode::FullName:
|
uint32_t* fli = FirstFileIndex[lookupindex];
|
||||||
fli = FirstFileIndex_FullName;
|
uint32_t* nli = NextFileIndex[lookupindex];
|
||||||
nli = NextFileIndex_FullName;
|
|
||||||
break;
|
for (i = fli[int(lname) % NumEntries]; i != NULL_INDEX; i = nli[i])
|
||||||
|
|
||||||
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 (filenum > 0 && FileInfo[i].rfnum != filenum) continue;
|
||||||
auto lump = FileInfo[i].lump;
|
auto lump = FileInfo[i].lump;
|
||||||
if (FileInfo[i].rfnum != filenum) continue;
|
if (lump->LumpName[lookupindex] == lname) return i;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
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.
|
// 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.
|
// Prepares the lumpinfos for hashing.
|
||||||
// (Hey! This looks suspiciously like something from Boom! :-)
|
// (Hey! This looks suspiciously like something from Boom! :-)
|
||||||
|
@ -388,68 +404,26 @@ int FileSystem::GetFileFlags (int lump)
|
||||||
|
|
||||||
void FileSystem::InitHashChains (void)
|
void FileSystem::InitHashChains (void)
|
||||||
{
|
{
|
||||||
char name[8];
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
// Mark all buckets as empty
|
// Mark all buckets as empty
|
||||||
memset(FirstFileIndex_BaseExt, 255, NumEntries * sizeof(FirstFileIndex_BaseExt[0]));
|
memset(Hashes.Data(), 255, Hashes.Size() * sizeof(Hashes[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]));
|
|
||||||
|
|
||||||
// Now set up the chains
|
// 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 lump = FileInfo[i].lump;
|
||||||
auto& Name = lump->FullName;
|
for (int l = 0; l < NumLookupModes; l++)
|
||||||
if (Name.IsNotEmpty())
|
|
||||||
{
|
{
|
||||||
j = MakeKey(Name) % NumEntries;
|
int hash;
|
||||||
NextFileIndex_FullName[i] = FirstFileIndex_FullName[j];
|
if (l != (int)ELookupMode::IdWithType && lump->LumpName[l] != NAME_None)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
j = MakeKey(Name, lump->ExtStart) % NumEntries;
|
hash = int(lump->LumpName[l]) % 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;
|
|
||||||
}
|
}
|
||||||
else
|
else if (lump->ResourceId > 0)
|
||||||
{
|
{
|
||||||
NextFileIndex_NoExt[i] = NextFileIndex_FullName[i];
|
hash = int(lump->ResourceId) % NumEntries;
|
||||||
FirstFileIndex_NoExt[i] = FirstFileIndex_FullName[i];
|
|
||||||
|
|
||||||
NextFileIndex_BaseName[i] = NextFileIndex_BaseExt[i];
|
|
||||||
FirstFileIndex_BaseName[j] = FirstFileIndex_BaseExt[i];
|
|
||||||
}
|
}
|
||||||
|
NextFileIndex[l][hash] = FirstFileIndex[l][hash];
|
||||||
FString nameNoExt = Name;
|
FirstFileIndex[l][hash] = i;
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,36 +440,26 @@ void FileSystem::InitHashChains (void)
|
||||||
|
|
||||||
int FileSystem::Iterate (const char *name, int *lastlump, ELookupMode lookupmode)
|
int FileSystem::Iterate (const char *name, int *lastlump, ELookupMode lookupmode)
|
||||||
{
|
{
|
||||||
union
|
|
||||||
{
|
|
||||||
char name8[8];
|
|
||||||
uint64_t qname;
|
|
||||||
};
|
|
||||||
FileRecord *lump_p;
|
FileRecord *lump_p;
|
||||||
|
|
||||||
|
int lookupindex = static_cast<int>(lookupmode);
|
||||||
|
FName lname(name, true);
|
||||||
assert(lastlump != NULL && *lastlump >= 0);
|
assert(lastlump != NULL && *lastlump >= 0);
|
||||||
|
if (lname == NAME_None)
|
||||||
|
{
|
||||||
|
*lastlump = NumEntries;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
lump_p = &FileInfo[*lastlump];
|
lump_p = &FileInfo[*lastlump];
|
||||||
auto len = strlen(name);
|
|
||||||
while (lump_p < &FileInfo[NumEntries])
|
while (lump_p < &FileInfo[NumEntries])
|
||||||
{
|
{
|
||||||
auto lump = lump_p->lump;
|
auto lump = lump_p->lump;
|
||||||
const char* fn = lump->FullName.GetChars();
|
if (lump->LumpName[lookupindex] == lname)
|
||||||
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))
|
int lump = int(lump_p - &FileInfo[0]);
|
||||||
{
|
*lastlump = lump + 1;
|
||||||
int lump = int(lump_p - &FileInfo[0]);
|
return lump;
|
||||||
*lastlump = lump + 1;
|
|
||||||
return lump;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
lump_p++;
|
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)
|
if ((size_t)lump >= NumEntries)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else
|
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.
|
// 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
|
// 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
|
// 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)
|
if ((size_t)lump >= NumEntries)
|
||||||
return 0;
|
return -1;
|
||||||
else
|
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();
|
result.Clear();
|
||||||
for (unsigned i = 0; i < FileInfo.Size(); i++)
|
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.
|
// 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.
|
// 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)
|
TArray<uint8_t> FileSystem::GetFileData(int lump, int pad)
|
||||||
{
|
{
|
||||||
|
if ((size_t)lump >= FileInfo.Size())
|
||||||
|
return TArray<<uint8_t>();
|
||||||
|
|
||||||
auto lumpr = OpenFileReader(lump);
|
auto lumpr = OpenFileReader(lump);
|
||||||
auto size = lumpr.GetLength();
|
auto size = lumpr.GetLength();
|
||||||
TArray<uint8_t> data(size + pad, true);
|
TArray<uint8_t> data(size + pad, true);
|
||||||
|
@ -655,6 +622,33 @@ TArray<uint8_t> FileSystem::GetFileData(int lump, int pad)
|
||||||
return data;
|
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
|
// ReadFile - variant 2
|
||||||
|
@ -723,7 +717,7 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// GetFileRecordGetResourceFileName
|
// GetResourceFileName
|
||||||
//
|
//
|
||||||
// Returns the name of the given wad.
|
// 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
|
// Returns the name of the given wad, including any path
|
||||||
//
|
//
|
||||||
|
|
|
@ -49,14 +49,22 @@ struct FolderEntry
|
||||||
unsigned lumpnum;
|
unsigned lumpnum;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ELookupMode
|
enum class ELookupMode // Todo: Merge with FResourceLump::ENameType
|
||||||
{
|
{
|
||||||
FullName = 0,
|
FullName,
|
||||||
NoExtension = 1,
|
NoExtension,
|
||||||
BaseName = 2,
|
BaseName,
|
||||||
BaseWithExtension = 3
|
BaseWithExtension,
|
||||||
|
IdWithType,
|
||||||
|
NumLookupModes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NumLookupModes = (int)ELookupMode::NumLookupModes + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class FileSystem
|
class FileSystem
|
||||||
{
|
{
|
||||||
public:
|
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 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 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!)
|
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 (int file);
|
||||||
FileData ReadFile (const char *name) { return ReadFile (GetFile (name)); }
|
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 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.
|
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;
|
unsigned GetFilesInFolder(const char *path, TArray<FolderEntry> &result, bool atomic) const;
|
||||||
|
|
||||||
bool IsEncryptedFile(int file) const noexcept;
|
bool IsEncryptedFile(int file) const noexcept;
|
||||||
|
int GetResourceId(int file) const;
|
||||||
|
|
||||||
int GetNumResourceFiles() const { return NumFiles; }
|
int GetNumResourceFiles() const { return NumFiles; }
|
||||||
int GetNumEntries () const { return NumEntries; }
|
int GetNumEntries () const { return NumEntries; }
|
||||||
|
@ -117,17 +134,8 @@ protected:
|
||||||
TArray<FileRecord> FileInfo;
|
TArray<FileRecord> FileInfo;
|
||||||
|
|
||||||
TArray<uint32_t> Hashes; // one allocation for all hash lists.
|
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 *FirstFileIndex[NumLookupModes]; // Hash information for the base name (no path and no extension)
|
||||||
uint32_t *NextFileIndex_BaseName;
|
uint32_t *NextFileIndex[NumLookupModes];
|
||||||
|
|
||||||
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 NumFiles = 0; // Not necessarily the same as FileInfo.Size()
|
uint32_t NumFiles = 0; // Not necessarily the same as FileInfo.Size()
|
||||||
uint32_t NumEntries;
|
uint32_t NumEntries;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "resourcefile.h"
|
#include "resourcefile.h"
|
||||||
|
#include "name.h"
|
||||||
|
|
||||||
extern FString LumpFilter;
|
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)
|
void FResourceLump::LumpNameSetup(FString iname)
|
||||||
{
|
{
|
||||||
PathLen = iname.LastIndexOf('/') + 1;
|
auto pathLen = iname.LastIndexOf('/') + 1;
|
||||||
ExtStart = iname.LastIndexOf('.');
|
LumpName[FullNameType] = iname.GetChars();
|
||||||
if (ExtStart <= PathLen) ExtStart = -1;
|
LumpName[BaseNameType] = iname.GetChars() + pathLen;
|
||||||
FullName = iname;
|
|
||||||
|
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 FResourceLump::GetRawData()
|
||||||
{
|
{
|
||||||
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)LumpSize, METHOD_STORED, 0, 0, new char[LumpSize] };
|
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);
|
cbuf.mCRC32 = crc32(0, (uint8_t*)cbuf.mBuffer, LumpSize);
|
||||||
ReleaseCache();
|
Unlock(true);
|
||||||
return cbuf;
|
return cbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +146,7 @@ FileReader FResourceLump::NewReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void *FResourceLump::CacheLump()
|
void *FResourceLump::Lock()
|
||||||
{
|
{
|
||||||
if (Cache.Size())
|
if (Cache.Size())
|
||||||
{
|
{
|
||||||
|
@ -143,7 +154,23 @@ void *FResourceLump::CacheLump()
|
||||||
}
|
}
|
||||||
else if (LumpSize > 0)
|
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();
|
return Cache.Data();
|
||||||
}
|
}
|
||||||
|
@ -154,13 +181,13 @@ void *FResourceLump::CacheLump()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FResourceLump::ReleaseCache()
|
int FResourceLump::Unlock(bool mayfree)
|
||||||
{
|
{
|
||||||
if (LumpSize > 0 && RefCount > 0)
|
if (LumpSize > 0 && RefCount > 0)
|
||||||
{
|
{
|
||||||
if (--RefCount == 0)
|
if (--RefCount == 0)
|
||||||
{
|
{
|
||||||
Cache.Reset();
|
if (mayfree) Cache.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return RefCount;
|
return RefCount;
|
||||||
|
@ -246,8 +273,7 @@ int lumpcmp(const void * a, const void * b)
|
||||||
{
|
{
|
||||||
FResourceLump * rec1 = (FResourceLump *)a;
|
FResourceLump * rec1 = (FResourceLump *)a;
|
||||||
FResourceLump * rec2 = (FResourceLump *)b;
|
FResourceLump * rec2 = (FResourceLump *)b;
|
||||||
|
return stricmp(rec1->LumpName[FResourceLump::FullNameType].GetChars(), rec2->LumpName[FResourceLump::FullNameType].GetChars());
|
||||||
return rec1->FullName.CompareNoCase(rec2->FullName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -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)
|
for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize)
|
||||||
{
|
{
|
||||||
FResourceLump *lump = (FResourceLump *)lump_p;
|
FResourceLump *lump = (FResourceLump *)lump_p;
|
||||||
assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0);
|
assert(filter.CompareNoCase(lump->FullName(), (int)filter.Len()) == 0);
|
||||||
lump->LumpNameSetup(lump->FullName.Mid(filter.Len()));
|
lump->LumpNameSetup(lump->FullName() + filter.Len());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move filtered lumps to the end of the lump list.
|
// 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)
|
for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize)
|
||||||
{
|
{
|
||||||
FResourceLump *lump = (FResourceLump *)p;
|
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;
|
mid = min + (max - min) / 2;
|
||||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
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)
|
if (cmp == 0)
|
||||||
break;
|
break;
|
||||||
else if (cmp < 0)
|
else if (cmp > 0)
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
else
|
else
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
|
@ -423,7 +451,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
{
|
{
|
||||||
mid = min + (max - min) / 2;
|
mid = min + (max - min) / 2;
|
||||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
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.
|
// Go left on matches and right on misses.
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
|
@ -438,7 +466,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
{
|
{
|
||||||
mid = min + (max - min) / 2;
|
mid = min + (max - min) / 2;
|
||||||
lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize);
|
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.
|
// Go right on matches and left on misses.
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
|
@ -457,10 +485,12 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize
|
||||||
|
|
||||||
FResourceLump *FResourceFile::FindLump(const char *name)
|
FResourceLump *FResourceFile::FindLump(const char *name)
|
||||||
{
|
{
|
||||||
|
FName lname(name, true);
|
||||||
|
if (lname == NAME_None) return nullptr;
|
||||||
for (unsigned i = 0; i < NumLumps; i++)
|
for (unsigned i = 0; i < NumLumps; i++)
|
||||||
{
|
{
|
||||||
FResourceLump *lump = GetLump(i);
|
FResourceLump *lump = GetLump(i);
|
||||||
if (!stricmp(name, lump->FullName))
|
if (lump->LumpName[FResourceLump::FullNameType] == lname)
|
||||||
{
|
{
|
||||||
return lump;
|
return lump;
|
||||||
}
|
}
|
||||||
|
@ -486,12 +516,11 @@ FileReader *FUncompressedLump::GetReader()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FUncompressedLump::FillCache()
|
int FUncompressedLump::ValidateCache()
|
||||||
{
|
{
|
||||||
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
Owner->Reader.Seek(Position, FileReader::SeekSet);
|
||||||
Cache.Resize(LumpSize);
|
Cache.Resize(LumpSize);
|
||||||
Owner->Reader.Read(Cache.Data(), LumpSize);
|
Owner->Reader.Read(Cache.Data(), LumpSize);
|
||||||
RefCount = 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +575,7 @@ FExternalLump::FExternalLump(const char *_filename, int filesize)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int FExternalLump::FillCache()
|
int FExternalLump::ValidateCache()
|
||||||
{
|
{
|
||||||
Cache.Resize(LumpSize);
|
Cache.Resize(LumpSize);
|
||||||
FileReader f;
|
FileReader f;
|
||||||
|
@ -559,6 +588,5 @@ int FExternalLump::FillCache()
|
||||||
{
|
{
|
||||||
memset(Cache.Data(), 0, LumpSize);
|
memset(Cache.Data(), 0, LumpSize);
|
||||||
}
|
}
|
||||||
RefCount = 1;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,26 @@ struct FCompressedBuffer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FResourceLump
|
struct FResourceLump
|
||||||
{
|
{
|
||||||
|
enum ENameType
|
||||||
|
{
|
||||||
|
FullNameType,
|
||||||
|
FullNameNoExtType,
|
||||||
|
BaseNameType,
|
||||||
|
BaseNameNoExtType,
|
||||||
|
ExtensionType,
|
||||||
|
NUMNAMETYPES
|
||||||
|
};
|
||||||
|
|
||||||
friend class FResourceFile;
|
friend class FResourceFile;
|
||||||
|
|
||||||
unsigned LumpSize = 0;
|
unsigned LumpSize = 0;
|
||||||
int RefCount = 0;
|
int RefCount = 0;
|
||||||
int Flags = 0;
|
int Flags = 0;
|
||||||
int PathLen = 0;
|
|
||||||
int ExtStart = -1;
|
|
||||||
int ResourceId = -1;
|
int ResourceId = -1;
|
||||||
FString FullName; // Name with extension and path
|
FName LumpName[NUMNAMETYPES] = {};
|
||||||
FResourceFile * Owner = nullptr;
|
FResourceFile * Owner = nullptr;
|
||||||
TArray<uint8_t> Cache;
|
TArray<uint8_t> Cache;
|
||||||
|
|
||||||
|
@ -62,20 +71,22 @@ struct FResourceLump
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual FileReader NewReader();
|
virtual FileReader NewReader();
|
||||||
virtual int GetFileOffset() { return -1; }
|
virtual int GetFileOffset() { return -1; }
|
||||||
virtual int GetIndexNum() const { return 0; }
|
|
||||||
void LumpNameSetup(FString iname);
|
void LumpNameSetup(FString iname);
|
||||||
virtual FCompressedBuffer GetRawData();
|
virtual FCompressedBuffer GetRawData();
|
||||||
|
|
||||||
void *CacheLump();
|
void *Lock(); // validates the cache and increases the refcount.
|
||||||
int ReleaseCache();
|
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; }
|
unsigned Size() const{ return LumpSize; }
|
||||||
int LockCount() const { return RefCount; }
|
int LockCount() const { return RefCount; }
|
||||||
FString BaseName(); // don't know if these will be needed
|
const char *ResName() const { return LumpName[BaseNameNoExtType]; } needed
|
||||||
FString Type();
|
const char *ResType() { return LumpName[ExtensionType]; }
|
||||||
|
const char *FullName() const { return LumpName[FullNameType]; } needed
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int FillCache() { return -1; }
|
virtual int ValidateCache() { return -1; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,7 +138,7 @@ struct FUncompressedLump : public FResourceLump
|
||||||
int Position;
|
int Position;
|
||||||
|
|
||||||
virtual FileReader *GetReader();
|
virtual FileReader *GetReader();
|
||||||
virtual int FillCache();
|
int ValidateCache() override;
|
||||||
virtual int GetFileOffset() { return Position; }
|
virtual int GetFileOffset() { return Position; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -150,7 +161,7 @@ struct FExternalLump : public FResourceLump
|
||||||
FString Filename;
|
FString Filename;
|
||||||
|
|
||||||
FExternalLump(const char *_filename, int filesize = -1);
|
FExternalLump(const char *_filename, int filesize = -1);
|
||||||
virtual int FillCache();
|
virtual int ValidateCache() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue