shithub: choc

Download patch

ref: 56412813c70ba44a6f6a74cee5bf460ca6a31402
parent: 08e0b1471b357ae22a632d1752919d973db8983e
author: Simon Howard <fraggle@gmail.com>
date: Mon Feb 8 16:14:30 EST 2010

Add Heretic implementation of HHE "Text" section, add DEH_String()
around appropriate strings to allow string replacements.

Subversion-branch: /branches/raven-branch
Subversion-revision: 1867

--- a/src/heretic/Makefile.am
+++ b/src/heretic/Makefile.am
@@ -59,6 +59,7 @@
 FEATURE_DEHACKED_SOURCE_FILES =            \
 deh_ammo.c                                 \
 deh_frame.c                                \
+deh_htext.c                                \
 deh_htic.c                                 \
 deh_sound.c                                \
 deh_thing.c                                \
--- a/src/heretic/am_map.c
+++ b/src/heretic/am_map.c
@@ -27,6 +27,7 @@
 #include <stdio.h>
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_video.h"
 #include "m_controls.h"
 #include "p_local.h"
@@ -408,7 +409,7 @@
     sprintf(namebuf, "AMMNUM%d", i);
     marknums[i] = W_CacheLumpName(namebuf, PU_STATIC);
   }*/
-    maplump = W_CacheLumpName("AUTOPAGE", PU_STATIC);
+    maplump = W_CacheLumpName(DEH_String("AUTOPAGE"), PU_STATIC);
 }
 
 /*void AM_unloadPics(void)
@@ -1473,6 +1474,7 @@
 
 void AM_Drawer(void)
 {
+    char *level_name;
     int numepisodes;
 
     if (!automapactive)
@@ -1505,7 +1507,8 @@
 
     if (gameepisode <= numepisodes && gamemap < 10)
     {
-        MN_DrTextA(LevelNames[(gameepisode - 1) * 9 + gamemap - 1], 20, 145);
+        level_name = LevelNames[(gameepisode - 1) * 9 + gamemap - 1];
+        MN_DrTextA(DEH_String(level_name), 20, 145);
     }
 //  I_Update();
 //  V_MarkRect(f_x, f_y, f_w, f_h);
--- a/src/heretic/ct_chat.c
+++ b/src/heretic/ct_chat.c
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include "doomdef.h"
 #include "doomkeys.h"
+#include "deh_str.h"
 #include "p_local.h"
 #include "s_sound.h"
 #include "v_video.h"
@@ -115,7 +116,7 @@
         memset(plr_lastmsg[i], 0, MESSAGESIZE);
         memset(chat_msg[i], 0, MESSAGESIZE);
     }
-    FontABaseLump = W_GetNumForName("FONTA_S") + 1;
+    FontABaseLump = W_GetNumForName(DEH_String("FONTA_S")) + 1;
     return;
 }
 
@@ -300,7 +301,7 @@
                 CT_AddChar(i, 0);       // set the end of message character
                 if (numplayers > 2)
                 {
-                    strcpy(plr_lastmsg[i], CT_FromPlrText[i]);
+                    strcpy(plr_lastmsg[i], DEH_String(CT_FromPlrText[i]));
                     strcat(plr_lastmsg[i], chat_msg[i]);
                 }
                 else
@@ -320,13 +321,13 @@
                     if (numplayers > 1)
                     {
                         P_SetMessage(&players[consoleplayer],
-                                     "-MESSAGE SENT-", true);
+                                     DEH_String("-MESSAGE SENT-"), true);
                         S_StartSound(NULL, sfx_chat);
                     }
                     else
                     {
                         P_SetMessage(&players[consoleplayer],
-                                     "THERE ARE NO OTHER PLAYERS IN THE GAME!",
+                                     DEH_String("THERE ARE NO OTHER PLAYERS IN THE GAME!"),
                                      true);
                         S_StartSound(NULL, sfx_chat);
                     }
@@ -376,7 +377,7 @@
                 x += patch->width;
             }
         }
-        V_DrawPatch(x, 10, W_CacheLumpName("FONTA59", PU_CACHE));
+        V_DrawPatch(x, 10, W_CacheLumpName(DEH_String("FONTA59"), PU_CACHE));
         BorderTopRefresh = true;
         UpdateState |= I_MESSAGES;
     }
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -185,12 +185,12 @@
     {
         if (!netgame)
         {
-            V_DrawPatch(160, viewwindowy + 5, W_CacheLumpName("PAUSED",
+            V_DrawPatch(160, viewwindowy + 5, W_CacheLumpName(DEH_String("PAUSED"),
                                                               PU_CACHE));
         }
         else
         {
-            V_DrawPatch(160, 70, W_CacheLumpName("PAUSED", PU_CACHE));
+            V_DrawPatch(160, 70, W_CacheLumpName(DEH_String("PAUSED"), PU_CACHE));
         }
     }
     // Handle player messages
@@ -316,7 +316,7 @@
     V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
     if (demosequence == 1)
     {
-        V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
+        V_DrawPatch(4, 160, W_CacheLumpName(DEH_String("ADVISOR"), PU_CACHE));
     }
     UpdateState |= I_FULLSCRN;
 }
@@ -348,28 +348,28 @@
         case 0:
             pagetic = 210;
             gamestate = GS_DEMOSCREEN;
-            pagename = "TITLE";
+            pagename = DEH_String("TITLE");
             S_StartSong(mus_titl, false);
             break;
         case 1:
             pagetic = 140;
             gamestate = GS_DEMOSCREEN;
-            pagename = "TITLE";
+            pagename = DEH_String("TITLE");
             break;
         case 2:
             BorderNeedRefresh = true;
             UpdateState |= I_FULLSCRN;
-            G_DeferedPlayDemo("demo1");
+            G_DeferedPlayDemo(DEH_String("demo1"));
             break;
         case 3:
             pagetic = 200;
             gamestate = GS_DEMOSCREEN;
-            pagename = "CREDIT";
+            pagename = DEH_String("CREDIT");
             break;
         case 4:
             BorderNeedRefresh = true;
             UpdateState |= I_FULLSCRN;
-            G_DeferedPlayDemo("demo2");
+            G_DeferedPlayDemo(DEH_String("demo2"));
             break;
         case 5:
             pagetic = 200;
@@ -376,17 +376,17 @@
             gamestate = GS_DEMOSCREEN;
             if (gamemode == shareware)
             {
-                pagename = "ORDER";
+                pagename = DEH_String("ORDER");
             }
             else
             {
-                pagename = "CREDIT";
+                pagename = DEH_String("CREDIT");
             }
             break;
         case 6:
             BorderNeedRefresh = true;
             UpdateState |= I_FULLSCRN;
-            G_DeferedPlayDemo("demo3");
+            G_DeferedPlayDemo(DEH_String("demo3"));
             break;
     }
 }
@@ -639,7 +639,7 @@
 
     // Blit main screen
     textScreen = TXT_GetScreenData();
-    loading = W_CacheLumpName("LOADING", PU_CACHE);
+    loading = W_CacheLumpName(DEH_String("LOADING"), PU_CACHE);
     memcpy(textScreen, loading, 4000);
 
     // Print version string
@@ -699,7 +699,7 @@
 // haleyjd: moved up, removed WATCOMC code
 void CleanExit(void)
 {
-    printf("Exited from HERETIC.\n");
+    printf(DEH_String("Exited from HERETIC.\n"));
     exit(1);
 }
 
@@ -783,7 +783,7 @@
         return;
     }
 
-    endoom_data = W_CacheLumpName("ENDTEXT", PU_STATIC);
+    endoom_data = W_CacheLumpName(DEH_String("ENDTEXT"), PU_STATIC);
 
     I_Endoom(endoom_data);
 }
@@ -848,7 +848,7 @@
 //
 // init subsystems
 //
-    printf("V_Init: allocate screens.\n");
+    printf(DEH_String("V_Init: allocate screens.\n"));
     V_Init();
 
     // Check for -CDROM
@@ -873,7 +873,7 @@
 
     if (cdrom)
     {
-        M_SetConfigDir("c:\\heretic.cd\\");
+        M_SetConfigDir(DEH_String("c:\\heretic.cd"));
     }
     else
     {
@@ -881,7 +881,7 @@
     }
 
     // Load defaults before initing other systems
-    printf("M_LoadDefaults: Load system defaults.\n");
+    printf(DEH_String("M_LoadDefaults: Load system defaults.\n"));
     D_BindVariables();
     M_SetConfigFilenames("heretic.cfg", PROGRAM_PREFIX "heretic.cfg");
     M_LoadDefaults();
@@ -888,7 +888,7 @@
 
     I_AtExit(M_SaveDefaults, false);
 
-    printf("Z_Init: Init zone memory allocation daemon.\n");
+    printf(DEH_String("Z_Init: Init zone memory allocation daemon.\n"));
     Z_Init();
 
 #ifdef FEATURE_DEHACKED
@@ -896,7 +896,7 @@
     DEH_Init();
 #endif
 
-    printf("W_Init: Init WADfiles.\n");
+    printf(DEH_String("W_Init: Init WADfiles.\n"));
 
     iwadfile = D_FindIWAD(IWAD_MASK_HERETIC, &gamemission);
 
@@ -933,12 +933,12 @@
     }
     if (p && p < myargc - 1)
     {
-        sprintf(file, "%s.lmp", myargv[p + 1]);
+        sprintf(file, DEH_String("%s.lmp"), myargv[p + 1]);
         D_AddFile(file);
-        printf("Playing demo %s.lmp.\n", myargv[p + 1]);
+        printf(DEH_String("Playing demo %s.lmp.\n"), myargv[p + 1]);
     }
 
-    if (W_CheckNumForName("E2M1") == -1)
+    if (W_CheckNumForName(DEH_String("E2M1")) == -1)
     {
         gamemode = shareware;
         gamedescription = "Heretic (shareware)";
@@ -966,54 +966,54 @@
     //
     smsg[0] = 0;
     if (deathmatch)
-        status("DeathMatch...");
+        status(DEH_String("DeathMatch..."));
     if (nomonsters)
-        status("No Monsters...");
+        status(DEH_String("No Monsters..."));
     if (respawnparm)
-        status("Respawning...");
+        status(DEH_String("Respawning..."));
     if (autostart)
     {
         char temp[64];
-        sprintf(temp, "Warp to Episode %d, Map %d, Skill %d ",
+        sprintf(temp, DEH_String("Warp to Episode %d, Map %d, Skill %d "),
                 startepisode, startmap, startskill + 1);
         status(temp);
     }
     wadprintf();                // print the added wadfiles
 
-    tprintf("MN_Init: Init menu system.\n", 1);
+    tprintf(DEH_String("MN_Init: Init menu system.\n"), 1);
     MN_Init();
 
     CT_Init();
 
-    tprintf("R_Init: Init Heretic refresh daemon.", 1);
-    hprintf("Loading graphics");
+    tprintf(DEH_String("R_Init: Init Heretic refresh daemon."), 1);
+    hprintf(DEH_String("Loading graphics"));
     R_Init();
     tprintf("\n", 0);
 
-    tprintf("P_Init: Init Playloop state.\n", 1);
-    hprintf("Init game engine.");
+    tprintf(DEH_String("P_Init: Init Playloop state.\n"), 1);
+    hprintf(DEH_String("Init game engine."));
     P_Init();
     IncThermo();
 
-    tprintf("I_Init: Setting up machine state.\n", 1);
+    tprintf(DEH_String("I_Init: Setting up machine state.\n"), 1);
     I_CheckIsScreensaver();
     I_InitTimer();
     I_InitJoystick();
     IncThermo();
 
-    tprintf("S_Init: Setting up sound.\n", 1);
+    tprintf(DEH_String("S_Init: Setting up sound.\n"), 1);
     S_Init();
     //IO_StartupTimer();
     S_Start();
 
-    tprintf("D_CheckNetGame: Checking network game status.\n", 1);
-    hprintf("Checking network game status.");
+    tprintf(DEH_String("D_CheckNetGame: Checking network game status.\n"), 1);
+    hprintf(DEH_String("Checking network game status."));
     D_CheckNetGame();
     IncThermo();
 
     // haleyjd: removed WATCOMC
 
-    tprintf("SB_Init: Loading patches.\n", 1);
+    tprintf(DEH_String("SB_Init: Loading patches.\n"), 1);
     SB_Init();
     IncThermo();
 
--- /dev/null
+++ b/src/heretic/deh_htext.c
@@ -1,0 +1,903 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005-2010 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Parses Text substitution sections in dehacked files
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <string.h>
+
+#include "doomtype.h"
+#include "dstrings.h"
+
+#include "z_zone.h"
+
+#include "deh_defs.h"
+#include "deh_io.h"
+#include "deh_main.h"
+
+//
+// Ok, Greg, the action pointers thing was bad enough, but this really
+// takes the biscuit.  Why does HHE's text replacement address strings
+// by offset??!!  The dehacked way was much nicer, why change it?
+//
+// Anyway, this is the Heretic 1.0 string table, which can be seen in
+// HHE.  This is the string and its offset from the start of the
+// text section.  Not all the strings are here; this is a redacted list
+// that contains just the strings we support.
+//
+
+static const struct
+{
+    unsigned int offset;
+    char *string;
+}
+string_table[] =
+{
+    {      0, NULL },
+    {      4, NULL },
+    {     64, NULL },
+    {    104, NULL },
+    {    160, NULL },
+    {    200, NULL },
+    {    220, NULL },
+    {    228, "PLAYPAL" },
+    {    236, NULL },
+    {    244, NULL },
+    {    252, NULL },
+    {    272, NULL },
+    {    288, NULL },
+    {    296, NULL },
+    {    316, NULL },
+    {    332, NULL },
+    {    372, NULL },
+    {    436, NULL },
+    {    504, NULL },
+    {    536, NULL },
+    {    544, NULL },
+    {    560, NULL },
+    {    576, NULL },
+    {    584, "ENDTEXT" },
+    {    592, NULL },
+    {    612, NULL },
+    {    640, NULL },
+    {    664, NULL },
+    {    712, NULL },
+    {    744, NULL },
+    {    764, NULL },
+    {    808, NULL },
+    {    820, NULL },
+    {    828, NULL },
+    {    840, NULL },
+    {    876, NULL },
+    {    884, NULL },
+    {    908, NULL },
+    {    952, NULL },
+    {    992, NULL },
+    {   1028, NULL },
+    {   1036, NULL },
+    {   1048, NULL },
+    {   1088, NULL },
+    {   1128, NULL },
+    {   1160, NULL },
+    {   1192, NULL },
+    {   1212, NULL },
+    {   1240, "E1M1:  THE DOCKS" },
+    {   1260, "E1M2:  THE DUNGEONS" },
+    {   1280, "E1M3:  THE GATEHOUSE" },
+    {   1304, "E1M4:  THE GUARD TOWER" },
+    {   1328, "E1M5:  THE CITADEL" },
+    {   1348, "E1M6:  THE CATHEDRAL" },
+    {   1372, "E1M7:  THE CRYPTS" },
+    {   1392, "E1M8:  HELL'S MAW" },
+    {   1412, "E1M9:  THE GRAVEYARD" },
+    {   1436, "E2M1:  THE CRATER" },
+    {   1456, "E2M2:  THE LAVA PITS" },
+    {   1480, "E2M3:  THE RIVER OF FIRE" },
+    {   1508, "E2M4:  THE ICE GROTTO" },
+    {   1532, "E2M5:  THE CATACOMBS" },
+    {   1556, "E2M6:  THE LABYRINTH" },
+    {   1580, "E2M7:  THE GREAT HALL" },
+    {   1604, "E2M8:  THE PORTALS OF CHAOS" },
+    {   1632, "E2M9:  THE GLACIER" },
+    {   1652, "E3M1:  THE STOREHOUSE" },
+    {   1676, "E3M2:  THE CESSPOOL" },
+    {   1696, "E3M3:  THE CONFLUENCE" },
+    {   1720, "E3M4:  THE AZURE FORTRESS" },
+    {   1748, "E3M5:  THE OPHIDIAN LAIR" },
+    {   1776, "E3M6:  THE HALLS OF FEAR" },
+    {   1804, "E3M7:  THE CHASM" },
+    {   1824, "E3M8:  D'SPARIL'S KEEP" },
+    {   1848, "E3M9:  THE AQUIFER" },
+    {   1868, "AUTOPAGE" },
+    {   1880, "FOLLOW MODE ON" },
+    {   1896, "FOLLOW MODE OFF" },
+    {   1912, "GREEN:  " },
+    {   1936, "YELLOW:  " },
+    {   1948, "RED:  " },
+    {   1956, "BLUE:  " },
+    {   1964, "FONTA_S" },
+    {   1972, "-MESSAGE SENT-" },
+    {   1988, "THERE ARE NO OTHER PLAYERS IN THE GAME!" },
+    {   2028, "FONTA59" },
+    {   2036, "PAUSED" },
+    {   2044, NULL },
+    {   2056, NULL },
+    {   2072, "ADVISOR" },
+    {   2080, "TITLE" },
+    {   2088, "demo1" },
+    {   2096, "CREDIT" },
+    {   2104, "demo2" },
+    {   2112, "ORDER" },
+    {   2120, "demo3" },
+    {   2128, NULL },
+    {   2140, NULL },
+    {   2168, "hticsav%c.hsg" },
+    {   2184, "heretic.wad" },
+    {   2196, NULL },
+    {   2212, NULL },
+    {   2228, NULL },
+    {   2240, "heretic.cfg" },
+    {   2252, NULL },
+    {   2264, NULL },
+    {   2284, NULL },
+    {   2304, "Exited from HERETIC.\n" },
+    {   2328, NULL },
+    {   2340, NULL },
+    {   2352, NULL },
+    {   2364, NULL },
+    {   2372, NULL },
+    {   2388, NULL },
+    {   2404, NULL },
+    {   2412, "c:\\heretic.cd" },
+    {   2428, NULL },
+    {   2436, NULL },
+    {   2444, NULL },
+    {   2464, NULL },
+    {   2496, NULL },
+    {   2508, NULL },
+    {   2520, NULL },
+    {   2528, "Playing demo %s.lmp.\n" },
+    {   2552, NULL },
+    {   2564, NULL },
+    {   2572, NULL },
+    {   2584, NULL },
+    {   2592, "V_Init: allocate screens.\n" },
+    {   2620, "M_LoadDefaults: Load system defaults.\n" },
+    {   2660, "Z_Init: Init zone memory allocation daemon.\n" },
+    {   2708, "W_Init: Init WADfiles.\n" },
+    {   2732, "E2M1" },
+    {   2740, "LOADING" },
+    {   2748, "DeathMatch..." },
+    {   2764, "No Monsters..." },
+    {   2780, "Respawning..." },
+    {   2796, "Warp to Episode %d, Map %d, Skill %d " },
+    {   2836, "MN_Init: Init menu system.\n" },
+    {   2864, "R_Init: Init Heretic refresh daemon." },
+    {   2904, "Loading graphics" },
+    {   2924, "P_Init: Init Playloop state." },
+    {   2956, "Init game engine." },
+    {   2976, "I_Init: Setting up machine state.\n" },
+    {   3012, "D_CheckNetGame: Checking network game status.\n" },
+    {   3060, "Checking network game status." },
+    {   3092, "SB_Init: Loading patches.\n" },
+    {   3120, NULL },
+    {   3128, NULL },
+    {   3140, NULL },
+    {   3184, NULL },
+    {   3220, NULL },
+    {   3256, NULL },
+    {   3280, NULL },
+    {   3304, NULL },
+    {   3320, NULL },
+    {   3352, "PLAYER 1 HAS LEFT THE GAME" },
+    {   3380, NULL },
+    {   3432, NULL },
+    {   3464, NULL },
+    {   3508, NULL },
+    {   3548, NULL },
+    {   3600, NULL },
+    {   3624, NULL },
+    {   3664, NULL },
+    {   3696, NULL },
+    {   3736, "NET GAME" },
+    {   3748, "SAVE GAME" },
+    {   3760, "Only %i deathmatch spots, 4 required" },
+    {   3800, "version %i" },
+    {   3812, NULL },
+    {   3828, NULL },
+    {   3856, NULL },
+    {   3872, NULL },
+    {   3896, "GAME SAVED" },
+    {   3908, "SKY1" },
+    {   3916, "SKY2" },
+    {   3924, "SKY3" },
+    {   3932, NULL },
+    {   3940, NULL },
+    {   3976, NULL },
+    {   3996, NULL },
+    {   4016, E1TEXT },
+    {   4536, E2TEXT },
+    {   5068, E3TEXT },
+    {   5632, "FLOOR25" },
+    {   5640, "FLATHUH1" },
+    {   5652, "FLTWAWA2" },
+    {   5664, "FONTA_S" },
+    {   5672, "FINAL1" },
+    {   5680, "FINAL2" },
+    {   5688, "E2PAL" },
+    {   5696, "E2END" },
+    {   5704, "PLAYPAL" },
+    {   5712, "ORDER" },
+    {   5720, "IMPX" },
+    {   5728, "ACLO" },
+    {   5736, "PTN1" },
+    {   5744, "SHLD" },
+    {   5752, "SHD2" },
+    {   5760, "BAGH" },
+    {   5768, "SPMP" },
+    {   5776, "INVS" },
+    {   5784, "PTN2" },
+    {   5792, "SOAR" },
+    {   5800, "INVU" },
+    {   5808, "PWBK" },
+    {   5816, "EGGC" },
+    {   5824, "EGGM" },
+    {   5832, "FX01" },
+    {   5840, "SPHL" },
+    {   5848, "TRCH" },
+    {   5856, "FBMB" },
+    {   5864, "XPL1" },
+    {   5872, "ATLP" },
+    {   5880, "PPOD" },
+    {   5888, "AMG1" },
+    {   5896, "SPSH" },
+    {   5904, "LVAS" },
+    {   5912, "SLDG" },
+    {   5920, "SKH1" },
+    {   5928, "SKH2" },
+    {   5936, "SKH3" },
+    {   5944, "SKH4" },
+    {   5952, "CHDL" },
+    {   5960, "SRTC" },
+    {   5968, "SMPL" },
+    {   5976, "STGS" },
+    {   5984, "STGL" },
+    {   5992, "STCS" },
+    {   6000, "STCL" },
+    {   6008, "KFR1" },
+    {   6016, "BARL" },
+    {   6024, "BRPL" },
+    {   6032, "MOS1" },
+    {   6040, "MOS2" },
+    {   6048, "WTRH" },
+    {   6056, "HCOR" },
+    {   6064, "KGZ1" },
+    {   6072, "KGZB" },
+    {   6080, "KGZG" },
+    {   6088, "KGZY" },
+    {   6096, "VLCO" },
+    {   6104, "VFBL" },
+    {   6112, "VTFB" },
+    {   6120, "SFFI" },
+    {   6128, "TGLT" },
+    {   6136, "TELE" },
+    {   6144, "STFF" },
+    {   6152, "PUF3" },
+    {   6160, "PUF4" },
+    {   6168, "BEAK" },
+    {   6176, "WGNT" },
+    {   6184, "GAUN" },
+    {   6192, "PUF1" },
+    {   6200, "WBLS" },
+    {   6208, "BLSR" },
+    {   6216, "FX18" },
+    {   6224, "FX17" },
+    {   6232, "WMCE" },
+    {   6240, "MACE" },
+    {   6248, "FX02" },
+    {   6256, "WSKL" },
+    {   6264, "HROD" },
+    {   6272, "FX00" },
+    {   6280, "FX20" },
+    {   6288, "FX21" },
+    {   6296, "FX22" },
+    {   6304, "FX23" },
+    {   6312, "GWND" },
+    {   6320, "PUF2" },
+    {   6328, "WPHX" },
+    {   6336, "PHNX" },
+    {   6344, "FX04" },
+    {   6352, "FX08" },
+    {   6360, "FX09" },
+    {   6368, "WBOW" },
+    {   6376, "CRBW" },
+    {   6384, "FX03" },
+    {   6392, "BLOD" },
+    {   6400, "PLAY" },
+    {   6408, "FDTH" },
+    {   6416, "BSKL" },
+    {   6424, "CHKN" },
+    {   6432, "MUMM" },
+    {   6440, "FX15" },
+    {   6448, "BEAS" },
+    {   6456, "FRB1" },
+    {   6464, "SNKE" },
+    {   6472, "SNFX" },
+    {   6480, "HEAD" },
+    {   6488, "FX05" },
+    {   6496, "FX06" },
+    {   6504, "FX07" },
+    {   6512, "CLNK" },
+    {   6520, "WZRD" },
+    {   6528, "FX11" },
+    {   6536, "FX10" },
+    {   6544, "KNIG" },
+    {   6552, "SPAX" },
+    {   6560, "RAXE" },
+    {   6568, "SRCR" },
+    {   6576, "FX14" },
+    {   6584, "SOR2" },
+    {   6592, "SDTH" },
+    {   6600, "FX16" },
+    {   6608, "MNTR" },
+    {   6616, "FX12" },
+    {   6624, "FX13" },
+    {   6632, "AKYY" },
+    {   6640, "BKYY" },
+    {   6648, "CKYY" },
+    {   6656, "AMG2" },
+    {   6664, "AMM1" },
+    {   6672, "AMM2" },
+    {   6680, "AMC1" },
+    {   6688, "AMC2" },
+    {   6696, "AMS1" },
+    {   6704, "AMS2" },
+    {   6712, "AMP1" },
+    {   6720, "AMP2" },
+    {   6728, "AMB1" },
+    {   6736, "AMB2" },
+    {   6768, "PLAYPAL" },
+    {   6776, "MAPE1" },
+    {   6784, "MAPE2" },
+    {   6792, "MAPE3" },
+    {   6800, "IN_X" },
+    {   6808, "IN_YAH" },
+    {   6816, "FONTB16" },
+    {   6824, "FONTB_S" },
+    {   6832, "FONTB13" },
+    {   6840, "FONTB15" },
+    {   6848, "FONTB05" },
+    {   6856, "FACEA0" },
+    {   6864, "FACEB0" },
+    {   6872, NULL },
+    {   6896, NULL },
+    {   6940, "FLOOR16" },
+    {   6948, "FINISHED" },
+    {   6960, "NOW ENTERING:" },
+    {   6976, "KILLS" },
+    {   6984, "ITEMS" },
+    {   6992, "SECRETS" },
+    {   7000, "TIME" },
+    {   7008, "BONUS" },
+    {   7016, "SECRET" },
+    {   7024, "TOTAL" },
+    {   7032, "VICTIMS" },
+    {   7044, "NEW GAME" },
+    {   7056, "OPTIONS" },
+    {   7064, "GAME FILES" },
+    {   7076, "INFO" },
+    {   7084, "QUIT GAME" },
+    {   7096, "CITY OF THE DAMNED" },
+    {   7116, "HELL'S MAW" },
+    {   7128, "THE DOME OF D'SPARIL" },
+    {   7152, "LOAD GAME" },
+    {   7164, "SAVE GAME" },
+    {   7176, "THOU NEEDETH A WET-NURSE" },
+    {   7204, "YELLOWBELLIES-R-US" },
+    {   7224, "BRINGEST THEM ONETH" },
+    {   7244, "THOU ART A SMITE-MEISTER" },
+    {   7272, "BLACK PLAGUE POSSESSES THEE" },
+    {   7300, "END GAME" },
+    {   7312, "MESSAGES : " },
+    {   7324, "MOUSE SENSITIVITY" },
+    {   7344, "MORE..." },
+    {   7352, "SCREEN SIZE" },
+    {   7364, "SFX VOLUME" },
+    {   7376, "MUSIC VOLUME" },
+    {   7392, "M_SKL00" },
+    {   7400, "FONTA_S" },
+    {   7408, "FONTB_S" },
+    {   7416, "ARE YOU SURE YOU WANT TO QUIT?" },
+    {   7448, "ARE YOU SURE YOU WANT TO END THE GAME?" },
+    {   7488, "DO YOU WANT TO QUICKSAVE THE GAME NAMED" },
+    {   7528, "DO YOU WANT TO QUICKLOAD THE GAME NAMED" },
+    {   7572, "M_SLCTR1" },
+    {   7584, "M_SLCTR2" },
+    {   7596, "M_HTIC" },
+    {   7604, NULL },
+    {   7632, "hticsav%d.hsg" },
+    {   7652, "M_FSLOT" },
+    {   7668, "MESSAGES ON" },
+    {   7680, "MESSAGES OFF" },
+    {   7696, "YOU CAN'T START A NEW GAME FROM WITHIN A NETGAME!" },
+    {   7748, "ONLY AVAILABLE IN THE REGISTERED VERSION" },
+    {   7792, "PLAYPAL" },
+    {   7800, "QUICKSAVING...." },
+    {   7816, "QUICKLOADING...." },
+    {   7836, "CHOOSE A QUICKSAVE SLOT" },
+    {   7860, "CHOOSE A QUICKLOAD SLOT" },
+    {   7884, "TITLE" },
+    {   7892, "M_SLDLT" },
+    {   7900, "M_SLDMD1" },
+    {   7912, "M_SLDMD2" },
+    {   7924, "M_SLDRT" },
+    {   7932, "M_SLDKB" },
+    {   7940, NULL },
+    {   7968, NULL },
+    {   7992, NULL },
+    {   8020, NULL },
+    {   8028, NULL },
+    {   8056, NULL },
+    {   8076, NULL },
+    {   8088, NULL },
+    {   8104, NULL },
+    {   8116, NULL },
+    {   8128, NULL },
+    {   8136, NULL },
+    {   8148, NULL },
+    {   8164, NULL },
+    {   8180, NULL },
+    {   8192, NULL },
+    {   8204, NULL },
+    {   8220, NULL },
+    {   8232, NULL },
+    {   8248, NULL },
+    {   8264, NULL },
+    {   8276, NULL },
+    {   8292, NULL },
+    {   8308, NULL },
+    {   8320, NULL },
+    {   8328, NULL },
+    {   8340, NULL },
+    {   8352, NULL },
+    {   8364, NULL },
+    {   8376, NULL },
+    {   8392, NULL },
+    {   8408, NULL },
+    {   8424, NULL },
+    {   8436, NULL },
+    {   8448, NULL },
+    {   8460, NULL },
+    {   8472, NULL },
+    {   8488, NULL },
+    {   8504, NULL },
+    {   8520, NULL },
+    {   8536, NULL },
+    {   8548, NULL },
+    {   8560, NULL },
+    {   8572, NULL },
+    {   8584, NULL },
+    {   8596, NULL },
+    {   8612, NULL },
+    {   8624, NULL },
+    {   8648, NULL },
+    {   8660, NULL },
+    {   8668, NULL },
+    {   8680, NULL },
+    {   8708, NULL },
+    {   8720, NULL },
+    {   8728, NULL },
+    {   8740, NULL },
+    {   8752, NULL },
+    {   8764, NULL },
+    {   8788, NULL },
+    {   8800, NULL },
+    {   8812, NULL },
+    {   8824, NULL },
+    {   8848, NULL },
+    {   8880, NULL },
+    {   8888, NULL },
+    {   8896, NULL },
+    {   8916, NULL },
+    {   8968, "HRTIC00.pcx" },
+    {   8980, NULL },
+    {   9016, "SCREEN SHOT" },
+    {   9028, "YOU NEED A BLUE KEY TO OPEN THIS DOOR" },
+    {   9068, "YOU NEED A YELLOW KEY TO OPEN THIS DOOR" },
+    {   9108, "YOU NEED A GREEN KEY TO OPEN THIS DOOR" },
+    {   9148, NULL },
+    {   9172, NULL },
+    {   9220, NULL },
+    {   9244, "CRYSTAL VIAL" },
+    {   9260, "SILVER SHIELD" },
+    {   9276, "ENCHANTED SHIELD" },
+    {   9296, "BAG OF HOLDING" },
+    {   9312, "MAP SCROLL" },
+    {   9324, "BLUE KEY" },
+    {   9336, "YELLOW KEY" },
+    {   9348, "GREEN KEY" },
+    {   9360, "QUARTZ FLASK" },
+    {   9376, "WINGS OF WRATH" },
+    {   9392, "RING OF INVINCIBILITY" },
+    {   9416, "TOME OF POWER" },
+    {   9432, "SHADOWSPHERE" },
+    {   9448, "MORPH OVUM" },
+    {   9460, "MYSTIC URN" },
+    {   9472, "TORCH" },
+    {   9480, "TIME BOMB OF THE ANCIENTS" },
+    {   9508, "CHAOS DEVICE" },
+    {   9524, "WAND CRYSTAL" },
+    {   9540, "CRYSTAL GEODE" },
+    {   9556, "MACE SPHERES" },
+    {   9572, "PILE OF MACE SPHERES" },
+    {   9596, "ETHEREAL ARROWS" },
+    {   9612, "QUIVER OF ETHEREAL ARROWS" },
+    {   9640, "CLAW ORB" },
+    {   9652, "ENERGY ORB" },
+    {   9664, "LESSER RUNES" },
+    {   9680, "GREATER RUNES" },
+    {   9696, "FLAME ORB" },
+    {   9708, "INFERNO ORB" },
+    {   9720, "FIREMACE" },
+    {   9732, "ETHEREAL CROSSBOW" },
+    {   9752, "DRAGON CLAW" },
+    {   9764, "HELLSTAFF" },
+    {   9776, "PHOENIX ROD" },
+    {   9788, "GAUNTLETS OF THE NECROMANCER" },
+    {   9820, NULL },
+    {   9860, NULL },
+    {   9892, NULL },
+    {   9940, NULL },
+    {   9972, NULL },
+    {  10012, NULL },
+    {  10052, NULL },
+    {  10080, NULL },
+    {  10088, "FLTWAWA1" },
+    {  10100, "FLTFLWW1" },
+    {  10112, "FLTLAVA1" },
+    {  10124, "FLATHUH1" },
+    {  10136, "FLTSLUD1" },
+    {  10152, NULL },
+    {  10192, NULL },
+    {  10236, NULL },
+    {  10248, NULL },
+    {  10284, NULL },
+    {  10320, NULL },
+    {  10360, NULL },
+    {  10392, NULL },
+    {  10444, "PLAYPAL" },
+    {  10452, NULL },
+    {  10488, NULL },
+    {  10508, NULL },
+    {  10556, NULL },
+    {  10596, "PNAMES" },
+    {  10604, "TEXTURE1" },
+    {  10616, "TEXTURE2" },
+    {  10628, "S_END" },
+    {  10636, "S_START" },
+    {  10644, NULL },
+    {  10684, NULL },
+    {  10728, "F_START" },
+    {  10736, "F_END" },
+    {  10744, "COLORMAP" },
+    {  10756, "\nR_InitTextures " },
+    {  10776, "R_InitFlats\n" },
+    {  10792, "R_InitSpriteLumps " },
+    {  10812, NULL },
+    {  10844, NULL },
+    {  10880, NULL },
+    {  10912, NULL },
+    {  10948, "TINTTAB" },
+    {  10956, NULL },
+    {  10984, "FLOOR04" },
+    {  10992, "FLAT513" },
+    {  11000, "bordt" },
+    {  11008, "bordb" },
+    {  11016, "bordl" },
+    {  11024, "bordr" },
+    {  11032, "bordtl" },
+    {  11040, "bordtr" },
+    {  11048, "bordbr" },
+    {  11056, "bordbl" },
+    {  11064, "R_InitData " },
+    {  11076, "R_InitPointToAngle\n" },
+    {  11096, "R_InitTables " },
+    {  11112, "R_InitPlanes\n" },
+    {  11128, "R_InitLightTables " },
+    {  11148, "R_InitSkyMap\n" },
+    {  11164, "F_SKY1" },
+    {  11172, NULL },
+    {  11200, NULL },
+    {  11232, NULL },
+    {  11272, NULL },
+    {  11312, NULL },
+    {  11348, NULL },
+    {  11380, NULL },
+    {  11404, NULL },
+    {  11436, NULL },
+    {  11492, NULL },
+    {  11548, NULL },
+    {  11616, NULL },
+    {  11684, NULL },
+    {  11748, NULL },
+    {  11792, NULL },
+    {  11840, NULL },
+    {  11896, NULL },
+    {  11936, NULL },
+    {  11980, NULL },
+    {  12028, NULL },
+    {  12072, NULL },
+    {  12120, "LTFACE" },
+    {  12128, "RTFACE" },
+    {  12136, "BARBACK" },
+    {  12144, "INVBAR" },
+    {  12152, "CHAIN" },
+    {  12160, "STATBAR" },
+    {  12168, "LIFEBAR" },
+    {  12176, "LIFEGEM2" },
+    {  12188, "LIFEGEM0" },
+    {  12200, "LTFCTOP" },
+    {  12208, "RTFCTOP" },
+    {  12216, "ARTIBOX" },
+    {  12224, "SELECTBOX" },
+    {  12236, "INVGEML1" },
+    {  12248, "INVGEML2" },
+    {  12260, "INVGEMR1" },
+    {  12272, "INVGEMR2" },
+    {  12284, "BLACKSQ" },
+    {  12292, "ARMCLEAR" },
+    {  12304, "CHAINBACK" },
+    {  12320, "NEGNUM" },
+    {  12328, "FONTB16" },
+    {  12336, "SMALLIN0" },
+    {  12348, "PLAYPAL" },
+    {  12356, "SPINBK0" },
+    {  12364, "SPFLY0" },
+    {  12372, "LAME" },
+    {  12408, "NAME" },
+    {  12416, "MO.T" },
+    {  12424, "MO.X" },
+    {  12432, "MO.Y" },
+    {  12448, "DIST" },
+    {  12456, "------" },
+    {  12472, "GOD1" },
+    {  12480, "GOD2" },
+    {  12488, "useartia" },
+    {  12500, "ykeyicon" },
+    {  12512, "gkeyicon" },
+    {  12524, "bkeyicon" },
+    {  12536, "GOD MODE ON" },
+    {  12548, "GOD MODE OFF" },
+    {  12564, "NO CLIPPING ON" },
+    {  12580, "NO CLIPPING OFF" },
+    {  12596, "ALL WEAPONS" },
+    {  12608, "POWER OFF" },
+    {  12620, "POWER ON" },
+    {  12632, "FULL HEALTH" },
+    {  12644, "ALL KEYS" },
+    {  12656, "SOUND DEBUG ON" },
+    {  12672, "SOUND DEBUG OFF" },
+    {  12688, "TICKER ON" },
+    {  12700, "TICKER OFF" },
+    {  12712, "CHOOSE AN ARTIFACT ( A - J )" },
+    {  12744, "HOW MANY ( 1 - 9 )" },
+    {  12764, "YOU GOT IT" },
+    {  12776, "BAD INPUT" },
+    {  12788, "LEVEL WARP" },
+    {  12800, "CHICKEN OFF" },
+    {  12812, "CHICKEN ON" },
+    {  12824, "MASSACRE" },
+    {  12836, "CHEATER - YOU DON'T DESERVE WEAPONS" },
+    {  12872, "TRYING TO CHEAT, EH?  NOW YOU DIE!" },
+    {  12908, "Bad V_DrawPatch" },
+    {  12924, NULL },
+    {  12960, NULL },
+    {  12968, NULL },
+    {  12976, NULL },
+    {  13020, NULL },
+    {  13048, NULL },
+    {  13076, NULL },
+    {  13104, NULL },
+    {  13136, NULL },
+    {  13168, NULL },
+    {  13196, NULL },
+    {  13240, NULL },
+    {  13272, NULL },
+    {  13296, NULL },
+    {  13312, NULL },
+    {  13324, NULL },
+    {  13364, NULL },
+    {  13408, NULL },
+    {  13460, NULL },
+    {  13492, NULL },
+    {  13516, NULL },
+    {  13560, NULL },
+    {  13612, NULL },
+    {  13664, NULL },
+    {  13700, NULL },
+    {  13744, NULL },
+    {  13796, NULL },
+    {  13848, NULL },
+    {  13884, NULL },
+    {  13940, NULL },
+    {  13996, NULL },
+    {  14040, NULL },
+    {  14084, NULL },
+    {  14140, NULL },
+    {  14148, NULL },
+    {  14164, NULL },
+    {  14184, NULL },
+    {  14192, NULL },
+    {  14212, NULL },
+    {  14256, NULL },
+    {  14272, NULL },
+    {  14284, NULL },
+    {  14300, NULL },
+    {  14312, NULL },
+    {  14324, NULL },
+    {  14348, NULL },
+    {  14360, NULL },
+    {  14372, NULL },
+    {  14380, NULL },
+    {  14392, NULL },
+    {  14432, NULL },
+    {  14444, NULL },
+    {  14472, NULL },
+    {  14496, NULL },
+    {  14516, NULL },
+    {  14536, NULL },
+    {  14548, NULL },
+    {  14560, NULL },
+    {  14572, NULL },
+    {  14580, NULL },
+    {  14588, NULL },
+    {  14596, NULL },
+    {  14604, NULL },
+    {  14612, NULL },
+    {  14620, NULL },
+    {  14636, NULL },
+    {  14660, NULL },
+    {  14704, NULL },
+    {  14748, NULL },
+    {  14760, NULL },
+    {  14768, NULL },
+};
+
+static boolean GetStringByOffset(unsigned int offset, char **result)
+{
+    int i;
+
+    for (i=0; i<arrlen(string_table); ++i)
+    {
+        if (string_table[i].offset == offset)
+        {
+            *result = string_table[i].string;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+// Given a string length, find the maximum length of a 
+// string that can replace it.
+
+static int MaxStringLength(int len)
+{
+    // Enough bytes for the string and the NUL terminator
+
+    len += 1;
+
+    // All strings in doom.exe are on 4-byte boundaries, so we may be able
+    // to support a slightly longer string.
+    // Extend up to the next 4-byte boundary
+
+    len += (4 - (len % 4)) % 4;
+
+    // Less one for the NUL terminator.
+
+    return len - 1;
+}
+
+static void *DEH_TextStart(deh_context_t *context, char *line)
+{
+    char *repl_text;
+    char *orig_text;
+    int orig_offset, repl_len;
+    int i;
+
+    if (sscanf(line, "Text %i %i", &orig_offset, &repl_len) != 2)
+    {
+        DEH_Warning(context, "Parse error on section start");
+        return NULL;
+    }
+
+    repl_text = Z_Malloc(repl_len + 1, PU_STATIC, NULL);
+
+    // read in the "to" text
+
+    for (i=0; i<repl_len; ++i)
+    {
+        int c;
+
+        c = DEH_GetChar(context);
+
+        repl_text[i] = c;
+    }
+    repl_text[repl_len] = '\0';
+
+    // Find the string to replace:
+
+    if (!GetStringByOffset(orig_offset, &orig_text))
+    {
+        DEH_Error(context, "Unknown string offset: %i", orig_offset);
+    }
+
+    // We don't support all strings, but at least recognise them:
+
+    else if (orig_text == NULL)
+    {
+        DEH_Warning(context, "Unsupported string replacement: %i", orig_offset);
+    }
+
+    // Only allow string replacements that are possible in Vanilla Doom.  
+    // Chocolate Doom is unforgiving!
+
+    else if (!deh_allow_long_strings
+          && repl_len > MaxStringLength(strlen(orig_text)))
+    {
+        DEH_Error(context, "Replacement string is longer than the maximum "
+                           "possible in heretic.exe");
+    }
+    else
+    {
+        // Success.
+
+        DEH_AddStringReplacement(orig_text, repl_text);
+
+        return NULL;
+    }
+
+    // Failure.
+
+    Z_Free(repl_text);
+
+    return NULL;
+}
+
+static void DEH_TextParseLine(deh_context_t *context, char *line, void *tag)
+{
+    // not used
+}
+
+deh_section_t deh_section_heretic_text =
+{
+    "Text",
+    NULL,
+    DEH_TextStart,
+    DEH_TextParseLine,
+    NULL,
+    NULL,
+};
+
--- a/src/heretic/deh_htic.c
+++ b/src/heretic/deh_htic.c
@@ -44,8 +44,8 @@
 extern deh_section_t deh_section_pointer;
 // deh_sound.c
 extern deh_section_t deh_section_sound;
-// deh_text.c:
-extern deh_section_t deh_section_text;
+// deh_htext.c:
+extern deh_section_t deh_section_heretic_text;
 // deh_thing.c:
 extern deh_section_t deh_section_thing;
 // deh_weapon.c:
@@ -61,7 +61,7 @@
     &deh_section_frame,
 //    &deh_section_pointer, TODO
     &deh_section_sound,
-//    &deh_section_text, TODO
+    &deh_section_heretic_text,
     &deh_section_thing,
     &deh_section_weapon,
     NULL
--- a/src/heretic/f_finale.c
+++ b/src/heretic/f_finale.c
@@ -26,6 +26,7 @@
 #include <ctype.h>
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_swap.h"
 #include "i_video.h"
 #include "s_sound.h"
@@ -72,23 +73,23 @@
     switch (gameepisode)
     {
         case 1:
-            finaleflat = "FLOOR25";
+            finaleflat = DEH_String("FLOOR25");
             finaletext = e1text;
             break;
         case 2:
-            finaleflat = "FLATHUH1";
+            finaleflat = DEH_String("FLATHUH1");
             finaletext = e2text;
             break;
         case 3:
-            finaleflat = "FLTWAWA2";
+            finaleflat = DEH_String("FLTWAWA2");
             finaletext = e3text;
             break;
         case 4:
-            finaleflat = "FLOOR28";
+            finaleflat = DEH_String("FLOOR28");
             finaletext = e4text;
             break;
         case 5:
-            finaleflat = "FLOOR08";
+            finaleflat = DEH_String("FLOOR08");
             finaletext = e5text;
             break;
     }
@@ -95,7 +96,7 @@
 
     finalestage = 0;
     finalecount = 0;
-    FontABaseLump = W_GetNumForName("FONTA_S") + 1;
+    FontABaseLump = W_GetNumForName(DEH_String("FONTA_S")) + 1;
 
 //      S_ChangeMusic(mus_victor, true);
     S_StartSong(mus_cptd, true);
@@ -277,8 +278,8 @@
     {
         return;
     }
-    p1 = W_CacheLumpName("FINAL1", PU_LEVEL);
-    p2 = W_CacheLumpName("FINAL2", PU_LEVEL);
+    p1 = W_CacheLumpName(DEH_String("FINAL1"), PU_LEVEL);
+    p2 = W_CacheLumpName(DEH_String("FINAL2"), PU_LEVEL);
     if (finalecount < 70)
     {
         memcpy(I_VideoBuffer, p1, SCREENHEIGHT * SCREENWIDTH);
@@ -319,8 +320,8 @@
             {
                 underwawa = true;
                 memset((byte *) 0xa0000, 0, SCREENWIDTH * SCREENHEIGHT);
-                I_SetPalette(W_CacheLumpName("E2PAL", PU_CACHE));
-                V_DrawRawScreen(W_CacheLumpName("E2END", PU_CACHE));
+                I_SetPalette(W_CacheLumpName(DEH_String("E2PAL"), PU_CACHE));
+                V_DrawRawScreen(W_CacheLumpName(DEH_String("E2END"), PU_CACHE));
             }
             paused = false;
             MenuActive = false;
@@ -328,7 +329,7 @@
 
             break;
         case 2:
-            V_DrawRawScreen(W_CacheLumpName("TITLE", PU_CACHE));
+            V_DrawRawScreen(W_CacheLumpName(DEH_String("TITLE"), PU_CACHE));
             //D_StartTitle(); // go to intro/demo mode.
     }
 }
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include "doomdef.h"
 #include "doomkeys.h"
+#include "deh_str.h"
 #include "i_timer.h"
 #include "i_system.h"
 #include "m_controls.h"
@@ -862,11 +863,11 @@
                         {
                             if (netgame)
                             {
-                                strcpy(savedescription, "NET GAME");
+                                strcpy(savedescription, DEH_String("NET GAME"));
                             }
                             else
                             {
-                                strcpy(savedescription, "SAVE GAME");
+                                strcpy(savedescription, DEH_String("SAVE GAME"));
                             }
                         }
                         savegameslot =
@@ -1320,7 +1321,7 @@
     save_p = savebuffer + SAVESTRINGSIZE;
     // Skip the description field
     memset(vcheck, 0, sizeof(vcheck));
-    sprintf(vcheck, "version %i", HERETIC_VERSION);
+    sprintf(vcheck, DEH_String("version %i"), HERETIC_VERSION);
     if (strcmp((char *) save_p, vcheck) != 0)
     {                           // Bad version
         return;
@@ -1449,11 +1450,11 @@
     // Set the sky map
     if (episode > 5)
     {
-        skytexture = R_TextureNumForName("SKY1");
+        skytexture = R_TextureNumForName(DEH_String("SKY1"));
     }
     else
     {
-        skytexture = R_TextureNumForName(skyLumpNames[episode - 1]);
+        skytexture = R_TextureNumForName(DEH_String(skyLumpNames[episode - 1]));
     }
 
 //
@@ -1694,7 +1695,7 @@
     SV_Open(name);
     SV_Write(description, SAVESTRINGSIZE);
     memset(verString, 0, sizeof(verString));
-    sprintf(verString, "version %i", HERETIC_VERSION);
+    sprintf(verString, DEH_String("version %i"), HERETIC_VERSION);
     SV_Write(verString, VERSIONSIZE);
     SV_WriteByte(gameskill);
     SV_WriteByte(gameepisode);
--- a/src/heretic/in_lude.c
+++ b/src/heretic/in_lude.c
@@ -30,6 +30,7 @@
 */
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "s_sound.h"
 #include "i_system.h"
 #include "i_video.h"
