load IWAD from zip, cosmetic changes (#1703)

* Add more lump filters.

* Simplify `CheckIWAD` function, load IWAD from zip archive.

* Remove `PrintVersion` function.
This commit is contained in:
Roman Fomin 2024-05-25 21:10:29 +07:00 committed by GitHub
parent 045b3a2797
commit 49113c9d85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 68 additions and 118 deletions

View File

@ -28,20 +28,20 @@
#include "m_misc.h" #include "m_misc.h"
static const iwad_t iwads[] = { static const iwad_t iwads[] = {
{"doom2.wad", doom2, commercial, "Doom II" }, {"doom2.wad", doom2, commercial, "DOOM II: Hell on Earth" },
{"plutonia.wad", pack_plut, commercial, "Final Doom: Plutonia Experiment"}, {"plutonia.wad", pack_plut, commercial, "Final DOOM: Plutonia Experiment"},
{"tnt.wad", pack_tnt, commercial, "Final Doom: TNT: Evilution" }, {"tnt.wad", pack_tnt, commercial, "Final DOOM: TNT - Evilution" },
// "doom.wad" may be retail or registered // "doom.wad" may be retail or registered
{"doom.wad", doom, indetermined, "Doom" }, {"doom.wad", doom, indetermined, "DOOM" },
{"doom.wad", doom, registered, "Doom Registered" }, {"doom.wad", doom, registered, "DOOM Registered" },
{"doom.wad", doom, retail, "Ultimate Doom" }, {"doom.wad", doom, retail, "The Ultimate DOOM" },
{"doom1.wad", doom, shareware, "Doom Shareware" }, {"doom1.wad", doom, shareware, "DOOM Shareware" },
{"doom2f.wad", doom2, commercial, "Doom II: L'Enfer sur Terre" }, {"doom2f.wad", doom2, commercial, "DOOM II: L'Enfer sur Terre" },
{"freedoom2.wad", doom2, commercial, "Freedoom: Phase 2" }, {"freedoom2.wad", doom2, commercial, "Freedoom: Phase 2" },
{"freedoom1.wad", doom, retail, "Freedoom: Phase 1" }, {"freedoom1.wad", doom, retail, "Freedoom: Phase 1" },
{"freedm.wad", doom2, commercial, "FreeDM" }, {"freedm.wad", doom2, commercial, "FreeDM" },
{"chex.wad", pack_chex, retail, "Chex Quest" }, {"chex.wad", pack_chex, retail, "Chex Quest" },
{"hacx.wad", pack_hacx, commercial, "Hacx" }, {"hacx.wad", pack_hacx, commercial, "HACX: Twitch n' Kill" },
{"rekkrsa.wad", pack_rekkr, retail, "REKKR" }, {"rekkrsa.wad", pack_rekkr, retail, "REKKR" },
{"rekkrsl.wad", pack_rekkr, retail, "REKKR: Sunken Land" }, {"rekkrsl.wad", pack_rekkr, retail, "REKKR: Sunken Land" },
}; };
@ -747,7 +747,7 @@ char *D_FindLMPByName(const char *filename)
// D_FindIWADFile // D_FindIWADFile
// //
char *D_FindIWADFile(GameMode_t *mode, GameMission_t *mission) char *D_FindIWADFile(void)
{ {
char *result; char *result;
@ -792,22 +792,6 @@ char *D_FindIWADFile(GameMode_t *mode, GameMission_t *mission)
} }
} }
if (result)
{
int i;
const char *name = M_BaseName(result);
for (i = 0; i < arrlen(iwads); ++i)
{
if (!strcasecmp(name, iwads[i].name))
{
*mode = iwads[i].mode;
*mission = iwads[i].mission;
break;
}
}
}
return result; return result;
} }
@ -869,6 +853,20 @@ GameMission_t D_GetGameMissionByIWADName(const char *name)
return none; return none;
} }
void D_GetModeAndMissionByIWADName(const char *name, GameMode_t *mode,
GameMission_t *mission)
{
for (int i = 0; i < arrlen(iwads); ++i)
{
if (!strcasecmp(name, iwads[i].name))
{
*mode = iwads[i].mode;
*mission = iwads[i].mission;
break;
}
}
}
const char *D_GetIWADDescription(const char *name, GameMode_t mode, const char *D_GetIWADDescription(const char *name, GameMode_t mode,
GameMission_t mission) GameMission_t mission)
{ {

View File

@ -33,10 +33,12 @@ char *D_DoomExeDir(void); // killough 2/16/98: path to executable's dir
char *D_FindWADByName(const char *filename); char *D_FindWADByName(const char *filename);
char *D_TryFindWADByName(const char *filename); char *D_TryFindWADByName(const char *filename);
char *D_FindLMPByName(const char *filename); char *D_FindLMPByName(const char *filename);
char *D_FindIWADFile(GameMode_t *mode, GameMission_t *mission); char *D_FindIWADFile(void);
boolean D_IsIWADName(const char *name); boolean D_IsIWADName(const char *name);
const iwad_t **D_GetIwads(void); const iwad_t **D_GetIwads(void);
GameMission_t D_GetGameMissionByIWADName(const char *name); GameMission_t D_GetGameMissionByIWADName(const char *name);
void D_GetModeAndMissionByIWADName(const char *name, GameMode_t *mode,
GameMission_t *mission);
const char *D_GetIWADDescription(const char *name, GameMode_t mode, const char *D_GetIWADDescription(const char *name, GameMode_t mode,
GameMission_t mission); GameMission_t mission);

View File

@ -793,55 +793,16 @@ static void PrepareAutoloadPaths(void)
// CheckIWAD // CheckIWAD
// //
static void CheckIWAD(const char *iwadname) static void CheckIWAD(void)
{ {
int i; for (int i = 0; i < numlumps; ++i)
FILE *file;
wadinfo_t header;
filelump_t *fileinfo;
file = M_fopen(iwadname, "rb");
if (file == NULL)
{ {
I_Error("CheckIWAD: failed to read IWAD %s", iwadname); if (!strncasecmp(lumpinfo[i].name, "MAP01", 8))
}
// read IWAD header
if (fread(&header, sizeof(header), 1, file) != 1)
{
fclose(file);
I_Error("CheckIWAD: failed to read header %s", iwadname);
}
if (strncmp(header.identification, "IWAD", 4) &&
strncmp(header.identification, "PWAD", 4))
{
fclose(file);
I_Error("Wad file %s doesn't have IWAD or PWAD id\n", iwadname);
}
// read IWAD directory
header.numlumps = LONG(header.numlumps);
header.infotableofs = LONG(header.infotableofs);
fileinfo = malloc(header.numlumps * sizeof(filelump_t));
if (fseek(file, header.infotableofs, SEEK_SET) ||
fread(fileinfo, sizeof(filelump_t), header.numlumps, file) != header.numlumps)
{
free(fileinfo);
fclose(file);
I_Error("CheckIWAD: failed to read directory %s", iwadname);
}
for (i = 0; i < header.numlumps; ++i)
{
if (!strncasecmp(fileinfo[i].name, "MAP01", 8))
{ {
gamemission = doom2; gamemission = doom2;
break; break;
} }
else if (!strncasecmp(fileinfo[i].name, "E1M1", 8)) else if (!strncasecmp(lumpinfo[i].name, "E1M1", 8))
{ {
gamemode = shareware; gamemode = shareware;
gamemission = doom; gamemission = doom;
@ -855,23 +816,20 @@ static void CheckIWAD(const char *iwadname)
} }
else else
{ {
for (i = 0; i < header.numlumps; ++i) for (int i = 0; i < numlumps; ++i)
{ {
if (!strncasecmp(fileinfo[i].name, "E4M1", 8)) if (!strncasecmp(lumpinfo[i].name, "E4M1", 8))
{ {
gamemode = retail; gamemode = retail;
break; break;
} }
else if (!strncasecmp(fileinfo[i].name, "E3M1", 8)) else if (!strncasecmp(lumpinfo[i].name, "E3M1", 8))
{ {
gamemode = registered; gamemode = registered;
} }
} }
} }
free(fileinfo);
fclose(file);
if (gamemode == indetermined) if (gamemode == indetermined)
{ {
I_Error("Unknown or invalid IWAD file."); I_Error("Unknown or invalid IWAD file.");
@ -925,21 +883,6 @@ static boolean FileContainsMaps(const char *filename)
return false; return false;
} }
static void PrintVersion(const char *iwad)
{
I_Printf(VB_INFO, "IWAD found: %s", iwad); // jff 4/20/98 print only if
// found
I_Printf(VB_INFO, "%s\n", D_GetIWADDescription(M_BaseName(iwad), gamemode,
gamemission));
if (gamemode == indetermined)
{
I_Printf(VB_WARNING,
"Unknown Game Version, may not work\n"); // killough 8/8/98
}
}
// //
// IdentifyVersion // IdentifyVersion
// //
@ -1023,24 +966,26 @@ void IdentifyVersion(void)
// locate the IWAD and determine game mode from it // locate the IWAD and determine game mode from it
char *iwad = D_FindIWADFile(&gamemode, &gamemission); char *iwadfile = D_FindIWADFile();
if (iwad) if (!iwadfile)
{
if (gamemode == indetermined)
{
CheckIWAD(iwad);
}
PrintVersion(iwad);
I_Printf(VB_INFO, "W_Init: Init WADfiles.");
D_AddFile(iwad);
}
else
{ {
I_Error("IWAD not found"); I_Error("IWAD not found");
} }
I_Printf(VB_INFO, "W_Init: Init WADfiles.");
D_AddFile(iwadfile);
D_GetModeAndMissionByIWADName(M_BaseName(wadfiles[0]), &gamemode, &gamemission);
if (gamemode == indetermined)
{
CheckIWAD();
}
I_Printf(VB_INFO, " - \"%s\" version",
D_GetIWADDescription(M_BaseName(wadfiles[0]), gamemode, gamemission));
} }
// [FG] emulate a specific version of Doom // [FG] emulate a specific version of Doom
@ -2320,8 +2265,6 @@ void D_DoomMain(void)
W_ProcessInWads("BRGHTMPS", R_ParseBrightmaps, false); W_ProcessInWads("BRGHTMPS", R_ParseBrightmaps, false);
I_PutChar(VB_INFO, '\n'); // killough 3/6/98: add a newline, by popular demand :)
// Moved after WAD initialization because we are checking the COMPLVL lump // Moved after WAD initialization because we are checking the COMPLVL lump
G_ReloadDefaults(false); // killough 3/4/98: set defaults just loaded. G_ReloadDefaults(false); // 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
@ -2406,7 +2349,7 @@ void D_DoomMain(void)
} }
} }
I_Printf(VB_INFO, "Savegame directory: %s\n", basesavegame); I_Printf(VB_INFO, "Savegame directory: %s", basesavegame);
V_InitColorTranslation(); //jff 4/24/98 load color translation lumps V_InitColorTranslation(); //jff 4/24/98 load color translation lumps

