shithub: choc

Download patch

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);