@@ -161,7 +162,7 @@
 
 void IN_Start(void)
 {
-    I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
+    I_SetPalette(W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE));
     IN_LoadPics();
     IN_InitStats();
     intermission = true;
@@ -308,26 +309,26 @@
     switch (gameepisode)
     {
         case 1:
-            callback("MAPE1", 0, &patchINTERPIC);
+            callback(DEH_String("MAPE1"), 0, &patchINTERPIC);
             break;
         case 2:
-            callback("MAPE2", 0, &patchINTERPIC);
+            callback(DEH_String("MAPE2"), 0, &patchINTERPIC);
             break;
         case 3:
-            callback("MAPE3", 0, &patchINTERPIC);
+            callback(DEH_String("MAPE3"), 0, &patchINTERPIC);
             break;
         default:
             break;
     }
 
-    callback("IN_X", 0, &patchBEENTHERE);
-    callback("IN_YAH", 0, &patchGOINGTHERE);
-    callback("FONTB13", 0, &FontBNegative);
+    callback(DEH_String("IN_X"), 0, &patchBEENTHERE);
+    callback(DEH_String("IN_YAH"), 0, &patchGOINGTHERE);
+    callback(DEH_String("FONTB13"), 0, &FontBNegative);
 
-    callback("FONTB15", 0, &FontBSlash);
-    callback("FONTB05", 0, &FontBPercent);
+    callback(DEH_String("FONTB15"), 0, &FontBSlash);
+    callback(DEH_String("FONTB05"), 0, &FontBPercent);
 
