foxygit / doom Log in
commit 3f54daeaa3acf590569cb397eee24731f7de6c17
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Fri May 2 18:48:43 2008 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Fri May 2 18:48:43 2008 +0000

    Add W_CacheLumpNum,Name API to WAD code for releasing a lump back to
    cache when it is no longer needed. Switch existing code to use the new
    API instead of Z_ChangeTag.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 1134
---
 src/am_map.c     |   7 +-
 src/d_main.c     |   2 +-
 src/g_game.c     |   2 +-
 src/i_pcsound.c  |   4 +-
 src/i_sdlsound.c |   2 +-
 src/r_plane.c    |   8 +--
 src/s_sound.c    |   4 +-
 src/st_stuff.c   | 104 +++++++++++++++--------------
 src/w_wad.c      |  34 ++++++++++
 src/w_wad.h      |   3 +
 src/wi_stuff.c   | 194 +++++++++++++++++++++++++------------------------------
 11 files changed, 192 insertions(+), 172 deletions(-)

diff --git a/src/am_map.c b/src/am_map.c
index 41da0071..5fbe748a 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -525,10 +525,13 @@ void AM_loadPics(void)
 void AM_unloadPics(void)
 {
     int i;
+    char namebuf[9];

     for (i=0;i<10;i++)
-	Z_ChangeTag(marknums[i], PU_CACHE);
-
+    {
+	sprintf(namebuf, DEH_String("AMMNUM%d"), i);
+	W_ReleaseLumpName(namebuf);
+    }
 }

 void AM_clearMarks(void)
diff --git a/src/d_main.c b/src/d_main.c
index c0d37fdc..5e9d3f5b 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -583,7 +583,7 @@ char            title[128];

 static boolean D_AddFile(char *filename)
 {
-    FILE *handle;
+    wad_file_t *handle;

     printf(" adding %s\n", filename);
     handle = W_AddFile(filename);
diff --git a/src/g_game.c b/src/g_game.c
index 4f7a3d43..924b91eb 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2046,7 +2046,7 @@ boolean G_CheckDemoStatus (void)

     if (demoplayback)
     {
-	Z_ChangeTag (demobuffer, PU_CACHE);
+        W_ReleaseLumpName(defdemoname);
 	demoplayback = false;
 	netdemo = false;
 	netgame = false;
diff --git a/src/i_pcsound.c b/src/i_pcsound.c
index c41ba022..c2c77fe7 100644
--- a/src/i_pcsound.c
+++ b/src/i_pcsound.c
@@ -45,6 +45,7 @@ static uint8_t *current_sound_lump = NULL;
 static uint8_t *current_sound_pos = NULL;
 static unsigned int current_sound_remaining = 0;
 static int current_sound_handle = 0;
+static int current_sound_lump_num = -1;

 static const float frequencies[] = {
     0.0f, 175.00f, 180.02f, 185.01f, 190.02f, 196.02f, 202.02f, 208.01f, 214.02f, 220.02f,
@@ -111,7 +112,7 @@ static boolean CachePCSLump(int sound_id)

     if (current_sound_lump != NULL)
     {
-        Z_ChangeTag(current_sound_lump, PU_CACHE);
+        W_ReleaseLumpNum(current_sound_lump_num);
         current_sound_lump = NULL;
     }

@@ -138,6 +139,7 @@ static boolean CachePCSLump(int sound_id)

     current_sound_remaining = headerlen;
     current_sound_pos = current_sound_lump + 4;
+    current_sound_lump_num = S_sfx[sound_id].lumpnum;

     return true;
 }
diff --git a/src/i_sdlsound.c b/src/i_sdlsound.c
index 429581e2..b6fc9787 100644
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@ -410,7 +410,7 @@ static boolean CacheSFX(int sound)

     // don't need the original lump any more

-    Z_ChangeTag(data, PU_CACHE);
+    W_ReleaseLumpNum(lumpnum);

     return true;
 }
diff --git a/src/r_plane.c b/src/r_plane.c
index c0df67cb..400821d5 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -372,6 +372,7 @@ void R_DrawPlanes (void)
     int			x;
     int			stop;
     int			angle;
+    int                 lumpnum;

 #ifdef RANGECHECK
     if (ds_p - drawsegs > MAXDRAWSEGS)
@@ -421,9 +422,8 @@ void R_DrawPlanes (void)
 	}

 	// regular flat
