summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Howard2015-05-10 18:48:05 -0400
committerSimon Howard2015-05-10 18:48:05 -0400
commit3a140fe3b5bf1775276a0a454c52b6974b68055f (patch)
tree6a91104467ddd48eca6b6c94062096b7db54ff18 /src
parent14c50f0200a382dd5be45b9dca74b6d5e4d89730 (diff)
downloadchocolate-doom-3a140fe3b5bf1775276a0a454c52b6974b68055f.tar.gz
chocolate-doom-3a140fe3b5bf1775276a0a454c52b6974b68055f.tar.bz2
chocolate-doom-3a140fe3b5bf1775276a0a454c52b6974b68055f.zip
Add back the Doom PWAD reload hack.
This was removed back in d190b596c566394717324296cbf6b46e67c64f5c; at the time I didn't understand what it was or how it was supposed to be used - it seemed like cruft left over from Doom's development. It is actually a potentially useful feature for level authors when developing their maps. See here: http://doomwiki.org/wiki/Reload_hack The reload hack is a relatively obscure feature of limited usefulness nowadays, but nonetheless a technical curiosity that ought to be preserved in Chocolate Doom. The reimplementation here is a lot cleaner than the original version from the source release: W_Reload() is based on a call to W_AddFile(), we don't reopen the reload file every time we want to read a lump, and we include a check in W_AddFile() that we are not trying to use the hack on more than one PWAD file. This fixes #539.
Diffstat (limited to 'src')
-rw-r--r--src/doom/p_setup.c5
-rw-r--r--src/strife/p_setup.c3
-rw-r--r--src/w_wad.c87
-rw-r--r--src/w_wad.h1
4 files changed, 87 insertions, 9 deletions
diff --git a/src/doom/p_setup.c b/src/doom/p_setup.c
index 00306e84..08fed7aa 100644
--- a/src/doom/p_setup.c
+++ b/src/doom/p_setup.c
@@ -770,7 +770,10 @@ P_SetupLevel
// UNUSED W_Profile ();
P_InitThinkers ();
-
+
+ // if working with a devlopment map, reload it
+ W_Reload ();
+
// find map name
if ( gamemode == commercial)
{
diff --git a/src/strife/p_setup.c b/src/strife/p_setup.c
index 1fd889fa..fe1140bd 100644
--- a/src/strife/p_setup.c
+++ b/src/strife/p_setup.c
@@ -785,6 +785,9 @@ P_SetupLevel
// UNUSED W_Profile ();
P_InitThinkers ();
+ // if working with a devlopment map, reload it
+ W_Reload();
+
// [STRIFE] Removed ExMy map support
if (map<10)
DEH_snprintf(lumpname, 9, "map0%i", map);
diff --git a/src/w_wad.c b/src/w_wad.c
index aa0646af..a8a952b6 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -39,7 +39,7 @@
typedef struct
{
// Should be "IWAD" or "PWAD".
- char identification[4];
+ char identification[4];
int numlumps;
int infotableofs;
} PACKEDATTR wadinfo_t;
@@ -57,16 +57,20 @@ typedef struct
//
// Location of each lump on disk.
-
-lumpinfo_t *lumpinfo;
+lumpinfo_t *lumpinfo;
unsigned int numlumps = 0;
// Hash table for fast lookups
-
static lumpinfo_t **lumphash;
-// Hash function used for lump names.
+// Variables for the reload hack: filename of the PWAD to reload, and the
+// lumps from WADs before the reload file, so we can resent numlumps and
+// load the file again.
+static wad_file_t *reloadhandle = NULL;
+static char *reloadname = NULL;
+static int reloadlump = -1;
+// Hash function used for lump names.
unsigned int W_LumpNameHash(const char *s)
{
// This is the djb2 string hash function, modded to work on strings
@@ -148,8 +152,26 @@ wad_file_t *W_AddFile (char *filename)
filelump_t *filerover;
int newnumlumps;
- // open the file and add to directory
+ // If the filename begins with a ~, it indicates that we should use the
+ // reload hack.
+ if (filename[0] == '~')
+ {
+ if (reloadname != NULL)
+ {
+ I_Error("Prefixing a WAD filename with '~' indicates that the "
+ "WAD should be reloaded\n"
+ "on each level restart, for use by level authors for "
+ "rapid development. You\n"
+ "can only reload one WAD file, and it must be the last "
+ "file in the -file list.");
+ }
+ reloadname = strdup(filename);
+ reloadlump = numlumps;
+ ++filename;
+ }
+
+ // Open the file and add to directory
wad_file = W_OpenFile(filename);
if (wad_file == NULL)
@@ -158,6 +180,13 @@ wad_file_t *W_AddFile (char *filename)
return NULL;
}
+ // If this is the reload file, we need to save the file handle so that we
+ // can close it later on when we do a reload.
+ if (reloadname)
+ {
+ reloadhandle = wad_file;
+ }
+
newnumlumps = numlumps;
if (strcasecmp(filename+strlen(filename)-3 , "wad" ) )
@@ -539,8 +568,7 @@ void W_GenerateHashTable(void)
{
unsigned int i;
- // Free the old hash table, if there is one
-
+ // Free the old hash table, if there is one:
if (lumphash != NULL)
{
Z_Free(lumphash);
@@ -568,6 +596,49 @@ void W_GenerateHashTable(void)
// All done!
}
+// The Doom reload hack. The idea here is that if you give a WAD file to -file
+// prefixed with the ~ hack, that WAD file will be reloaded each time a new
+// level is loaded. This lets you use a level editor in parallel and make
+// incremental changes to the level you're working on without having to restart
+// the game after every change.
+// But: the reload feature is a fragile hack...
+void W_Reload(void)
+{
+ char *filename;
+ int i;
+
+ if (reloadname == NULL)
+ {
+ return;
+ }
+
+ // We must release any lumps being held in the PWAD we're about to reload:
+ for (i = reloadlump; i < numlumps; ++i)
+ {
+ if (lumpinfo[i].cache != NULL)
+ {
+ W_ReleaseLumpNum(i);
+ }
+ }
+
+ // Reset numlumps to remove the reload WAD file:
+ numlumps = reloadlump;
+
+ // Now reload the WAD file.
+ filename = reloadname;
+
+ W_CloseFile(reloadhandle);
+ reloadname = NULL;
+ reloadlump = -1;
+ reloadhandle = NULL;
+ W_AddFile(filename);
+ free(filename);
+
+ // The WAD directory has changed, so we have to regenerate the
+ // fast lookup hashtable:
+ W_GenerateHashTable();
+}
+
// Lump names that are unique to particular game types. This lets us check
// the user is not trying to play with the wrong executable, eg.
// chocolate-doom -iwad hexen.wad.
diff --git a/src/w_wad.h b/src/w_wad.h
index 71895749..e5dc18b3 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -56,6 +56,7 @@ extern lumpinfo_t *lumpinfo;
extern unsigned int numlumps;
wad_file_t *W_AddFile (char *filename);
+void W_Reload (void);
int W_CheckNumForName (char* name);
int W_GetNumForName (char* name);