mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 13:31:37 +00:00
- disabled Zip related code in IWAD detection for now
- forgot to add new files. SVN r1498 (trunk)
This commit is contained in:
parent
505031fa5a
commit
a150f6f9b7
3 changed files with 710 additions and 0 deletions
|
@ -1,4 +1,5 @@
|
|||
March 22, 2009 (Changes by Graf Zahl)
|
||||
- removed gamemission variable because it wasn't used anywhere.
|
||||
- removed gamemode variable. All it was used for were some checks that
|
||||
really should depend on GI_MAPxx.
|
||||
- Externalized all internal gameinfo definitions.
|
||||
|
|
691
src/d_iwad.cpp
Normal file
691
src/d_iwad.cpp
Normal file
|
@ -0,0 +1,691 @@
|
|||
/*
|
||||
** d_iwad.cpp
|
||||
** IWAD detection code
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2009 Randy Heit
|
||||
** Copyright 2009 CHristoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
#include "d_main.h"
|
||||
#include "gi.h"
|
||||
#include "cmdlib.h"
|
||||
#include "doomstat.h"
|
||||
#include "i_system.h"
|
||||
#include "w_wad.h"
|
||||
#include "w_zip.h"
|
||||
#include "v_palette.h"
|
||||
#include "m_argv.h"
|
||||
#include "c_cvars.h"
|
||||
#include "gameconfigfile.h"
|
||||
|
||||
|
||||
CVAR (Bool, queryiwad, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||
CVAR (String, defaultiwad, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||
|
||||
// If autoname is NULL, that's either because that game doesn't allow
|
||||
// loading of external wads or because it's already caught by the
|
||||
// general game-specific wads section.
|
||||
const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
|
||||
{
|
||||
// banner text, autoname, fg color, bg color
|
||||
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx },
|
||||
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx },
|
||||
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
|
||||
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
|
||||
{ "Hexen: Demo Version", "HexenDemo",MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_SHAREWARE },
|
||||
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
|
||||
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/hereticsw.txt",GI_SHAREWARE },
|
||||
{ "Heretic: Shadow of the Serpent Riders", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt", GI_MENUHACK_EXTENDED },
|
||||
{ "Heretic", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt" },
|
||||
{ "DOOM Shareware", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt", GI_SHAREWARE },
|
||||
{ "The Ultimate DOOM", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/ultdoom.txt" },
|
||||
{ "DOOM Registered", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt" },
|
||||
{ "Strife: Quest for the Sigil", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx },
|
||||
{ "Strife: Teaser (Old Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx | GI_SHAREWARE },
|
||||
{ "Strife: Teaser (New Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx | GI_SHAREWARE | GI_TEASER2 },
|
||||
{ "Freedoom", "Freedoom", MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
|
||||
{ "Freedoom \"Demo\"", "Freedoom1",MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom1.txt" },
|
||||
{ "FreeDM", "FreeDM", MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
|
||||
{ "Chex(R) Quest", "Chex1", MAKERGB(255,255,0), MAKERGB(0,192,0), GAME_Chex, "mapinfo/chex.txt" },
|
||||
{ "Chex(R) Quest 3", "Chex3", MAKERGB(255,255,0), MAKERGB(0,192,0), GAME_Chex, "mapinfo/chex3.txt" },
|
||||
//{ "ZDoom Engine", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168) },
|
||||
};
|
||||
|
||||
static const char *IWADNames[] =
|
||||
{
|
||||
NULL,
|
||||
"doom2f.wad",
|
||||
"doom2.wad",
|
||||
"plutonia.wad",
|
||||
"tnt.wad",
|
||||
"doomu.wad", // Hack from original Linux version. Not necessary, but I threw it in anyway.
|
||||
"doom.wad",
|
||||
"doom1.wad",
|
||||
"heretic.wad",
|
||||
"heretic1.wad",
|
||||
"hexen.wad",
|
||||
"hexdd.wad",
|
||||
"hexendemo.wad",
|
||||
"hexdemo.wad",
|
||||
"strife1.wad",
|
||||
"strife0.wad",
|
||||
"freedoom.wad", // Freedoom.wad is distributed as Doom2.wad, but this allows to have both in the same directory.
|
||||
"freedoom1.wad",
|
||||
"freedm.wad",
|
||||
"chex.wad",
|
||||
"chex3.wad",
|
||||
#ifdef unix
|
||||
"DOOM2.WAD", // Also look for all-uppercase names
|
||||
"PLUTONIA.WAD",
|
||||
"TNT.WAD",
|
||||
"DOOM.WAD",
|
||||
"DOOM1.WAD",
|
||||
"HERETIC.WAD",
|
||||
"HERETIC1.WAD",
|
||||
"HEXEN.WAD",
|
||||
"HEXDD.WAD",
|
||||
"HEXENDEMO.WAD",
|
||||
"HEXDEMO.WAD",
|
||||
"STRIFE1.WAD",
|
||||
"STRIFE0.WAD",
|
||||
"FREEDOOM.WAD",
|
||||
"FREEDOOM1.WAD",
|
||||
"FREEDM.WAD",
|
||||
"CHEX.WAD",
|
||||
"CHEX3.WAD",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanIWAD
|
||||
//
|
||||
// Scan the contents of an IWAD to determine which one it is
|
||||
//==========================================================================
|
||||
|
||||
static EIWADType ScanIWAD (const char *iwad)
|
||||
{
|
||||
static const char checklumps[][8] =
|
||||
{
|
||||
"E1M1",
|
||||
"E4M2",
|
||||
"MAP01",
|
||||
"MAP40",
|
||||
"MAP60",
|
||||
"TITLE",
|
||||
"REDTNT2",
|
||||
"CAMO1",
|
||||
{ 'E','X','T','E','N','D','E','D'},
|
||||
"ENDSTRF",
|
||||
"MAP33",
|
||||
"INVCURS",
|
||||
{ 'F','R','E','E','D','O','O','M' },
|
||||
"W94_1",
|
||||
{ 'P','O','S','S','H','0','M','0' },
|
||||
"CYCLA1",
|
||||
"FLMBA1",
|
||||
"MAPINFO",
|
||||
{ 'G','A','M','E','I','N','F','O' },
|
||||
"E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9",
|
||||
"E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9",
|
||||
"DPHOOF","BFGGA0","HEADA1","CYBRA1",
|
||||
{ 'S','P','I','D','A','1','D','1' },
|
||||
|
||||
};
|
||||
#define NUM_CHECKLUMPS (sizeof(checklumps)/8)
|
||||
enum
|
||||
{
|
||||
Check_e1m1,
|
||||
Check_e4m1,
|
||||
Check_map01,
|
||||
Check_map40,
|
||||
Check_map60,
|
||||
Check_title,
|
||||
Check_redtnt2,
|
||||
Check_cam01,
|
||||
Check_Extended,
|
||||
Check_endstrf,
|
||||
Check_map33,
|
||||
Check_invcurs,
|
||||
Check_FreeDoom,
|
||||
Check_W94_1,
|
||||
Check_POSSH0M0,
|
||||
Check_Cycla1,
|
||||
Check_Flmba1,
|
||||
Check_Mapinfo,
|
||||
Check_Gameinfo,
|
||||
Check_e2m1
|
||||
};
|
||||
int lumpsfound[NUM_CHECKLUMPS];
|
||||
size_t i;
|
||||
wadinfo_t header;
|
||||
FILE *f;
|
||||
|
||||
memset (lumpsfound, 0, sizeof(lumpsfound));
|
||||
if ( (f = fopen (iwad, "rb")) )
|
||||
{
|
||||
fread (&header, sizeof(header), 1, f);
|
||||
if (header.Magic == IWAD_ID || header.Magic == PWAD_ID)
|
||||
{
|
||||
header.NumLumps = LittleLong(header.NumLumps);
|
||||
if (0 == fseek (f, LittleLong(header.InfoTableOfs), SEEK_SET))
|
||||
{
|
||||
for (i = 0; i < (size_t)header.NumLumps; i++)
|
||||
{
|
||||
wadlump_t lump;
|
||||
size_t j;
|
||||
|
||||
if (0 == fread (&lump, sizeof(lump), 1, f))
|
||||
break;
|
||||
for (j = 0; j < NUM_CHECKLUMPS; j++)
|
||||
if (strnicmp (lump.Name, checklumps[j], 8) == 0)
|
||||
lumpsfound[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (header.Magic == ZIP_ID)
|
||||
{ // Using a zip as an IWAD replacement requires that the key lumps be in the global scope.
|
||||
// This is because most of them will be "Custom IWADs" so all that we really should need
|
||||
// to find is GAMEINFO, but why limit ourselves?
|
||||
header.NumLumps = 0;
|
||||
FileReader *reader = new FileReader(f);
|
||||
DWORD centraldir = Zip_FindCentralDir(reader);
|
||||
delete reader;
|
||||
if (fseek(f, centraldir, SEEK_SET) == 0)
|
||||
{
|
||||
// First locate directory
|
||||
FZipEndOfCentralDirectory directory;
|
||||
if (0 != fread(&directory, sizeof(directory), 1, f) && LittleLong(directory.Magic) == 0x06054b50)
|
||||
{
|
||||
header.NumLumps += LittleLong(directory.NumEntries);
|
||||
if (fseek(f, LittleLong(directory.DirectoryOffset), SEEK_SET) == 0)
|
||||
{
|
||||
// Scan directory for lumps in the global scope with key names.
|
||||
do
|
||||
{
|
||||
FZipCentralDirectoryInfo entry;
|
||||
if (0 == fread(&entry, sizeof(entry), 1, f))
|
||||
break;
|
||||
if (LittleLong(entry.Magic) == 0x02014b50)
|
||||
{
|
||||
// Now determine the lump's short name
|
||||
char* fullname = new char[LittleLong(entry.NameLength)];
|
||||
if (0 == fread(fullname, LittleLong(entry.NameLength), 1, f))
|
||||
{
|
||||
delete[] fullname;
|
||||
break;
|
||||
}
|
||||
FString name = fullname;
|
||||
delete[] fullname;
|
||||
|
||||
if(name.LastIndexOf('/') != -1)
|
||||
continue;
|
||||
name.Truncate(name.LastIndexOf('.'));
|
||||
|
||||
for (size_t j = 0; j < NUM_CHECKLUMPS; j++)
|
||||
if (strnicmp (name, checklumps[j], 8) == 0)
|
||||
lumpsfound[j]++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
// Always check for custom iwads first.
|
||||
#if 0
|
||||
if (lumpsfound[Check_Gameinfo])
|
||||
{
|
||||
return IWAD_Custom;
|
||||
}
|
||||
#endif
|
||||
if (lumpsfound[Check_title] && lumpsfound[Check_map60])
|
||||
{
|
||||
return IWAD_HexenDK;
|
||||
}
|
||||
else if (lumpsfound[Check_map33] && lumpsfound[Check_endstrf])
|
||||
{
|
||||
if (lumpsfound[Check_map01])
|
||||
{
|
||||
return IWAD_Strife;
|
||||
}
|
||||
else if (lumpsfound[Check_invcurs])
|
||||
{
|
||||
return IWAD_StrifeTeaser2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_StrifeTeaser;
|
||||
}
|
||||
}
|
||||
else if (lumpsfound[Check_map01])
|
||||
{
|
||||
if (lumpsfound[Check_FreeDoom])
|
||||
{
|
||||
// Is there a 100% reliable way to tell FreeDoom and FreeDM
|
||||
// apart based solely on the lump names?
|
||||
if (strstr(iwad, "freedm.wad") || strstr(iwad, "FREEDM.WAD"))
|
||||
{
|
||||
return IWAD_FreeDM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_FreeDoom;
|
||||
}
|
||||
}
|
||||
else if (lumpsfound[Check_redtnt2])
|
||||
{
|
||||
return IWAD_Doom2TNT;
|
||||
}
|
||||
else if (lumpsfound[Check_cam01])
|
||||
{
|
||||
return IWAD_Doom2Plutonia;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lumpsfound[Check_title])
|
||||
{
|
||||
if (lumpsfound[Check_map40])
|
||||
{
|
||||
return IWAD_Hexen;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_HexenDemo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_Doom2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lumpsfound[Check_e1m1])
|
||||
{
|
||||
if (lumpsfound[Check_title])
|
||||
{
|
||||
if (!lumpsfound[Check_e2m1])
|
||||
{
|
||||
return IWAD_HereticShareware;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lumpsfound[Check_Extended])
|
||||
{
|
||||
return IWAD_HereticExtended;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_Heretic;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lumpsfound[Check_Cycla1] && lumpsfound[Check_Flmba1])
|
||||
{
|
||||
if (!lumpsfound[Check_Mapinfo])
|
||||
{
|
||||
// The original release won't work without its hacked custom EXE.
|
||||
//I_FatalError("Found an incompatible version of Chex Quest 3");
|
||||
return NUM_IWAD_TYPES; // Can't use it.
|
||||
}
|
||||
return IWAD_ChexQuest3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lumpsfound[Check_FreeDoom])
|
||||
{
|
||||
return IWAD_FreeDoom1;
|
||||
}
|
||||
for (i = Check_e2m1; i < NUM_CHECKLUMPS; i++)
|
||||
{
|
||||
if (!lumpsfound[i])
|
||||
{
|
||||
return IWAD_DoomShareware;
|
||||
}
|
||||
}
|
||||
if (i == NUM_CHECKLUMPS)
|
||||
{
|
||||
if (lumpsfound[Check_e4m1])
|
||||
{
|
||||
if (lumpsfound[Check_W94_1] && lumpsfound[Check_POSSH0M0])
|
||||
{
|
||||
return IWAD_ChexQuest;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_UltimateDoom;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return IWAD_DoomRegistered;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NUM_IWAD_TYPES; // Don't know
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckIWAD
|
||||
//
|
||||
// Tries to find an IWAD from a set of known IWAD names, and checks the
|
||||
// contents of each one found to determine which game it belongs to.
|
||||
// Returns the number of new wads found in this pass (does not count wads
|
||||
// found from a previous call).
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
|
||||
{
|
||||
const char *slash;
|
||||
int i;
|
||||
int numfound;
|
||||
|
||||
numfound = 0;
|
||||
|
||||
slash = (doomwaddir[0] && doomwaddir[strlen (doomwaddir)-1] != '/') ? "/" : "";
|
||||
|
||||
// Search for a pre-defined IWAD
|
||||
for (i = IWADNames[0] ? 0 : 1; IWADNames[i]; i++)
|
||||
{
|
||||
if (wads[i].Path.IsEmpty())
|
||||
{
|
||||
FString iwad;
|
||||
|
||||
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
|
||||
FixPathSeperator (iwad.LockBuffer());
|
||||
iwad.UnlockBuffer();
|
||||
if (FileExists (iwad))
|
||||
{
|
||||
wads[i].Type = ScanIWAD (iwad);
|
||||
if (wads[i].Type != NUM_IWAD_TYPES)
|
||||
{
|
||||
wads[i].Path = iwad;
|
||||
numfound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return numfound;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckIWADinEnvDir
|
||||
//
|
||||
// Checks for an IWAD in a path that contains one or more environment
|
||||
// variables.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int CheckIWADinEnvDir (const char *str, WadStuff *wads)
|
||||
{
|
||||
FString expanded = ExpandEnvVars (str);
|
||||
|
||||
if (!expanded.IsEmpty())
|
||||
{
|
||||
char *dir = expanded.LockBuffer ();
|
||||
FixPathSeperator (dir);
|
||||
expanded.UnlockBuffer ();
|
||||
if (expanded[expanded.Len() - 1] != '/')
|
||||
{
|
||||
expanded += '/';
|
||||
}
|
||||
return CheckIWAD (expanded, wads);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// IdentifyVersion
|
||||
//
|
||||
// Tries to find an IWAD in one of four directories under DOS or Win32:
|
||||
// 1. Current directory
|
||||
// 2. Executable directory
|
||||
// 3. $DOOMWADDIR
|
||||
// 4. $HOME
|
||||
//
|
||||
// Under UNIX OSes, the search path is:
|
||||
// 1. Current directory
|
||||
// 2. $DOOMWADDIR
|
||||
// 3. $HOME/.zdoom
|
||||
// 4. The share directory defined at compile time (/usr/local/share/zdoom)
|
||||
//
|
||||
// The search path can be altered by editing the IWADSearch.Directories
|
||||
// section of the config file.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static EIWADType IdentifyVersion (const char *zdoom_wad)
|
||||
{
|
||||
WadStuff wads[countof(IWADNames)];
|
||||
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
|
||||
const char *iwadparm = Args->CheckValue ("-iwad");
|
||||
size_t numwads;
|
||||
int pickwad;
|
||||
size_t i;
|
||||
bool iwadparmfound = false;
|
||||
FString custwad;
|
||||
|
||||
if (iwadparm)
|
||||
{
|
||||
custwad = iwadparm;
|
||||
FixPathSeperator (custwad.LockBuffer());
|
||||
if (CheckIWAD (custwad, wads))
|
||||
{ // -iwad parameter was a directory
|
||||
iwadparm = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultExtension (custwad, ".wad");
|
||||
iwadparm = custwad;
|
||||
IWADNames[0] = iwadparm;
|
||||
CheckIWAD ("", wads);
|
||||
}
|
||||
}
|
||||
|
||||
if (iwadparm == NULL || wads[0].Path.IsEmpty())
|
||||
{
|
||||
if (GameConfig->SetSection ("IWADSearch.Directories"))
|
||||
{
|
||||
const char *key;
|
||||
const char *value;
|
||||
|
||||
while (GameConfig->NextInSection (key, value))
|
||||
{
|
||||
if (stricmp (key, "Path") == 0)
|
||||
{
|
||||
if (strchr (value, '$') != NULL)
|
||||
{
|
||||
CheckIWADinEnvDir (value, wads);
|
||||
}
|
||||
#ifdef unix
|
||||
else if (*value == '~' && (*(value + 1) == 0 || *(value + 1) == '/'))
|
||||
{
|
||||
FString homepath = GetUserFile (*(value + 1) ? value + 2 : value + 1, true);
|
||||
CheckIWAD (homepath, wads);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
CheckIWAD (value, wads);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
FString steam_path = I_GetSteamPath();
|
||||
if (steam_path.IsNotEmpty())
|
||||
{
|
||||
static const char *const steam_dirs[] =
|
||||
{
|
||||
"doom 2/base",
|
||||
"final doom/base",
|
||||
"heretic shadow of the serpent riders/base",
|
||||
"hexen/base",
|
||||
"hexen deathkings of the dark citadel/base",
|
||||
"ultimate doom/base"
|
||||
};
|
||||
steam_path += "/SteamApps/common/";
|
||||
for (i = 0; i < countof(steam_dirs); ++i)
|
||||
{
|
||||
CheckIWAD (steam_path + steam_dirs[i], wads);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (iwadparm != NULL && !wads[0].Path.IsEmpty())
|
||||
{
|
||||
iwadparmfound = true;
|
||||
}
|
||||
|
||||
for (i = numwads = 0; i < countof(IWADNames); i++)
|
||||
{
|
||||
if (!wads[i].Path.IsEmpty())
|
||||
{
|
||||
if (i != numwads)
|
||||
{
|
||||
wads[numwads] = wads[i];
|
||||
}
|
||||
foundwads[wads[numwads].Type] = numwads + 1;
|
||||
numwads++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundwads[IWAD_HexenDK] && !foundwads[IWAD_Hexen])
|
||||
{ // Cannot play Hexen DK without Hexen
|
||||
size_t kill = foundwads[IWAD_HexenDK];
|
||||
for (i = kill; i < numwads; ++i)
|
||||
{
|
||||
wads[i - 1] = wads[i];
|
||||
}
|
||||
numwads--;
|
||||
foundwads[IWAD_HexenDK] = 0;
|
||||
for (i = 0; i < NUM_IWAD_TYPES; ++i)
|
||||
{
|
||||
if (foundwads[i] > kill)
|
||||
{
|
||||
foundwads[i]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numwads == 0)
|
||||
{
|
||||
I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n"
|
||||
"Did you install ZDoom properly? You can do either of the following:\n"
|
||||
"\n"
|
||||
"1. Place one or more of these wads in the same directory as ZDoom.\n"
|
||||
"2. Edit your zdoom-username.ini and add the directories of your iwads\n"
|
||||
"to the list beneath [IWADSearch.Directories]");
|
||||
}
|
||||
|
||||
pickwad = 0;
|
||||
|
||||
if (!iwadparmfound && numwads > 1)
|
||||
{
|
||||
int defiwad = 0;
|
||||
|
||||
// Locate the user's prefered IWAD, if it was found.
|
||||
if (defaultiwad[0] != '\0')
|
||||
{
|
||||
for (i = 0; i < numwads; ++i)
|
||||
{
|
||||
FString basename = ExtractFileBase (wads[i].Path);
|
||||
if (stricmp (basename, defaultiwad) == 0)
|
||||
{
|
||||
defiwad = (int)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pickwad = I_PickIWad (wads, (int)numwads, queryiwad, defiwad);
|
||||
if (pickwad >= 0)
|
||||
{
|
||||
// The newly selected IWAD becomes the new default
|
||||
FString basename = ExtractFileBase (wads[pickwad].Path);
|
||||
defaultiwad = basename;
|
||||
}
|
||||
}
|
||||
|
||||
if (pickwad < 0)
|
||||
exit (0);
|
||||
|
||||
// zdoom.pk3 must always be the first file loaded and the IWAD second.
|
||||
D_AddFile (zdoom_wad);
|
||||
|
||||
if (wads[pickwad].Type == IWAD_HexenDK)
|
||||
{ // load hexen.wad before loading hexdd.wad
|
||||
D_AddFile (wads[foundwads[IWAD_Hexen]-1].Path);
|
||||
}
|
||||
|
||||
D_AddFile (wads[pickwad].Path);
|
||||
|
||||
if (wads[pickwad].Type == IWAD_Strife)
|
||||
{ // Try to load voices.wad along with strife1.wad
|
||||
long lastslash = wads[pickwad].Path.LastIndexOf ('/');
|
||||
FString path;
|
||||
|
||||
if (lastslash == -1)
|
||||
{
|
||||
path = "";// wads[pickwad].Path;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = FString (wads[pickwad].Path.GetChars(), lastslash + 1);
|
||||
}
|
||||
path += "voices.wad";
|
||||
D_AddFile (path);
|
||||
}
|
||||
|
||||
return wads[pickwad].Type;
|
||||
}
|
||||
|
||||
|
||||
const IWADInfo *D_FindIWAD(const char *basewad)
|
||||
{
|
||||
EIWADType iwadType = IdentifyVersion(basewad);
|
||||
const IWADInfo *iwad_info = &IWADInfos[iwadType];
|
||||
I_SetIWADInfo(iwad_info);
|
||||
return iwad_info;
|
||||
}
|
18
src/gametype.h
Normal file
18
src/gametype.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef EGAMETYPE
|
||||
#define EGAMETYPE
|
||||
enum EGameType
|
||||
{
|
||||
GAME_Any = 0,
|
||||
GAME_Doom = 1,
|
||||
GAME_Heretic = 2,
|
||||
GAME_Hexen = 4,
|
||||
GAME_Strife = 8,
|
||||
GAME_Chex = 16, //Chex is basically Doom, but we need to have a different set of actors.
|
||||
|
||||
GAME_Raven = GAME_Heretic|GAME_Hexen,
|
||||
GAME_DoomStrife = GAME_Doom|GAME_Strife,
|
||||
GAME_DoomChex = GAME_Doom|GAME_Chex,
|
||||
GAME_DoomStrifeChex = GAME_Doom|GAME_Strife|GAME_Chex
|
||||
};
|
||||
#endif
|
||||
|
Loading…
Reference in a new issue