View File

@ -113,10 +113,13 @@ static struct
GameMode_t mode; GameMode_t mode;
GameMission_t mission; GameMission_t mission;
} filters[] = { } filters[] = {
{"filter/doom", -1, -1 }, {"filter/doom", indetermined, none },
{"filter/doom.id", retail, doom }, {"filter/doom.id", indetermined, doom },
{"filter/doom.id", commercial, doom2 }, {"filter/doom.id.doom1", indetermined, doom },
{"filter/doom.id.doom2", commercial, doom2 }, {"filter/doom.id.doom1.registered", registered, doom },
{"filter/doom.id.doom1.ultimate", retail, doom },
{"filter/doom.id", indetermined, doom2 },
{"filter/doom.id.doom2", indetermined, doom2 },
{"filter/doom.id.doom2.commercial", commercial, doom2 }, {"filter/doom.id.doom2.commercial", commercial, doom2 },
{"filter/doom.id.doom2.plutonia", commercial, pack_plut}, {"filter/doom.id.doom2.plutonia", commercial, pack_plut},
{"filter/doom.id.doom2.tnt", commercial, pack_tnt }, {"filter/doom.id.doom2.tnt", commercial, pack_tnt },
@ -164,9 +167,13 @@ boolean W_AddPath(const char *path)
for (int i = 0; i < arrlen(filters); ++i) for (int i = 0; i < arrlen(filters); ++i)
{ {
if ((filters[i].mode >= 0 && filters[i].mode != gamemode) if (filters[i].mode != indetermined && filters[i].mode != gamemode)
|| (filters[i].mission >= 0 && gamemission > doom2 {
&& filters[i].mission != gamemission)) continue;
}
if (filters[i].mission != none && filters[i].mission != gamemission
&& !(gamemission > doom2 && filters[i].mission == doom2))
{ {
continue; continue;
} }