mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 15:42:34 +00:00
- added initial support for a GAMEINFO lump in PWADs. When the game is started
all files loaded with '-file' are scanned for this lump. This lump is read before any WAD initialization takes place, in particular the IWAD is not yet loaded at this time. This allows PWADs the option to specify an IWAD they want to run with and optionally autoload external resource WADs. - Fixed a few places where FixPathSeperator was called with a locked FString buffer. It's better to use the FString version of this function instead. SVN r2073 (trunk)
This commit is contained in:
parent
370eff9014
commit
90ea0c3f6f
6 changed files with 145 additions and 20 deletions
|
@ -1,4 +1,11 @@
|
||||||
January 1, 2010 (Changes by Graf Zahl)
|
January 1, 2010 (Changes by Graf Zahl)
|
||||||
|
- added initial support for a GAMEINFO lump in PWADs. When the game is started
|
||||||
|
all files loaded with '-file' are scanned for this lump. This lump is read
|
||||||
|
before any WAD initialization takes place, in particular the IWAD is not yet
|
||||||
|
loaded at this time. This allows PWADs the option to specify an IWAD they
|
||||||
|
want to run with and optionally autoload external resource WADs.
|
||||||
|
- Fixed a few places where FixPathSeperator was called with a locked FString buffer.
|
||||||
|
It's better to use the FString version of this function instead.
|
||||||
- replaced wadlist_t with an array of FStrings and added a list parameter to
|
- replaced wadlist_t with an array of FStrings and added a list parameter to
|
||||||
everything that eventually calls D_AddFile. Also create the list of files
|
everything that eventually calls D_AddFile. Also create the list of files
|
||||||
loaded on the command line separately to allow further checks on them.
|
loaded on the command line separately to allow further checks on them.
|
||||||
|
|
|
@ -446,8 +446,7 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
|
||||||
FString iwad;
|
FString iwad;
|
||||||
|
|
||||||
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
|
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
|
||||||
FixPathSeperator (iwad.LockBuffer());
|
FixPathSeperator (iwad);
|
||||||
iwad.UnlockBuffer();
|
|
||||||
if (FileExists (iwad))
|
if (FileExists (iwad))
|
||||||
{
|
{
|
||||||
wads[i].Type = ScanIWAD (iwad);
|
wads[i].Type = ScanIWAD (iwad);
|
||||||
|
@ -484,7 +483,7 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *zdoom_wad)
|
static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad)
|
||||||
{
|
{
|
||||||
WadStuff wads[countof(IWADNames)];
|
WadStuff wads[countof(IWADNames)];
|
||||||
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
|
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
|
||||||
|
@ -495,10 +494,15 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *zdoom_w
|
||||||
bool iwadparmfound = false;
|
bool iwadparmfound = false;
|
||||||
FString custwad;
|
FString custwad;
|
||||||
|
|
||||||
|
if (iwadparm == NULL && iwad != NULL && *iwad != 0)
|
||||||
|
{
|
||||||
|
iwadparm = iwad;
|
||||||
|
}
|
||||||
|
|
||||||
if (iwadparm)
|
if (iwadparm)
|
||||||
{
|
{
|
||||||
custwad = iwadparm;
|
custwad = iwadparm;
|
||||||
FixPathSeperator (custwad.LockBuffer());
|
FixPathSeperator (custwad);
|
||||||
if (CheckIWAD (custwad, wads))
|
if (CheckIWAD (custwad, wads))
|
||||||
{ // -iwad parameter was a directory
|
{ // -iwad parameter was a directory
|
||||||
iwadparm = NULL;
|
iwadparm = NULL;
|
||||||
|
@ -524,8 +528,7 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *zdoom_w
|
||||||
if (stricmp (key, "Path") == 0)
|
if (stricmp (key, "Path") == 0)
|
||||||
{
|
{
|
||||||
FString nice = NicePath(value);
|
FString nice = NicePath(value);
|
||||||
FixPathSeperator(nice.LockBuffer());
|
FixPathSeperator(nice);
|
||||||
nice.UnlockBuffer();
|
|
||||||
CheckIWAD(nice, wads);
|
CheckIWAD(nice, wads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -660,9 +663,9 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *zdoom_w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *basewad)
|
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad)
|
||||||
{
|
{
|
||||||
EIWADType iwadType = IdentifyVersion(wadfiles, basewad);
|
EIWADType iwadType = IdentifyVersion(wadfiles, iwad, basewad);
|
||||||
gameiwad = iwadType;
|
gameiwad = iwadType;
|
||||||
const IWADInfo *iwad_info = &IWADInfos[iwadType];
|
const IWADInfo *iwad_info = &IWADInfos[iwadType];
|
||||||
I_SetIWADInfo(iwad_info);
|
I_SetIWADInfo(iwad_info);
|
||||||
|
|
131
src/d_main.cpp
131
src/d_main.cpp
|
@ -45,6 +45,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "doomerrors.h"
|
#include "doomerrors.h"
|
||||||
|
|
||||||
|
@ -102,6 +103,8 @@
|
||||||
#include "m_cheat.h"
|
#include "m_cheat.h"
|
||||||
#include "compatibility.h"
|
#include "compatibility.h"
|
||||||
#include "m_joy.h"
|
#include "m_joy.h"
|
||||||
|
#include "sc_man.h"
|
||||||
|
#include "resourcefiles/resourcefile.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, hud_althud)
|
EXTERN_CVAR(Bool, hud_althud)
|
||||||
void DrawHUD();
|
void DrawHUD();
|
||||||
|
@ -118,7 +121,7 @@ extern void R_ExecuteSetViewSize ();
|
||||||
extern void G_NewInit ();
|
extern void G_NewInit ();
|
||||||
extern void SetupPlayerClasses ();
|
extern void SetupPlayerClasses ();
|
||||||
extern bool CheckCheatmode ();
|
extern bool CheckCheatmode ();
|
||||||
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *basewad);
|
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||||
|
|
||||||
|
@ -1241,11 +1244,11 @@ CCMD (endgame)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void D_AddFile (TArray<FString> &wadfiles, const char *file, bool check)
|
bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check, int position)
|
||||||
{
|
{
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check && !DirEntryExists (file))
|
if (check && !DirEntryExists (file))
|
||||||
|
@ -1254,14 +1257,16 @@ void D_AddFile (TArray<FString> &wadfiles, const char *file, bool check)
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
Printf ("Can't find '%s'\n", file);
|
Printf ("Can't find '%s'\n", file);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
file = f;
|
file = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
FString f = file;
|
FString f = file;
|
||||||
FixPathSeperator(f);
|
FixPathSeperator(f);
|
||||||
wadfiles.Push(f);
|
if (position == -1) wadfiles.Push(f);
|
||||||
|
else wadfiles.Insert(position, f);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1628,6 +1633,114 @@ static void CopyFiles(TArray<FString> &to, TArray<FString> &from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char *data, int size)
|
||||||
|
{
|
||||||
|
FScanner sc;
|
||||||
|
FString iwad;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
const char *lastSlash = strrchr (fn, '/');
|
||||||
|
|
||||||
|
sc.OpenMem("GAMEINFO", data, size);
|
||||||
|
while(sc.GetToken())
|
||||||
|
{
|
||||||
|
sc.TokenMustBe(TK_Identifier);
|
||||||
|
FString nextKey = sc.String;
|
||||||
|
sc.MustGetToken('=');
|
||||||
|
if (!nextKey.CompareNoCase("IWAD"))
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
iwad = sc.String;
|
||||||
|
}
|
||||||
|
else if (!nextKey.CompareNoCase("LOAD"))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sc.MustGetToken(TK_StringConst);
|
||||||
|
|
||||||
|
// Try looking for the wad in the same directory as the .wad
|
||||||
|
// before looking for it in the current directory.
|
||||||
|
|
||||||
|
if (lastSlash != NULL)
|
||||||
|
{
|
||||||
|
FString checkpath(fn, (lastSlash - fn) + 1);
|
||||||
|
checkpath += sc.String;
|
||||||
|
|
||||||
|
if (!FileExists (checkpath))
|
||||||
|
{
|
||||||
|
pos += D_AddFile(pwads, sc.String, true, pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += D_AddFile(pwads, checkpath, true, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (sc.CheckToken(','));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iwad;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FString CheckGameInfo(TArray<FString> & pwads)
|
||||||
|
{
|
||||||
|
DWORD t = I_FPSTime();
|
||||||
|
// scan the list of WADs backwards to find the last one that contains a GAMEINFO lump
|
||||||
|
for(int i=pwads.Size()-1; i>=0; i--)
|
||||||
|
{
|
||||||
|
bool isdir = false;
|
||||||
|
FileReader *wadinfo;
|
||||||
|
FResourceFile *resfile;
|
||||||
|
const char *filename = pwads[i];
|
||||||
|
|
||||||
|
// Does this exist? If so, is it a directory?
|
||||||
|
struct stat info;
|
||||||
|
if (stat(pwads[i], &info) != 0)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_RED "Could not stat %s\n", filename);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
isdir = (info.st_mode & S_IFDIR) != 0;
|
||||||
|
|
||||||
|
if (!isdir)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wadinfo = new FileReader(filename);
|
||||||
|
}
|
||||||
|
catch (CRecoverableError &)
|
||||||
|
{
|
||||||
|
// Didn't find file
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
resfile = FResourceFile::OpenResourceFile(filename, wadinfo, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
resfile = FResourceFile::OpenDirectory(filename, true);
|
||||||
|
|
||||||
|
if (resfile != NULL)
|
||||||
|
{
|
||||||
|
DWORD cnt = resfile->LumpCount();
|
||||||
|
for(int i=cnt-1; i>=0; i--)
|
||||||
|
{
|
||||||
|
FResourceLump *lmp = resfile->GetLump(i);
|
||||||
|
|
||||||
|
if (lmp->Namespace == ns_global && !stricmp(lmp->Name, "GAMEINFO"))
|
||||||
|
{
|
||||||
|
// Found one!
|
||||||
|
FString iwad = ParseGameInfo(pwads, resfile->Filename, (const char*)lmp->CacheLump(), lmp->LumpSize);
|
||||||
|
delete resfile;
|
||||||
|
return iwad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete resfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t = I_FPSTime() - t;
|
||||||
|
Printf("Gameinfo scan took %d ms\n", t);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// D_DoomMain
|
// D_DoomMain
|
||||||
|
@ -1681,11 +1794,15 @@ void D_DoomMain (void)
|
||||||
{
|
{
|
||||||
I_FatalError ("Cannot find " BASEWAD);
|
I_FatalError ("Cannot find " BASEWAD);
|
||||||
}
|
}
|
||||||
|
FString basewad = wad;
|
||||||
|
|
||||||
// Load zdoom.pk3 alone so that we can get access to the internal gameinfos before
|
// Load zdoom.pk3 alone so that we can get access to the internal gameinfos before
|
||||||
// the IWAD is known.
|
// the IWAD is known.
|
||||||
|
|
||||||
const IWADInfo *iwad_info = D_FindIWAD(allwads, wad);
|
GetCmdLineFiles(pwads);
|
||||||
|
FString iwad = CheckGameInfo(pwads);
|
||||||
|
|
||||||
|
const IWADInfo *iwad_info = D_FindIWAD(allwads, iwad, basewad);
|
||||||
gameinfo.gametype = iwad_info->gametype;
|
gameinfo.gametype = iwad_info->gametype;
|
||||||
gameinfo.flags = iwad_info->flags;
|
gameinfo.flags = iwad_info->flags;
|
||||||
|
|
||||||
|
@ -1748,8 +1865,6 @@ void D_DoomMain (void)
|
||||||
|
|
||||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||||
|
|
||||||
GetCmdLineFiles(pwads);
|
|
||||||
|
|
||||||
CopyFiles(allwads, pwads);
|
CopyFiles(allwads, pwads);
|
||||||
|
|
||||||
Printf ("W_Init: Init WADfiles.\n");
|
Printf ("W_Init: Init WADfiles.\n");
|
||||||
|
|
|
@ -49,7 +49,7 @@ void D_PageTicker (void);
|
||||||
void D_PageDrawer (void);
|
void D_PageDrawer (void);
|
||||||
void D_AdvanceDemo (void);
|
void D_AdvanceDemo (void);
|
||||||
void D_StartTitle (void);
|
void D_StartTitle (void);
|
||||||
void D_AddFile (TArray<FString> &wadfiles, const char *file, bool check = true);
|
bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check = true, int position = -1);
|
||||||
|
|
||||||
|
|
||||||
// [RH] Set this to something to draw an icon during the next screen refresh.
|
// [RH] Set this to something to draw an icon during the next screen refresh.
|
||||||
|
|
|
@ -283,9 +283,9 @@ FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FResourceFile *FResourceFile::OpenDirectory(const char *filename)
|
FResourceFile *FResourceFile::OpenDirectory(const char *filename, bool quiet)
|
||||||
{
|
{
|
||||||
return CheckDir(filename, NULL, false);
|
return CheckDir(filename, NULL, quiet);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -67,7 +67,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static FResourceFile *OpenResourceFile(const char *filename, FileReader *file, bool quiet = false);
|
static FResourceFile *OpenResourceFile(const char *filename, FileReader *file, bool quiet = false);
|
||||||
static FResourceFile *OpenDirectory(const char *filename);
|
static FResourceFile *OpenDirectory(const char *filename, bool quiet = false);
|
||||||
virtual ~FResourceFile();
|
virtual ~FResourceFile();
|
||||||
FileReader *GetReader() const { return Reader; }
|
FileReader *GetReader() const { return Reader; }
|
||||||
DWORD LumpCount() const { return NumLumps; }
|
DWORD LumpCount() const { return NumLumps; }
|
||||||
|
|
Loading…
Reference in a new issue