From 8cae6e48779beb3dc8e95a5c32b422b2504b5722 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 30 Sep 2008 22:50:24 +0000 Subject: Move d_iwad.c into common code and update Heretic to use it on startup to locate the IWAD file. Subversion-branch: /branches/raven-branch Subversion-revision: 1308 --- src/Makefile.am | 1 + src/d_iwad.c | 637 +++++++++++++++++++++++++++++++++++ src/d_iwad.h | 44 +++ src/d_mode.h | 2 + src/doom/Makefile.am | 1 - src/doom/d_iwad.c | 913 --------------------------------------------------- src/doom/d_iwad.h | 39 --- src/doom/d_main.c | 238 +++++++++++++- src/heretic/d_main.c | 149 +++------ 9 files changed, 964 insertions(+), 1060 deletions(-) create mode 100644 src/d_iwad.c create mode 100644 src/d_iwad.h delete mode 100644 src/doom/d_iwad.c delete mode 100644 src/doom/d_iwad.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index c931d27f..a7746831 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ d_event.c d_event.h \ doomkeys.h \ doomfeatures.h \ doomtype.h \ +d_iwad.c d_iwad.h \ d_mode.c d_mode.h \ d_ticcmd.h \ i_cdmus.c i_cdmus.h \ diff --git a/src/d_iwad.c b/src/d_iwad.c new file mode 100644 index 00000000..6f7bff70 --- /dev/null +++ b/src/d_iwad.c @@ -0,0 +1,637 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2006 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// DESCRIPTION: +// Search for and locate an IWAD file, and initialise according +// to the IWAD type. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include + +#include "deh_str.h" +#include "doomkeys.h" +#include "d_iwad.h" +#include "i_system.h" +#include "m_argv.h" +#include "m_config.h" +#include "m_misc.h" +#include "w_wad.h" +#include "z_zone.h" + +// Array of locations to search for IWAD files +// +// "128 IWAD search directories should be enough for anybody". + +#define MAX_IWAD_DIRS 128 + +static boolean iwad_dirs_built = false; +static char *iwad_dirs[MAX_IWAD_DIRS]; +static int num_iwad_dirs = 0; + +static void AddIWADDir(char *dir) +{ + if (num_iwad_dirs < MAX_IWAD_DIRS) + { + iwad_dirs[num_iwad_dirs] = dir; + ++num_iwad_dirs; + } +} + +// This is Windows-specific code that automatically finds the location +// of installed IWAD files. The registry is inspected to find special +// keys installed by the Windows installers for various CD versions +// of Doom. From these keys we can deduce where to find an IWAD. + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct +{ + HKEY root; + char *path; + char *value; +} registry_value_t; + +#define UNINSTALLER_STRING "\\uninstl.exe /S " + +// Keys installed by the various CD editions. These are actually the +// commands to invoke the uninstaller and look like this: +// +// C:\Program Files\Path\uninstl.exe /S C:\Program Files\Path +// +// With some munging we can find where Doom was installed. + +static registry_value_t uninstall_values[] = +{ + // Ultimate Doom, CD version (Depths of Doom trilogy) + + { + HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\" + "Uninstall\\Ultimate Doom for Windows 95", + "UninstallString", + }, + + // Doom II, CD version (Depths of Doom trilogy) + + { + HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\" + "Uninstall\\Doom II for Windows 95", + "UninstallString", + }, + + // Final Doom + + { + HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\" + "Uninstall\\Final Doom for Windows 95", + "UninstallString", + }, + + // Shareware version + + { + HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\" + "Uninstall\\Doom Shareware for Windows 95", + "UninstallString", + }, +}; + +// Value installed by the Collector's Edition when it is installed + +static registry_value_t collectors_edition_value = +{ + HKEY_LOCAL_MACHINE, + "Software\\Activision\\DOOM Collector's Edition\\v1.0", + "INSTALLPATH", +}; + +// Subdirectories of the above install path, where IWADs are installed. + +static char *collectors_edition_subdirs[] = +{ + "Doom2", + "Final Doom", + "Ultimate Doom", +}; + +// Location where Steam is installed + +static registry_value_t steam_install_location = +{ + HKEY_LOCAL_MACHINE, + "Software\\Valve\\Steam", + "InstallPath", +}; + +// Subdirs of the steam install directory where IWADs are found + +static char *steam_install_subdirs[] = +{ + "steamapps\\common\\doom 2\\base", + "steamapps\\common\\final doom\\base", + "steamapps\\common\\ultimate doom\\base", +}; + +static char *GetRegistryString(registry_value_t *reg_val) +{ + HKEY key; + DWORD len; + DWORD valtype; + char *result; + + // Open the key (directory where the value is stored) + + if (RegOpenKeyEx(reg_val->root, reg_val->path, 0, KEY_READ, &key) + != ERROR_SUCCESS) + { + return NULL; + } + + // Find the type and length of the string + + if (RegQueryValueEx(key, reg_val->value, NULL, &valtype, NULL, &len) + != ERROR_SUCCESS) + { + return NULL; + } + + // Only accept strings + + if (valtype != REG_SZ) + { + return NULL; + } + + // Allocate a buffer for the value and read the value + + result = malloc(len); + + if (RegQueryValueEx(key, reg_val->value, NULL, &valtype, (unsigned char *) result, &len) + != ERROR_SUCCESS) + { + free(result); + return NULL; + } + + // Close the key + + RegCloseKey(key); + + return result; +} + +// Check for the uninstall strings from the CD versions + +static void CheckUninstallStrings(void) +{ + unsigned int i; + + for (i=0; i + // + + iwadparm = M_CheckParm("-iwad"); + + if (iwadparm) + { + // Search through IWAD dirs for an IWAD with the given name. + + iwadfile = myargv[iwadparm + 1]; + + result = D_FindWADByName(iwadfile); + + if (result == NULL) + { + I_Error("IWAD file '%s' not found!", iwadfile); + } + + *mission = IdentifyIWADByName(result, iwads); + } + else + { + // Search through the list and look for an IWAD + + result = NULL; + + BuildIWADDirList(); + + for (i=0; result == NULL && i -#include -#include -#include - -#include "deh_main.h" -#include "doomkeys.h" -#include "doomdef.h" -#include "doomstat.h" -#include "i_system.h" -#include "m_argv.h" -#include "m_config.h" -#include "m_misc.h" -#include "w_wad.h" -#include "z_zone.h" - -// Array of locations to search for IWAD files -// -// "128 IWAD search directories should be enough for anybody". - -#define MAX_IWAD_DIRS 128 - -static boolean iwad_dirs_built = false; -static char *iwad_dirs[MAX_IWAD_DIRS]; -static int num_iwad_dirs = 0; - -static void AddIWADDir(char *dir) -{ - if (num_iwad_dirs < MAX_IWAD_DIRS) - { - iwad_dirs[num_iwad_dirs] = dir; - ++num_iwad_dirs; - } -} - -// This is Windows-specific code that automatically finds the location -// of installed IWAD files. The registry is inspected to find special -// keys installed by the Windows installers for various CD versions -// of Doom. From these keys we can deduce where to find an IWAD. - -#ifdef _WIN32 - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct -{ - HKEY root; - char *path; - char *value; -} registry_value_t; - -#define UNINSTALLER_STRING "\\uninstl.exe /S " - -// Keys installed by the various CD editions. These are actually the -// commands to invoke the uninstaller and look like this: -// -// C:\Program Files\Path\uninstl.exe /S C:\Program Files\Path -// -// With some munging we can find where Doom was installed. - -static registry_value_t uninstall_values[] = -{ - // Ultimate Doom, CD version (Depths of Doom trilogy) - - { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" - "Uninstall\\Ultimate Doom for Windows 95", - "UninstallString", - }, - - // Doom II, CD version (Depths of Doom trilogy) - - { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" - "Uninstall\\Doom II for Windows 95", - "UninstallString", - }, - - // Final Doom - - { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" - "Uninstall\\Final Doom for Windows 95", - "UninstallString", - }, - - // Shareware version - - { - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\" - "Uninstall\\Doom Shareware for Windows 95", - "UninstallString", - }, -}; - -// Value installed by the Collector's Edition when it is installed - -static registry_value_t collectors_edition_value = -{ - HKEY_LOCAL_MACHINE, - "Software\\Activision\\DOOM Collector's Edition\\v1.0", - "INSTALLPATH", -}; - -// Subdirectories of the above install path, where IWADs are installed. - -static char *collectors_edition_subdirs[] = -{ - "Doom2", - "Final Doom", - "Ultimate Doom", -}; - -// Location where Steam is installed - -static registry_value_t steam_install_location = -{ - HKEY_LOCAL_MACHINE, - "Software\\Valve\\Steam", - "InstallPath", -}; - -// Subdirs of the steam install directory where IWADs are found - -static char *steam_install_subdirs[] = -{ - "steamapps\\common\\doom 2\\base", - "steamapps\\common\\final doom\\base", - "steamapps\\common\\ultimate doom\\base", -}; - -static char *GetRegistryString(registry_value_t *reg_val) -{ - HKEY key; - DWORD len; - DWORD valtype; - char *result; - - // Open the key (directory where the value is stored) - - if (RegOpenKeyEx(reg_val->root, reg_val->path, 0, KEY_READ, &key) - != ERROR_SUCCESS) - { - return NULL; - } - - // Find the type and length of the string - - if (RegQueryValueEx(key, reg_val->value, NULL, &valtype, NULL, &len) - != ERROR_SUCCESS) - { - return NULL; - } - - // Only accept strings - - if (valtype != REG_SZ) - { - return NULL; - } - - // Allocate a buffer for the value and read the value - - result = malloc(len); - - if (RegQueryValueEx(key, reg_val->value, NULL, &valtype, (unsigned char *) result, &len) - != ERROR_SUCCESS) - { - free(result); - return NULL; - } - - // Close the key - - RegCloseKey(key); - - return result; -} - -// Check for the uninstall strings from the CD versions - -static void CheckUninstallStrings(void) -{ - unsigned int i; - - for (i=0; i - // - - iwadparm = M_CheckParm("-iwad"); - - if (iwadparm) - { - // Search through IWAD dirs for an IWAD with the given name. - - iwadfile = myargv[iwadparm + 1]; - - result = D_FindWADByName(iwadfile); - - if (result == NULL) - { - I_Error("IWAD file '%s' not found!", iwadfile); - } - - IdentifyIWADByName(result); - } - else - { - // Search through the list and look for an IWAD - - result = NULL; - - BuildIWADDirList(); - - for (i=0; result == NULL && i 0) - { - // Ultimate Doom - - gamemode = retail; - } - else if (W_CheckNumForName("E3M1") > 0) - { - gamemode = registered; - } - else - { - gamemode = shareware; - } - } - else - { - // Doom 2 of some kind. - - gamemode = commercial; - } -} - -// Set the gamedescription string - -void D_SetGameDescription(void) -{ - gamedescription = "Unknown"; - - if (gamemission == doom) - { - // Doom 1. But which version? - - if (gamemode == retail) - { - // Ultimate Doom - - gamedescription = GetGameName("The Ultimate DOOM"); - } - else if (gamemode == registered) - { - gamedescription = GetGameName("DOOM Registered"); - } - else if (gamemode == shareware) - { - gamedescription = GetGameName("DOOM Shareware"); - } - } - 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"); - } -} - -// 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) -{ - unsigned int i; - int result; - - BuildIWADDirList(); - - result = 0; - - for (i=0; i 0) + { + // Ultimate Doom + + gamemode = retail; + } + else if (W_CheckNumForName("E3M1") > 0) + { + gamemode = registered; + } + else + { + gamemode = shareware; + } + } + else + { + // Doom 2 of some kind. + + gamemode = commercial; + } +} + +// Set the gamedescription string + +void D_SetGameDescription(void) +{ + gamedescription = "Unknown"; + + if (gamemission == doom) + { + // Doom 1. But which version? + + if (gamemode == retail) + { + // Ultimate Doom + + gamedescription = GetGameName("The Ultimate DOOM"); + } + else if (gamemode == registered) + { + gamedescription = GetGameName("DOOM Registered"); + } + else if (gamemode == shareware) + { + gamedescription = GetGameName("DOOM Shareware"); + } + } + 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"); + } +} + +static void SetSaveGameDir(char *iwad_filename) +{ + char *sep; + char *basefile; + + // Extract the base filename + + sep = strrchr(iwad_filename, DIR_SEPARATOR); + + if (sep == NULL) + { + basefile = iwad_filename; + } + else + { + basefile = sep + 1; + } + + // eg. ~/.chocolate-doom/savegames/doom2.wad/ + + savegamedir = malloc(strlen(configdir) + strlen(basefile) + 10); + sprintf(savegamedir, "%ssavegames%c%s%c", + configdir, DIR_SEPARATOR, basefile, DIR_SEPARATOR); +} + +// Check if the IWAD file is the Chex Quest IWAD. +// Returns true if this is chex.wad. + +static boolean CheckChex(char *iwadname) +{ + char *chex_iwadname = "chex.wad"; + return (strlen(iwadname) > strlen(chex_iwadname) + && !strcasecmp(iwadname + strlen(iwadname) - strlen(chex_iwadname), + chex_iwadname)); +} // print title for every printed line char title[128]; @@ -711,9 +937,11 @@ static void InitGameVersion(void) { // Determine automatically - if (gameversion == exe_chex) + if (CheckChex(iwadfile)) { - // Already determined + // chex.exe - identified by iwad filename + + gameversion = exe_chex; } else if (gamemode == shareware || gamemode == registered) { @@ -833,7 +1061,7 @@ void D_DoomMain (void) if (M_CheckParm("-findiwads") > 0) { - D_FindInstalledIWADs(); + D_FindInstalledIWADs(iwads); } // print banner @@ -890,7 +1118,7 @@ void D_DoomMain (void) DEH_Init(); #endif - iwadfile = D_FindIWAD(); + iwadfile = D_FindIWAD(iwads, &gamemission); // None found? @@ -1259,7 +1487,7 @@ void D_DoomMain (void) InitGameVersion(); LoadChexDeh(); D_SetGameDescription(); - D_SetSaveGameDir(); + SetSaveGameDir(iwadfile); // Check for -file in shareware if (modifiedgame) diff --git a/src/heretic/d_main.c b/src/heretic/d_main.c index 19944c21..669d7b3d 100644 --- a/src/heretic/d_main.c +++ b/src/heretic/d_main.c @@ -29,6 +29,7 @@ #include "config.h" #include "ct_chat.h" #include "doomdef.h" +#include "d_iwad.h" #include "i_system.h" #include "i_video.h" #include "m_argv.h" @@ -434,8 +435,6 @@ void D_CheckRecordFrom(void) =============== */ -#define MAXWADFILES 20 - // MAPDIR should be defined as the directory that holds development maps // for the -wart # # command @@ -443,14 +442,15 @@ void D_CheckRecordFrom(void) #define SHAREWAREWADNAME "heretic1.wad" -char *wadfiles[MAXWADFILES] = { - "heretic.wad", +static iwad_t iwads[] = { + { "heretic.wad", heretic }, + { "heretic1.wad", heretic }, + { NULL, none }, }; -char *basedefault = "heretic.cfg"; +char *iwadfile; -char exrnwads[80]; -char exrnwads2[80]; +char *basedefault = "heretic.cfg"; void wadprintf(void) { @@ -468,41 +468,15 @@ void wadprintf(void) #endif } -void D_AddFile(char *file) +boolean D_AddFile(char *file) { - int numwadfiles; - char *new; -// char text[256]; - - for (numwadfiles = 0; wadfiles[numwadfiles]; numwadfiles++); - new = malloc(strlen(file) + 1); - strcpy(new, file); - if (strlen(exrnwads) + strlen(file) < 78) - { - if (strlen(exrnwads)) - { - strcat(exrnwads, ", "); - } - else - { - strcpy(exrnwads, "External Wadfiles: "); - } - strcat(exrnwads, file); - } - else if (strlen(exrnwads2) + strlen(file) < 79) - { - if (strlen(exrnwads2)) - { - strcat(exrnwads2, ", "); - } - else - { - strcpy(exrnwads2, " "); - strcat(exrnwads, ","); - } - strcat(exrnwads2, file); - } - wadfiles[numwadfiles] = new; + wad_file_t *handle; + + printf(" adding %s\n", file); + + handle = W_AddFile(file); + + return handle != NULL; } //========================================================== @@ -789,13 +763,8 @@ static void D_Endoom(void) void D_DoomMain(void) { - int i; int p; - int e; - int m; char file[256]; - FILE *fp; - boolean devMap; I_PrintBanner(PACKAGE_STRING); @@ -813,17 +782,6 @@ void D_DoomMain(void) startmap = 1; autostart = false; - // wadfiles[0] is a char * to the main wad - fp = fopen(wadfiles[0], "rb"); - if (fp) - { - fclose(fp); - } - else - { // Change to look for shareware wad - wadfiles[0] = SHAREWAREWADNAME; - } - // Check for -CDROM cdrom = false; #ifdef __WATCOMC__ @@ -834,48 +792,6 @@ void D_DoomMain(void) } #endif - // -FILE [filename] [filename] ... - // Add files to the wad list. - p = M_CheckParm("-file"); - if (p) - { // the parms after p are wadfile/lump names, until end of parms - // or another - preceded parm - while (++p != myargc && myargv[p][0] != '-') - { - D_AddFile(myargv[p]); - } - } - - // -DEVMAP - // Adds a map wad from the development directory to the wad list, - // and sets the start episode and the start map. - devMap = false; - p = M_CheckParm("-devmap"); - if (p && p < myargc - 2) - { - e = myargv[p + 1][0]; - m = myargv[p + 2][0]; - sprintf(file, MAPDIR "E%cM%c.wad", e, m); - D_AddFile(file); - printf("DEVMAP: Episode %c, Map %c.\n", e, m); - startepisode = e - '0'; - startmap = m - '0'; - autostart = true; - devMap = true; - } - - p = M_CheckParm("-playdemo"); - if (!p) - { - p = M_CheckParm("-timedemo"); - } - if (p && p < myargc - 1) - { - sprintf(file, "%s.lmp", myargv[p + 1]); - D_AddFile(file); - printf("Playing demo %s.lmp.\n", myargv[p + 1]); - } - // // get skill / episode / map from parms // @@ -928,9 +844,38 @@ void D_DoomMain(void) printf("W_Init: Init WADfiles.\n"); - for (i=0; wadfiles[i] != NULL; ++i) + iwadfile = D_FindIWAD(iwads, &gamemission); + + if (iwadfile == NULL) { - W_AddFile(wadfiles[i]); + I_Error("Game mode indeterminate. No IWAD was found. Try specifying\n" + "one with the '-iwad' command line parameter."); + } + + D_AddFile(iwadfile); + + // -FILE [filename] [filename] ... + // Add files to the wad list. + p = M_CheckParm("-file"); + if (p) + { // the parms after p are wadfile/lump names, until end of parms + // or another - preceded parm + while (++p != myargc && myargv[p][0] != '-') + { + D_AddFile(myargv[p]); + } + } + + p = M_CheckParm("-playdemo"); + if (!p) + { + p = M_CheckParm("-timedemo"); + } + if (p && p < myargc - 1) + { + sprintf(file, "%s.lmp", myargv[p + 1]); + D_AddFile(file); + printf("Playing demo %s.lmp.\n", myargv[p + 1]); } if (W_CheckNumForName("E2M1") == -1) @@ -1064,7 +1009,7 @@ void D_DoomMain(void) } // Check valid episode and map - if ((autostart || netgame) && (devMap == false)) + if (autostart || netgame) { if (M_ValidEpisodeMap(startepisode, startmap) == false) { -- cgit v1.2.3