- 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
commit eded2ef345
16 changed files with 663 additions and 446 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;
}