-	ds_source = W_CacheLumpNum(firstflat +
-				   flattranslation[pl->picnum],
-				   PU_STATIC);
+        lumpnum = firstflat + flattranslation[pl->picnum];
+	ds_source = W_CacheLumpNum(lumpnum, PU_STATIC);

 	planeheight = abs(pl->height-viewz);
 	light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
@@ -449,6 +449,6 @@ void R_DrawPlanes (void)
 			pl->bottom[x]);
 	}

-	Z_ChangeTag (ds_source, PU_CACHE);
+        W_ReleaseLumpNum(lumpnum);
     }
 }
diff --git a/src/s_sound.c b/src/s_sound.c
index cc071bde..70fa75f3 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -830,7 +830,7 @@ void S_ChangeMusic(int musicnum, int looping)
     {
         // Load & register it

-        music->data = W_CacheLumpNum(music->lumpnum, PU_MUSIC);
+        music->data = W_CacheLumpNum(music->lumpnum, PU_STATIC);
         handle = music_module->RegisterSong(music->data,
                                             W_LumpLength(music->lumpnum));
         music->handle = handle;
@@ -868,7 +868,7 @@ void S_StopMusic(void)

             music_module->StopSong();
             music_module->UnRegisterSong(mus_playing->handle);
-            Z_ChangeTag(mus_playing->data, PU_CACHE);
+            W_ReleaseLumpNum(mus_playing->lumpnum);

             mus_playing->data = NULL;
         }
diff --git a/src/st_stuff.c b/src/st_stuff.c
index 6d502afd..766a0ec1 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -1053,7 +1053,12 @@ void ST_Drawer (boolean fullscreen, boolean refresh)

 }

-void ST_loadGraphics(void)
+typedef void (*load_callback_t)(char *lumpname, patch_t **variable);
+
+// Iterates through all graphics to be loaded or unloaded, along with
+// the variable they use, invoking the specified callback function.
+
+static void ST_loadUnloadGraphics(load_callback_t callback)
 {

     int		i;
@@ -1066,33 +1071,34 @@ void ST_loadGraphics(void)
     for (i=0;i<10;i++)
     {
 	sprintf(namebuf, DEH_String("STTNUM%d"), i);
-	tallnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &tallnum[i]);

 	sprintf(namebuf, DEH_String("STYSNUM%d"), i);
-	shortnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &shortnum[i]);
     }

     // Load percent key.
     //Note: why not load STMINUS here, too?
-    tallpercent = (patch_t *) W_CacheLumpName(DEH_String("STTPRCNT"), PU_STATIC);
+
+    callback(DEH_String("STTPRCNT"), &tallpercent);

     // key cards
     for (i=0;i<NUMCARDS;i++)
     {
 	sprintf(namebuf, DEH_String("STKEYS%d"), i);
-	keys[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &keys[i]);
     }

     // arms background
-    armsbg = (patch_t *) W_CacheLumpName(DEH_String("STARMS"), PU_STATIC);
+    callback(DEH_String("STARMS"), &armsbg);

     // arms ownership widgets
-    for (i=0;i<6;i++)
+    for (i=0; i<6; i++)
     {
 	sprintf(namebuf, DEH_String("STGNUM%d"), i+2);

 	// gray #
-	arms[i][0] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &arms[i][0]);

 	// yellow #
 	arms[i][1] = shortnum[i+2];
@@ -1100,34 +1106,52 @@ void ST_loadGraphics(void)

     // face backgrounds for different color players
     sprintf(namebuf, DEH_String("STFB%d"), consoleplayer);
-    faceback = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
+    callback(namebuf, &faceback);

     // status bar background bits
-    sbar = (patch_t *) W_CacheLumpName(DEH_String("STBAR"), PU_STATIC);
+    callback(DEH_String("STBAR"), &sbar);

     // face states
     facenum = 0;
-    for (i=0;i<ST_NUMPAINFACES;i++)
+    for (i=0; i<ST_NUMPAINFACES; i++)
     {
-	for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
+	for (j=0; j<ST_NUMSTRAIGHTFACES; j++)
 	{
 	    sprintf(namebuf, DEH_String("STFST%d%d"), i, j);
-	    faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
+            callback(namebuf, &faces[facenum]);
+            ++facenum;
 	}
 	sprintf(namebuf, DEH_String("STFTR%d0"), i);	// turn right
-	faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &faces[facenum]);
+        ++facenum;
 	sprintf(namebuf, DEH_String("STFTL%d0"), i);	// turn left
