- Each IWAD can now define its own config section. Hacx, Harmony and Action Doom2 now do that.

- moved IWAD identification data into a lump in zdoom.pk3.
- rewrote IWAD checking code 

SVN r2943 (trunk)
This commit is contained in:
Christoph Oelckers 2010-10-15 15:13:53 +00:00
parent 7068c1df48
commit eded2ef345
16 changed files with 683 additions and 466 deletions

View file

@ -43,6 +43,8 @@
#include "m_argv.h"
#include "m_misc.h"
#include "c_cvars.h"
#include "sc_man.h"
#include "v_video.h"
#include "gameconfigfile.h"
#include "resourcefiles/resourcefile.h"
@ -50,99 +52,224 @@
CVAR (Bool, queryiwad, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
CVAR (String, defaultiwad, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
EIWADType gameiwad;
//==========================================================================
//
// Clear check list
//
//==========================================================================
// 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] =
void FIWadManager::ClearChecks()
{
// 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 | GI_COMPATSHORTTEX | GI_COMPATSTAIRS },
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx | GI_COMPATSHORTTEX },
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_COMPATPOLY1 },
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexdd.txt", GI_MAPxx | GI_COMPATPOLY1 | GI_COMPATPOLY2 },
{ "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 | GI_COMPATSHORTTEX },
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/hereticsw.txt",GI_SHAREWARE },
{ "Heretic: Shadow of the Serpent Riders", "Heretic1", MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt", GI_MENUHACK_EXTENDED },
{ "Heretic", "Heretic1", 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 | GI_COMPATSHORTTEX },
{ "The Ultimate DOOM", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/ultdoom.txt", GI_COMPATSHORTTEX },
{ "DOOM Registered", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt", GI_COMPATSHORTTEX },
{ "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 },
{ "Ultimate Freedoom", "Freedoom1",MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom1.txt" },
{ "Freedoom \"Demo\"", NULL, 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 },
{ "Blasphemer", "Blasphemer",MAKERGB(115,0,0), MAKERGB(0,0,0), GAME_Heretic, "mapinfo/heretic.txt" },
{ "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", GI_NOTEXTCOLOR },
{ "Action Doom 2: Urban Brawl", "UrbanBrawl",MAKERGB(168,168,0), MAKERGB(168,0,0), GAME_Doom, "mapinfo/urbanbrawl.txt", GI_MAPxx },
{ "Harmony", "Harmony", MAKERGB(110,180,230), MAKERGB(69,79,126), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "Hacx: Twitch n' Kill", "Hacx", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
//{ "ZDoom Engine", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168) },
};
mLumpsFound.Resize(mIWads.Size());
for(unsigned i=0;i<mLumpsFound.Size(); i++)
{
mLumpsFound[i] = 0;
}
}
static const char *IWADNames[] =
//==========================================================================
//
// Check one lump
//
//==========================================================================
void FIWadManager::CheckLumpName(const char *name)
{
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",
"freedoomu.wad",
"freedm.wad",
"blasphem.wad",
"blasphemer.wad",
"chex.wad",
"chex3.wad",
"action2.wad",
"harm1.wad",
"hacx.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",
"FREEDOOMU.WAD",
"FREEDM.WAD",
"BLASPHEM.WAD",
"BLASPHEMER.WAD",
"CHEX.WAD",
"CHEX3.WAD",
"ACTION2.WAD",
"HARM1.WAD",
"HACX.WAD",
for(unsigned i=0; i< mIWads.Size(); i++)
{
for(unsigned j=0; j < mIWads[i].Lumps.Size(); j++)
{
if (!mIWads[i].Lumps[j].CompareNoCase(name))
{
mLumpsFound[i] |= (1<<j);
}
}
}
}
//==========================================================================
//
// Returns check result
//
//==========================================================================
int FIWadManager::GetIWadInfo()
{
for(unsigned i=0; i< mIWads.Size(); i++)
{
if (mLumpsFound[i] == (1 << mIWads[i].Lumps.Size()) - 1)
{
return i;
}
}
return -1;
}
//==========================================================================
//
// Parses IWAD definitions
//
//==========================================================================
void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize)
{
FScanner sc;
sc.OpenMem("IWADINFO", data, datasize);
while (sc.GetString())
{
if (sc.Compare("IWAD"))
{
FIWADInfo *iwad = &mIWads[mIWads.Reserve(1)];
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("Name"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->Name = sc.String;
}
else if (sc.Compare("Autoname"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->Autoname = sc.String;
}
else if (sc.Compare("Config"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->Configname = sc.String;
}
else if (sc.Compare("Game"))
{
sc.MustGetStringName("=");
sc.MustGetString();
if (sc.Compare("Doom")) iwad->gametype = GAME_Doom;
else if (sc.Compare("Heretic")) iwad->gametype = GAME_Heretic;
else if (sc.Compare("Hexen")) iwad->gametype = GAME_Hexen;
else if (sc.Compare("Strife")) iwad->gametype = GAME_Strife;
else if (sc.Compare("Chex")) iwad->gametype = GAME_Chex;
else sc.ScriptError(NULL);
}
else if (sc.Compare("Mapinfo"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->MapInfo = sc.String;
}
else if (sc.Compare("Compatibility"))
{
sc.MustGetStringName("=");
do
{
sc.MustGetString();
if(sc.Compare("NoTextcolor")) iwad->flags |= GI_NOTEXTCOLOR;
else if(sc.Compare("Poly1")) iwad->flags |= GI_COMPATPOLY1;
else if(sc.Compare("Poly2")) iwad->flags |= GI_COMPATPOLY2;
else if(sc.Compare("Shareware")) iwad->flags |= GI_SHAREWARE;
else if(sc.Compare("Teaser2")) iwad->flags |= GI_TEASER2;
else if(sc.Compare("Extended")) iwad->flags |= GI_MENUHACK_EXTENDED;
else if(sc.Compare("Shorttex")) iwad->flags |= GI_COMPATSHORTTEX;
else if(sc.Compare("Stairs")) iwad->flags |= GI_COMPATSTAIRS;
else sc.ScriptError(NULL);
}
while (sc.CheckString(","));
}
else if (sc.Compare("MustContain"))
{
sc.MustGetStringName("=");
do
{
sc.MustGetString();
iwad->Lumps.Push(FString(sc.String));
}
while (sc.CheckString(","));
}
else if (sc.Compare("BannerColors"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->FgColor = V_GetColor(NULL, sc.String);
sc.MustGetStringName(",");
sc.MustGetString();
iwad->BkColor = V_GetColor(NULL, sc.String);
}
else if (sc.Compare("Load"))
{
sc.MustGetStringName("=");
do
{
sc.MustGetString();
iwad->Load.Push(FString(sc.String));
}
while (sc.CheckString(","));
}
else if (sc.Compare("Required"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->Required = sc.String;
}
else
{
sc.ScriptError("Unknown keyword '%s'", sc.String);
}
}
}
else if (sc.Compare("NAMES"))
{
sc.MustGetStringName("{");
mIWadNames.Push(FString());
while (!sc.CheckString("}"))
{
sc.MustGetString();
FString wadname = sc.String;
#ifdef _WIN32
mIWadNames.Push(wadname);
#else
// check for lowercase, uppercased first letter and full uppercase on Linux etc.
wadname.ToLower();
mIWadNames.Push(wadname);
wadname[0] = toupper(wadname[0]);
mIWadNames.Push(wadname);
wadname.ToUpper();
mIWadNames.Push(wadname);
#endif
NULL
};
}
}
}
}
//==========================================================================
//
// Lool for IWAD definition lump
//
//==========================================================================
void FIWadManager::ParseIWadInfos(const char *fn)
{
FResourceFile *resfile = FResourceFile::OpenResourceFile(fn, NULL, 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, "IWADINFO"))
{
// Found one!
ParseIWadInfo(resfile->Filename, (const char*)lmp->CacheLump(), lmp->LumpSize);
break;
}
}
delete resfile;
}
}
//==========================================================================
//
@ -151,279 +278,30 @@ static const char *IWADNames[] =
// Scan the contents of an IWAD to determine which one it is
//==========================================================================
static EIWADType ScanIWAD (const char *iwad)
int FIWadManager::ScanIWAD (const char *iwad)
{
static const char checklumps[][8] =
{
"AD2LIB",
"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' },
{ 'B','L','A','S','P','H','E','M' },
"W94_1",
{ 'P','O','S','S','H','0','M','0' },
"CYCLA1",
"FLMBA1",
"MAPINFO",
"0HAWK01",
"0CARA3",
"0NOSE1",
"HACX-R",
{ '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 (countof(checklumps))
enum
{
Check_ad2lib,
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_Blasphem,
Check_W94_1,
Check_POSSH0M0,
Check_Cycla1,
Check_Flmba1,
Check_Mapinfo,
Check_Hawk,
Check_Car,
Check_Nose,
Check_Hacx,
Check_Gameinfo,
Check_e2m1
};
bool lumpsfound[NUM_CHECKLUMPS];
size_t i;
memset (lumpsfound, 0, sizeof(lumpsfound));
FResourceFile *iwadfile = FResourceFile::OpenResourceFile(iwad, NULL, true);
if (iwadfile != NULL)
{
ClearChecks();
for(DWORD ii = 0; ii < iwadfile->LumpCount(); ii++)
{
FResourceLump *lump = iwadfile->GetLump(ii);
size_t j;
for (j = 0; j < NUM_CHECKLUMPS; j++)
CheckLumpName(lump->Name);
if (lump->FullName != NULL)
{
if (!lumpsfound[j])
if (strnicmp(lump->FullName, "maps/", 5) == 0)
{
if (strnicmp (lump->Name, checklumps[j], 8) == 0)
{
lumpsfound[j] = true;
break;
}
// Check for maps inside zips, too.
else if (lump->FullName != NULL)
{
if (checklumps[j][0] == 'E' && checklumps[j][2] == 'M' && checklumps[j][4] == '\0')
{
if (strnicmp(lump->FullName, "maps/", 5) == 0 &&
strnicmp(lump->FullName + 5, checklumps[j], 4) == 0 &&
stricmp(lump->FullName + 9, ".wad") == 0)
{
lumpsfound[j] = true;
break;
}
}
else if (checklumps[j][0] == 'M' && checklumps[j][1] == 'A' && checklumps[j][2] == 'P' &&
checklumps[j][5] == '\0')
{
if (strnicmp(lump->FullName, "maps/", 5) == 0 &&
strnicmp(lump->FullName + 5, checklumps[j], 5) == 0 &&
stricmp(lump->FullName + 10, ".wad") == 0)
{
lumpsfound[j] = true;
break;
}
}
}
FString mapname(lump->FullName+5, strcspn(lump->FullName+5, "."));
CheckLumpName(mapname);
}
}
}
delete iwadfile;
}
// 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; // Strife0.wad from 14 Mar 1996
}
else
{
return IWAD_StrifeTeaser; // Strife0.wad from 22 Feb 1996
}
}
else if (lumpsfound[Check_map01])
{
if (lumpsfound[Check_ad2lib])
{
return IWAD_ActionDoom2;
}
else if (lumpsfound[Check_Hawk] && lumpsfound[Check_Car] && lumpsfound[Check_Nose])
{
return IWAD_Harmony;
}
else if (lumpsfound[Check_Hacx])
{
return IWAD_Hacx;
}
else 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_Blasphem])
{
return IWAD_Blasphemer;
}
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])
{
if (!lumpsfound[Check_e2m1])
{
return IWAD_FreeDoom1;
}
else
{
return IWAD_FreeDoomU;
}
}
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
return GetIWadInfo();
}
//==========================================================================
@ -437,10 +315,9 @@ static EIWADType ScanIWAD (const char *iwad)
//
//==========================================================================
static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads)
{
const char *slash;
int i;
int numfound;
numfound = 0;
@ -448,20 +325,21 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
slash = (doomwaddir[0] && doomwaddir[strlen (doomwaddir)-1] != '/') ? "/" : "";
// Search for a pre-defined IWAD
for (i = IWADNames[0] ? 0 : 1; IWADNames[i]; i++)
for (unsigned i=0; i< mIWadNames.Size(); i++)
{
if (wads[i].Path.IsEmpty())
if (mIWadNames[i].IsNotEmpty() && wads[i].Path.IsEmpty())
{
FString iwad;
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
iwad.Format ("%s%s%s", doomwaddir, slash, mIWadNames[i]);
FixPathSeperator (iwad);
if (FileExists (iwad))
{
wads[i].Type = ScanIWAD (iwad);
if (wads[i].Type != NUM_IWAD_TYPES)
if (wads[i].Type != -1)
{
wads[i].Path = iwad;
wads[i].Name = mIWads[wads[i].Type].Name;
numfound++;
}
}
@ -492,10 +370,10 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
//
//==========================================================================
static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad)
int FIWadManager::IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad)
{
WadStuff wads[countof(IWADNames)];
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
TArray<WadStuff> wads;
TArray<size_t> foundwads;
const char *iwadparm = Args->CheckValue ("-iwad");
size_t numwads;
int pickwad;
@ -503,6 +381,11 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
bool iwadparmfound = false;
FString custwad;
ParseIWadInfos(zdoom_wad);
wads.Resize(mIWadNames.Size());
foundwads.Resize(mIWads.Size());
memset(&foundwads[0], 0, foundwads.Size() * sizeof(foundwads[0]));
if (iwadparm == NULL && iwad != NULL && *iwad != 0)
{
iwadparm = iwad;
@ -512,7 +395,7 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
{
custwad = iwadparm;
FixPathSeperator (custwad);
if (CheckIWAD (custwad, wads))
if (CheckIWAD (custwad, &wads[0]))
{ // -iwad parameter was a directory
iwadparm = NULL;
}
@ -520,8 +403,8 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
{
DefaultExtension (custwad, ".wad");
iwadparm = custwad;
IWADNames[0] = iwadparm;
CheckIWAD ("", wads);
mIWadNames[0] = custwad;
CheckIWAD ("", &wads[0]);
}
}
@ -538,7 +421,7 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
{
FString nice = NicePath(value);
FixPathSeperator(nice);
CheckIWAD(nice, wads);
CheckIWAD(nice, &wads[0]);
}
}
}
@ -558,7 +441,7 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
steam_path += "/SteamApps/common/";
for (i = 0; i < countof(steam_dirs); ++i)
{
CheckIWAD (steam_path + steam_dirs[i], wads);
CheckIWAD (steam_path + steam_dirs[i], &wads[0]);
}
}
#endif
@ -569,7 +452,7 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
iwadparmfound = true;
}
for (i = numwads = 0; i < countof(IWADNames); i++)
for (i = numwads = 0; i < mIWadNames.Size(); i++)
{
if (!wads[i].Path.IsEmpty())
{
@ -582,20 +465,42 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
}
}
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)
for (unsigned i=0; i<mIWads.Size(); i++)
{
if (mIWads[i].Required.IsNotEmpty() && foundwads[i])
{
wads[i - 1] = wads[i];
}
numwads--;
foundwads[IWAD_HexenDK] = 0;
for (i = 0; i < NUM_IWAD_TYPES; ++i)
{
if (foundwads[i] > kill)
bool found = false;
// needs to be loaded with another IWAD (HexenDK)
for (unsigned j=0; j<mIWads.Size(); j++)
{
foundwads[i]--;
if (!mIWads[i].Required.Compare(mIWads[j].Name))
{
if (foundwads[j])
{
found = true;
mIWads[i].preload = j;
}
break;
}
}
// The required WAD is not there so this one can't be used and must be deleted from the list
if (!found)
{
size_t kill = foundwads[i];
for (size_t j = kill; j < numwads; ++j)
{
wads[j - 1] = wads[j];
}
numwads--;
foundwads[i] = 0;
for (unsigned j = 0; j < foundwads.Size(); ++j)
{
if (foundwads[j] > kill)
{
foundwads[j]--;
}
}
}
}
}
@ -629,7 +534,7 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
}
}
}
pickwad = I_PickIWad (wads, (int)numwads, queryiwad, defiwad);
pickwad = I_PickIWad (&wads[0], (int)numwads, queryiwad, defiwad);
if (pickwad >= 0)
{
// The newly selected IWAD becomes the new default
@ -644,15 +549,14 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
// zdoom.pk3 must always be the first file loaded and the IWAD second.
D_AddFile (wadfiles, zdoom_wad);
if (wads[pickwad].Type == IWAD_HexenDK)
{ // load hexen.wad before loading hexdd.wad
D_AddFile (wadfiles, wads[foundwads[IWAD_Hexen]-1].Path);
if (mIWads[wads[pickwad].Type].preload >= 0)
{
D_AddFile (wadfiles, wads[foundwads[mIWads[wads[pickwad].Type].preload]-1].Path);
}
D_AddFile (wadfiles, wads[pickwad].Path);
if (wads[pickwad].Type == IWAD_Strife)
{ // Try to load voices.wad along with strife1.wad
for (unsigned i=0; i < mIWads[wads[pickwad].Type].Load.Size(); i++)
{
long lastslash = wads[pickwad].Path.LastIndexOf ('/');
FString path;
@ -664,25 +568,31 @@ static EIWADType IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, c
{
path = FString (wads[pickwad].Path.GetChars(), lastslash + 1);
}
path += "voices.wad";
path += mIWads[wads[pickwad].Type].Load[i];
D_AddFile (wadfiles, path);
}
}
return wads[pickwad].Type;
}
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad)
//==========================================================================
//
// Find an IWAD to use for this game
//
//==========================================================================
const FIWADInfo *FIWadManager::FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad)
{
EIWADType iwadType = IdentifyVersion(wadfiles, iwad, basewad);
gameiwad = iwadType;
const IWADInfo *iwad_info = &IWADInfos[iwadType];
int iwadType = IdentifyVersion(wadfiles, iwad, basewad);
//gameiwad = iwadType;
const FIWADInfo *iwad_info = &mIWads[iwadType];
if (DoomStartupInfo.Name.IsEmpty()) DoomStartupInfo.Name = iwad_info->Name;
if (DoomStartupInfo.BkColor == 0 && DoomStartupInfo.FgColor == 0)
{
DoomStartupInfo.BkColor = iwad_info->BkColor;
DoomStartupInfo.FgColor = iwad_info->FgColor;
}
I_SetIWADInfo(iwad_info);
I_SetIWADInfo();
return iwad_info;
}

View file

@ -122,7 +122,7 @@ extern void M_SetDefaultMode ();
extern void R_ExecuteSetViewSize ();
extern void G_NewInit ();
extern void SetupPlayerClasses ();
const IWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -1873,11 +1873,13 @@ void D_DoomMain (void)
GetCmdLineFiles(pwads);
FString iwad = CheckGameInfo(pwads);
const IWADInfo *iwad_info = D_FindIWAD(allwads, iwad, basewad);
FIWadManager *iwad_man = new FIWadManager;
const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad);
gameinfo.gametype = iwad_info->gametype;
gameinfo.flags = iwad_info->flags;
gameinfo.ConfigName = iwad_info->Configname;
GameConfig->DoGameSetup (GameName());
GameConfig->DoGameSetup (gameinfo.ConfigName);
if (!(gameinfo.flags & GI_SHAREWARE) && !Args->CheckParm("-noautoload"))
{
@ -1910,7 +1912,7 @@ void D_DoomMain (void)
D_AddConfigWads (allwads, "Global.Autoload");
// Add game-specific wads
file = GameName();
file = gameinfo.ConfigName;
file += ".Autoload";
D_AddConfigWads (allwads, file);
@ -1925,7 +1927,7 @@ void D_DoomMain (void)
// Run automatically executed files
execFiles = new DArgs;
GameConfig->AddAutoexec (execFiles, GameName());
GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName);
D_MultiExec (execFiles, true);
// Run .cfg files at the start of the command line.
@ -2145,7 +2147,7 @@ void D_DoomMain (void)
StartScreen->Progress ();
Printf ("R_Init: Init %s refresh subsystem.\n", GameName());
Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars());
StartScreen->LoadingStatus ("Loading graphics", 0x3f);
R_Init ();
@ -2223,6 +2225,8 @@ void D_DoomMain (void)
// about to begin the game.
FBaseCVar::EnableNoSet ();
delete iwad_man; // now we won't need this anymore
// [RH] Run any saved commands from the command line or autoexec.cfg now.
gamestate = GS_FULLCONSOLE;
Net_NewMakeTic ();

View file

@ -56,55 +56,31 @@ bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check = true,
extern const char *D_DrawIcon;
enum EIWADType
{
IWAD_Doom2TNT,
IWAD_Doom2Plutonia,
IWAD_Hexen,
IWAD_HexenDK,
IWAD_HexenDemo,
IWAD_Doom2,
IWAD_HereticShareware,
IWAD_HereticExtended,
IWAD_Heretic,
IWAD_DoomShareware,
IWAD_UltimateDoom,
IWAD_DoomRegistered,
IWAD_Strife,
IWAD_StrifeTeaser,
IWAD_StrifeTeaser2,
IWAD_FreeDoom,
IWAD_FreeDoomU,
IWAD_FreeDoom1,
IWAD_FreeDM,
IWAD_Blasphemer,
IWAD_ChexQuest,
IWAD_ChexQuest3,
IWAD_ActionDoom2,
IWAD_Harmony,
IWAD_Hacx,
IWAD_Custom,
NUM_IWAD_TYPES
};
struct WadStuff
{
WadStuff() : Type(IWAD_Doom2TNT) {}
WadStuff() : Type(0) {}
FString Path;
EIWADType Type;
FString Name;
int Type;
};
struct IWADInfo
struct FIWADInfo
{
const char *Name; // Title banner text for this IWAD
const char *Autoname; // Name of autoload ini section for this IWAD
FString Name; // Title banner text for this IWAD
FString Autoname; // Name of autoload ini section for this IWAD
FString Configname; // Name of config section for this IWAD
FString Required; // Requires another IWAD
DWORD FgColor; // Foreground color for title banner
DWORD BkColor; // Background color for title banner
EGameType gametype; // which game are we playing?
const char *MapInfo; // Base mapinfo to load
FString MapInfo; // Base mapinfo to load
TArray<FString> Load; // Wads to be loaded with this one.
TArray<FString> Lumps; // Lump names for identification
int flags;
int preload;
FIWADInfo() { flags = 0; preload = -1; FgColor = 0; BkColor= 0xc0c0c0; gametype = GAME_Doom; }
};
struct FStartupInfo
@ -116,7 +92,30 @@ struct FStartupInfo
extern FStartupInfo DoomStartupInfo;
extern const IWADInfo IWADInfos[NUM_IWAD_TYPES];
extern EIWADType gameiwad;
//==========================================================================
//
// IWAD identifier class
//
//==========================================================================
struct FIWadManager
{
private:
TArray<FIWADInfo> mIWads;
TArray<FString> mIWadNames;
TArray<int> mLumpsFound;
void ParseIWadInfo(const char *fn, const char *data, int datasize);
void ParseIWadInfos(const char *fn);
void ClearChecks();
void CheckLumpName(const char *name);
int GetIWadInfo();
int ScanIWAD (const char *iwad);
int CheckIWAD (const char *doomwaddir, WadStuff *wads);
int IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad);
public:
const FIWADInfo *FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
};
#endif

View file

@ -62,6 +62,7 @@ extern HWND Window;
#include "a_pickups.h"
#include "doomstat.h"
#include "i_system.h"
#include "gi.h"
EXTERN_CVAR (Bool, con_centernotify)
EXTERN_CVAR (Int, msg0color)
@ -347,18 +348,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
{
const char *key;
const char *value;
enum { Doom, Heretic, Hexen, Strife, Chex } game;
if (strcmp (gamename, "Heretic") == 0)
game = Heretic;
else if (strcmp (gamename, "Hexen") == 0)
game = Hexen;
else if (strcmp (gamename, "Strife") == 0)
game = Strife;
else if (strcmp (gamename, "Chex") == 0)
game = Chex;
else
game = Doom;
if (bMigrating)
{
@ -380,9 +369,9 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
ReadCVars (0);
}
if (game == Heretic || game == Hexen)
if (gameinfo.gametype & GAME_Raven)
{
SetRavenDefaults (game == Hexen);
SetRavenDefaults (gameinfo.gametype == GAME_Hexen);
}
// The NetServerInfo section will be read when it's determined that

View file

@ -70,6 +70,7 @@ struct gameinfo_t
{
int flags;
EGameType gametype;
FString ConfigName;
char titlePage[9];
bool drawreadthis;
@ -135,7 +136,7 @@ struct gameinfo_t
extern gameinfo_t gameinfo;
inline const char *GameName()
inline const char *GameTypeName()
{
return GameNames[gameinfo.gametype];
}

View file

@ -48,10 +48,7 @@ static void LoadKeys (const char *modname, bool dbl)
{
char section[64];
if (GameName() == NULL)
return;
mysnprintf (section, countof(section), "%s.%s%sBindings", GameName(), modname,
mysnprintf (section, countof(section), "%s.%s%sBindings", gameinfo.ConfigName, modname,
dbl ? ".Double" : ".");
FKeyBindings *bindings = dbl? &DoubleBindings : &Bindings;

View file

@ -375,9 +375,9 @@ bool M_SaveDefaults (const char *filename)
GameConfig->ChangePathName (filename);
}
GameConfig->ArchiveGlobalData ();
if (GameName() != NULL)
if (gameinfo.ConfigName.IsNotEmpty())
{
GameConfig->ArchiveGameData (GameName());
GameConfig->ArchiveGameData (gameinfo.ConfigName);
}
success = GameConfig->WriteConfigFile ();
if (filename != NULL)
@ -619,7 +619,7 @@ static bool FindFreeName (FString &fullname, const char *extension)
for (i = 0; i <= 9999; i++)
{
const char *gamename = GameName();
const char *gamename = gameinfo.ConfigName;
time_t now;
tm *tm;

View file

@ -960,6 +960,6 @@ CCMD(reset2defaults)
CCMD(reset2saved)
{
GameConfig->DoGlobalSetup ();
GameConfig->DoGameSetup (GameName());
GameConfig->DoGameSetup (gameinfo.ConfigName);
R_SetViewSize (screenblocks);
}

View file

@ -1449,7 +1449,7 @@ public:
floordrop = true;
break;
default:
Printf("Unknown namespace %s. Using defaults for %s\n", sc.String, GameName());
Printf("Unknown namespace %s. Using defaults for %s\n", sc.String, GameTypeName());
switch (gameinfo.gametype)
{
default: // Shh, GCC

View file

@ -414,7 +414,7 @@ void STACK_ARGS I_Error (const char *error, ...)
throw CRecoverableError (errortext);
}
void I_SetIWADInfo (const IWADInfo *info)
void I_SetIWADInfo ()
{
}
@ -511,7 +511,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
0, filepart,
1, IWADInfos[wads[i].Type].Name,
1, wads[i].Name,
2, i,
-1);
if (i == defaultiwad)
@ -625,7 +625,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
filepart = wads[i].Path;
else
filepart++;
printf ("%d. %s (%s)\n", i+1, IWADInfos[wads[i].Type].Name, filepart);
printf ("%d. %s (%s)\n", i+1, wads[i].Name, filepart);
}
printf ("Which one? ");
scanf ("%d", &i);

View file

@ -115,8 +115,7 @@ void popterm ();
void I_PrintStr (const char *str);
// Set the title string of the startup window
struct IWADInfo;
void I_SetIWADInfo (const IWADInfo *info);
void I_SetIWADInfo ();
// Pick from multiple IWADs to use
int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad);

View file

@ -231,7 +231,7 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
sc.MustGetStringName("ifgame");
sc.MustGetStringName("(");
sc.MustGetString();
skip |= !sc.Compare(GameName());
skip |= !sc.Compare(GameTypeName());
sc.MustGetStringName(")");
sc.MustGetString();

View file

@ -406,7 +406,7 @@ void LayoutMainWindow (HWND hWnd, HWND pane)
//
//==========================================================================
void I_SetIWADInfo(const IWADInfo *info)
void I_SetIWADInfo()
{
// Make the startup banner show itself
LayoutMainWindow(Window, NULL);

View file

@ -1107,7 +1107,7 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
filepart = WadList[i].Path;
else
filepart++;
work.Format("%s (%s)", IWADInfos[WadList[i].Type].Name, filepart);
work.Format("%s (%s)", WadList[i].Name, filepart);
SendMessage(ctrl, LB_ADDSTRING, 0, (LPARAM)work.GetChars());
SendMessage(ctrl, LB_SETITEMDATA, i, (LPARAM)i);
}

View file

@ -125,8 +125,7 @@ void I_PaintConsole (void);
void I_PrintStr (const char *cp);
// Set the title string of the startup window
struct IWADInfo;
void I_SetIWADInfo (const IWADInfo *title);
void I_SetIWADInfo ();
// Pick from multiple IWADs to use
int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad);

