Added recursive paths for IWADs and file searching

Adds a RecursivePath= key for checking subfolders in a given path. Only supports finding direct files and not directories. Currently configs and dehacked aren't supported.
This commit is contained in:
Boondorl 2025-08-03 21:18:17 -04:00 committed by Ricardo Luís Vaz Silva
commit 18300448ee
5 changed files with 83 additions and 3 deletions

View file

@ -150,6 +150,38 @@ bool FileExists (const char *filename)
return res && !isdir;
}
//==========================================================================
//
// RecursiveFileExists
//
// Returns the path to the file if it was found within a subdirectory,
// otherwise returning an empty string.
//
//==========================================================================
FString RecursiveFileExists(const FString& path, const FString& file)
{
if (FileExists(path + "/" + file))
return path + "/" + file;
// If we couldn't find it in the base directory, time to start searching.
FileSys::FileList list;
if (FileSys::ScanDirectory(list, path.GetChars(), "*"))
{
for (auto& entry : list)
{
if (entry.isDirectory && !entry.isHidden && !entry.isSystem)
{
FStringf f("%s/%s", entry.FilePath.c_str(), file.GetChars());
if (FileExists(f))
return f;
}
}
}
return "";
}
//==========================================================================
//
// FileReadable

View file

@ -34,6 +34,7 @@ char(&_ArraySizeHelper(T(&array)[N]))[N];
#define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type))
bool FileExists (const char *filename);
FString RecursiveFileExists(const FString& path, const FString& file);
inline bool FileExists(const FString& filename)
{
return FileExists(filename.GetChars());

View file

@ -263,6 +263,25 @@ const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinpr
}
}
}
else if (stricmp(key, "RecursivePath") == 0)
{
FString dir;
dir = NicePath(value);
if (dir.IsNotEmpty())
{
if (dir.Back() == '/')
dir.Truncate(dir.Len() - 1);
// Folders can't be used here since those are going to be checked
// recursively, so only find actual files.
FString path = RecursiveFileExists(dir, file);
if (path.IsNotEmpty())
{
return path.GetChars();
}
}
}
}
}

View file

@ -468,6 +468,11 @@ void FIWadManager::CollectSearchPaths()
FString nice = NicePath(value);
if (nice.Len() > 0) mSearchPaths.Push(nice);
}
else if (stricmp(key, "RecursivePath") == 0)
{
FString nice = NicePath(value);
if (nice.Len() > 0) mRecursiveSearchPaths.Push(nice);
}
}
}
mSearchPaths.Append(I_GetGogPaths());
@ -480,6 +485,11 @@ void FIWadManager::CollectSearchPaths()
FixPathSeperator(str);
if (str.Back() == '/') str.Truncate(str.Len() - 1);
}
for (auto& str : mRecursiveSearchPaths)
{
FixPathSeperator(str);
if (str.Back() == '/') str.Truncate(str.Len() - 1);
}
}
//==========================================================================
@ -490,11 +500,11 @@ void FIWadManager::CollectSearchPaths()
//
//==========================================================================
void FIWadManager::AddIWADCandidates(const char *dir)
void FIWadManager::AddIWADCandidates(const char *dir, bool nosubdir)
{
FileSys::FileList list;
if (FileSys::ScanDirectory(list, dir, "*", true))
if (FileSys::ScanDirectory(list, dir, "*", nosubdir))
{
for(auto& entry : list)
{
@ -580,6 +590,11 @@ FString FIWadManager::IWADPathFileSearch(const FString &file)
FString f = path + "/" + file;
if(FileExists(f)) return f;
}
for (const FString& path : mRecursiveSearchPaths)
{
FString f = RecursiveFileExists(path, file);
if (f.IsNotEmpty()) return f;
}
return "";
}
@ -596,6 +611,10 @@ int FIWadManager::IdentifyVersion (std::vector<std::string>&wadfiles, const char
{
AddIWADCandidates(dir.GetChars());
}
for (auto& dir : mRecursiveSearchPaths)
{
AddIWADCandidates(dir.GetChars(), false);
}
unsigned numFoundWads = mFoundWads.Size();
if (iwadparm)
@ -626,6 +645,14 @@ int FIWadManager::IdentifyVersion (std::vector<std::string>&wadfiles, const char
mFoundWads.Push({ fullpath, "", -1 });
}
}
for (const auto& dir : mRecursiveSearchPaths)
{
FString fullpath = RecursiveFileExists(dir, custwad);
if (fullpath.IsNotEmpty())
{
mFoundWads.Push({ fullpath, "", -1 });
}
}
}
if (mFoundWads.Size() != numFoundWads)

View file

@ -123,6 +123,7 @@ class FIWadManager
TArray<FIWADInfo> mIWadInfos;
TArray<FString> mIWadNames;
TArray<FString> mSearchPaths;
TArray<FString> mRecursiveSearchPaths;
TArray<FString> mOrderNames;
TArray<FFoundWadInfo> mFoundWads;
TArray<int> mLumpsFound;
@ -132,7 +133,7 @@ class FIWadManager
int CheckIWADInfo(const char *iwad);
int IdentifyVersion (std::vector<std::string>& wadfiles, const char *iwad, const char *zdoom_wad, const char *optional_wad);
void CollectSearchPaths();
void AddIWADCandidates(const char *dir);
void AddIWADCandidates(const char *dir, bool nosubdir = true);
void ValidateIWADs();
FString IWADPathFileSearch(const FString &file);
public: