- moved file lookup functions to utilities and matched to GZDoom's version.

This commit is contained in:
Christoph Oelckers 2020-04-12 00:07:52 +02:00
parent a60a0eeefa
commit 2883553ed2
7 changed files with 288 additions and 268 deletions

View file

@ -51,247 +51,7 @@
#define PATH_MAX 260
#endif
//==========================================================================
//
// BaseFileSearch
//
// If a file does not exist at <file>, looks for it in the directories
// specified in the config file. Returns the path to the file, if found,
// or nullptr if it could not be found.
//
//==========================================================================
FString BaseFileSearch (const char *file, const char *ext, bool lookfirstinprogdir)
{
FString wad;
if (file == nullptr || *file == '\0')
{
return nullptr;
}
if (lookfirstinprogdir)
{
wad.Format("%s%s%s", progdir.GetChars(), progdir.Back() == '/' ? "" : "/", file);
if (DirEntryExists (wad))
{
return wad;
}
}
if (DirEntryExists (file))
{
wad.Format("%s", file);
return wad;
}
if (GameConfig != nullptr && GameConfig->SetSection ("FileSearch.Directories"))
{
const char *key;
const char *value;
while (GameConfig->NextInSection (key, value))
{
if (stricmp (key, "Path") == 0)
{
FString dir;
dir = NicePath(value);
if (dir.IsNotEmpty())
{
wad.Format("%s%s%s", dir.GetChars(), dir.Back() == '/' ? "" : "/", file);
if (DirEntryExists (wad))
{
return wad;
}
}
}
}
}
// Retry, this time with a default extension
if (ext != nullptr)
{
FString tmp = file;
DefaultExtension (tmp, ext);
return BaseFileSearch (tmp, nullptr, lookfirstinprogdir);
}
return nullptr;
}
//==========================================================================
//
// D_AddFile
//
//==========================================================================
bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check = true, int position = -1)
{
if (file == NULL || *file == '\0')
{
return false;
}
if (check && !DirEntryExists (file))
{
const char *f = BaseFileSearch (file, ".grp", false);
if (f == NULL)
{
Printf ("Can't find '%s'\n", file);
return false;
}
file = f;
}
FString f = file;
f.Substitute("\\", "/");
if (position == -1) wadfiles.Push(f);
else wadfiles.Insert(position, f);
return true;
}
//==========================================================================
//
// D_AddWildFile
//
//==========================================================================
void D_AddWildFile (TArray<FString> &wadfiles, const char *value)
{
if (value == NULL || *value == '\0')
{
return;
}
FString wadfile = BaseFileSearch (value, ".wad", false);
if (wadfile.Len() != 0)
{
D_AddFile (wadfiles, wadfile);
}
else
{ // Try pattern matching
findstate_t findstate;
char path[260];
char *sep;
void *handle = I_FindFirst (value, &findstate);
strcpy (path, value);
sep = strrchr (path, '/');
if (sep == NULL)
{
sep = strrchr (path, '\\');
#ifdef _WIN32
if (sep == NULL && path[1] == ':')
{
sep = path + 1;
}
#endif
}
if (handle != ((void *)-1))
{
do
{
if (!(I_FindAttr(&findstate) & FA_DIREC))
{
if (sep == NULL)
{
D_AddFile (wadfiles, I_FindName (&findstate));
}
else
{
strcpy (sep+1, I_FindName (&findstate));
D_AddFile (wadfiles, path, false );
}
}
} while (I_FindNext (handle, &findstate) == 0);
}
I_FindClose (handle);
}
}
//==========================================================================
//
// D_AddConfigWads
//
// Adds all files in the specified config file section.
//
//==========================================================================
void D_AddConfigWads (TArray<FString> &wadfiles, const char *section)
{
if (GameConfig->SetSection (section))
{
const char *key;
const char *value;
FConfigFile::Position pos;
while (GameConfig->NextInSection (key, value))
{
if (stricmp (key, "Path") == 0)
{
// D_AddWildFile resets GameConfig's position, so remember it
GameConfig->GetPosition (pos);
D_AddWildFile (wadfiles, ExpandEnvVars(value));
// Reset GameConfig's position to get next wad
GameConfig->SetPosition (pos);
}
}
}
}
//==========================================================================
//
// D_AddDirectory
//
// Add all .wad files in a directory. Does not descend into subdirectories.
//
//==========================================================================
static void D_AddDirectory (TArray<FString> &wadfiles, const char *dir)
{
char curdir[PATH_MAX];
if (getcwd (curdir, PATH_MAX))
{
char skindir[PATH_MAX];
findstate_t findstate;
void *handle;
size_t stuffstart;
stuffstart = strlen (dir);
memcpy (skindir, dir, stuffstart*sizeof(*dir));
skindir[stuffstart] = 0;
if (skindir[stuffstart-1] == '/')
{
skindir[--stuffstart] = 0;
}
if (!chdir (skindir))
{
skindir[stuffstart++] = '/';
int savedstart = stuffstart;
static const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat", "*.rff" };
for (auto ext : validexts)
{
stuffstart = savedstart;
if ((handle = I_FindFirst(ext, &findstate)) != (void*)-1)
{
do
{
if (!(I_FindAttr(&findstate) & FA_DIREC))
{
strcpy(skindir + stuffstart, I_FindName(&findstate));
D_AddFile(wadfiles, skindir);
}
} while (I_FindNext(handle, &findstate) == 0);
I_FindClose(handle);
}
}
}
chdir (curdir);
}
}
static const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat", "*.rff" };
//==========================================================================
//
@ -340,11 +100,11 @@ static FString ParseGameInfo(TArray<FString>& pwads, const char* fn, const char*
}
if (!FileExists(checkpath))
{
pos += D_AddFile(pwads, sc.String, true, pos);
pos += D_AddFile(pwads, sc.String, true, pos, GameConfig);
}
else
{
pos += D_AddFile(pwads, checkpath, true, pos);
pos += D_AddFile(pwads, checkpath, true, pos, GameConfig);
}
} while (sc.CheckToken(','));
}
@ -446,13 +206,13 @@ FString GetGameFronUserFiles()
if (userConfig.AddFilesPre) for (auto& file : *userConfig.AddFilesPre)
{
D_AddFile(Files, file);
D_AddFile(Files, file, true, -1, GameConfig);
}
if (userConfig.AddFiles)
{
for (auto& file : *userConfig.AddFiles)
{
D_AddFile(Files, file);
D_AddFile(Files, file, true, -1, GameConfig);
}
// Finally, if the last entry in the chain is a directory, it's being considered the mod directory, and all GRPs inside need to be loaded, too.
@ -465,7 +225,10 @@ FString GetGameFronUserFiles()
// Insert the GRPs before this entry itself.
FString lastfn;
Files.Pop(lastfn);
D_AddDirectory(Files, fn);
for (auto ext : validexts)
{
D_AddDirectory(Files, fn, ext, GameConfig);
}
Files.Push(lastfn);
}
}
@ -518,7 +281,7 @@ void InitFileSystem(TArray<GrpEntry>& groups)
// First comes the engine's own stuff.
FString baseres = progdir + ENGINERES_FILE;
D_AddFile(Files, baseres);
D_AddFile(Files, baseres, true, -1, GameConfig);
bool insertdirectoriesafter = Args->CheckParm("-insertdirafter");
@ -532,7 +295,7 @@ void InitFileSystem(TArray<GrpEntry>& groups)
// This can be overridden via command line switch if needed.
if (!grp.FileInfo.loaddirectory && grp.FileName.IsNotEmpty())
{
D_AddFile(Files, grp.FileName);
D_AddFile(Files, grp.FileName, true, -1, GameConfig);
fn = ExtractFilePath(grp.FileName);
if (fn.Len() > 0 && fn.Back() != '/') fn += '/';
}
@ -540,7 +303,7 @@ void InitFileSystem(TArray<GrpEntry>& groups)
for (auto& fname : grp.FileInfo.loadfiles)
{
FString newname = fn + fname;
D_AddFile(Files, newname);
D_AddFile(Files, newname, true, -1, GameConfig);
}
bool insert = (!insertdirectoriesafter && &grp == &groups[0]) || (insertdirectoriesafter && &grp == &groups.Last());
@ -551,10 +314,10 @@ void InitFileSystem(TArray<GrpEntry>& groups)
// Do this only if explicitly requested because this severely limits the usability of GRP files.
if (insertdirectoriesafter && userConfig.AddFilesPre) for (auto& file : *userConfig.AddFilesPre)
{
D_AddFile(Files, '*' + file); // The * tells the file system not to pull in all subdirectories.
D_AddFile(Files, file, true, -1, GameConfig);
}
D_AddFile(Files, fn);
D_AddFile(Files, fn, true, -1, GameConfig);
}
i--;
}
@ -568,20 +331,20 @@ void InitFileSystem(TArray<GrpEntry>& groups)
if (stricmp(key, "Path") == 0)
{
FString nice = NicePath(value);
D_AddFile(Files, nice);
D_AddFile(Files, nice, true, -1, GameConfig);
}
}
}
if (!insertdirectoriesafter && userConfig.AddFilesPre) for (auto& file : *userConfig.AddFilesPre)
{
D_AddFile(Files, file);
D_AddFile(Files, file, true, -1, GameConfig);
}
if (userConfig.AddFiles)
{
for (auto& file : *userConfig.AddFiles)
{
D_AddFile(Files, file);
D_AddFile(Files, file, true, -1, GameConfig);
}
// Finally, if the last entry in the chain is a directory, it's being considered the mod directory, and all GRPs inside need to be loaded, too.
@ -594,7 +357,10 @@ void InitFileSystem(TArray<GrpEntry>& groups)
// Insert the GRPs before this entry itself.
FString lastfn;
Files.Pop(lastfn);
D_AddDirectory(Files, fn);
for (auto ext : validexts)
{
D_AddDirectory(Files, fn, ext, GameConfig);
}
Files.Push(lastfn);
}
}