mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-23 03:52:12 -04:00
Simplify FindIWADFile and CheckIWAD (#499)
* simplify FindIWADFile and CheckIWAD * remove description * fix gcc warning * set haswolflevels after init wads * check default extension
This commit is contained in:
parent
eb82b4f64d
commit
fe54bb771d
347
Source/d_main.c
347
Source/d_main.c
@ -146,24 +146,28 @@ boolean main_loop_started = false;
|
|||||||
boolean coop_spawns = false;
|
boolean coop_spawns = false;
|
||||||
|
|
||||||
//jff 4/19/98 list of standard IWAD names
|
//jff 4/19/98 list of standard IWAD names
|
||||||
const char *const standard_iwads[]=
|
typedef struct
|
||||||
{
|
{
|
||||||
DIR_SEPARATOR_S"doom2f.wad",
|
const char *name;
|
||||||
DIR_SEPARATOR_S"doom2.wad",
|
GameMission_t mission;
|
||||||
DIR_SEPARATOR_S"plutonia.wad",
|
GameMode_t mode;
|
||||||
DIR_SEPARATOR_S"tnt.wad",
|
} iwad_t;
|
||||||
DIR_SEPARATOR_S"doom.wad",
|
|
||||||
DIR_SEPARATOR_S"doom1.wad",
|
|
||||||
// [FG] support the Freedoom IWADs
|
|
||||||
DIR_SEPARATOR_S"freedoom2.wad",
|
|
||||||
DIR_SEPARATOR_S"freedoom1.wad",
|
|
||||||
DIR_SEPARATOR_S"freedm.wad",
|
|
||||||
|
|
||||||
DIR_SEPARATOR_S"chex.wad",
|
static iwad_t standard_iwads[] =
|
||||||
DIR_SEPARATOR_S"hacx.wad",
|
{
|
||||||
DIR_SEPARATOR_S"rekkrsa.wad",
|
{ "doom2.wad", doom2, commercial },
|
||||||
|
{ "plutonia.wad", pack_plut, commercial },
|
||||||
|
{ "tnt.wad", pack_tnt, commercial },
|
||||||
|
{ "doom.wad", doom, retail },
|
||||||
|
{ "doom1.wad", doom, shareware },
|
||||||
|
{ "doom2f.wad", doom2, commercial },
|
||||||
|
{ "chex.wad", pack_chex, retail },
|
||||||
|
{ "hacx.wad", pack_hacx, commercial },
|
||||||
|
{ "freedoom2.wad", doom2, commercial },
|
||||||
|
{ "freedoom1.wad", doom, retail },
|
||||||
|
{ "freedm.wad", doom2, commercial },
|
||||||
|
{ "rekkrsa.wad", pack_rekkr, retail }
|
||||||
};
|
};
|
||||||
static const int nstandard_iwads = sizeof standard_iwads/sizeof*standard_iwads;
|
|
||||||
|
|
||||||
void D_ConnectNetGame (void);
|
void D_ConnectNetGame (void);
|
||||||
void D_CheckNetGame (void);
|
void D_CheckNetGame (void);
|
||||||
@ -743,281 +747,67 @@ static void PrepareAutoloadPaths (void)
|
|||||||
//
|
//
|
||||||
// CheckIWAD
|
// CheckIWAD
|
||||||
//
|
//
|
||||||
// Verify a file is indeed tagged as an IWAD
|
|
||||||
// Scan its lumps for levelnames and return gamemode as indicated
|
|
||||||
// Detect missing wolf levels in DOOM II
|
|
||||||
//
|
|
||||||
// The filename to check is passed in iwadname, the gamemode detected is
|
|
||||||
// returned in gmode, hassec returns the presence of secret levels
|
|
||||||
//
|
|
||||||
// jff 4/19/98 Add routine to test IWAD for validity and determine
|
|
||||||
// the gamemode from it. Also note if DOOM II, whether secret levels exist
|
|
||||||
//
|
|
||||||
// killough 11/98:
|
|
||||||
// Rewritten to considerably simplify
|
|
||||||
// Added Final Doom support (thanks to Joel Murdoch)
|
|
||||||
//
|
|
||||||
|
|
||||||
static void CheckIWAD(const char *iwadname,
|
static void CheckIWAD(const char *iwadname,
|
||||||
GameMode_t *gmode,
|
GameMode_t *gmode,
|
||||||
GameMission_t *gmission, // joel 10/17/98 Final DOOM fix
|
GameMission_t *gmission) // joel 10/17/98 Final DOOM fix
|
||||||
boolean *hassec)
|
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(iwadname, "rb");
|
int i;
|
||||||
int ud, rg, sw, cm, sc, tnt, plut, hacx, chex, rekkr;
|
const char *name = M_BaseName(iwadname);
|
||||||
filelump_t lump;
|
|
||||||
wadinfo_t header;
|
|
||||||
const char *n = lump.name;
|
|
||||||
|
|
||||||
if (!fp)
|
for (i = 0; i < arrlen(standard_iwads); ++i)
|
||||||
I_Error("Can't open IWAD: %s\n",iwadname);
|
|
||||||
|
|
||||||
// read IWAD header
|
|
||||||
if (fread(&header, 1, sizeof header, fp) != sizeof header ||
|
|
||||||
header.identification[0] != 'I' || header.identification[1] != 'W' ||
|
|
||||||
header.identification[2] != 'A' || header.identification[3] != 'D')
|
|
||||||
// [FG] make non-fatal
|
|
||||||
fprintf(stderr,"IWAD tag not present: %s\n",iwadname);
|
|
||||||
|
|
||||||
fseek(fp, LONG(header.infotableofs), SEEK_SET);
|
|
||||||
|
|
||||||
// Determine game mode from levels present
|
|
||||||
// Must be a full set for whichever mode is present
|
|
||||||
// Lack of wolf-3d levels also detected here
|
|
||||||
|
|
||||||
for (ud=rg=sw=cm=sc=tnt=plut=hacx=chex=rekkr=0, header.numlumps = LONG(header.numlumps);
|
|
||||||
header.numlumps && fread(&lump, sizeof lump, 1, fp); header.numlumps--)
|
|
||||||
{
|
|
||||||
*n=='E' && n[2]=='M' && !n[4] ?
|
|
||||||
n[1]=='4' ? ++ud : n[1]!='1' ? rg += n[1]=='3' || n[1]=='2' : ++sw :
|
|
||||||
*n=='M' && n[1]=='A' && n[2]=='P' && !n[5] ?
|
|
||||||
++cm, sc += n[3]=='3' && (n[4]=='1' || n[4]=='2') :
|
|
||||||
*n=='C' && n[1]=='A' && n[2]=='V' && !n[7] ? ++tnt :
|
|
||||||
*n=='M' && n[1]=='C' && !n[3] && ++plut;
|
|
||||||
|
|
||||||
if (strncmp(n,"HACX",4) == 0)
|
|
||||||
++hacx;
|
|
||||||
if (strncmp(n,"W94_1",5) == 0)
|
|
||||||
++chex;
|
|
||||||
if (strncmp(n,"POSSH0M0",8) == 0)
|
|
||||||
++chex;
|
|
||||||
if (strncmp(n,"REKCREDS",8) == 0)
|
|
||||||
++rekkr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
*gmission = doom;
|
|
||||||
*hassec = false;
|
|
||||||
*gmode =
|
|
||||||
// [FG] improve gamemission detection to support the Freedoom IWADs
|
|
||||||
cm >= 30 ? (*gmission = (tnt >= 4 && plut < 8) ? pack_tnt :
|
|
||||||
(plut >= 8 && tnt < 4) ? pack_plut : doom2,
|
|
||||||
*hassec = sc >= 2, commercial) :
|
|
||||||
ud >= 9 ? retail :
|
|
||||||
rg >= 18 ? registered :
|
|
||||||
sw >= 9 ? shareware :
|
|
||||||
(cm >= 20 && hacx) ? (*gmission = pack_hacx, commercial) :
|
|
||||||
indetermined;
|
|
||||||
|
|
||||||
if (*gmode == retail && chex == 2)
|
|
||||||
*gmission = pack_chex;
|
|
||||||
if (*gmode == retail && rekkr)
|
|
||||||
*gmission = pack_rekkr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jff 4/19/98 Add routine to check a pathname for existence as
|
|
||||||
// a file or directory. If neither append .wad and check if it
|
|
||||||
// exists as a file then. Else return non-existent.
|
|
||||||
|
|
||||||
boolean WadFileStatus(char *filename,boolean *isdir)
|
|
||||||
{
|
|
||||||
struct stat sbuf;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
*isdir = false; //default is directory to false
|
|
||||||
if (!filename || !*filename) //if path NULL or empty, doesn't exist
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!stat(filename,&sbuf)) //check for existence
|
|
||||||
{
|
{
|
||||||
*isdir=S_ISDIR(sbuf.st_mode); //if it does, set whether a dir or not
|
if (!strcasecmp(name, standard_iwads[i].name))
|
||||||
return true; //return does exist
|
{
|
||||||
|
*gmode = standard_iwads[i].mode;
|
||||||
|
*gmission = standard_iwads[i].mission;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i = strlen(filename); //get length of path
|
|
||||||
if (i>=4)
|
|
||||||
if(!strnicmp(filename+i-4,".wad",4))
|
|
||||||
return false; //if already ends in .wad, not found
|
|
||||||
|
|
||||||
strcat(filename,".wad"); //try it with .wad added
|
|
||||||
if (!stat(filename,&sbuf)) //if it exists then
|
|
||||||
{
|
|
||||||
if (S_ISDIR(sbuf.st_mode)) //but is a dir, then say we didn't find it
|
|
||||||
return false;
|
|
||||||
return true; //otherwise return file found, w/ .wad added
|
|
||||||
}
|
|
||||||
filename[i]=0; //remove .wad
|
|
||||||
return false; //and report doesn't exist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// FindIWADFIle
|
// FindIWADFIle
|
||||||
//
|
//
|
||||||
// Search in all the usual places until an IWAD is found.
|
|
||||||
//
|
|
||||||
// The global baseiwad contains either a full IWAD file specification
|
|
||||||
// or a directory to look for an IWAD in, or the name of the IWAD desired.
|
|
||||||
//
|
|
||||||
// The global standard_iwads lists the standard IWAD names
|
|
||||||
//
|
|
||||||
// The result of search is returned in baseiwad, or set blank if none found
|
|
||||||
//
|
|
||||||
// IWAD search algorithm:
|
|
||||||
//
|
|
||||||
// Set customiwad blank
|
|
||||||
// If -iwad present set baseiwad to normalized path from -iwad parameter
|
|
||||||
// If baseiwad is an existing file, thats it
|
|
||||||
// If baseiwad is an existing dir, try appending all standard iwads
|
|
||||||
// If haven't found it, and no : or / is in baseiwad,
|
|
||||||
// append .wad if missing and set customiwad to baseiwad
|
|
||||||
//
|
|
||||||
// Look in . for customiwad if set, else all standard iwads
|
|
||||||
//
|
|
||||||
// Look in DoomExeDir. for customiwad if set, else all standard iwads
|
|
||||||
//
|
|
||||||
// If $DOOMWADDIR is an existing file
|
|
||||||
// If customiwad is not set, thats it
|
|
||||||
// else replace filename with customiwad, if exists thats it
|
|
||||||
// If $DOOMWADDIR is existing dir, try customiwad if set, else standard iwads
|
|
||||||
//
|
|
||||||
// If $HOME is an existing file
|
|
||||||
// If customiwad is not set, thats it
|
|
||||||
// else replace filename with customiwad, if exists thats it
|
|
||||||
// If $HOME is an existing dir, try customiwad if set, else standard iwads
|
|
||||||
//
|
|
||||||
// IWAD not found
|
|
||||||
//
|
|
||||||
// jff 4/19/98 Add routine to search for a standard or custom IWAD in one
|
|
||||||
// of the standard places. Returns a blank string if not found.
|
|
||||||
//
|
|
||||||
// killough 11/98: simplified, removed error-prone cut-n-pasted code
|
|
||||||
//
|
|
||||||
|
|
||||||
char *FindIWADFile(void)
|
char *FindIWADFile(void)
|
||||||
{
|
{
|
||||||
static const char *envvars[] = {"DOOMWADDIR", "HOME"};
|
char *result;
|
||||||
char *iwad = NULL;
|
int iwadparm = M_CheckParmWithArgs("-iwad", 1);
|
||||||
char *customiwad = NULL;
|
|
||||||
boolean isdir=false;
|
|
||||||
int i,j;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
int lbuf = 512;
|
if (iwadparm)
|
||||||
int lcustomiwad = 0;
|
|
||||||
|
|
||||||
//jff 3/24/98 get -iwad parm if specified else use .
|
|
||||||
if ((i = M_CheckParm("-iwad")) && i < myargc-1)
|
|
||||||
{
|
{
|
||||||
iwad = (malloc)(strlen(myargv[i+1]) + lbuf);
|
// Search through IWAD dirs for an IWAD with the given name.
|
||||||
strcpy(iwad,myargv[i+1]);
|
|
||||||
NormalizeSlashes(iwad);
|
char *iwadfile = myargv[iwadparm + 1];
|
||||||
if (WadFileStatus(iwad,&isdir))
|
|
||||||
if (!isdir)
|
char *file = (malloc)(strlen(iwadfile) + 5);
|
||||||
return iwad;
|
AddDefaultExtension(strcpy(file, iwadfile), ".wad");
|
||||||
else
|
|
||||||
for (i=0;i<nstandard_iwads;i++)
|
result = D_FindWADByName(file);
|
||||||
{
|
|
||||||
int n = strlen(iwad);
|
if (result == NULL)
|
||||||
strcat(iwad,standard_iwads[i]);
|
|
||||||
if (WadFileStatus(iwad,&isdir) && !isdir)
|
|
||||||
return iwad;
|
|
||||||
iwad[n] = 0; // reset iwad length to former
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (!strchr(iwad,':') && !strchr(iwad,DIR_SEPARATOR))
|
|
||||||
{
|
{
|
||||||
lcustomiwad = strlen(iwad) + 6;
|
I_Error("IWAD file '%s' not found!", file);
|
||||||
customiwad = (malloc)(lcustomiwad);
|
}
|
||||||
AddDefaultExtension(strcat(strcpy(customiwad, DIR_SEPARATOR_S), iwad), ".wad");
|
|
||||||
|
(free)(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Search through the list and look for an IWAD
|
||||||
|
|
||||||
|
result = NULL;
|
||||||
|
|
||||||
|
for (i = 0; result == NULL && i < arrlen(standard_iwads); ++i)
|
||||||
|
{
|
||||||
|
result = D_FindWADByName(standard_iwads[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iwad)
|
return result;
|
||||||
iwad = (malloc)(lcustomiwad + lbuf);
|
|
||||||
|
|
||||||
for (j=0; j<num_iwad_dirs; j++)
|
|
||||||
{
|
|
||||||
strcpy(iwad, iwad_dirs[j]);
|
|
||||||
NormalizeSlashes(iwad);
|
|
||||||
printf("Looking in %s\n",iwad); // killough 8/8/98
|
|
||||||
if (customiwad)
|
|
||||||
{
|
|
||||||
strcat(iwad,customiwad);
|
|
||||||
if (WadFileStatus(iwad,&isdir) && !isdir)
|
|
||||||
return iwad;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for (i=0;i<nstandard_iwads;i++)
|
|
||||||
{
|
|
||||||
int n = strlen(iwad);
|
|
||||||
strcat(iwad,standard_iwads[i]);
|
|
||||||
if (WadFileStatus(iwad,&isdir) && !isdir)
|
|
||||||
return iwad;
|
|
||||||
iwad[n] = 0; // reset iwad length to former
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<sizeof envvars/sizeof *envvars;i++)
|
|
||||||
if ((p = getenv(envvars[i])))
|
|
||||||
{
|
|
||||||
NormalizeSlashes(strcpy(iwad,p));
|
|
||||||
if (WadFileStatus(iwad,&isdir))
|
|
||||||
{
|
|
||||||
if (!isdir)
|
|
||||||
{
|
|
||||||
if (!customiwad)
|
|
||||||
return printf("Looking for %s\n",iwad), iwad; // killough 8/8/98
|
|
||||||
else
|
|
||||||
if ((p = strrchr(iwad,DIR_SEPARATOR)))
|
|
||||||
{
|
|
||||||
*p=0;
|
|
||||||
strcat(iwad,customiwad);
|
|
||||||
printf("Looking for %s\n",iwad); // killough 8/8/98
|
|
||||||
if (WadFileStatus(iwad,&isdir) && !isdir)
|
|
||||||
{
|
|
||||||
(free)(customiwad);
|
|
||||||
return iwad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Looking in %s\n",iwad); // killough 8/8/98
|
|
||||||
if (customiwad)
|
|
||||||
{
|
|
||||||
if (WadFileStatus(strcat(iwad,customiwad),&isdir) && !isdir)
|
|
||||||
{
|
|
||||||
(free)(customiwad);
|
|
||||||
return iwad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for (i=0;i<nstandard_iwads;i++)
|
|
||||||
{
|
|
||||||
int n = strlen(iwad);
|
|
||||||
strcat(iwad,standard_iwads[i]);
|
|
||||||
if (WadFileStatus(iwad,&isdir) && !isdir)
|
|
||||||
return iwad;
|
|
||||||
iwad[n] = 0; // reset iwad length to former
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iwad) (free)(iwad);
|
|
||||||
if (customiwad) (free)(customiwad);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1068,9 +858,6 @@ void IdentifyVersion (void)
|
|||||||
|
|
||||||
// locate the IWAD and determine game mode from it
|
// locate the IWAD and determine game mode from it
|
||||||
|
|
||||||
// [FG] create array of locations to search for IWAD files
|
|
||||||
BuildIWADDirList();
|
|
||||||
|
|
||||||
iwad = FindIWADFile();
|
iwad = FindIWADFile();
|
||||||
|
|
||||||
if (iwad && *iwad)
|
if (iwad && *iwad)
|
||||||
@ -1079,8 +866,7 @@ void IdentifyVersion (void)
|
|||||||
|
|
||||||
CheckIWAD(iwad,
|
CheckIWAD(iwad,
|
||||||
&gamemode,
|
&gamemode,
|
||||||
&gamemission, // joel 10/16/98 gamemission added
|
&gamemission); // joel 10/16/98 gamemission added
|
||||||
&haswolflevels);
|
|
||||||
|
|
||||||
switch(gamemode)
|
switch(gamemode)
|
||||||
{
|
{
|
||||||
@ -1128,8 +914,7 @@ void IdentifyVersion (void)
|
|||||||
puts("DOOM II version, French language"); // killough 8/8/98
|
puts("DOOM II version, French language"); // killough 8/8/98
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
puts(haswolflevels ? "DOOM II version" : // killough 10/98
|
puts("DOOM II version");
|
||||||
"DOOM II version, german edition, no wolf levels");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// joel 10/16/88 end Final DOOM fix
|
// joel 10/16/88 end Final DOOM fix
|
||||||
@ -1334,9 +1119,9 @@ static boolean D_IsIWADName(const char *name)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < nstandard_iwads; i++)
|
for (i = 0; i < arrlen(standard_iwads); i++)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(name, standard_iwads[i] + 1)) // [FG] skip leading slash
|
if (!strcasecmp(name, standard_iwads[i].name))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2190,6 +1975,12 @@ void D_DoomMain(void)
|
|||||||
puts("W_Init: Init WADfiles.");
|
puts("W_Init: Init WADfiles.");
|
||||||
W_InitMultipleFiles(wadfiles);
|
W_InitMultipleFiles(wadfiles);
|
||||||
|
|
||||||
|
// Check for wolf levels
|
||||||
|
{
|
||||||
|
int lumpnum = W_CheckNumForName("map31");
|
||||||
|
haswolflevels = (lumpnum >= 0 && W_IsIWADLump(lumpnum));
|
||||||
|
}
|
||||||
|
|
||||||
// Moved after WAD initialization because we are checking the COMPLVL lump
|
// Moved after WAD initialization because we are checking the COMPLVL lump
|
||||||
G_ReloadDefaults(); // killough 3/4/98: set defaults just loaded.
|
G_ReloadDefaults(); // killough 3/4/98: set defaults just loaded.
|
||||||
// jff 3/24/98 this sets startskill if it was -1
|
// jff 3/24/98 this sets startskill if it was -1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user