-    FontBLumpBase = W_GetNumForName("FONTB16");
+    FontBLumpBase = W_GetNumForName(DEH_String("FONTB16"));
 
     for (i = 0; i < 10; i++)
     {
@@ -355,9 +356,9 @@
 
 void IN_LoadPics(void)
 {
-    FontBLump = W_GetNumForName("FONTB_S") + 1;
-    patchFaceOkayBase = W_GetNumForName("FACEA0");
-    patchFaceDeadBase = W_GetNumForName("FACEB0");
+    FontBLump = W_GetNumForName(DEH_String("FONTB_S")) + 1;
+    patchFaceOkayBase = W_GetNumForName(DEH_String("FACEA0"));
+    patchFaceDeadBase = W_GetNumForName(DEH_String("FACEB0"));
 
     IN_LoadUnloadPics(LoadLumpCallback);
 }
@@ -580,7 +581,7 @@
     byte *src;
     byte *dest;
 
-    src = W_CacheLumpName("FLOOR16", PU_CACHE);
+    src = W_CacheLumpName(DEH_String("FLOOR16"), PU_CACHE);
     dest = I_VideoBuffer;
 
     for (y = 0; y < SCREENHEIGHT; y++)
@@ -612,8 +613,8 @@
     x = 160 - MN_TextBWidth(LevelNames[(gameepisode - 1) * 9 + prevmap - 1] +
                             7) / 2;
     IN_DrTextB(LevelNames[(gameepisode - 1) * 9 + prevmap - 1] + 7, x, 3);
-    x = 160 - MN_TextAWidth("FINISHED") / 2;
-    MN_DrTextA("FINISHED", x, 25);
+    x = 160 - MN_TextAWidth(DEH_String("FINISHED")) / 2;
+    MN_DrTextA(DEH_String("FINISHED"), x, 25);
 
     if (prevmap == 9)
     {
@@ -660,8 +661,8 @@
     int i;
     int x;
 
-    x = 160 - MN_TextAWidth("NOW ENTERING:") / 2;
-    MN_DrTextA("NOW ENTERING:", x, 10);
+    x = 160 - MN_TextAWidth(DEH_String("NOW ENTERING:")) / 2;
+    MN_DrTextA(DEH_String("NOW ENTERING:"), x, 10);
     x = 160 - MN_TextBWidth(LevelNames[(gameepisode - 1) * 9 + gamemap - 1] +
                             7) / 2;
     IN_DrTextB(LevelNames[(gameepisode - 1) * 9 + gamemap - 1] + 7, x, 20);
@@ -698,15 +699,15 @@
     int x;
     static int sounds;
 
-    IN_DrTextB("KILLS", 50, 65);
-    IN_DrTextB("ITEMS", 50, 90);
-    IN_DrTextB("SECRETS", 50, 115);
+    IN_DrTextB(DEH_String("KILLS"), 50, 65);
+    IN_DrTextB(DEH_String("ITEMS"), 50, 90);
+    IN_DrTextB(DEH_String("SECRETS"), 50, 115);
 
     x = 160 - MN_TextBWidth(LevelNames[(gameepisode - 1) * 9 + prevmap - 1] +
                             7) / 2;
     IN_DrTextB(LevelNames[(gameepisode - 1) * 9 + prevmap - 1] + 7, x, 3);
-    x = 160 - MN_TextAWidth("FINISHED") / 2;
-    MN_DrTextA("FINISHED", x, 25);
+    x = 160 - MN_TextAWidth(DEH_String("FINISHED")) / 2;
+    MN_DrTextA(DEH_String("FINISHED"), x, 25);
 
     if (intertime < 30)
     {
@@ -757,13 +758,13 @@
 
     if (gamemode != retail || gameepisode <= 3)
     {
-        IN_DrTextB("TIME", 85, 160);
+        IN_DrTextB(DEH_String("TIME"), 85, 160);
         IN_DrawTime(155, 160, hours, minutes, seconds);
     }
     else
     {
-        x = 160 - MN_TextAWidth("NOW ENTERING:") / 2;
-        MN_DrTextA("NOW ENTERING:", x, 160);
+        x = 160 - MN_TextAWidth(DEH_String("NOW ENTERING:")) / 2;
+        MN_DrTextA(DEH_String("NOW ENTERING:"), x, 160);
         x = 160 -
             MN_TextBWidth(LevelNames[(gameepisode - 1) * 9 + gamemap - 1] +
                           7) / 2;
@@ -787,14 +788,14 @@
 
     static int sounds;
 
-    IN_DrTextB("KILLS", 95, 35);
-    IN_DrTextB("BONUS", 155, 35);
-    IN_DrTextB("SECRET", 232, 35);
+    IN_DrTextB(DEH_String("KILLS"), 95, 35);
+    IN_DrTextB(DEH_String("BONUS"), 155, 35);
+    IN_DrTextB(DEH_String("SECRET"), 232, 35);
     x = 160 - MN_TextBWidth(LevelNames[(gameepisode - 1) * 9 + prevmap - 1] +
                             7) / 2;
     IN_DrTextB(LevelNames[(gameepisode - 1) * 9 + prevmap - 1] + 7, x, 3);
-    x = 160 - MN_TextAWidth("FINISHED") / 2;
-    MN_DrTextA("FINISHED", x, 25);
+    x = 160 - MN_TextAWidth(DEH_String("FINISHED")) / 2;
+    MN_DrTextA(DEH_String("FINISHED"), x, 25);
 
     ypos = 50;
     for (i = 0; i < MAXPLAYERS; i++)
@@ -845,8 +846,8 @@
     xpos = 90;
     ypos = 55;
 
-    IN_DrTextB("TOTAL", 265, 30);
-    MN_DrTextA("VICTIMS", 140, 8);
+    IN_DrTextB(DEH_String("TOTAL"), 265, 30);
+    MN_DrTextA(DEH_String("VICTIMS"), 140, 8);
     for (i = 0; i < 7; i++)
     {
         MN_DrTextA(KillersText[i], 10, 80 + 9 * i);
--- a/src/heretic/mn_menu.c
+++ b/src/heretic/mn_menu.c
@@ -25,6 +25,8 @@
 // MN_menu.c
 
 #include <ctype.h>
+
+#include "deh_str.h"
 #include "doomdef.h"
 #include "doomkeys.h"
 #include "i_system.h"
@@ -73,7 +75,7 @@
 {
     ItemType_t type;
     char *text;
-      boolean(*func) (int option);
+    boolean(*func) (int option);
     int option;
     MenuType_t menu;
 } MenuItem_t;
@@ -305,7 +307,7 @@
     InitFonts();
     MenuActive = false;
     messageson = true;
-    SkullBaseLump = W_GetNumForName("M_SKL00");
+    SkullBaseLump = W_GetNumForName(DEH_String("M_SKL00"));
 
     if (gamemode == retail)
     {                           // Add episodes 4 and 5 to the menu
@@ -322,8 +324,8 @@
 
 static void InitFonts(void)
 {
-    FontABaseLump = W_GetNumForName("FONTA_S") + 1;
-    FontBBaseLump = W_GetNumForName("FONTB_S") + 1;
+    FontABaseLump = W_GetNumForName(DEH_String("FONTA_S")) + 1;
+    FontBBaseLump = W_GetNumForName(DEH_String("FONTB_S")) + 1;
 }
 
 //---------------------------------------------------------------------------
@@ -476,6 +478,7 @@
     int x;
     int y;
     MenuItem_t *item;
+    char *message;
     char *selName;
 
     if (MenuActive == false)
@@ -482,8 +485,9 @@
     {
         if (askforquit)
         {
-            MN_DrTextA(QuitEndMsg[typeofask - 1], 160 -
-                       MN_TextAWidth(QuitEndMsg[typeofask - 1]) / 2, 80);
+            message = DEH_String(QuitEndMsg[typeofask - 1]);
+
+            MN_DrTextA(message, 160 - MN_TextAWidth(message) / 2, 80);
             if (typeofask == 3)
             {
                 MN_DrTextA(SlotText[quicksave - 1], 160 -
@@ -525,13 +529,13 @@
         {
             if (item->type != ITT_EMPTY && item->text)
             {
-                MN_DrTextB(item->text, x, y);
+                MN_DrTextB(DEH_String(item->text), x, y);
             }
             y += ITEM_HEIGHT;
             item++;
         }
         y = CurrentMenu->y + (CurrentItPos * ITEM_HEIGHT) + SELECTOR_YOFFSET;
-        selName = MenuTime & 16 ? "M_SLCTR1" : "M_SLCTR2";
+        selName = DEH_String(MenuTime & 16 ? "M_SLCTR1" : "M_SLCTR2");
         V_DrawPatch(x + SELECTOR_XOFFSET, y,
                     W_CacheLumpName(selName, PU_CACHE));
     }
@@ -548,7 +552,7 @@
     int frame;
 
     frame = (MenuTime / 3) % 18;
-    V_DrawPatch(88, 0, W_CacheLumpName("M_HTIC", PU_CACHE));
+    V_DrawPatch(88, 0, W_CacheLumpName(DEH_String("M_HTIC"), PU_CACHE));
     V_DrawPatch(40, 10, W_CacheLumpNum(SkullBaseLump + (17 - frame),
                                        PU_CACHE));
     V_DrawPatch(232, 10, W_CacheLumpNum(SkullBaseLump + frame, PU_CACHE));
@@ -597,7 +601,11 @@
 
 static void DrawLoadMenu(void)
 {
-    MN_DrTextB("LOAD GAME", 160 - MN_TextBWidth("LOAD GAME") / 2, 10);
+    char *title;
+
+    title = DEH_String("LOAD GAME");
+
+    MN_DrTextB(title, 160 - MN_TextBWidth(title) / 2, 10);
     if (!slottextloaded)
     {
         MN_LoadSlotText();
@@ -613,7 +621,11 @@
 
 static void DrawSaveMenu(void)
 {
-    MN_DrTextB("SAVE GAME", 160 - MN_TextBWidth("SAVE GAME") / 2, 10);
+    char *title;
+
+    title = DEH_String("SAVE GAME");
+
+    MN_DrTextB(title, 160 - MN_TextBWidth(title) / 2, 10);
     if (!slottextloaded)
     {
         MN_LoadSlotText();
@@ -675,7 +687,7 @@
     y = menu->y;
     for (i = 0; i < 6; i++)
     {
-        V_DrawPatch(x, y, W_CacheLumpName("M_FSLOT", PU_CACHE));
+        V_DrawPatch(x, y, W_CacheLumpName(DEH_String("M_FSLOT"), PU_CACHE));
         if (SlotStatus[i])
         {
             MN_DrTextA(SlotText[i], x + 5, y + 5);
@@ -796,11 +808,11 @@
     messageson ^= 1;
     if (messageson)
     {
-        P_SetMessage(&players[consoleplayer], "MESSAGES ON", true);
+        P_SetMessage(&players[consoleplayer], DEH_String("MESSAGES ON"), true);
     }
     else
     {
-        P_SetMessage(&players[consoleplayer], "MESSAGES OFF", true);
+        P_SetMessage(&players[consoleplayer], DEH_String("MESSAGES OFF"), true);
     }
     S_StartSound(NULL, sfx_chat);
     return true;
@@ -1460,7 +1472,7 @@
                 if (CurrentMenu->items[i].text)
                 {
                     if (toupper(charTyped)
-                        == toupper(CurrentMenu->items[i].text[0]))
+                        == toupper(DEH_String(CurrentMenu->items[i].text)[0]))
                     {
                         CurrentItPos = i;
                         return (true);
@@ -1628,13 +1640,13 @@
 
     x = menu->x + 24;
     y = menu->y + 2 + (item * ITEM_HEIGHT);
-    V_DrawPatch(x - 32, y, W_CacheLumpName("M_SLDLT", PU_CACHE));
+    V_DrawPatch(x - 32, y, W_CacheLumpName(DEH_String("M_SLDLT"), PU_CACHE));
     for (x2 = x, count = width; count--; x2 += 8)
     {
-        V_DrawPatch(x2, y, W_CacheLumpName(count & 1 ? "M_SLDMD1"
-                                           : "M_SLDMD2", PU_CACHE));
+        V_DrawPatch(x2, y, W_CacheLumpName(DEH_String(count & 1 ? "M_SLDMD1"
+                                           : "M_SLDMD2"), PU_CACHE));
     }
-    V_DrawPatch(x2, y, W_CacheLumpName("M_SLDRT", PU_CACHE));
+    V_DrawPatch(x2, y, W_CacheLumpName(DEH_String("M_SLDRT"), PU_CACHE));
     V_DrawPatch(x + 4 + slot * 8, y + 7,
-                W_CacheLumpName("M_SLDKB", PU_CACHE));
+                W_CacheLumpName(DEH_String("M_SLDKB"), PU_CACHE));
 }
--- a/src/heretic/p_spec.c
+++ b/src/heretic/p_spec.c
@@ -25,6 +25,7 @@
 // P_Spec.c
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_system.h"
 #include "i_timer.h"
 #include "m_random.h"
@@ -204,18 +205,12 @@
     int type;
 } TerrainTypeDefs[] =
 {
-    {
-    "FLTWAWA1", FLOOR_WATER},
-    {
-    "FLTFLWW1", FLOOR_WATER},
-    {
-    "FLTLAVA1", FLOOR_LAVA},
-    {
-    "FLATHUH1", FLOOR_LAVA},
-    {
-    "FLTSLUD1", FLOOR_SLUDGE},
-    {
-    "END", -1}
+    { "FLTWAWA1", FLOOR_WATER },
+    { "FLTFLWW1", FLOOR_WATER },
+    { "FLTLAVA1", FLOOR_LAVA },
+    { "FLATHUH1", FLOOR_LAVA },
+    { "FLTSLUD1", FLOOR_SLUDGE },
+    { "END", -1 }
 };
 
 mobj_t LavaInflictor;
@@ -266,28 +261,33 @@
 
 void P_InitPicAnims(void)
 {
+    char *startname;
+    char *endname;
     int i;
 
     lastanim = anims;
     for (i = 0; animdefs[i].istexture != -1; i++)
     {
+        startname = DEH_String(animdefs[i].startname);
+        endname = DEH_String(animdefs[i].endname);
+
         if (animdefs[i].istexture)
         {                       // Texture animation
-            if (R_CheckTextureNumForName(animdefs[i].startname) == -1)
+            if (R_CheckTextureNumForName(startname) == -1)
             {                   // Texture doesn't exist
                 continue;
             }
-            lastanim->picnum = R_TextureNumForName(animdefs[i].endname);
-            lastanim->basepic = R_TextureNumForName(animdefs[i].startname);
+            lastanim->picnum = R_TextureNumForName(endname);
+            lastanim->basepic = R_TextureNumForName(startname);
         }
         else
         {                       // Flat animation
-            if (W_CheckNumForName(animdefs[i].startname) == -1)
+            if (W_CheckNumForName(startname) == -1)
             {                   // Flat doesn't exist
                 continue;
             }
-            lastanim->picnum = R_FlatNumForName(animdefs[i].endname);
-            lastanim->basepic = R_FlatNumForName(animdefs[i].startname);
+            lastanim->picnum = R_FlatNumForName(endname);
+            lastanim->basepic = R_FlatNumForName(startname);
         }
         lastanim->istexture = animdefs[i].istexture;
         lastanim->numpics = lastanim->picnum - lastanim->basepic + 1;
@@ -294,7 +294,7 @@
         if (lastanim->numpics < 2)
         {
             I_Error("P_InitPicAnims: bad cycle from %s to %s",
-                    animdefs[i].startname, animdefs[i].endname);
+                    startname, endname);
         }
         lastanim->speed = animdefs[i].speed;
         lastanim++;
@@ -1132,7 +1132,7 @@
     int episode;
 
     episode = 1;
-    if (W_CheckNumForName("texture2") >= 0)
+    if (W_CheckNumForName(DEH_String("texture2")) >= 0)
         episode = 2;
 
     //
--- a/src/heretic/p_switch.c
+++ b/src/heretic/p_switch.c
@@ -23,6 +23,7 @@
 //-----------------------------------------------------------------------------
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_system.h"
 #include "p_local.h"
 #include "s_sound.h"
@@ -129,9 +130,9 @@
         if (alphSwitchList[i].episode <= episode)
         {
             switchlist[index++] =
-                R_TextureNumForName(alphSwitchList[i].name1);
+                R_TextureNumForName(DEH_String(alphSwitchList[i].name1));
             switchlist[index++] =
-                R_TextureNumForName(alphSwitchList[i].name2);
+                R_TextureNumForName(DEH_String(alphSwitchList[i].name2));
         }
     }
 }
--- a/src/heretic/p_user.c
+++ b/src/heretic/p_user.c
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "m_random.h"
 #include "p_local.h"
 #include "s_sound.h"
@@ -394,7 +395,7 @@
     {
         if (player == &players[consoleplayer])
         {
-            I_SetPalette((byte *) W_CacheLumpName("PLAYPAL", PU_CACHE));
+            I_SetPalette(W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE));
             inv_ptr = 0;
             curpos = 0;
             newtorch = 0;
--- a/src/heretic/r_data.c
+++ b/src/heretic/r_data.c
@@ -316,12 +316,17 @@
     int offset, maxoff, maxoff2;
     int numtextures1, numtextures2;
     int *directory;
+    char *texture1, *texture2, *pnames;
 
+    texture1 = DEH_String("TEXTURE1");
+    texture2 = DEH_String("TEXTURE2");
+    pnames = DEH_String("PNAMES");
+
 //
 // load the patch names from pnames.lmp
 //
     name[8] = 0;
-    names = W_CacheLumpName("PNAMES", PU_STATIC);
+    names = W_CacheLumpName(pnames, PU_STATIC);
     nummappatches = LONG(*((int *) names));
     name_p = names + 4;
     patchlookup = Z_Malloc(nummappatches * sizeof(*patchlookup), PU_STATIC, NULL);
@@ -330,21 +335,21 @@
         strncpy(name, name_p + i * 8, 8);
         patchlookup[i] = W_CheckNumForName(name);
     }
-    W_ReleaseLumpName("PNAMES");
+    W_ReleaseLumpName(pnames);
 
 //
 // load the map texture definitions from textures.lmp
 //
-    maptex = maptex1 = W_CacheLumpName("TEXTURE1", PU_STATIC);
+    maptex = maptex1 = W_CacheLumpName(texture1, PU_STATIC);
     numtextures1 = LONG(*maptex);
-    maxoff = W_LumpLength(W_GetNumForName("TEXTURE1"));
+    maxoff = W_LumpLength(W_GetNumForName(texture1));
     directory = maptex + 1;
 
-    if (W_CheckNumForName("TEXTURE2") != -1)
+    if (W_CheckNumForName(texture2) != -1)
     {
-        maptex2 = W_CacheLumpName("TEXTURE2", PU_STATIC);
+        maptex2 = W_CacheLumpName(texture2, PU_STATIC);
         numtextures2 = LONG(*maptex2);
-        maxoff2 = W_LumpLength(W_GetNumForName("TEXTURE2"));
+        maxoff2 = W_LumpLength(W_GetNumForName(texture2));
     }
     else
     {
@@ -358,8 +363,11 @@
     //      Init the startup thermometer at this point...
     //
     {
+        int start, end;
         int spramount;
-        spramount = W_GetNumForName("S_END") - W_GetNumForName("S_START") + 1;
+        start = W_GetNumForName(DEH_String("S_START"));
+        end = W_GetNumForName(DEH_String("S_END"));
+        spramount = end - start + 1;
         InitThermo(spramount + numtextures + 6);
     }
 
@@ -427,10 +435,10 @@
 
     Z_Free(patchlookup);
 
-    W_ReleaseLumpName("TEXTURE1");
+    W_ReleaseLumpName(texture1);
     if (maptex2)
     {
-        W_ReleaseLumpName("TEXTURE2");
+        W_ReleaseLumpName(texture2);
     }
 
 //
@@ -463,8 +471,8 @@
 {
     int i;
 
-    firstflat = W_GetNumForName("F_START") + 1;
-    lastflat = W_GetNumForName("F_END") - 1;
+    firstflat = W_GetNumForName(DEH_String("F_START")) + 1;
+    lastflat = W_GetNumForName(DEH_String("F_END")) - 1;
     numflats = lastflat - firstflat + 1;
 
 // translation table for global animation
@@ -489,8 +497,8 @@
     int i;
     patch_t *patch;
 
-    firstspritelump = W_GetNumForName("S_START") + 1;
-    lastspritelump = W_GetNumForName("S_END") - 1;
+    firstspritelump = W_GetNumForName(DEH_String("S_START")) + 1;
+    lastspritelump = W_GetNumForName(DEH_String("S_END")) - 1;
     numspritelumps = lastspritelump - firstspritelump + 1;
     spritewidth = Z_Malloc(numspritelumps * sizeof(fixed_t), PU_STATIC, 0);
     spriteoffset = Z_Malloc(numspritelumps * sizeof(fixed_t), PU_STATIC, 0);
@@ -527,7 +535,7 @@
 // load in the light tables
 // 256 byte align tables
 //
-    lump = W_GetNumForName("COLORMAP");
+    lump = W_GetNumForName(DEH_String("COLORMAP"));
     length = W_LumpLength(lump);
     colormaps = Z_Malloc(length, PU_STATIC, 0);
     W_ReadLump(lump, colormaps);
--- a/src/heretic/r_draw.c
+++ b/src/heretic/r_draw.c
@@ -24,6 +24,7 @@
 // R_draw.c
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "r_local.h"
 #include "i_video.h"
 #include "v_video.h"
@@ -386,11 +387,11 @@
 
     if (gamemode == shareware)
     {
-        src = W_CacheLumpName("FLOOR04", PU_CACHE);
+        src = W_CacheLumpName(DEH_String("FLOOR04"), PU_CACHE);
     }
     else
     {
-        src = W_CacheLumpName("FLAT513", PU_CACHE);
+        src = W_CacheLumpName(DEH_String("FLAT513"), PU_CACHE);
     }
     dest = I_VideoBuffer;
 
@@ -409,24 +410,26 @@
     }
     for (x = viewwindowx; x < viewwindowx + viewwidth; x += 16)
     {
-        V_DrawPatch(x, viewwindowy - 4, W_CacheLumpName("bordt", PU_CACHE));
-        V_DrawPatch(x, viewwindowy + viewheight, W_CacheLumpName("bordb",
-                                                                 PU_CACHE));
+        V_DrawPatch(x, viewwindowy - 4,
+                    W_CacheLumpName(DEH_String("bordt"), PU_CACHE));
+        V_DrawPatch(x, viewwindowy + viewheight,
+                    W_CacheLumpName(DEH_String("bordb"), PU_CACHE));
     }
     for (y = viewwindowy; y < viewwindowy + viewheight; y += 16)
     {
-        V_DrawPatch(viewwindowx - 4, y, W_CacheLumpName("bordl", PU_CACHE));
-        V_DrawPatch(viewwindowx + viewwidth, y, W_CacheLumpName("bordr",
-                                                                PU_CACHE));
+        V_DrawPatch(viewwindowx - 4, y,
+                    W_CacheLumpName(DEH_String("bordl"), PU_CACHE));
+        V_DrawPatch(viewwindowx + viewwidth, y,
+                    W_CacheLumpName(DEH_String("bordr"), PU_CACHE));
     }
-    V_DrawPatch(viewwindowx - 4, viewwindowy - 4, W_CacheLumpName("bordtl",
-                                                                  PU_CACHE));
+    V_DrawPatch(viewwindowx - 4, viewwindowy - 4,
+                W_CacheLumpName(DEH_String("bordtl"), PU_CACHE));
     V_DrawPatch(viewwindowx + viewwidth, viewwindowy - 4,
-                W_CacheLumpName("bordtr", PU_CACHE));
+                W_CacheLumpName(DEH_String("bordtr"), PU_CACHE));
     V_DrawPatch(viewwindowx + viewwidth, viewwindowy + viewheight,
-                W_CacheLumpName("bordbr", PU_CACHE));
+                W_CacheLumpName(DEH_String("bordbr"), PU_CACHE));
     V_DrawPatch(viewwindowx - 4, viewwindowy + viewheight,
-                W_CacheLumpName("bordbl", PU_CACHE));
+                W_CacheLumpName(DEH_String("bordbl"), PU_CACHE));
 }
 
 /*
@@ -450,11 +453,11 @@
 
     if (gamemode == shareware)
     {
-        src = W_CacheLumpName("FLOOR04", PU_CACHE);
+        src = W_CacheLumpName(DEH_String("FLOOR04"), PU_CACHE);
     }
     else
     {
-        src = W_CacheLumpName("FLAT513", PU_CACHE);
+        src = W_CacheLumpName(DEH_String("FLAT513"), PU_CACHE);
     }
     dest = I_VideoBuffer;
 
@@ -476,20 +479,20 @@
         for (x = viewwindowx; x < viewwindowx + viewwidth; x += 16)
         {
             V_DrawPatch(x, viewwindowy - 4,
-                        W_CacheLumpName("bordt", PU_CACHE));
+                        W_CacheLumpName(DEH_String("bordt"), PU_CACHE));
         }
-        V_DrawPatch(viewwindowx - 4, viewwindowy, W_CacheLumpName("bordl",
-                                                                  PU_CACHE));
+        V_DrawPatch(viewwindowx - 4, viewwindowy,
+                    W_CacheLumpName(DEH_String("bordl"), PU_CACHE));
         V_DrawPatch(viewwindowx + viewwidth, viewwindowy,
-                    W_CacheLumpName("bordr", PU_CACHE));
+                    W_CacheLumpName(DEH_String("bordr"), PU_CACHE));
         V_DrawPatch(viewwindowx - 4, viewwindowy + 16,
-                    W_CacheLumpName("bordl", PU_CACHE));
+                    W_CacheLumpName(DEH_String("bordl"), PU_CACHE));
         V_DrawPatch(viewwindowx + viewwidth, viewwindowy + 16,
-                    W_CacheLumpName("bordr", PU_CACHE));
+                    W_CacheLumpName(DEH_String("bordr"), PU_CACHE));
 
         V_DrawPatch(viewwindowx - 4, viewwindowy - 4,
-                    W_CacheLumpName("bordtl", PU_CACHE));
+                    W_CacheLumpName(DEH_String("bordtl"), PU_CACHE));
         V_DrawPatch(viewwindowx + viewwidth, viewwindowy - 4,
-                    W_CacheLumpName("bordtr", PU_CACHE));
+                    W_CacheLumpName(DEH_String("bordtr"), PU_CACHE));
     }
 }
--- a/src/heretic/r_plane.c
+++ b/src/heretic/r_plane.c
@@ -25,6 +25,7 @@
 
 #include <stdlib.h>
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_system.h"
 #include "r_local.h"
 
@@ -90,7 +91,7 @@
 
 void R_InitSkyMap(void)
 {
-    skyflatnum = R_FlatNumForName("F_SKY1");
+    skyflatnum = R_FlatNumForName(DEH_String("F_SKY1"));
     skytexturemid = 200 * FRACUNIT;
     skyiscale = FRACUNIT;
 }
--- a/src/heretic/r_things.c
+++ b/src/heretic/r_things.c
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_swap.h"
 #include "i_system.h"
 #include "r_local.h"
@@ -154,7 +155,7 @@
 void R_InitSpriteDefs(char **namelist)
 {
     char **check;
-    int i, l, intname, frame, rotation;
+    int i, l, frame, rotation;
     int start, end;
 
 // count the number of sprite names
@@ -176,17 +177,16 @@
 // Just compare 4 characters as ints
     for (i = 0; i < numsprites; i++)
     {
-        spritename = namelist[i];
+        spritename = DEH_String(namelist[i]);
         memset(sprtemp, -1, sizeof(sprtemp));
 
         maxframe = -1;
-        intname = *(int *) namelist[i];
 
         //
         // scan the lumps, filling in the frames for whatever is found
         //
         for (l = start + 1; l < end; l++)
-            if (*(int *) lumpinfo[l].name == intname)
+            if (!strncasecmp(lumpinfo[l].name, spritename, 4))
             {
                 frame = lumpinfo[l].name[4] - 'A';
                 rotation = lumpinfo[l].name[5] - '0';
@@ -209,7 +209,7 @@
             if (gamemode == shareware)
                 continue;
             I_Error("R_InitSprites: No lumps found for sprite %s",
-                    namelist[i]);
+                    spritename);
         }
 
         maxframe++;
@@ -219,7 +219,7 @@
             {
                 case -1:       // no rotations were found for that frame at all
                     I_Error("R_InitSprites: No patches found for %s frame %c",
-                            namelist[i], frame + 'A');
+                            spritename, frame + 'A');
                 case 0:        // only the first rotation is needed
                     break;
 
@@ -228,7 +228,7 @@
                         if (sprtemp[frame].lump[rotation] == -1)
                             I_Error
                                 ("R_InitSprites: Sprite %s frame %c is missing rotations",
-                                 namelist[i], frame + 'A');
+                                 spritename, frame + 'A');
             }
         }
 
--- a/src/heretic/sb_bar.c
+++ b/src/heretic/sb_bar.c
@@ -25,6 +25,7 @@
 // SB_bar.c
 
 #include "doomdef.h"
+#include "deh_str.h"
 #include "i_video.h"
 #include "m_cheat.h"
 #include "m_misc.h"
@@ -196,53 +197,53 @@
     int i;
     int startLump;
 
-    PatchLTFACE = W_CacheLumpName("LTFACE", PU_STATIC);
-    PatchRTFACE = W_CacheLumpName("RTFACE", PU_STATIC);
-    PatchBARBACK = W_CacheLumpName("BARBACK", PU_STATIC);
-    PatchINVBAR = W_CacheLumpName("INVBAR", PU_STATIC);
-    PatchCHAIN = W_CacheLumpName("CHAIN", PU_STATIC);
+    PatchLTFACE = W_CacheLumpName(DEH_String("LTFACE"), PU_STATIC);
+    PatchRTFACE = W_CacheLumpName(DEH_String("RTFACE"), PU_STATIC);
+    PatchBARBACK = W_CacheLumpName(DEH_String("BARBACK"), PU_STATIC);
+    PatchINVBAR = W_CacheLumpName(DEH_String("INVBAR"), PU_STATIC);
+    PatchCHAIN = W_CacheLumpName(DEH_String("CHAIN"), PU_STATIC);
     if (deathmatch)
     {
-        PatchSTATBAR = W_CacheLumpName("STATBAR", PU_STATIC);
+        PatchSTATBAR = W_CacheLumpName(DEH_String("STATBAR"), PU_STATIC);
     }
     else
     {
-        PatchSTATBAR = W_CacheLumpName("LIFEBAR", PU_STATIC);
+        PatchSTATBAR = W_CacheLumpName(DEH_String("LIFEBAR"), PU_STATIC);
     }
     if (!netgame)
     {                           // single player game uses red life gem
-        PatchLIFEGEM = W_CacheLumpName("LIFEGEM2", PU_STATIC);
+        PatchLIFEGEM = W_CacheLumpName(DEH_String("LIFEGEM2"), PU_STATIC);
     }
     else
     {
-        PatchLIFEGEM = W_CacheLumpNum(W_GetNumForName("LIFEGEM0")
+        PatchLIFEGEM = W_CacheLumpNum(W_GetNumForName(DEH_String("LIFEGEM0"))
                                       + consoleplayer, PU_STATIC);
     }
-    PatchLTFCTOP = W_CacheLumpName("LTFCTOP", PU_STATIC);
-    PatchRTFCTOP = W_CacheLumpName("RTFCTOP", PU_STATIC);
-    PatchSELECTBOX = W_CacheLumpName("SELECTBOX", PU_STATIC);
-    PatchINVLFGEM1 = W_CacheLumpName("INVGEML1", PU_STATIC);
-    PatchINVLFGEM2 = W_CacheLumpName("INVGEML2", PU_STATIC);
-    PatchINVRTGEM1 = W_CacheLumpName("INVGEMR1", PU_STATIC);
-    PatchINVRTGEM2 = W_CacheLumpName("INVGEMR2", PU_STATIC);
-    PatchBLACKSQ = W_CacheLumpName("BLACKSQ", PU_STATIC);
-    PatchARMCLEAR = W_CacheLumpName("ARMCLEAR", PU_STATIC);
-    PatchCHAINBACK = W_CacheLumpName("CHAINBACK", PU_STATIC);
-    startLump = W_GetNumForName("IN0");
+    PatchLTFCTOP = W_CacheLumpName(DEH_String("LTFCTOP"), PU_STATIC);
+    PatchRTFCTOP = W_CacheLumpName(DEH_String("RTFCTOP"), PU_STATIC);
+    PatchSELECTBOX = W_CacheLumpName(DEH_String("SELECTBOX"), PU_STATIC);
+    PatchINVLFGEM1 = W_CacheLumpName(DEH_String("INVGEML1"), PU_STATIC);
+    PatchINVLFGEM2 = W_CacheLumpName(DEH_String("INVGEML2"), PU_STATIC);
+    PatchINVRTGEM1 = W_CacheLumpName(DEH_String("INVGEMR1"), PU_STATIC);
+    PatchINVRTGEM2 = W_CacheLumpName(DEH_String("INVGEMR2"), PU_STATIC);
+    PatchBLACKSQ = W_CacheLumpName(DEH_String("BLACKSQ"), PU_STATIC);
+    PatchARMCLEAR = W_CacheLumpName(DEH_String("ARMCLEAR"), PU_STATIC);
+    PatchCHAINBACK = W_CacheLumpName(DEH_String("CHAINBACK"), PU_STATIC);
+    startLump = W_GetNumForName(DEH_String("IN0"));
     for (i = 0; i < 10; i++)
     {
         PatchINumbers[i] = W_CacheLumpNum(startLump + i, PU_STATIC);
     }
-    PatchNEGATIVE = W_CacheLumpName("NEGNUM", PU_STATIC);
-    FontBNumBase = W_GetNumForName("FONTB16");
-    startLump = W_GetNumForName("SMALLIN0");
+    PatchNEGATIVE = W_CacheLumpName(DEH_String("NEGNUM"), PU_STATIC);
+    FontBNumBase = W_GetNumForName(DEH_String("FONTB16"));
+    startLump = W_GetNumForName(DEH_String("SMALLIN0"));
     for (i = 0; i < 10; i++)
     {
         PatchSmNumbers[i] = W_CacheLumpNum(startLump + i, PU_STATIC);
     }
-    playpalette = W_GetNumForName("PLAYPAL");
-    spinbooklump = W_GetNumForName("SPINBK0");
-    spinflylump = W_GetNumForName("SPFLY0");
+    playpalette = W_GetNumForName(DEH_String("PLAYPAL"));
+    spinbooklump = W_GetNumForName(DEH_String("SPINBK0"));
+    spinflylump = W_GetNumForName(DEH_String("SPFLY0"));
 }
 
 //---------------------------------------------------------------------------
@@ -311,7 +312,7 @@
     {
         if (val < -9)
         {
-            V_DrawPatch(x + 1, y + 1, W_CacheLumpName("LAME", PU_CACHE));
+            V_DrawPatch(x + 1, y + 1, W_CacheLumpName(DEH_String("LAME"), PU_CACHE));
         }
         else
         {
@@ -458,7 +459,7 @@
 
     if (leveltime & 16)
     {
-        MN_DrTextA("*** SOUND DEBUG INFO ***", xPos[0], 20);
+        MN_DrTextA(DEH_String("*** SOUND DEBUG INFO ***"), xPos[0], 20);
     }
     S_GetChannelInfo(&s);
     if (s.channelCount == 0)
@@ -466,13 +467,13 @@
         return;
     }
     x = 0;
-    MN_DrTextA("NAME", xPos[x++], 30);
-    MN_DrTextA("MO.T", xPos[x++], 30);
-    MN_DrTextA("MO.X", xPos[x++], 30);
-    MN_DrTextA("MO.Y", xPos[x++], 30);
-    MN_DrTextA("ID", xPos[x++], 30);
-    MN_DrTextA("PRI", xPos[x++], 30);
-    MN_DrTextA("DIST", xPos[x++], 30);
+    MN_DrTextA(DEH_String("NAME"), xPos[x++], 30);
+    MN_DrTextA(DEH_String("MO.T"), xPos[x++], 30);
+    MN_DrTextA(DEH_String("MO.X"), xPos[x++], 30);
+    MN_DrTextA(DEH_String("MO.Y"), xPos[x++], 30);
+    MN_DrTextA(DEH_String("ID"), xPos[x++], 30);
+    MN_DrTextA(DEH_String("PRI"), xPos[x++], 30);
+    MN_DrTextA(DEH_String("DIST"), xPos[x++], 30);
     for (i = 0; i < s.channelCount; i++)
     {
         c = &s.chan[i];
@@ -480,7 +481,7 @@
         y = 40 + i * 10;
         if (c->mo == NULL)
         {                       // Channel is unused
-            MN_DrTextA("------", xPos[0], y);
+            MN_DrTextA(DEH_String("------"), xPos[0], y);
             continue;
         }
         sprintf(text, "%s", c->name);
@@ -570,8 +571,10 @@
             V_DrawPatch(0, 158, PatchBARBACK);
             if (players[consoleplayer].cheats & CF_GODMODE)
             {
-                V_DrawPatch(16, 167, W_CacheLumpName("GOD1", PU_CACHE));
-                V_DrawPatch(287, 167, W_CacheLumpName("GOD2", PU_CACHE));
+                V_DrawPatch(16, 167,
+                            W_CacheLumpName(DEH_String("GOD1"), PU_CACHE));
+                V_DrawPatch(287, 167,
+                            W_CacheLumpName(DEH_String("GOD2"), PU_CACHE));
             }
             oldhealth = -1;
         }
@@ -776,8 +779,10 @@
     if (ArtifactFlash)
     {
         V_DrawPatch(180, 161, PatchBLACKSQ);
-        V_DrawPatch(182, 161, W_CacheLumpNum(W_GetNumForName("useartia")
-                                             + ArtifactFlash - 1, PU_CACHE));
+
+        temp = W_GetNumForName(DEH_String("useartia")) + ArtifactFlash - 1;
+
+        V_DrawPatch(182, 161, W_CacheLumpNum(temp, PU_CACHE));
         ArtifactFlash--;
         oldarti = -1;           // so that the correct artifact fills in after the flash
         UpdateState |= I_STATBAR;
@@ -789,7 +794,7 @@
         if (CPlayer->readyArtifact > 0)
         {
             V_DrawPatch(179, 160,
-                        W_CacheLumpName(patcharti[CPlayer->readyArtifact],
+                        W_CacheLumpName(DEH_String(patcharti[CPlayer->readyArtifact]),
                                         PU_CACHE));
             DrSmallNumber(CPlayer->inventory[inv_ptr].count, 201, 182);
         }
@@ -839,15 +844,15 @@
     {
         if (CPlayer->keys[key_yellow])
         {
-            V_DrawPatch(153, 164, W_CacheLumpName("ykeyicon", PU_CACHE));
+            V_DrawPatch(153, 164, W_CacheLumpName(DEH_String("ykeyicon"), PU_CACHE));
         }
         if (CPlayer->keys[key_green])
         {
-            V_DrawPatch(153, 172, W_CacheLumpName("gkeyicon", PU_CACHE));
+            V_DrawPatch(153, 172, W_CacheLumpName(DEH_String("gkeyicon"), PU_CACHE));
         }
         if (CPlayer->keys[key_blue])
         {
-            V_DrawPatch(153, 180, W_CacheLumpName("bkeyicon", PU_CACHE));
+            V_DrawPatch(153, 180, W_CacheLumpName(DEH_String("bkeyicon"), PU_CACHE));
         }
         oldkeys = playerkeys;
         UpdateState |= I_STATBAR;
@@ -861,7 +866,7 @@
         {
             DrINumber(temp, 109, 162);
             V_DrawPatch(111, 172,
-                        W_CacheLumpName(ammopic[CPlayer->readyweapon - 1],
+                        W_CacheLumpName(DEH_String(ammopic[CPlayer->readyweapon - 1]),
                                         PU_CACHE));
         }
         oldammo = temp;
@@ -887,6 +892,7 @@
 
 void DrawInventoryBar(void)
 {
+    char *patch;
     int i;
     int x;
 
@@ -899,10 +905,9 @@
         if (CPlayer->inventorySlotNum > x + i
             && CPlayer->inventory[x + i].type != arti_none)
         {
-            V_DrawPatch(50 + i * 31, 160,
-                        W_CacheLumpName(patcharti
-                                        [CPlayer->inventory[x + i].type],
-                                        PU_CACHE));
+            patch = DEH_String(patcharti[CPlayer->inventory[x + i].type]);
+
+            V_DrawPatch(50 + i * 31, 160, W_CacheLumpName(patch, PU_CACHE));
             DrSmallNumber(CPlayer->inventory[x + i].count, 69 + i * 31, 182);
         }
     }
@@ -921,6 +926,7 @@
 
 void DrawFullScreenStuff(void)
 {
+    char *patch;
     int i;
     int x;
     int temp;
@@ -950,10 +956,9 @@
     {
         if (CPlayer->readyArtifact > 0)
         {
-            V_DrawTLPatch(286, 170, W_CacheLumpName("ARTIBOX", PU_CACHE));
-            V_DrawPatch(286, 170,
-                        W_CacheLumpName(patcharti[CPlayer->readyArtifact],
-                                        PU_CACHE));
+            patch = DEH_String(patcharti[CPlayer->readyArtifact]);
+            V_DrawTLPatch(286, 170, W_CacheLumpName(DEH_String("ARTIBOX"), PU_CACHE));
+            V_DrawPatch(286, 170, W_CacheLumpName(patch, PU_CACHE));
             DrSmallNumber(CPlayer->inventory[inv_ptr].count, 307, 192);
         }
     }
@@ -962,15 +967,14 @@
         x = inv_ptr - curpos;
         for (i = 0; i < 7; i++)
         {
-            V_DrawTLPatch(50 + i * 31, 168, W_CacheLumpName("ARTIBOX",
-                                                            PU_CACHE));
+            V_DrawTLPatch(50 + i * 31, 168,
+                          W_CacheLumpName(DEH_String("ARTIBOX"), PU_CACHE));
             if (CPlayer->inventorySlotNum > x + i
                 && CPlayer->inventory[x + i].type != arti_none)
             {
+                patch = DEH_String(patcharti[CPlayer->inventory[x + i].type]);
                 V_DrawPatch(50 + i * 31, 168,
-                            W_CacheLumpName(patcharti
-                                            [CPlayer->inventory[x + i].type],
-                                            PU_CACHE));
+                            W_CacheLumpName(patch, PU_CACHE));
                 DrSmallNumber(CPlayer->inventory[x + i].count, 69 + i * 31,
                               190);
             }