-	faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &faces[facenum]);
+        ++facenum;
 	sprintf(namebuf, DEH_String("STFOUCH%d"), i);	// ouch!
-	faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &faces[facenum]);
+        ++facenum;
 	sprintf(namebuf, DEH_String("STFEVL%d"), i);	// evil grin ;)
-	faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &faces[facenum]);
+        ++facenum;
 	sprintf(namebuf, DEH_String("STFKILL%d"), i);	// pissed off
-	faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
+        callback(namebuf, &faces[facenum]);
+        ++facenum;
     }
-    faces[facenum++] = W_CacheLumpName(DEH_String("STFGOD0"), PU_STATIC);
-    faces[facenum++] = W_CacheLumpName(DEH_String("STFDEAD0"), PU_STATIC);

+    callback(DEH_String("STFGOD0"), &faces[facenum]);
+    ++facenum;
+    callback(DEH_String("STFDEAD0"), &faces[facenum]);
+    ++facenum;
+}
+
+static void ST_loadCallback(char *lumpname, patch_t **variable)
+{
+    *variable = W_CacheLumpName(lumpname, PU_STATIC);
+}
+
+void ST_loadGraphics(void)
+{
+    ST_loadUnloadGraphics(ST_loadCallback);
 }

 void ST_loadData(void)
@@ -1136,41 +1160,15 @@ void ST_loadData(void)
     ST_loadGraphics();
 }

-void ST_unloadGraphics(void)
+static void ST_unloadCallback(char *lumpname, patch_t **variable)
 {
+    W_ReleaseLumpName(lumpname);
+    *variable = NULL;
+}

-    int i;
-
-    // unload the numbers, tall and short
-    for (i=0;i<10;i++)
-    {
-	Z_ChangeTag(tallnum[i], PU_CACHE);
-	Z_ChangeTag(shortnum[i], PU_CACHE);
-    }
-    // unload tall percent
-    Z_ChangeTag(tallpercent, PU_CACHE);
-
-    // unload arms background
-    Z_ChangeTag(armsbg, PU_CACHE);
-
-    // unload gray #'s
-    for (i=0;i<6;i++)
-	Z_ChangeTag(arms[i][0], PU_CACHE);
-
-    // unload the key cards
-    for (i=0;i<NUMCARDS;i++)
-	Z_ChangeTag(keys[i], PU_CACHE);
-
-    Z_ChangeTag(sbar, PU_CACHE);
-    Z_ChangeTag(faceback, PU_CACHE);
-
-    for (i=0;i<ST_NUMFACES;i++)
-	Z_ChangeTag(faces[i], PU_CACHE);
-
-    // Note: nobody ain't seen no unloading
-    //   of stminus yet. Dude.
-
-
+void ST_unloadGraphics(void)
+{
+    ST_loadUnloadGraphics(ST_unloadCallback);
 }

 void ST_unloadData(void)
diff --git a/src/w_wad.c b/src/w_wad.c
index becdcf71..8960bb92 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -457,6 +457,15 @@ void W_ReadLump(unsigned int lump, void *dest)
 //
 // W_CacheLumpNum
 //
+// Load a lump into memory and return a pointer to a buffer containing
+// the lump data.
+//
+// 'tag' is the type of zone memory buffer to allocate for the lump
+// (usually PU_STATIC or PU_CACHE).  If the lump is loaded as
+// PU_STATIC, it should be released back using W_ReleaseLumpNum
+// when no longer needed (do not use Z_ChangeTag).
+//
+
 void *W_CacheLumpNum(int lump, int tag)
 {
     byte*	ptr;
@@ -491,6 +500,31 @@ void *W_CacheLumpName(char *name, int tag)
     return W_CacheLumpNum(W_GetNumForName(name), tag);
 }

