- fixed game resource lookup.

The algorithm was a bit too complicated and missed the smallest defined game resource.
GrpInfo was renamed because there were two of them which created a debugger conflict.
This commit is contained in:
Christoph Oelckers 2021-02-13 10:05:46 +01:00
parent 266dab81cd
commit 5aacb2370d
4 changed files with 24 additions and 56 deletions

View file

@ -42,7 +42,7 @@
//
//==========================================================================
struct GrpInfo
struct GrpHeader
{
uint32_t Magic[3];
uint32_t NumLumps;
@ -95,7 +95,7 @@ FGrpFile::FGrpFile(const char *filename, FileReader &file)
bool FGrpFile::Open(bool quiet, LumpFilterInfo*)
{
GrpInfo header;
GrpHeader header;
Reader.Read(&header, sizeof(header));
NumLumps = LittleLong(header.NumLumps);
@ -105,7 +105,7 @@ bool FGrpFile::Open(bool quiet, LumpFilterInfo*)
Lumps.Resize(NumLumps);
int Position = sizeof(GrpInfo) + NumLumps * sizeof(GrpLump);
int Position = sizeof(GrpHeader) + NumLumps * sizeof(GrpLump);
for(uint32_t i = 0; i < NumLumps; i++)
{

View file

@ -133,7 +133,7 @@ enum
};
struct GrpInfo
struct GrpDefInfo
{
FString name;
FString scriptname;
@ -156,7 +156,7 @@ struct GrpInfo
struct GrpEntry
{
FString FileName;
GrpInfo FileInfo;
GrpDefInfo FileInfo;
uint32_t FileIndex;
};
extern int g_gameType;

View file

@ -378,9 +378,9 @@ void SaveCRCs(TArray<FileEntry>& crclist)
//
//==========================================================================
static TArray<GrpInfo> ParseGrpInfo(const char *fn, FileReader &fr, TMap<FString, uint32_t> &CRCMap)
static TArray<GrpDefInfo> ParseGrpInfo(const char *fn, FileReader &fr, TMap<FString, uint32_t> &CRCMap)
{
TArray<GrpInfo> groups;
TArray<GrpDefInfo> groups;
TMap<FString, int> FlagMap;
FlagMap.Insert("GAMEFLAG_DUKE", GAMEFLAG_DUKE);
@ -580,9 +580,9 @@ static TArray<GrpInfo> ParseGrpInfo(const char *fn, FileReader &fr, TMap<FString
//
//==========================================================================
TArray<GrpInfo> ParseAllGrpInfos(TArray<FileEntry>& filelist)
TArray<GrpDefInfo> ParseAllGrpInfos(TArray<FileEntry>& filelist)
{
TArray<GrpInfo> groups;
TArray<GrpDefInfo> groups;
TMap<FString, uint32_t> CRCMap;
// This opens the base resource only for reading the grpinfo from it which we need before setting up the game state.
std::unique_ptr<FResourceFile> engine_res;
@ -655,7 +655,7 @@ void GetCRC(FileEntry *entry, TArray<FileEntry> &CRCCache)
}
}
GrpInfo *IdentifyGroup(FileEntry *entry, TArray<GrpInfo *> &groups)
GrpDefInfo *IdentifyGroup(FileEntry *entry, TArray<GrpDefInfo *> &groups)
{
for (auto g : groups)
{
@ -671,7 +671,7 @@ GrpInfo *IdentifyGroup(FileEntry *entry, TArray<GrpInfo *> &groups)
//
//==========================================================================
static bool CheckAddon(GrpInfo* addon, GrpInfo* main, const char* filename)
static bool CheckAddon(GrpDefInfo* addon, GrpDefInfo* main, const char* filename)
{
if (addon->dependencyCRC != main->CRC) return false;
FString path = ExtractFilePath(filename);
@ -702,9 +702,9 @@ TArray<GrpEntry> GrpScan()
TArray<GrpEntry> foundGames;
TArray<FileEntry*> sortedFileList;
TArray<GrpInfo*> sortedGroupList;
TArray<GrpInfo*> contentGroupList;
TArray<GrpInfo*> addonList;
TArray<GrpDefInfo*> sortedGroupList;
TArray<GrpDefInfo*> contentGroupList;
TArray<GrpDefInfo*> addonList;
auto allFiles = CollectAllFilesInSearchPath();
auto allGroups = ParseAllGrpInfos(allFiles);
@ -770,42 +770,22 @@ TArray<GrpEntry> GrpScan()
}
}
TMap<size_t, bool> sizeLookup;
TArray<FileEntry*> matchedFileList;
std::sort(sortedFileList.begin(), sortedFileList.end(), [](FileEntry* lhs, FileEntry* rhs) { return lhs->FileLength < rhs->FileLength; });
std::sort(sortedGroupList.begin(), sortedGroupList.end(), [](GrpInfo* lhs, GrpInfo* rhs) { return lhs->size < rhs->size; });
int findex = sortedFileList.Size() - 1;
int gindex = sortedGroupList.Size() - 1;
while (findex > 0 && gindex > 0)
for (auto& entry : sortedGroupList)
{
if (sortedFileList[findex]->FileLength > sortedGroupList[gindex]->size)
{
// File is larger than the largest known group so it cannot be a candidate.
sortedFileList.Delete(findex--);
}
else if (sortedFileList[findex]->FileLength < sortedGroupList[gindex]->size)
{
// The largest available file is smaller than this group so we cannot possibly have it.
sortedGroupList.Delete(gindex--);
}
else
{
findex--;
gindex--;
// We found a matching file. Skip over all other entries of the same size so we can analyze those later as well
while (findex > 0 && sortedFileList[findex]->FileLength == sortedFileList[findex + 1]->FileLength) findex--;
while (gindex > 0 && sortedGroupList[gindex]->size == sortedGroupList[gindex + 1]->size) gindex--;
}
sizeLookup.Insert(entry->size, true);
}
for (auto entry : sortedFileList)
{
if (sizeLookup.CheckKey(entry->FileLength)) matchedFileList.Push(entry);
}
sortedFileList.Delete(0, findex + 1);
sortedGroupList.Delete(0, gindex + 1);
if (sortedGroupList.Size() == 0 || sortedFileList.Size() == 0)
if (matchedFileList.Size() == 0)
return foundGames;
for (auto entry : sortedFileList)
for (auto entry : matchedFileList)
{
GetCRC(entry, cachedCRCs);
auto grp = IdentifyGroup(entry, sortedGroupList);

View file

@ -672,18 +672,6 @@ grpinfo
gamefilter "Witchaven.Witchaven"
}
grpinfo
{
// The file identification info here is for joesnd which is one of two containers in the game data.
name "Witchaven"
flags GAMEFLAG_WITCHAVEN
crc 0x4CC892B7
size 2797568
defname "witchaven.def"
loadgrp "SONGS"
gamefilter "Witchaven.Witchaven"
}
grpinfo
{
// The file identification info here is for joesnd which is one of three containers in the game data.