From fe54bb771d6f6a11b17834d6d875767f027f44a8 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Mon, 11 Apr 2022 00:23:40 +0700 Subject: [PATCH] Simplify FindIWADFile and CheckIWAD (#499) * simplify FindIWADFile and CheckIWAD * remove description * fix gcc warning * set haswolflevels after init wads * check default extension --- Source/d_main.c | 347 ++++++++++-------------------------------------- 1 file changed, 69 insertions(+), 278 deletions(-) diff --git a/Source/d_main.c b/Source/d_main.c index c44d12af..55ff22ac 100644 --- a/Source/d_main.c +++ b/Source/d_main.c @@ -146,24 +146,28 @@ boolean main_loop_started = false; boolean coop_spawns = false; //jff 4/19/98 list of standard IWAD names -const char *const standard_iwads[]= +typedef struct { - DIR_SEPARATOR_S"doom2f.wad", - DIR_SEPARATOR_S"doom2.wad", - DIR_SEPARATOR_S"plutonia.wad", - DIR_SEPARATOR_S"tnt.wad", - 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", + const char *name; + GameMission_t mission; + GameMode_t mode; +} iwad_t; - DIR_SEPARATOR_S"chex.wad", - DIR_SEPARATOR_S"hacx.wad", - DIR_SEPARATOR_S"rekkrsa.wad", +static iwad_t standard_iwads[] = +{ + { "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_CheckNetGame (void); @@ -743,281 +747,67 @@ static void PrepareAutoloadPaths (void) // // 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, GameMode_t *gmode, - GameMission_t *gmission, // joel 10/17/98 Final DOOM fix - boolean *hassec) + GameMission_t *gmission) // joel 10/17/98 Final DOOM fix { - FILE *fp = fopen(iwadname, "rb"); - int ud, rg, sw, cm, sc, tnt, plut, hacx, chex, rekkr; - filelump_t lump; - wadinfo_t header; - const char *n = lump.name; + int i; + const char *name = M_BaseName(iwadname); - if (!fp) - 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 + for (i = 0; i < arrlen(standard_iwads); ++i) { - *isdir=S_ISDIR(sbuf.st_mode); //if it does, set whether a dir or not - return true; //return does exist + if (!strcasecmp(name, standard_iwads[i].name)) + { + *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 // -// 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) { - static const char *envvars[] = {"DOOMWADDIR", "HOME"}; - char *iwad = NULL; - char *customiwad = NULL; - boolean isdir=false; - int i,j; - char *p; + char *result; + int iwadparm = M_CheckParmWithArgs("-iwad", 1); - int lbuf = 512; - int lcustomiwad = 0; - - //jff 3/24/98 get -iwad parm if specified else use . - if ((i = M_CheckParm("-iwad")) && i < myargc-1) + if (iwadparm) { - iwad = (malloc)(strlen(myargv[i+1]) + lbuf); - strcpy(iwad,myargv[i+1]); - NormalizeSlashes(iwad); - if (WadFileStatus(iwad,&isdir)) - if (!isdir) - return iwad; - else - for (i=0;i= 0 && W_IsIWADLump(lumpnum)); + } + // Moved after WAD initialization because we are checking the COMPLVL lump G_ReloadDefaults(); // killough 3/4/98: set defaults just loaded. // jff 3/24/98 this sets startskill if it was -1