+//
+// Release a lump back to the cache, so that it can be reused later
+// without having to read from disk again, or alternatively, discarded
+// if we run out of memory.
+//
+// Back in Vanilla Doom, this was just done using Z_ChangeTag
+// directly, but now that we have WAD mmap, things are a bit more
+// complicated ...
+//
+
+void W_ReleaseLumpNum(int lump)
+{
+    if ((unsigned)lump >= numlumps)
+    {
+	I_Error ("W_ReleaseLumpNum: %i >= numlumps", lump);
+    }
+
+    Z_ChangeTag(lumpinfo[lump].cache, PU_CACHE);
+}
+
+void W_ReleaseLumpName(char *name)
+{
+    W_ReleaseLumpNum(W_GetNumForName(name));
+}
+
 #if 0

 //
diff --git a/src/w_wad.h b/src/w_wad.h
index 85a42db8..f28b5e37 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -79,5 +79,8 @@ void    W_GenerateHashTable(void);

 extern unsigned int W_LumpNameHash(const char *s);

+void    W_ReleaseLumpNum(int lump);
+void    W_ReleaseLumpName(char *name);
+

 #endif
diff --git a/src/wi_stuff.c b/src/wi_stuff.c
index c6e5c359..bea7054f 100644
--- a/src/wi_stuff.c
+++ b/src/wi_stuff.c
@@ -346,9 +346,6 @@ static int		NUMCMAPS;
 //	GRAPHICS
 //

-// background (map of levels).
-static patch_t*		bg;
-
 // You Are Here graphic
 static patch_t*		yah[2];

@@ -1547,29 +1544,18 @@ void WI_Ticker(void)

 }

-void WI_loadData(void)
+typedef void (*load_callback_t)(char *lumpname, patch_t **variable);
+
+// Common load/unload function.  Iterates over all the graphics
+// lumps to be loaded/unloaded into memory.
+
+static void WI_loadUnloadData(load_callback_t callback)
 {
     int		i;
     int		j;
     char	name[9];
     anim_t*	a;

-    if (gamemode == commercial)
-	strcpy(name, DEH_String("INTERPIC"));
-    else
-	sprintf(name, DEH_String("WIMAP%d"), wbs->epsd);
-
-    if ( gamemode == retail )
-    {
-      if (wbs->epsd == 3)
-	strcpy(name, DEH_String("INTERPIC"));
-    }
-
-    // background
-    bg = W_CacheLumpName(name, PU_CACHE);
-    V_DrawPatch(0, 0, 1, bg);
-
-
     // UNUSED unsigned char *pic = screens[1];
     // if (gamemode == commercial)
     // {
@@ -1583,33 +1569,28 @@ void WI_loadData(void)

     if (gamemode == commercial)
     {
-	NUMCMAPS = 32;
-	lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMCMAPS,
-				       PU_STATIC, 0);
 	for (i=0 ; i<NUMCMAPS ; i++)
 	{
 	    sprintf(name, DEH_String("CWILV%2.2d"), i);
-	    lnames[i] = W_CacheLumpName(name, PU_STATIC);
+            callback(name, &lnames[i]);
 	}
     }
     else
     {
-	lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMMAPS,
-				       PU_STATIC, 0);
 	for (i=0 ; i<NUMMAPS ; i++)
 	{
 	    sprintf(name, DEH_String("WILV%d%d"), wbs->epsd, i);
-	    lnames[i] = W_CacheLumpName(name, PU_STATIC);
+            callback(name, &lnames[i]);
 	}

 	// you are here
-	yah[0] = W_CacheLumpName(DEH_String("WIURH0"), PU_STATIC);
+        callback(DEH_String("WIURH0"), &yah[0]);

 	// you are here (alt.)
-	yah[1] = W_CacheLumpName(DEH_String("WIURH1"), PU_STATIC);
+        callback(DEH_String("WIURH1"), &yah[1]);

 	// splat
-	splat = W_CacheLumpName(DEH_String("WISPLAT"), PU_STATIC);
+        callback(DEH_String("WISPLAT"), &splat);

 	if (wbs->epsd < 3)
 	{
@@ -1624,7 +1605,7 @@ void WI_loadData(void)
 			// animations
 			sprintf(name, DEH_String("WIA%d%.2d%.2d"),
 				      wbs->epsd, j, i);
-			a->p[i] = W_CacheLumpName(name, PU_STATIC);
+                        callback(name, &a->p[i]);
 		    }
 		    else
 		    {
@@ -1637,150 +1618,149 @@ void WI_loadData(void)
     }

     // More hacks on minus sign.