319
wadsrc/static/iwadinfo.txt Normal file
View file

@ -0,0 +1,319 @@
// Must be sorted in identification order (easiest to recognize first!)
IWad
{
Name = "Harmony"
Game = "Doom"
Config = "Harmony"
Mapinfo = "mapinfo/doom2.txt"
MustContain = "MAP01", "0HAWK01", "0CARA3", "0NOSE1"
BannerColors = "6e b4 d6", "45 4f 7e"
}
IWad
{
Name = "Hacx: Twitch'n Kill"
Game = "Doom"
Config = "Hacx"
Mapinfo = "mapinfo/doom2.txt"
MustContain = "MAP01", "HACX-R"
BannerColors = "00 00 a8", "a8 a8 a8"
}
IWad
{
Name = "Action Doom 2: Urban Brawl"
Game = "Doom"
Config = "UrbanBrawl"
Mapinfo = "mapinfo/doom2.txt"
MustContain = "MAP01", "AD2LIB"
BannerColors = "a8 a8 00", "a8 00 00"
}
IWad
{
Name = "Chex(R) Quest 3"
Autoname = "Chex3"
Game = "Chex"
Config = "Chex"
Mapinfo = "mapinfo/chex.txt"
Compatibility = "NoTextcolor"
MustContain = "E1M1", "CYCLA1", "FLMBA1", "MAPINFO"
BannerColors = "ff ff 00", "00 c0 00"
}
IWad
{
Name = "Chex(R) Quest"
Autoname = "Chex1"
Game = "Chex"
Config = "Chex"
Mapinfo = "mapinfo/chex.txt"
MustContain = "E1M1", "E4M1", "W94_1", "POSSH0M0"
BannerColors = "ff ff 00", "00 c0 00"
}
IWad
{
Name = "Strife: Quest for the Sigil"
Game = "Strife"
Config = "Strife"
Mapinfo = "mapinfo/strife.txt"
MustContain = "MAP01", "MAP33", "ENDSTRF"
BannerColors = "d0 ad 99", "00 6b 65"
Load = "voices.wad"
}
IWad
{
Name = "Strife: Teaser (New Version)"
Game = "Strife"
Config = "Strife"
Mapinfo = "mapinfo/strife.txt"
Compatibility = "Shareware", "Teaser2"
MustContain = "MAP33", "ENDSTRF", "INVCURS"
BannerColors = "d0 ad 99", "00 6b 65"
}
IWad
{
Name = "Strife: Teaser (Old Version)"
Game = "Strife"
Config = "Strife"
Mapinfo = "mapinfo/strife.txt"
Compatibility = "Shareware"
MustContain = "MAP33", "ENDSTRF"
BannerColors = "d0 ad 99", "00 6b 65"
}
IWad
{
Name = "Hexen: Beyond Heretic"
Game = "Hexen"
Config = "Hexen"
Mapinfo = "mapinfo/doom2.txt"
Compatibility = "Poly1"
MustContain = "TITLE", "MAP01", "MAP40", "WINNOWR"
BannerColors = "f0 f0 f0", "6b 3c 18"
}
IWad
{
Name = "Hexen: Deathkings of the Dark Citadel"
Autoname = "HexenDK"
Game = "Hexen"
Config = "Hexen"
Mapinfo = "mapinfo/hexen.txt"
Compatibility = "Poly1", "Poly2"
MustContain = "TITLE", "MAP60", "CLUS1MSG"
BannerColors = "f0 f0 f0", "6b 3c 18"
Required = "Hexen: Beyond Heretic"
}
IWad
{
Name = "Hexen: Demo Version"
Game = "Hexen"
Config = "Hexen"
Mapinfo = "mapinfo/doom2.txt"
Compatibility = "Shareware"
MustContain = "TITLE", "MAP01", "WINNOWR"
BannerColors = "f0 f0 f0", "6b 3c 18"
}
IWad
{
Name = "Blasphemer"
Autoname = "Blasphemer"
Game = "Heretic"
Config = "Heretic"
Mapinfo = "mapinfo/heretic.txt"
MustContain = "E1M1", "E2M1", "TITLE", "BLASPHEM"
BannerColors = "73 00 00", "00 00 00"
}
IWad
{
Name = "Heretic: Shadow of the Serpent Riders"
Autoname = "Heretic1"
Game = "Heretic"
Config = "Heretic"
Mapinfo = "mapinfo/heretic.txt"
Compatibility = "Extended"
MustContain = "E1M1", "E2M1", "TITLE", "MUS_E1M1", "EXTENDED"
BannerColors = "fc fc 00", "a8 00 00"
}
IWad
{
Name = "Heretic"
Autoname = "Heretic1"
Game = "Heretic"
Config = "Heretic"
Mapinfo = "mapinfo/heretic.txt"
MustContain = "E1M1", "E2M1", "TITLE", "MUS_E1M1"
BannerColors = "fc fc 00", "a8 00 00"
}
IWad
{
Name = "Heretic Shareware"
Game = "Heretic"
Config = "Heretic"
Mapinfo = "mapinfo/hereticsw.txt"
Compatibility = "Shareware"
MustContain = "E1M1", "TITLE", "MUS_E1M1"
BannerColors = "fc fc 00", "a8 00 00"
}
IWad
{
Name = "FreeDM"
Autoname = "FreeDM"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"
MustContain = "MAP01", "FREEDM"
BannerColors = "32 54 43", "c6 dc d1"
}
IWad
{
Name = "Freedoom"
Autoname = "Freedoom"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"
MustContain = "MAP01", "FREEDOOM"
BannerColors = "32 54 43", "c6 dc d1"
}
IWad
{
Name = "Ultimate Freedoom"
Autoname = "Freedoom1"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
MustContain = "E1M1", "E2M1", "E3M1", "FREEDOOM"
BannerColors = "32 54 43", "c6 dc d1"
}
IWad
{
Name = "Freedoom 'Demo'"
Autoname = "Freedoom1"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"
MustContain = "E1M1", "FREEDOOM"
BannerColors = "32 54 43", "c6 dc d1"
}
IWad
{
Name = "The Ultimate DOOM"
Autoname = "Doom1"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
Compatibility = "Shorttex"
MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9",
"E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9",
"DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1", "E4M2"
BannerColors = "54 54 54", "a8 a8 a8"
}
IWad
{
Name = "DOOM Registered"
Autoname = "Doom1"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
Compatibility = "Shorttex"
MustContain = "E1M1","E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9",
"E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9",
"DPHOOF","BFGGA0","HEADA1","CYBRA1","SPIDA1D1"
BannerColors = "54 54 54", "a8 a8 a8"
}
IWad
{
Name = "DOOM Shareware"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
Compatibility = "Shareware", "Shorttex"
MustContain = "E1M1"
BannerColors = "54 54 54", "a8 a8 a8"
}
IWad
{
Name = "Final Doom: TNT - Evilution"
Autoname = "TNT"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/tnt.txt"
Compatibility = "Shorttex", "Stairs"
MustContain = "MAP01", "REDTNT2"
BannerColors = "a8 00 00", "a8 a8 a8"
}
IWad
{
Name = "Final Doom: Plutonia Experiment"
Autoname = "Plutonia"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/plutonia.txt"
Compatibility = "Shorttex"
MustContain = "MAP01", "CAMO1"
BannerColors = "a8 00 00", "a8 a8 a8"
}
// Doom 2 must be last to be checked becaude MAP01 is its only requirement
IWad
{
Name = "DOOM 2: Hell on Earth"
Autoname = "Doom2"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"
Compatibility = "Shorttex"
MustContain = "MAP01"
BannerColors = "a8 00 00", "a8 a8 a8"
}
Names
{
"doom2f.wad"
"doom2.wad"
"plutonia.wad"
"tnt.wad"
"doomu.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"
"freedoomu.wad"
"freedm.wad"
"blasphem.wad"
"blasphemer.wad"
"chex.wad"
"chex3.wad"
"action2.wad"
"harm1.wad"
"hacx.wad"
}