ref: 3a140fe3b5bf1775276a0a454c52b6974b68055f
parent: 14c50f0200a382dd5be45b9dca74b6d5e4d89730
author: Simon Howard <fraggle@soulsphere.org>
date: Sun May 10 14:48:05 EDT 2015
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.
--- a/src/doom/p_setup.c
+++ b/src/doom/p_setup.c
@@ -770,7 +770,10 @@
// UNUSED W_Profile ();
P_InitThinkers ();
-
+
+ // if working with a devlopment map, reload it
+ W_Reload ();
+
// find map name
if ( gamemode == commercial)
{
--- a/src/strife/p_setup.c
+++ b/src/strife/p_setup.c
@@ -785,6 +785,9 @@
// 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);
--- 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 @@
//
// 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 @@
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 @@
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 @@
{
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);
@@ -566,6 +594,49 @@
}
// 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
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -56,6 +56,7 @@
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);