-    wiminus = W_CacheLumpName(DEH_String("WIMINUS"), PU_STATIC);
+    callback(DEH_String("WIMINUS"), &wiminus);

     for (i=0;i<10;i++)
     {
 	 // numbers 0-9
 	sprintf(name, DEH_String("WINUM%d"), i);
-	num[i] = W_CacheLumpName(name, PU_STATIC);
+        callback(name, &num[i]);
     }

     // percent sign
-    percent = W_CacheLumpName(DEH_String("WIPCNT"), PU_STATIC);
+    callback(DEH_String("WIPCNT"), &percent);

     // "finished"
-    finished = W_CacheLumpName(DEH_String("WIF"), PU_STATIC);
+    callback(DEH_String("WIF"), &finished);

     // "entering"
-    entering = W_CacheLumpName(DEH_String("WIENTER"), PU_STATIC);
+    callback(DEH_String("WIENTER"), &entering);

     // "kills"
-    kills = W_CacheLumpName(DEH_String("WIOSTK"), PU_STATIC);
+    callback(DEH_String("WIOSTK"), &kills);

     // "scrt"
-    secret = W_CacheLumpName(DEH_String("WIOSTS"), PU_STATIC);
+    callback(DEH_String("WIOSTS"), &secret);

      // "secret"
-    sp_secret = W_CacheLumpName(DEH_String("WISCRT2"), PU_STATIC);
+    callback(DEH_String("WISCRT2"), &sp_secret);

     // french wad uses WIOBJ (?)
     if (W_CheckNumForName(DEH_String("WIOBJ")) >= 0)
     {
     	// "items"
     	if (netgame && !deathmatch)
-            items = W_CacheLumpName(DEH_String("WIOBJ"), PU_STATIC);
+            callback(DEH_String("WIOBJ"), &items);
     	else
-            items = W_CacheLumpName(DEH_String("WIOSTI"), PU_STATIC);
+            callback(DEH_String("WIOSTI"), &items);
     } else {
-	items = W_CacheLumpName(DEH_String("WIOSTI"), PU_STATIC);
+        callback(DEH_String("WIOSTI"), &items);
     }

     // "frgs"
-    frags = W_CacheLumpName(DEH_String("WIFRGS"), PU_STATIC);
+    callback(DEH_String("WIFRGS"), &frags);

     // ":"
-    colon = W_CacheLumpName(DEH_String("WICOLON"), PU_STATIC);
+    callback(DEH_String("WICOLON"), &colon);

     // "time"
-    timepatch = W_CacheLumpName(DEH_String("WITIME"), PU_STATIC);
+    callback(DEH_String("WITIME"), &timepatch);

     // "sucks"
-    sucks = W_CacheLumpName(DEH_String("WISUCKS"), PU_STATIC);
+    callback(DEH_String("WISUCKS"), &sucks);

     // "par"
-    par = W_CacheLumpName(DEH_String("WIPAR"), PU_STATIC);
+    callback(DEH_String("WIPAR"), &par);

     // "killers" (vertical)
-    killers = W_CacheLumpName(DEH_String("WIKILRS"), PU_STATIC);
+    callback(DEH_String("WIKILRS"), &killers);

     // "victims" (horiz)
-    victims = W_CacheLumpName(DEH_String("WIVCTMS"), PU_STATIC);
+    callback(DEH_String("WIVCTMS"), &victims);

     // "total"
-    total = W_CacheLumpName(DEH_String("WIMSTT"), PU_STATIC);
-
-    // your face
-    star = W_CacheLumpName(DEH_String("STFST01"), PU_STATIC);
-
-    // dead face
-    bstar = W_CacheLumpName(DEH_String("STFDEAD0"), PU_STATIC);
+    callback(DEH_String("WIMSTT"), &total);

     for (i=0 ; i<MAXPLAYERS ; i++)
     {
 	// "1,2,3,4"
 	sprintf(name, DEH_String("STPB%d"), i);
-	p[i] = W_CacheLumpName(name, PU_STATIC);
+        callback(name, &p[i]);

 	// "1,2,3,4"
 	sprintf(name, DEH_String("WIBP%d"), i+1);
-	bp[i] = W_CacheLumpName(name, PU_STATIC);
+        callback(name, &bp[i]);
     }

 }

