diff options
Diffstat (limited to 'src/d_iwad.c')
-rw-r--r-- | src/d_iwad.c | 420 |
1 files changed, 117 insertions, 303 deletions
diff --git a/src/d_iwad.c b/src/d_iwad.c index a810f2a2..438947af 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -29,9 +29,9 @@ #include <ctype.h> #include <string.h> -#include "deh_main.h" -#include "doomdef.h" -#include "doomstat.h" +#include "deh_str.h" +#include "doomkeys.h" +#include "d_iwad.h" #include "i_system.h" #include "m_argv.h" #include "m_config.h" @@ -39,6 +39,22 @@ #include "w_wad.h" #include "z_zone.h" +static iwad_t iwads[] = +{ + { "doom2.wad", doom2, commercial, "Doom II" }, + { "plutonia.wad", pack_plut, commercial, "Final Doom: Plutonia Experiment" }, + { "tnt.wad", pack_tnt, commercial, "Final Doom: TNT: Evilution" }, + { "doom.wad", doom, retail, "Doom" }, + { "doom1.wad", doom, shareware, "Doom Shareware" }, + { "chex.wad", pack_chex, shareware, "Chex Quest" }, + { "hacx.wad", pack_hacx, commercial, "Hacx" }, + { "heretic.wad", heretic, retail, "Heretic" }, + { "heretic1.wad", heretic, shareware, "Heretic Shareware" }, + { "hexen.wad", hexen, commercial, "Hexen" }, + //{ "strife0.wad", strife, commercial, "Strife" }, // haleyjd: STRIFE-FIXME + { "strife1.wad", strife, commercial, "Strife" }, +}; + // Array of locations to search for IWAD files // // "128 IWAD search directories should be enough for anybody". @@ -84,13 +100,21 @@ typedef struct // // With some munging we can find where Doom was installed. -static registry_value_t uninstall_values[] = +// [AlexMax] From the persepctive of a 64-bit executable, 32-bit registry +// keys are located in a different spot. +#if _WIN64 +#define SOFTWARE_KEY "Software\\Wow6432Node" +#else +#define SOFTWARE_KEY "Software" +#endif + +static registry_value_t uninstall_values[] = { // Ultimate Doom, CD version (Depths of Doom trilogy) { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" + HKEY_LOCAL_MACHINE, + SOFTWARE_KEY "\\Microsoft\\Windows\\CurrentVersion\\" "Uninstall\\Ultimate Doom for Windows 95", "UninstallString", }, @@ -98,8 +122,8 @@ static registry_value_t uninstall_values[] = // Doom II, CD version (Depths of Doom trilogy) { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" + HKEY_LOCAL_MACHINE, + SOFTWARE_KEY "\\Microsoft\\Windows\\CurrentVersion\\" "Uninstall\\Doom II for Windows 95", "UninstallString", }, @@ -107,8 +131,8 @@ static registry_value_t uninstall_values[] = // Final Doom { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" + HKEY_LOCAL_MACHINE, + SOFTWARE_KEY "\\Microsoft\\Windows\\CurrentVersion\\" "Uninstall\\Final Doom for Windows 95", "UninstallString", }, @@ -116,8 +140,8 @@ static registry_value_t uninstall_values[] = // Shareware version { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" + HKEY_LOCAL_MACHINE, + SOFTWARE_KEY "\\Microsoft\\Windows\\CurrentVersion\\" "Uninstall\\Doom Shareware for Windows 95", "UninstallString", }, @@ -128,7 +152,7 @@ static registry_value_t uninstall_values[] = static registry_value_t collectors_edition_value = { HKEY_LOCAL_MACHINE, - "Software\\Activision\\DOOM Collector's Edition\\v1.0", + SOFTWARE_KEY "\\Activision\\DOOM Collector's Edition\\v1.0", "INSTALLPATH", }; @@ -146,7 +170,7 @@ static char *collectors_edition_subdirs[] = static registry_value_t steam_install_location = { HKEY_LOCAL_MACHINE, - "Software\\Valve\\Steam", + SOFTWARE_KEY "\\Valve\\Steam", "InstallPath", }; @@ -157,6 +181,8 @@ static char *steam_install_subdirs[] = "steamapps\\common\\doom 2\\base", "steamapps\\common\\final doom\\base", "steamapps\\common\\ultimate doom\\base", + "steamapps\\common\\hexen\\base", + "steamapps\\common\\heretic shadow of the serpent riders\\base", // From Doom 3: BFG Edition: @@ -311,39 +337,18 @@ static void CheckDOSDefaults(void) AddIWADDir("\\doom"); // Shareware / Registered Doom AddIWADDir("\\dooms"); // Shareware versions AddIWADDir("\\doomsw"); -} -#endif + AddIWADDir("\\heretic"); // Heretic + AddIWADDir("\\hrtic_se"); // Heretic Shareware from Quake disc -static struct -{ - char *name; - GameMission_t mission; -} iwads[] = { - {"doom2.wad", doom2}, - {"plutonia.wad", pack_plut}, - {"tnt.wad", pack_tnt}, - {"doom.wad", doom}, - {"doom1.wad", doom}, - {"chex.wad", doom}, - {"hacx.wad", doom2}, -}; - -// Hack for chex quest mode + AddIWADDir("\\hexen"); // Hexen + AddIWADDir("\\hexendk"); // Hexen Deathkings of the Dark Citadel -static void CheckSpecialIWADs(char *iwad_name) -{ - if (!strcasecmp(iwad_name, "chex.wad")) - { - gameversion = exe_chex; - } - - if (!strcasecmp(iwad_name, "hacx.wad")) - { - gameversion = exe_hacx; - } + AddIWADDir("\\strife"); // Strife } +#endif + // Returns true if the specified path is a path to a file // of the specified name. @@ -403,19 +408,23 @@ static char *CheckDirectoryHasIWAD(char *dir, char *iwadname) // Search a directory to try to find an IWAD // Returns the location of the IWAD if found, otherwise NULL. -static char *SearchDirectoryForIWAD(char *dir) +static char *SearchDirectoryForIWAD(char *dir, int mask, GameMission_t *mission) { char *filename; size_t i; for (i=0; i<arrlen(iwads); ++i) { + if (((1 << iwads[i].mission) & mask) == 0) + { + continue; + } + filename = CheckDirectoryHasIWAD(dir, DEH_String(iwads[i].name)); if (filename != NULL) { - CheckSpecialIWADs(iwads[i].name); - gamemission = iwads[i].mission; + *mission = iwads[i].mission; return filename; } @@ -427,13 +436,12 @@ static char *SearchDirectoryForIWAD(char *dir) // When given an IWAD with the '-iwad' parameter, // attempt to identify it by its name. -static void IdentifyIWADByName(char *name) +static GameMission_t IdentifyIWADByName(char *name, int mask) { size_t i; + GameMission_t mission; char *p; - // Trim down the name to just the filename, ignoring the path. - p = strrchr(name, DIR_SEPARATOR); if (p != NULL) @@ -441,24 +449,32 @@ static void IdentifyIWADByName(char *name) name = p + 1; } - gamemission = none; + mission = none; for (i=0; i<arrlen(iwads); ++i) { // Check if the filename is this IWAD name. - if (!strcasecmp(name, DEH_String(iwads[i].name))) + // Only use supported missions: + + if (((1 << iwads[i].mission) & mask) == 0) + continue; + + // Check if it ends in this IWAD name. + + if (!strcasecmp(name, iwads[i].name)) { - CheckSpecialIWADs(iwads[i].name); - gamemission = iwads[i].mission; + mission = iwads[i].mission; break; } } + + return mission; } // // Add directories from the list in the DOOMWADPATH environment variable. -// +// static void AddDoomWadPath(void) { @@ -536,14 +552,7 @@ static void BuildIWADDirList(void) AddDoomWadPath(); -#if defined(_WIN32_WCE) - - // Windows CE locations: - - AddIWADDir("\\Storage Card"); - AddIWADDir(getenv("HOME")); - -#elif defined(_WIN32) +#ifdef _WIN32 // Search the registry and find where IWADs have been installed. @@ -645,7 +654,7 @@ char *D_TryFindWADByName(char *filename) // should be executed (notably loading PWADs). // -char *D_FindIWAD(void) +char *D_FindIWAD(int mask, GameMission_t *mission) { char *result; char *iwadfile; @@ -675,7 +684,7 @@ char *D_FindIWAD(void) I_Error("IWAD file '%s' not found!", iwadfile); } - IdentifyIWADByName(result); + *mission = IdentifyIWADByName(result, mask); } else { @@ -687,300 +696,105 @@ char *D_FindIWAD(void) for (i=0; result == NULL && i<num_iwad_dirs; ++i) { - result = SearchDirectoryForIWAD(iwad_dirs[i]); + result = SearchDirectoryForIWAD(iwad_dirs[i], mask, mission); } } return result; } -// -// Get the IWAD name used for savegames. -// +// Find all IWADs in the IWAD search path matching the given mask. -static char *SaveGameIWADName(void) +iwad_t **D_FindAllIWADs(int mask) { - size_t i; - - // Chex quest hack - - if (gameversion == exe_chex) - { - return "chex.wad"; - } - - // Hacx hack + iwad_t **result; + int result_len; + char *filename; + int i; - if (gameversion == exe_hacx) - { - return "hacx.wad"; - } + result = malloc(sizeof(iwad_t *) * (arrlen(iwads) + 1)); + result_len = 0; - // Find what subdirectory to use for savegames - // - // They should be stored in something like - // ~/.chocolate-doom/savegames/doom.wad/ - // - // The directory depends on the IWAD, so that savegames for - // different IWADs are kept separate. - // - // Note that we match on gamemission rather than on IWAD name. - // This ensures that doom1.wad and doom.wad saves are stored - // in the same place. + // Try to find all IWADs for (i=0; i<arrlen(iwads); ++i) { - if (gamemission == iwads[i].mission) + if (((1 << iwads[i].mission) & mask) == 0) { - return iwads[i].name; + continue; } - } - - return NULL; -} -// -// SetSaveGameDir -// -// Chooses the directory used to store saved games. -// - -void D_SetSaveGameDir(void) -{ - char *iwad_name; - - if (!strcmp(configdir, "")) - { - // Use the current directory, just like configdir. - - savegamedir = strdup(""); - } - else - { - // Directory for savegames - iwad_name = SaveGameIWADName(); + filename = D_FindWADByName(iwads[i].name); - if (iwad_name == NULL) + if (filename != NULL) { - iwad_name = "unknown.wad"; + result[result_len] = &iwads[i]; + ++result_len; } + } - savegamedir = Z_Malloc(strlen(configdir) + 30, PU_STATIC, 0); - sprintf(savegamedir, "%ssavegames%c", configdir, - DIR_SEPARATOR); - - M_MakeDirectory(savegamedir); + // End of list - sprintf(savegamedir + strlen(savegamedir), "%s%c", - iwad_name, DIR_SEPARATOR); + result[result_len] = NULL; - M_MakeDirectory(savegamedir); - } + return result; } -// Strings for dehacked replacements of the startup banner // -// These are from the original source: some of them are perhaps -// not used in any dehacked patches - -static char *banners[] = -{ - // doom2.wad - " " - "DOOM 2: Hell on Earth v%i.%i" - " ", - // doom1.wad - " " - "DOOM Shareware Startup v%i.%i" - " ", - // doom.wad - " " - "DOOM Registered Startup v%i.%i" - " ", - // Registered DOOM uses this - " " - "DOOM System Startup v%i.%i" - " ", - // doom.wad (Ultimate DOOM) - " " - "The Ultimate DOOM Startup v%i.%i" - " ", - // tnt.wad - " " - "DOOM 2: TNT - Evilution v%i.%i" - " ", - // plutonia.wad - " " - "DOOM 2: Plutonia Experiment v%i.%i" - " ", -}; - +// Get the IWAD name used for savegames. // -// Get game name: if the startup banner has been replaced, use that. -// Otherwise, use the name given -// -static char *GetGameName(char *gamename) +char *D_SaveGameIWADName(GameMission_t gamemission) { size_t i; - char *deh_sub; - - for (i=0; i<arrlen(banners); ++i) - { - // Has the banner been replaced? - - deh_sub = DEH_String(banners[i]); - - if (deh_sub != banners[i]) - { - // Has been replaced - // We need to expand via printf to include the Doom version - // number - // We also need to cut off spaces to get the basic name - - gamename = Z_Malloc(strlen(deh_sub) + 10, PU_STATIC, 0); - sprintf(gamename, deh_sub, DOOM_VERSION / 100, DOOM_VERSION % 100); - - while (gamename[0] != '\0' && isspace(gamename[0])) - strcpy(gamename, gamename+1); - while (gamename[0] != '\0' && isspace(gamename[strlen(gamename)-1])) - gamename[strlen(gamename) - 1] = '\0'; - - return gamename; - } - } - - return gamename; -} - - -// -// Find out what version of Doom is playing. -// - -void D_IdentifyVersion(void) -{ - // gamemission is set up by the D_FindIWAD function. But if - // we specify '-iwad', we have to identify using - // IdentifyIWADByName. However, if the iwad does not match - // any known IWAD name, we may have a dilemma. Try to - // identify by its contents. + // Determine the IWAD name to use for savegames. + // This determines the directory the savegame files get put into. + // + // Note that we match on gamemission rather than on IWAD name. + // This ensures that doom1.wad and doom.wad saves are stored + // in the same place. - if (gamemission == none) + for (i=0; i<arrlen(iwads); ++i) { - unsigned int i; - - for (i=0; i<numlumps; ++i) - { - if (!strncasecmp(lumpinfo[i].name, "MAP01", 8)) - { - gamemission = doom2; - break; - } - else if (!strncasecmp(lumpinfo[i].name, "E1M1", 8)) - { - gamemission = doom; - break; - } - } - - if (gamemission == none) + if (gamemission == iwads[i].mission) { - // Still no idea. I don't think this is going to work. - - I_Error("Unknown or invalid IWAD file."); + return iwads[i].name; } } - // Make sure gamemode is set up correctly - - if (gamemission == doom) - { - // Doom 1. But which version? - - if (W_CheckNumForName("E4M1") > 0) - { - // Ultimate Doom - - gamemode = retail; - } - else if (W_CheckNumForName("E3M1") > 0) - { - gamemode = registered; - } - else - { - gamemode = shareware; - } - } - else - { - // Doom 2 of some kind. + // Default fallback: - gamemode = commercial; - } + return "unknown.wad"; } -// Set the gamedescription string - -void D_SetGameDescription(void) +char *D_SuggestIWADName(GameMission_t mission, GameMode_t mode) { - gamedescription = "Unknown"; + int i; - if (gamemission == doom) + for (i = 0; i < arrlen(iwads); ++i) { - // Doom 1. But which version? - - if (gamemode == retail) - { - // Ultimate Doom - - gamedescription = GetGameName("The Ultimate DOOM"); - } - else if (gamemode == registered) + if (iwads[i].mission == mission && iwads[i].mode == mode) { - gamedescription = GetGameName("DOOM Registered"); - } - else if (gamemode == shareware) - { - gamedescription = GetGameName("DOOM Shareware"); + return iwads[i].name; } } - else - { - // Doom 2 of some kind. But which mission? - if (gamemission == doom2) - gamedescription = GetGameName("DOOM 2: Hell on Earth"); - else if (gamemission == pack_plut) - gamedescription = GetGameName("DOOM 2: Plutonia Experiment"); - else if (gamemission == pack_tnt) - gamedescription = GetGameName("DOOM 2: TNT - Evilution"); - } + return "unknown.wad"; } -// Clever hack: Setup can invoke Doom to determine which IWADs are installed. -// Doom searches install paths and exits with the return code being a -// bitmask of the installed IWAD files. - -void D_FindInstalledIWADs(void) +char *D_SuggestGameName(GameMission_t mission, GameMode_t mode) { - unsigned int i; - int result; - - BuildIWADDirList(); - - result = 0; + int i; - for (i=0; i<arrlen(iwads); ++i) + for (i = 0; i < arrlen(iwads); ++i) { - if (D_FindWADByName(iwads[i].name) != NULL) + if (iwads[i].mission == mission && iwads[i].mode == mode) { - result |= 1 << i; + return iwads[i].description; } } - exit(result); + return "Unknown game?"; } |