summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Howard2014-09-13 01:29:27 -0400
committerSimon Howard2014-09-13 01:30:54 -0400
commiteb1ea531fdba58cddfd583a6e7cef81a10f87242 (patch)
tree440bd1ed864f28983f87e5ff8a12921e66676b38 /src
parent204814c7bb16a8ad45435a15328072681978ea57 (diff)
parent78ca3a89b94dea261c88441df044709dd4ca8e7a (diff)
downloadchocolate-doom-eb1ea531fdba58cddfd583a6e7cef81a10f87242.tar.gz
chocolate-doom-eb1ea531fdba58cddfd583a6e7cef81a10f87242.tar.bz2
chocolate-doom-eb1ea531fdba58cddfd583a6e7cef81a10f87242.zip
Add support for the BEX extended string syntax.
Boom added an alternate method for overriding Dehacked strings, using the [STRINGS] section with special symbolic names for each of the strings that can possibly be replaced. This format is used in the Freedoom DEHACKED lump (deliberately, so that the Freedoom WAD does not include the original text to be replaced). As we want to have support for the Freedoom IWADs with Chocolate Doom, add support for the BEX [STRINGS] section, but protected by a magic comment that must be included in Dehacked/BEX files that use it. Thanks to Fabian Greffrath for implementing this.
Diffstat (limited to 'src')
-rw-r--r--src/deh_io.c37
-rw-r--r--src/deh_io.h2
-rw-r--r--src/deh_main.c31
-rw-r--r--src/deh_main.h1
-rw-r--r--src/doom/Makefile.am1
-rw-r--r--src/doom/deh_bexstr.c376
-rw-r--r--src/doom/deh_doom.c3
7 files changed, 447 insertions, 4 deletions
diff --git a/src/deh_io.c b/src/deh_io.c
index 778170fd..fa02aa2e 100644
--- a/src/deh_io.c
+++ b/src/deh_io.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "i_system.h"
#include "m_misc.h"
@@ -224,10 +225,11 @@ static void IncreaseReadBuffer(deh_context_t *context)
// Read a whole line
-char *DEH_ReadLine(deh_context_t *context)
+char *DEH_ReadLine(deh_context_t *context, boolean extended)
{
int c;
int pos;
+ boolean escaped = false;
for (pos = 0;;)
{
@@ -247,6 +249,39 @@ char *DEH_ReadLine(deh_context_t *context)
IncreaseReadBuffer(context);
}
+ // extended string support
+ if (extended && c == '\\')
+ {
+ c = DEH_GetChar(context);
+
+ // "\n" in the middle of a string indicates an internal linefeed
+ if (c == 'n')
+ {
+ context->readbuffer[pos] = '\n';
+ ++pos;
+ continue;
+ }
+
+ // values to be assigned may be split onto multiple lines by ending
+ // each line that is to be continued with a backslash
+ if (c == '\n')
+ {
+ escaped = true;
+ continue;
+ }
+ }
+
+ // blanks before the backslash are included in the string
+ // but indentation after the linefeed is not
+ if (escaped && isspace(c) && c != '\n')
+ {
+ continue;
+ }
+ else
+ {
+ escaped = false;
+ }
+
if (c == '\n')
{
// end of line: a full line has been read
diff --git a/src/deh_io.h b/src/deh_io.h
index 50daf244..0995cda1 100644
--- a/src/deh_io.h
+++ b/src/deh_io.h
@@ -24,7 +24,7 @@ deh_context_t *DEH_OpenFile(char *filename);
deh_context_t *DEH_OpenLump(int lumpnum);
void DEH_CloseFile(deh_context_t *context);
int DEH_GetChar(deh_context_t *context);
-char *DEH_ReadLine(deh_context_t *context);
+char *DEH_ReadLine(deh_context_t *context, boolean extended);
void DEH_Error(deh_context_t *context, char *msg, ...);
void DEH_Warning(deh_context_t *context, char *msg, ...);
diff --git a/src/deh_main.c b/src/deh_main.c
index c98962a9..be1e5611 100644
--- a/src/deh_main.c
+++ b/src/deh_main.c
@@ -33,6 +33,10 @@ extern char *deh_signatures[];
static boolean deh_initialized = false;
+// If true, we can parse [STRINGS] sections in BEX format.
+
+boolean deh_allow_extended_strings = false;
+
// If true, we can do long string replacements.
boolean deh_allow_long_strings = false;
@@ -84,6 +88,14 @@ static deh_section_t *GetSectionByName(char *name)
{
unsigned int i;
+ // we explicitely do not recognize [STRINGS] sections at all
+ // if extended strings are not allowed
+
+ if (!deh_allow_extended_strings && !strncasecmp("[STRINGS]", name, 9))
+ {
+ return NULL;
+ }
+
for (i=0; deh_section_types[i] != NULL; ++i)
{
if (!strcasecmp(deh_section_types[i]->name, name))
@@ -175,7 +187,7 @@ static boolean CheckSignatures(deh_context_t *context)
// Read the first line
- line = DEH_ReadLine(context);
+ line = DEH_ReadLine(context, false);
if (line == NULL)
{
@@ -220,6 +232,16 @@ static void DEH_ParseComment(char *comment)
{
deh_allow_long_cheats = true;
}
+
+ // Allow magic comments to allow parsing [STRINGS] section
+ // that are usually only found in BEX format files. This allows
+ // for substitution of map and episode names when loading
+ // Freedoom/FreeDM IWADs.
+
+ if (strstr(comment, "*allow-extended-strings*") != NULL)
+ {
+ deh_allow_extended_strings = true;
+ }
}
// Parses a dehacked file by reading from the context
@@ -230,6 +252,7 @@ static void DEH_ParseContext(deh_context_t *context)
char section_name[20];
void *tag = NULL;
char *line;
+ deh_section_t *bexstr;
// Read the header and check it matches the signature
@@ -238,13 +261,17 @@ static void DEH_ParseContext(deh_context_t *context)
DEH_Error(context, "This is not a valid dehacked patch file!");
}
+ // extended string support required?
+
+ bexstr = GetSectionByName("[STRINGS]");
+
// Read the file
for (;;)
{
// read a new line
- line = DEH_ReadLine(context);
+ line = DEH_ReadLine(context, bexstr && current_section == bexstr);
// end of file?
diff --git a/src/deh_main.h b/src/deh_main.h
index 9689d1c2..4b3f9d8a 100644
--- a/src/deh_main.h
+++ b/src/deh_main.h
@@ -39,6 +39,7 @@ boolean DEH_ParseAssignment(char *line, char **variable_name, char **value);
void DEH_Checksum(sha1_digest_t digest);
+extern boolean deh_allow_extended_strings;
extern boolean deh_allow_long_strings;
extern boolean deh_allow_long_cheats;
extern boolean deh_apply_cheats;
diff --git a/src/doom/Makefile.am b/src/doom/Makefile.am
index eb229acb..74ba7014 100644
--- a/src/doom/Makefile.am
+++ b/src/doom/Makefile.am
@@ -63,6 +63,7 @@ wi_stuff.c wi_stuff.h
FEATURE_DEHACKED_SOURCE_FILES = \
deh_ammo.c \
+deh_bexstr.c \
deh_cheat.c \
deh_doom.c \
deh_frame.c \
diff --git a/src/doom/deh_bexstr.c b/src/doom/deh_bexstr.c
new file mode 100644
index 00000000..e29b71dc
--- /dev/null
+++ b/src/doom/deh_bexstr.c
@@ -0,0 +1,376 @@
+//
+// Copyright(C) 2005-2014 Simon Howard
+// Copyright(C) 2014 Fabian Greffrath
+//
+// 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.
+//
+//
+// Parses [STRINGS] sections in BEX files
+//
+
+#include <stdio.h>
+#include <string.h>
+
+#include "deh_defs.h"
+#include "deh_io.h"
+#include "deh_main.h"
+
+#include "dstrings.h"
+
+typedef struct {
+ char *macro;
+ char *string;
+} bex_string_t;
+
+// mnemonic keys table
+static const bex_string_t bex_stringtable[] = {
+ // part 1 - general initialization and prompts
+ {"D_DEVSTR", D_DEVSTR},
+ {"D_CDROM", D_CDROM},
+ {"QUITMSG", QUITMSG},
+ {"LOADNET", LOADNET},
+ {"QLOADNET", QLOADNET},
+ {"QSAVESPOT", QSAVESPOT},
+ {"SAVEDEAD", SAVEDEAD},
+ {"QSPROMPT", QSPROMPT},
+ {"QLPROMPT", QLPROMPT},
+ {"NEWGAME", NEWGAME},
+ {"NIGHTMARE", NIGHTMARE},
+ {"SWSTRING", SWSTRING},
+ {"MSGOFF", MSGOFF},
+ {"MSGON", MSGON},
+ {"NETEND", NETEND},
+ {"ENDGAME", ENDGAME},
+ {"DETAILHI", DETAILHI},
+ {"DETAILLO", DETAILLO},
+ {"GAMMALVL0", GAMMALVL0},
+ {"GAMMALVL1", GAMMALVL1},
+ {"GAMMALVL2", GAMMALVL2},
+ {"GAMMALVL3", GAMMALVL3},
+ {"GAMMALVL4", GAMMALVL4},
+ {"EMPTYSTRING", EMPTYSTRING},
+ {"GGSAVED", GGSAVED},
+ {"SAVEGAMENAME", SAVEGAMENAME},
+ // part 2 - messages when the player gets things
+ {"GOTARMOR", GOTARMOR},
+ {"GOTMEGA", GOTMEGA},
+ {"GOTHTHBONUS", GOTHTHBONUS},
+ {"GOTARMBONUS", GOTARMBONUS},
+ {"GOTSTIM", GOTSTIM},
+ {"GOTMEDINEED", GOTMEDINEED},
+ {"GOTMEDIKIT", GOTMEDIKIT},
+ {"GOTSUPER", GOTSUPER},
+ {"GOTBLUECARD", GOTBLUECARD},
+ {"GOTYELWCARD", GOTYELWCARD},
+ {"GOTREDCARD", GOTREDCARD},
+ {"GOTBLUESKUL", GOTBLUESKUL},
+ {"GOTYELWSKUL", GOTYELWSKUL},
+ {"GOTREDSKULL", GOTREDSKULL},
+ {"GOTINVUL", GOTINVUL},
+ {"GOTBERSERK", GOTBERSERK},
+ {"GOTINVIS", GOTINVIS},
+ {"GOTSUIT", GOTSUIT},
+ {"GOTMAP", GOTMAP},
+ {"GOTVISOR", GOTVISOR},
+ {"GOTMSPHERE", GOTMSPHERE},
+ {"GOTCLIP", GOTCLIP},
+ {"GOTCLIPBOX", GOTCLIPBOX},
+ {"GOTROCKET", GOTROCKET},
+ {"GOTROCKBOX", GOTROCKBOX},
+ {"GOTCELL", GOTCELL},
+ {"GOTCELLBOX", GOTCELLBOX},
+ {"GOTSHELLS", GOTSHELLS},
+ {"GOTSHELLBOX", GOTSHELLBOX},
+ {"GOTBACKPACK", GOTBACKPACK},
+ {"GOTBFG9000", GOTBFG9000},
+ {"GOTCHAINGUN", GOTCHAINGUN},
+ {"GOTCHAINSAW", GOTCHAINSAW},
+ {"GOTLAUNCHER", GOTLAUNCHER},
+ {"GOTPLASMA", GOTPLASMA},
+ {"GOTSHOTGUN", GOTSHOTGUN},
+ {"GOTSHOTGUN2", GOTSHOTGUN2},
+ // part 3 - messages when keys are needed
+ {"PD_BLUEO", PD_BLUEO},
+ {"PD_REDO", PD_REDO},
+ {"PD_YELLOWO", PD_YELLOWO},
+ {"PD_BLUEK", PD_BLUEK},
+ {"PD_REDK", PD_REDK},
+ {"PD_YELLOWK", PD_YELLOWK},
+ // part 4 - multiplayer messaging
+ {"HUSTR_MSGU", HUSTR_MSGU},
+ {"HUSTR_MESSAGESENT", HUSTR_MESSAGESENT},
+ {"HUSTR_CHATMACRO0", HUSTR_CHATMACRO0},
+ {"HUSTR_CHATMACRO1", HUSTR_CHATMACRO1},
+ {"HUSTR_CHATMACRO2", HUSTR_CHATMACRO2},
+ {"HUSTR_CHATMACRO3", HUSTR_CHATMACRO3},
+ {"HUSTR_CHATMACRO4", HUSTR_CHATMACRO4},
+ {"HUSTR_CHATMACRO5", HUSTR_CHATMACRO5},
+ {"HUSTR_CHATMACRO6", HUSTR_CHATMACRO6},
+ {"HUSTR_CHATMACRO7", HUSTR_CHATMACRO7},
+ {"HUSTR_CHATMACRO8", HUSTR_CHATMACRO8},
+ {"HUSTR_CHATMACRO9", HUSTR_CHATMACRO9},
+ {"HUSTR_TALKTOSELF1", HUSTR_TALKTOSELF1},
+ {"HUSTR_TALKTOSELF2", HUSTR_TALKTOSELF2},
+ {"HUSTR_TALKTOSELF3", HUSTR_TALKTOSELF3},
+ {"HUSTR_TALKTOSELF4", HUSTR_TALKTOSELF4},
+ {"HUSTR_TALKTOSELF5", HUSTR_TALKTOSELF5},
+ {"HUSTR_PLRGREEN", HUSTR_PLRGREEN},
+ {"HUSTR_PLRINDIGO", HUSTR_PLRINDIGO},
+ {"HUSTR_PLRBROWN", HUSTR_PLRBROWN},
+ {"HUSTR_PLRRED", HUSTR_PLRRED},
+ // part 5 - level names in the automap
+ {"HUSTR_E1M1", HUSTR_E1M1},
+ {"HUSTR_E1M2", HUSTR_E1M2},
+ {"HUSTR_E1M3", HUSTR_E1M3},
+ {"HUSTR_E1M4", HUSTR_E1M4},
+ {"HUSTR_E1M5", HUSTR_E1M5},
+ {"HUSTR_E1M6", HUSTR_E1M6},
+ {"HUSTR_E1M7", HUSTR_E1M7},
+ {"HUSTR_E1M8", HUSTR_E1M8},
+ {"HUSTR_E1M9", HUSTR_E1M9},
+ {"HUSTR_E2M1", HUSTR_E2M1},
+ {"HUSTR_E2M2", HUSTR_E2M2},
+ {"HUSTR_E2M3", HUSTR_E2M3},
+ {"HUSTR_E2M4", HUSTR_E2M4},
+ {"HUSTR_E2M5", HUSTR_E2M5},
+ {"HUSTR_E2M6", HUSTR_E2M6},
+ {"HUSTR_E2M7", HUSTR_E2M7},
+ {"HUSTR_E2M8", HUSTR_E2M8},
+ {"HUSTR_E2M9", HUSTR_E2M9},
+ {"HUSTR_E3M1", HUSTR_E3M1},
+ {"HUSTR_E3M2", HUSTR_E3M2},
+ {"HUSTR_E3M3", HUSTR_E3M3},
+ {"HUSTR_E3M4", HUSTR_E3M4},
+ {"HUSTR_E3M5", HUSTR_E3M5},
+ {"HUSTR_E3M6", HUSTR_E3M6},
+ {"HUSTR_E3M7", HUSTR_E3M7},
+ {"HUSTR_E3M8", HUSTR_E3M8},
+ {"HUSTR_E3M9", HUSTR_E3M9},
+ {"HUSTR_E4M1", HUSTR_E4M1},
+ {"HUSTR_E4M2", HUSTR_E4M2},
+ {"HUSTR_E4M3", HUSTR_E4M3},
+ {"HUSTR_E4M4", HUSTR_E4M4},
+ {"HUSTR_E4M5", HUSTR_E4M5},
+ {"HUSTR_E4M6", HUSTR_E4M6},
+ {"HUSTR_E4M7", HUSTR_E4M7},
+ {"HUSTR_E4M8", HUSTR_E4M8},
+ {"HUSTR_E4M9", HUSTR_E4M9},
+ {"HUSTR_1", HUSTR_1},
+ {"HUSTR_2", HUSTR_2},
+ {"HUSTR_3", HUSTR_3},
+ {"HUSTR_4", HUSTR_4},
+ {"HUSTR_5", HUSTR_5},
+ {"HUSTR_6", HUSTR_6},
+ {"HUSTR_7", HUSTR_7},
+ {"HUSTR_8", HUSTR_8},
+ {"HUSTR_9", HUSTR_9},
+ {"HUSTR_10", HUSTR_10},
+ {"HUSTR_11", HUSTR_11},
+ {"HUSTR_12", HUSTR_12},
+ {"HUSTR_13", HUSTR_13},
+ {"HUSTR_14", HUSTR_14},
+ {"HUSTR_15", HUSTR_15},
+ {"HUSTR_16", HUSTR_16},
+ {"HUSTR_17", HUSTR_17},
+ {"HUSTR_18", HUSTR_18},
+ {"HUSTR_19", HUSTR_19},
+ {"HUSTR_20", HUSTR_20},
+ {"HUSTR_21", HUSTR_21},
+ {"HUSTR_22", HUSTR_22},
+ {"HUSTR_23", HUSTR_23},
+ {"HUSTR_24", HUSTR_24},
+ {"HUSTR_25", HUSTR_25},
+ {"HUSTR_26", HUSTR_26},
+ {"HUSTR_27", HUSTR_27},
+ {"HUSTR_28", HUSTR_28},
+ {"HUSTR_29", HUSTR_29},
+ {"HUSTR_30", HUSTR_30},
+ {"HUSTR_31", HUSTR_31},
+ {"HUSTR_32", HUSTR_32},
+ {"PHUSTR_1", PHUSTR_1},
+ {"PHUSTR_2", PHUSTR_2},
+ {"PHUSTR_3", PHUSTR_3},
+ {"PHUSTR_4", PHUSTR_4},
+ {"PHUSTR_5", PHUSTR_5},
+ {"PHUSTR_6", PHUSTR_6},
+ {"PHUSTR_7", PHUSTR_7},
+ {"PHUSTR_8", PHUSTR_8},
+ {"PHUSTR_9", PHUSTR_9},
+ {"PHUSTR_10", PHUSTR_10},
+ {"PHUSTR_11", PHUSTR_11},
+ {"PHUSTR_12", PHUSTR_12},
+ {"PHUSTR_13", PHUSTR_13},
+ {"PHUSTR_14", PHUSTR_14},
+ {"PHUSTR_15", PHUSTR_15},
+ {"PHUSTR_16", PHUSTR_16},
+ {"PHUSTR_17", PHUSTR_17},
+ {"PHUSTR_18", PHUSTR_18},
+ {"PHUSTR_19", PHUSTR_19},
+ {"PHUSTR_20", PHUSTR_20},
+ {"PHUSTR_21", PHUSTR_21},
+ {"PHUSTR_22", PHUSTR_22},
+ {"PHUSTR_23", PHUSTR_23},
+ {"PHUSTR_24", PHUSTR_24},
+ {"PHUSTR_25", PHUSTR_25},
+ {"PHUSTR_26", PHUSTR_26},
+ {"PHUSTR_27", PHUSTR_27},
+ {"PHUSTR_28", PHUSTR_28},
+ {"PHUSTR_29", PHUSTR_29},
+ {"PHUSTR_30", PHUSTR_30},
+ {"PHUSTR_31", PHUSTR_31},
+ {"PHUSTR_32", PHUSTR_32},
+ {"THUSTR_1", THUSTR_1},
+ {"THUSTR_2", THUSTR_2},
+ {"THUSTR_3", THUSTR_3},
+ {"THUSTR_4", THUSTR_4},
+ {"THUSTR_5", THUSTR_5},
+ {"THUSTR_6", THUSTR_6},
+ {"THUSTR_7", THUSTR_7},
+ {"THUSTR_8", THUSTR_8},
+ {"THUSTR_9", THUSTR_9},
+ {"THUSTR_10", THUSTR_10},
+ {"THUSTR_11", THUSTR_11},
+ {"THUSTR_12", THUSTR_12},
+ {"THUSTR_13", THUSTR_13},
+ {"THUSTR_14", THUSTR_14},
+ {"THUSTR_15", THUSTR_15},
+ {"THUSTR_16", THUSTR_16},
+ {"THUSTR_17", THUSTR_17},
+ {"THUSTR_18", THUSTR_18},
+ {"THUSTR_19", THUSTR_19},
+ {"THUSTR_20", THUSTR_20},
+ {"THUSTR_21", THUSTR_21},
+ {"THUSTR_22", THUSTR_22},
+ {"THUSTR_23", THUSTR_23},
+ {"THUSTR_24", THUSTR_24},
+ {"THUSTR_25", THUSTR_25},
+ {"THUSTR_26", THUSTR_26},
+ {"THUSTR_27", THUSTR_27},
+ {"THUSTR_28", THUSTR_28},
+ {"THUSTR_29", THUSTR_29},
+ {"THUSTR_30", THUSTR_30},
+ {"THUSTR_31", THUSTR_31},
+ {"THUSTR_32", THUSTR_32},
+ // part 6 - messages as a result of toggling states
+ {"AMSTR_FOLLOWON", AMSTR_FOLLOWON},
+ {"AMSTR_FOLLOWOFF", AMSTR_FOLLOWOFF},
+ {"AMSTR_GRIDON", AMSTR_GRIDON},
+ {"AMSTR_GRIDOFF", AMSTR_GRIDOFF},
+ {"AMSTR_MARKEDSPOT", AMSTR_MARKEDSPOT},
+ {"AMSTR_MARKSCLEARED", AMSTR_MARKSCLEARED},
+ {"STSTR_MUS", STSTR_MUS},
+ {"STSTR_NOMUS", STSTR_NOMUS},
+ {"STSTR_DQDON", STSTR_DQDON},
+ {"STSTR_DQDOFF", STSTR_DQDOFF},
+ {"STSTR_KFAADDED", STSTR_KFAADDED},
+ {"STSTR_FAADDED", STSTR_FAADDED},
+ {"STSTR_NCON", STSTR_NCON},
+ {"STSTR_NCOFF", STSTR_NCOFF},
+ {"STSTR_BEHOLD", STSTR_BEHOLD},
+ {"STSTR_BEHOLDX", STSTR_BEHOLDX},
+ {"STSTR_CHOPPERS", STSTR_CHOPPERS},
+ {"STSTR_CLEV", STSTR_CLEV},
+ // part 7 - episode intermission texts
+ {"E1TEXT", E1TEXT},
+ {"E2TEXT", E2TEXT},
+ {"E3TEXT", E3TEXT},
+ {"E4TEXT", E4TEXT},
+ {"C1TEXT", C1TEXT},
+ {"C2TEXT", C2TEXT},
+ {"C3TEXT", C3TEXT},
+ {"C4TEXT", C4TEXT},
+ {"C5TEXT", C5TEXT},
+ {"C6TEXT", C6TEXT},
+ {"P1TEXT", P1TEXT},
+ {"P2TEXT", P2TEXT},
+ {"P3TEXT", P3TEXT},
+ {"P4TEXT", P4TEXT},
+ {"P5TEXT", P5TEXT},
+ {"P6TEXT", P6TEXT},
+ {"T1TEXT", T1TEXT},
+ {"T2TEXT", T2TEXT},
+ {"T3TEXT", T3TEXT},
+ {"T4TEXT", T4TEXT},
+ {"T5TEXT", T5TEXT},
+ {"T6TEXT", T6TEXT},
+ // part 8 - creature names for the finale
+ {"CC_ZOMBIE", CC_ZOMBIE},
+ {"CC_SHOTGUN", CC_SHOTGUN},
+ {"CC_HEAVY", CC_HEAVY},
+ {"CC_IMP", CC_IMP},
+ {"CC_DEMON", CC_DEMON},
+ {"CC_LOST", CC_LOST},
+ {"CC_CACO", CC_CACO},
+ {"CC_HELL", CC_HELL},
+ {"CC_BARON", CC_BARON},
+ {"CC_ARACH", CC_ARACH},
+ {"CC_PAIN", CC_PAIN},
+ {"CC_REVEN", CC_REVEN},
+ {"CC_MANCU", CC_MANCU},
+ {"CC_ARCH", CC_ARCH},
+ {"CC_SPIDER", CC_SPIDER},
+ {"CC_CYBER", CC_CYBER},
+ {"CC_HERO", CC_HERO},
+ // part 9 - intermission tiled backgrounds
+ {"BGFLATE1", "FLOOR4_8"},
+ {"BGFLATE2", "SFLR6_1"},
+ {"BGFLATE3", "MFLR8_4"},
+ {"BGFLATE4", "MFLR8_3"},
+ {"BGFLAT06", "SLIME16"},
+ {"BGFLAT11", "RROCK14"},
+ {"BGFLAT20", "RROCK07"},
+ {"BGFLAT30", "RROCK17"},
+ {"BGFLAT15", "RROCK13"},
+ {"BGFLAT31", "RROCK19"},
+ {"BGCASTCALL", "BOSSBACK"},
+};
+
+static void *DEH_BEXStrStart(deh_context_t *context, char *line)
+{
+ char s[10];
+
+ if (sscanf(line, "%9s", s) == 0 || strncmp("[STRINGS]", s, sizeof(s)))
+ {
+ DEH_Warning(context, "Parse error on section start");
+ }
+
+ return NULL;
+}
+
+static void DEH_BEXStrParseLine(deh_context_t *context, char *line, void *tag)
+{
+ char *variable_name, *value;
+ int i;
+
+ if (!DEH_ParseAssignment(line, &variable_name, &value))
+ {
+ DEH_Warning(context, "Failed to parse assignment");
+ return;
+ }
+
+ for (i = 0; i < arrlen(bex_stringtable); i++)
+ {
+ if (!strcmp(bex_stringtable[i].macro, variable_name))
+ {
+ DEH_AddStringReplacement(bex_stringtable[i].string, strdup(value));
+ }
+ }
+}
+
+deh_section_t deh_section_bexstr =
+{
+ "[STRINGS]",
+ NULL,
+ DEH_BEXStrStart,
+ DEH_BEXStrParseLine,
+ NULL,
+ NULL,
+};
diff --git a/src/doom/deh_doom.c b/src/doom/deh_doom.c
index a8a7d28f..fc5cafd1 100644
--- a/src/doom/deh_doom.c
+++ b/src/doom/deh_doom.c
@@ -44,6 +44,8 @@ extern deh_section_t deh_section_text;
extern deh_section_t deh_section_thing;
// deh_weapon.c:
extern deh_section_t deh_section_weapon;
+// deh_bexstr.c:
+extern deh_section_t deh_section_bexstr;
//
// List of section types:
@@ -60,6 +62,7 @@ deh_section_t *deh_section_types[] =
&deh_section_text,
&deh_section_thing,
&deh_section_weapon,
+ &deh_section_bexstr,
NULL
};