-void WI_unloadData(void)
+static void WI_loadCallback(char *name, patch_t **variable)
 {
-    int		i;
-    int		j;
+    *variable = W_CacheLumpName(name, PU_STATIC);
+}

-    Z_ChangeTag(wiminus, PU_CACHE);
+void WI_loadData(void)
+{
+    char bg_lumpname[9];
+    patch_t *bg;

-    for (i=0 ; i<10 ; i++)
-	Z_ChangeTag(num[i], PU_CACHE);
-
     if (gamemode == commercial)
     {
-  	for (i=0 ; i<NUMCMAPS ; i++)
-	    Z_ChangeTag(lnames[i], PU_CACHE);
+	NUMCMAPS = 32;
+	lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMCMAPS,
+				       PU_STATIC, NULL);
     }
     else
     {
-	Z_ChangeTag(yah[0], PU_CACHE);
-	Z_ChangeTag(yah[1], PU_CACHE);
+	lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMMAPS,
+				       PU_STATIC, NULL);
+    }

-	Z_ChangeTag(splat, PU_CACHE);
+    WI_loadUnloadData(WI_loadCallback);

-	for (i=0 ; i<NUMMAPS ; i++)
-	    Z_ChangeTag(lnames[i], PU_CACHE);
-
-	if (wbs->epsd < 3)
-	{
-	    for (j=0;j<NUMANIMS[wbs->epsd];j++)
-	    {
-		if (wbs->epsd != 1 || j != 8)
-		    for (i=0;i<anims[wbs->epsd][j].nanims;i++)
-			Z_ChangeTag(anims[wbs->epsd][j].p[i], PU_CACHE);
-	    }
-	}
+    // These two graphics are special cased because we're sharing
+    // them with the status bar code
+
+    // your face
+    star = W_CacheLumpName(DEH_String("STFST01"), PU_STATIC);
+
+    // dead face
+    bstar = W_CacheLumpName(DEH_String("STFDEAD0"), PU_STATIC);
+
+    // Background image
+
+    if (gamemode == commercial)
+    {
+	strcpy(bg_lumpname, DEH_String("INTERPIC"));
+    }
+    else if (gamemode == retail && wbs->epsd == 3)
+    {
+	strcpy(bg_lumpname, DEH_String("INTERPIC"));
+    }
+    else
+    {
+	sprintf(bg_lumpname, DEH_String("WIMAP%d"), wbs->epsd);
     }

-    Z_Free(lnames);
-
-    Z_ChangeTag(percent, PU_CACHE);
-    Z_ChangeTag(colon, PU_CACHE);
-    Z_ChangeTag(finished, PU_CACHE);
-    Z_ChangeTag(entering, PU_CACHE);
-    Z_ChangeTag(kills, PU_CACHE);
-    Z_ChangeTag(secret, PU_CACHE);
-    Z_ChangeTag(sp_secret, PU_CACHE);
-    Z_ChangeTag(items, PU_CACHE);
-    Z_ChangeTag(frags, PU_CACHE);
-    Z_ChangeTag(timepatch, PU_CACHE);
-    Z_ChangeTag(sucks, PU_CACHE);
-    Z_ChangeTag(par, PU_CACHE);
-
-    Z_ChangeTag(victims, PU_CACHE);
-    Z_ChangeTag(killers, PU_CACHE);
-    Z_ChangeTag(total, PU_CACHE);
-    //  Z_ChangeTag(star, PU_CACHE);
-    //  Z_ChangeTag(bstar, PU_CACHE);
-
-    for (i=0 ; i<MAXPLAYERS ; i++)
-	Z_ChangeTag(p[i], PU_CACHE);
+    bg = W_CacheLumpName(bg_lumpname, PU_CACHE);
+    V_DrawPatch(0, 0, 1, bg);
+}

-    for (i=0 ; i<MAXPLAYERS ; i++)
-	Z_ChangeTag(bp[i], PU_CACHE);
+static void WI_unloadCallback(char *name, patch_t **variable)
+{
+    W_ReleaseLumpName(name);
+    *variable = NULL;
+}
+
+void WI_unloadData(void)
+{
+    WI_loadUnloadData(WI_unloadCallback);
+
+    // We do not free these lumps as they are shared with the status
+    // bar code.
+
+    // W_ReleaseLumpName("STFST01");
+    // W_ReleaseLumpName("STFDEAD0");
 }

 void WI_Drawer (void)