ref: 8a77b34e936a3fd752db3bc1113e3d7bd0555440
parent: 8f6edc1f7402215c5e38d1f03939ce6b5ff5e3ae
author: Simon Howard <fraggle@gmail.com>
date: Tue Feb 2 14:02:16 EST 2010
Move parts of dehacked code into top-level common code, to allow future HHE and SEH support. Subversion-branch: /branches/raven-branch Subversion-revision: 1841
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,6 +50,7 @@
d_iwad.c d_iwad.h \
d_mode.c d_mode.h \
d_ticcmd.h \
+deh_str.c deh_str.h \
i_cdmus.c i_cdmus.h \
i_endoom.c i_endoom.h \
i_joystick.c i_joystick.h \
@@ -79,8 +80,12 @@
# source files needed for FEATURE_DEHACKED
-FEATURE_DEHACKED_SOURCE_FILES= \
-deh_str.c deh_str.h
+FEATURE_DEHACKED_SOURCE_FILES = \
+deh_defs.h \
+deh_io.c deh_io.h \
+deh_main.c deh_main.h \
+deh_mapping.c deh_mapping.h \
+deh_text.c
# source files needed for FEATURE_MULTIPLAYER
@@ -111,12 +116,15 @@
i_sdlmusic.c \
mus2mid.c mus2mid.h
+# Some games support dehacked patches, some don't:
+
SOURCE_FILES = $(COMMON_SOURCE_FILES) \
$(GAME_SOURCE_FILES) \
- $(FEATURE_DEHACKED_SOURCE_FILES) \
$(FEATURE_WAD_MERGE_SOURCE_FILES) \
$(FEATURE_SOUND_SOURCE_FILES)
+SOURCE_FILES_WITH_DEH = $(SOURCE_FILES) \
+ $(FEATURE_DEHACKED_SOURCE_FILES)
EXTRA_LIBS = \
$(top_builddir)/wince/libc_wince.a \
@@ -128,9 +136,9 @@
@SDLNET_LIBS@
if HAVE_WINDRES
-@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES) resource.rc
+@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc
else
-@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES)
+@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH)
endif
@PROGRAM_PREFIX@doom_LDADD = doom/libdoom.a $(EXTRA_LIBS)
--- /dev/null
+++ b/src/deh_defs.h
@@ -1,0 +1,68 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Definitions for use in the dehacked code
+//
+//-----------------------------------------------------------------------------
+
+#ifndef DEH_DEFS_H
+#define DEH_DEFS_H
+
+#include "md5.h"
+
+typedef struct deh_context_s deh_context_t;
+typedef struct deh_section_s deh_section_t;
+typedef void (*deh_section_init_t)(void);
+typedef void *(*deh_section_start_t)(deh_context_t *context, char *line);
+typedef void (*deh_section_end_t)(deh_context_t *context, void *tag);
+typedef void (*deh_line_parser_t)(deh_context_t *context, char *line, void *tag);
+typedef void (*deh_md5_hash_t)(md5_context_t *context);
+
+struct deh_section_s
+{
+ char *name;
+
+ // Called on startup to initialize code
+
+ deh_section_init_t init;
+
+ // This is called when a new section is started. The pointer
+ // returned is used as a tag for the following calls.
+
+ deh_section_start_t start;
+
+ // This is called for each line in the section
+
+ deh_line_parser_t line_parser;
+
+ // This is called at the end of the section for any cleanup
+
+ deh_section_end_t end;
+
+ // Called when generating an MD5 sum of the dehacked state
+
+ deh_md5_hash_t md5_hash;
+};
+
+#endif /* #ifndef DEH_DEFS_H */
+
+
--- /dev/null
+++ b/src/deh_io.c
@@ -1,0 +1,211 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Dehacked I/O code (does all reads from dehacked files)
+//
+//-----------------------------------------------------------------------------
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "i_system.h"
+#include "z_zone.h"
+
+#include "deh_defs.h"
+#include "deh_io.h"
+
+struct deh_context_s
+{
+ FILE *stream;
+ char *filename;
+ int linenum;
+ boolean last_was_newline;
+ char *readbuffer;
+ int readbuffer_size;
+};
+
+// Open a dehacked file for reading
+// Returns NULL if open failed
+
+deh_context_t *DEH_OpenFile(char *filename)
+{
+ FILE *fstream;
+ deh_context_t *context;
+
+ fstream = fopen(filename, "r");
+
+ if (fstream == NULL)
+ return NULL;
+
+ context = Z_Malloc(sizeof(*context), PU_STATIC, NULL);
+ context->stream = fstream;
+
+ // Initial read buffer size of 128 bytes
+
+ context->readbuffer_size = 128;
+ context->readbuffer = Z_Malloc(context->readbuffer_size, PU_STATIC, NULL);
+ context->filename = filename;
+ context->linenum = 0;
+ context->last_was_newline = true;
+
+ return context;
+}
+
+// Close dehacked file
+
+void DEH_CloseFile(deh_context_t *context)
+{
+ fclose(context->stream);
+ Z_Free(context->readbuffer);
+ Z_Free(context);
+}
+
+// Reads a single character from a dehacked file
+
+int DEH_GetChar(deh_context_t *context)
+{
+ int result;
+
+ // Read characters, but ignore carriage returns
+ // Essentially this is a DOS->Unix conversion
+
+ do
+ {
+ if (feof(context->stream))
+ {
+ // end of file
+
+ result = -1;
+ }
+ else
+ {
+ result = fgetc(context->stream);
+ }
+
+ } while (result == '\r');
+
+ // Track the current line number
+
+ if (context->last_was_newline)
+ {
+ ++context->linenum;
+ }
+
+ context->last_was_newline = result == '\n';
+
+ return result;
+}
+
+// Increase the read buffer size
+
+static void IncreaseReadBuffer(deh_context_t *context)
+{
+ char *newbuffer;
+ int newbuffer_size;
+
+ newbuffer_size = context->readbuffer_size * 2;
+ newbuffer = Z_Malloc(newbuffer_size, PU_STATIC, NULL);
+
+ memcpy(newbuffer, context->readbuffer, context->readbuffer_size);
+
+ Z_Free(context->readbuffer);
+
+ context->readbuffer = newbuffer;
+ context->readbuffer_size = newbuffer_size;
+}
+
+// Read a whole line
+
+char *DEH_ReadLine(deh_context_t *context)
+{
+ int c;
+ int pos;
+
+ for (pos = 0;;)
+ {
+ c = DEH_GetChar(context);
+
+ if (c < 0)
+ {
+ // end of file
+
+ return NULL;
+ }
+
+ // cope with lines of any length: increase the buffer size
+
+ if (pos >= context->readbuffer_size)
+ {
+ IncreaseReadBuffer(context);
+ }
+
+ if (c == '\n')
+ {
+ // end of line: a full line has been read
+
+ context->readbuffer[pos] = '\0';
+ break;
+ }
+ else if (c != '\0')
+ {
+ // normal character; don't allow NUL characters to be
+ // added.
+
+ context->readbuffer[pos] = (char) c;
+ ++pos;
+ }
+ }
+
+ return context->readbuffer;
+}
+
+void DEH_Warning(deh_context_t *context, char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+
+ fprintf(stderr, "%s:%i: warning: ", context->filename, context->linenum);
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n");
+
+ va_end(args);
+}
+
+void DEH_Error(deh_context_t *context, char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+
+ fprintf(stderr, "%s:%i: ", context->filename, context->linenum);
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n");
+
+ va_end(args);
+
+ I_Error("Error parsing dehacked file");
+}
+
+
--- /dev/null
+++ b/src/deh_io.h
@@ -1,0 +1,40 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Dehacked I/O code (does all reads from dehacked files)
+//
+//-----------------------------------------------------------------------------
+
+#ifndef DEH_IO_H
+#define DEH_IO_H
+
+#include "deh_defs.h"
+
+deh_context_t *DEH_OpenFile(char *filename);
+void DEH_CloseFile(deh_context_t *context);
+int DEH_GetChar(deh_context_t *context);
+char *DEH_ReadLine(deh_context_t *context);
+void DEH_Error(deh_context_t *context, char *msg, ...);
+void DEH_Warning(deh_context_t *context, char *msg, ...);
+
+#endif /* #ifndef DEH_IO_H */
+
--- /dev/null
+++ b/src/deh_main.c
@@ -1,0 +1,384 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Main dehacked code
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "doomtype.h"
+#include "d_iwad.h"
+#include "m_argv.h"
+
+#include "deh_defs.h"
+#include "deh_io.h"
+
+extern deh_section_t *deh_section_types[];
+extern char *deh_signatures[];
+
+// If true, we can do long string replacements.
+
+boolean deh_allow_long_strings = false;
+
+// If true, we can do cheat replacements longer than the originals.
+
+boolean deh_allow_long_cheats = false;
+
+// If false, dehacked cheat replacements are ignored.
+
+boolean deh_apply_cheats = true;
+
+void DEH_Checksum(md5_digest_t digest)
+{
+ md5_context_t md5_context;
+ unsigned int i;
+
+ MD5_Init(&md5_context);
+
+ for (i=0; deh_section_types[i] != NULL; ++i)
+ {
+ if (deh_section_types[i]->md5_hash != NULL)
+ {
+ deh_section_types[i]->md5_hash(&md5_context);
+ }
+ }
+
+ MD5_Final(digest, &md5_context);
+}
+
+// Called on startup to call the Init functions
+
+static void InitializeSections(void)
+{
+ unsigned int i;
+
+ for (i=0; deh_section_types[i] != NULL; ++i)
+ {
+ if (deh_section_types[i]->init != NULL)
+ {
+ deh_section_types[i]->init();
+ }
+ }
+}
+
+// Given a section name, get the section structure which corresponds
+
+static deh_section_t *GetSectionByName(char *name)
+{
+ unsigned int i;
+
+ for (i=0; deh_section_types[i] != NULL; ++i)
+ {
+ if (!strcasecmp(deh_section_types[i]->name, name))
+ {
+ return deh_section_types[i];
+ }
+ }
+
+ return NULL;
+}
+
+// Is the string passed just whitespace?
+
+static boolean IsWhitespace(char *s)
+{
+ for (; *s; ++s)
+ {
+ if (!isspace(*s))
+ return false;
+ }
+
+ return true;
+}
+
+// Strip whitespace from the start and end of a string
+
+static char *CleanString(char *s)
+{
+ char *strending;
+
+ // Leading whitespace
+
+ while (*s && isspace(*s))
+ ++s;
+
+ // Trailing whitespace
+
+ strending = s + strlen(s) - 1;
+
+ while (strlen(s) > 0 && isspace(*strending))
+ {
+ *strending = '\0';
+ --strending;
+ }
+
+ return s;
+}
+
+// This pattern is used a lot of times in different sections,
+// an assignment is essentially just a statement of the form:
+//
+// Variable Name = Value
+//
+// The variable name can include spaces or any other characters.
+// The string is split on the '=', essentially.
+//
+// Returns true if read correctly
+
+boolean DEH_ParseAssignment(char *line, char **variable_name, char **value)
+{
+ char *p;
+
+ // find the equals
+
+ p = strchr(line, '=');
+
+ if (p == NULL && p-line > 2)
+ {
+ return false;
+ }
+
+ // variable name at the start
+ // turn the '=' into a \0 to terminate the string here
+
+ *p = '\0';
+ *variable_name = CleanString(line);
+
+ // value immediately follows the '='
+
+ *value = CleanString(p+1);
+
+ return true;
+}
+
+static boolean CheckSignatures(deh_context_t *context)
+{
+ size_t i;
+ char *line;
+
+ // Read the first line
+
+ line = DEH_ReadLine(context);
+
+ if (line == NULL)
+ {
+ return false;
+ }
+
+ // Check all signatures to see if one matches
+
+ for (i=0; deh_signatures[i] != NULL; ++i)
+ {
+ if (!strcmp(deh_signatures[i], line))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Parses a comment string in a dehacked file.
+
+static void DEH_ParseComment(char *comment)
+{
+ // Allow comments containing this special value to allow string
+ // replacements longer than those permitted by DOS dehacked.
+ // This allows us to use a dehacked patch for doing string
+ // replacements for emulating Chex Quest.
+ //
+ // If you use this, your dehacked patch may not work in Vanilla
+ // Doom.
+
+ if (strstr(comment, "*allow-long-strings*") != NULL)
+ {
+ deh_allow_long_strings = true;
+ }
+
+ // Allow magic comments to allow longer cheat replacements than
+ // those permitted by DOS dehacked. This is also for Chex
+ // Quest.
+
+ if (strstr(comment, "*allow-long-cheats*") != NULL)
+ {
+ deh_allow_long_cheats = true;
+ }
+}
+
+// Parses a dehacked file by reading from the context
+
+static void DEH_ParseContext(deh_context_t *context)
+{
+ deh_section_t *current_section = NULL;
+ char section_name[20];
+ void *tag = NULL;
+ char *line;
+
+ // Read the header and check it matches the signature
+
+ if (!CheckSignatures(context))
+ {
+ DEH_Error(context, "This is not a valid dehacked patch file!");
+ }
+
+ deh_allow_long_strings = false;
+ deh_allow_long_cheats = false;
+
+ // Read the file
+
+ for (;;)
+ {
+ // read a new line
+
+ line = DEH_ReadLine(context);
+
+ // end of file?
+
+ if (line == NULL)
+ return;
+
+ while (line[0] != '\0' && isspace(line[0]))
+ ++line;
+
+ if (line[0] == '#')
+ {
+ // comment
+
+ DEH_ParseComment(line);
+ continue;
+ }
+
+ if (IsWhitespace(line))
+ {
+ if (current_section != NULL)
+ {
+ // end of section
+
+ if (current_section->end != NULL)
+ {
+ current_section->end(context, tag);
+ }
+
+ //printf("end %s tag\n", current_section->name);
+ current_section = NULL;
+ }
+ }
+ else
+ {
+ if (current_section != NULL)
+ {
+ // parse this line
+
+ current_section->line_parser(context, line, tag);
+ }
+ else
+ {
+ // possibly the start of a new section
+
+ sscanf(line, "%19s", section_name);
+
+ current_section = GetSectionByName(section_name);
+
+ if (current_section != NULL)
+ {
+ tag = current_section->start(context, line);
+ //printf("started %s tag\n", section_name);
+ }
+ else
+ {
+ //printf("unknown section name %s\n", section_name);
+ }
+ }
+ }
+ }
+}
+
+// Parses a dehacked file
+
+int DEH_LoadFile(char *filename)
+{
+ deh_context_t *context;
+
+ printf(" loading %s\n", filename);
+
+ context = DEH_OpenFile(filename);
+
+ if (context == NULL)
+ {
+ fprintf(stderr, "DEH_LoadFile: Unable to open %s\n", filename);
+ return 0;
+ }
+
+ DEH_ParseContext(context);
+
+ DEH_CloseFile(context);
+
+ return 1;
+}
+
+// Checks the command line for -deh argument
+
+void DEH_Init(void)
+{
+ char *filename;
+ int p;
+
+ InitializeSections();
+
+ //!
+ // @category mod
+ //
+ // Ignore cheats in dehacked files.
+ //
+
+ if (M_CheckParm("-nocheats") > 0)
+ {
+ deh_apply_cheats = false;
+ }
+
+ //!
+ // @arg <files>
+ // @category mod
+ //
+ // Load the given dehacked patch(es)
+ //
+
+ p = M_CheckParm("-deh");
+
+ if (p > 0)
+ {
+ ++p;
+
+ while (p < myargc && myargv[p][0] != '-')
+ {
+ filename = D_TryFindWADByName(myargv[p]);
+ DEH_LoadFile(filename);
+ ++p;
+ }
+ }
+}
+
+
--- /dev/null
+++ b/src/deh_main.h
@@ -1,0 +1,54 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Dehacked entrypoint and common code
+//
+//-----------------------------------------------------------------------------
+
+#ifndef DEH_MAIN_H
+#define DEH_MAIN_H
+
+#include "doomtype.h"
+#include "doomfeatures.h"
+#include "md5.h"
+#include "deh_str.h"
+
+// These are the limits that dehacked uses (from dheinit.h in the dehacked
+// source). If these limits are exceeded, it does not generate an error, but
+// a warning is displayed.
+
+#define DEH_VANILLA_NUMSTATES 966
+#define DEH_VANILLA_NUMSFX 107
+
+void DEH_Init(void);
+int DEH_LoadFile(char *filename);
+
+boolean DEH_ParseAssignment(char *line, char **variable_name, char **value);
+
+void DEH_Checksum(md5_digest_t digest);
+
+extern boolean deh_allow_long_strings;
+extern boolean deh_allow_long_cheats;
+extern boolean deh_apply_cheats;
+
+#endif /* #ifndef DEH_MAIN_H */
+
--- /dev/null
+++ b/src/deh_mapping.c
@@ -1,0 +1,133 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Dehacked "mapping" code
+// Allows the fields in structures to be mapped out and accessed by
+// name
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "doomtype.h"
+#include "i_system.h"
+#include "deh_mapping.h"
+
+//
+// Set the value of a particular field in a structure by name
+//
+
+boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
+ void *structptr, char *name, int value)
+{
+ int i;
+
+ for (i=0; mapping->entries[i].name != NULL; ++i)
+ {
+ deh_mapping_entry_t *entry = &mapping->entries[i];
+
+ if (!strcasecmp(entry->name, name))
+ {
+ void *location;
+
+ if (entry->location == NULL)
+ {
+ DEH_Warning(context, "Field '%s' is unsupported", name);
+ return false;
+ }
+
+ location = (uint8_t *)structptr + ((uint8_t *)entry->location - (uint8_t *)mapping->base);
+
+ // printf("Setting %p::%s to %i (%i bytes)\n",
+ // structptr, name, value, entry->size);
+
+ switch (entry->size)
+ {
+ case 1:
+ * ((uint8_t *) location) = value;
+ break;
+ case 2:
+ * ((uint16_t *) location) = value;
+ break;
+ case 4:
+ * ((uint32_t *) location) = value;
+ break;
+ default:
+ DEH_Error(context, "Unknown field type for '%s' (BUG)", name);
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ // field with this name not found
+
+ DEH_Warning(context, "Field named '%s' not found", name);
+
+ return false;
+}
+
+void DEH_StructMD5Sum(md5_context_t *context, deh_mapping_t *mapping,
+ void *structptr)
+{
+ int i;
+
+ // Go through each mapping
+
+ for (i=0; mapping->entries[i].name != NULL; ++i)
+ {
+ deh_mapping_entry_t *entry = &mapping->entries[i];
+ void *location;
+
+ if (entry->location == NULL)
+ {
+ // Unsupported field
+
+ continue;
+ }
+
+ // Add in data for this field
+
+ location = (uint8_t *)structptr + ((uint8_t *)entry->location - (uint8_t *)mapping->base);
+
+ switch (entry->size)
+ {
+ case 1:
+ MD5_UpdateInt32(context, *((uint8_t *) location));
+ break;
+ case 2:
+ MD5_UpdateInt32(context, *((uint16_t *) location));
+ break;
+ case 4:
+ MD5_UpdateInt32(context, *((uint32_t *) location));
+ break;
+ default:
+ I_Error("Unknown dehacked mapping field type for '%s' (BUG)",
+ entry->name);
+ break;
+ }
+ }
+}
+
--- /dev/null
+++ b/src/deh_mapping.h
@@ -1,0 +1,90 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Dehacked "mapping" code
+// Allows the fields in structures to be mapped out and accessed by
+// name
+//
+//-----------------------------------------------------------------------------
+
+#ifndef DEH_MAPPING_H
+#define DEH_MAPPING_H
+
+#include "doomtype.h"
+#include "deh_io.h"
+#include "md5.h"
+
+#define DEH_BEGIN_MAPPING(mapping_name, structname) \
+ static structname deh_mapping_base; \
+ static deh_mapping_t mapping_name = \
+ { \
+ &deh_mapping_base, \
+ {
+
+#define DEH_MAPPING(deh_name, fieldname) \
+ {deh_name, &deh_mapping_base.fieldname, \
+ sizeof(deh_mapping_base.fieldname)},
+
+#define DEH_UNSUPPORTED_MAPPING(deh_name) \
+ {deh_name, NULL, -1},
+
+#define DEH_END_MAPPING \
+ {NULL, NULL, -1} \
+ } \
+ };
+
+
+
+#define MAX_MAPPING_ENTRIES 32
+
+typedef struct deh_mapping_s deh_mapping_t;
+typedef struct deh_mapping_entry_s deh_mapping_entry_t;
+
+struct deh_mapping_entry_s
+{
+ // field name
+
+ char *name;
+
+ // location relative to the base in the deh_mapping_t struct
+ // If this is NULL, it is an unsupported mapping
+
+ void *location;
+
+ // field size
+
+ int size;
+};
+
+struct deh_mapping_s
+{
+ void *base;
+ deh_mapping_entry_t entries[MAX_MAPPING_ENTRIES];
+};
+
+boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
+ void *structptr, char *name, int value);
+void DEH_StructMD5Sum(md5_context_t *context, deh_mapping_t *mapping,
+ void *structptr);
+
+#endif /* #ifndef DEH_MAPPING_H */
+
--- /dev/null
+++ b/src/deh_text.c
@@ -1,0 +1,127 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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 "z_zone.h"
+
+#include "deh_defs.h"
+#include "deh_io.h"
+#include "deh_main.h"
+
+// Given a string length, find the maximum length of a
+// string that can replace it.
+
+static int TXT_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 *from_text, *to_text;
+ int fromlen, tolen;
+ int i;
+
+ if (sscanf(line, "Text %i %i", &fromlen, &tolen) != 2)
+ {
+ DEH_Warning(context, "Parse error on section start");
+ return NULL;
+ }
+
+ // Only allow string replacements that are possible in Vanilla Doom.
+ // Chocolate Doom is unforgiving!
+
+ if (!deh_allow_long_strings && tolen > TXT_MaxStringLength(fromlen))
+ {
+ DEH_Error(context, "Replacement string is longer than the maximum "
+ "possible in doom.exe");
+ return NULL;
+ }
+
+ from_text = Z_Malloc(fromlen + 1, PU_STATIC, NULL);
+ to_text = Z_Malloc(tolen + 1, PU_STATIC, NULL);
+
+ // read in the "from" text
+
+ for (i=0; i<fromlen; ++i)
+ {
+ int c;
+
+ c = DEH_GetChar(context);
+
+ from_text[i] = c;
+ }
+
+ from_text[fromlen] = '\0';
+
+ // read in the "to" text
+
+ for (i=0; i<tolen; ++i)
+ {
+ int c;
+
+ c = DEH_GetChar(context);
+
+ to_text[i] = c;
+ }
+ to_text[tolen] = '\0';
+
+ DEH_AddStringReplacement(from_text, to_text);
+
+ return NULL;
+}
+
+static void DEH_TextParseLine(deh_context_t *context, char *line, void *tag)
+{
+ // not used
+}
+
+deh_section_t deh_section_text =
+{
+ "Text",
+ NULL,
+ DEH_TextStart,
+ DEH_TextParseLine,
+ NULL,
+ NULL,
+};
+
--- a/src/doom/Makefile.am
+++ b/src/doom/Makefile.am
@@ -63,15 +63,11 @@
FEATURE_DEHACKED_SOURCE_FILES = \
deh_ammo.c \
deh_cheat.c \
-deh_defs.h \
+deh_doom.c \
deh_frame.c \
-deh_io.c deh_io.h \
-deh_main.c deh_main.h \
-deh_mapping.c deh_mapping.h \
deh_misc.c deh_misc.h \
deh_ptr.c \
deh_sound.c \
-deh_text.c \
deh_thing.c \
deh_weapon.c
--- a/src/doom/deh_defs.h
+++ /dev/null
@@ -1,68 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Definitions for use in the dehacked code
-//
-//-----------------------------------------------------------------------------
-
-#ifndef DEH_DEFS_H
-#define DEH_DEFS_H
-
-#include "md5.h"
-
-typedef struct deh_context_s deh_context_t;
-typedef struct deh_section_s deh_section_t;
-typedef void (*deh_section_init_t)(void);
-typedef void *(*deh_section_start_t)(deh_context_t *context, char *line);
-typedef void (*deh_section_end_t)(deh_context_t *context, void *tag);
-typedef void (*deh_line_parser_t)(deh_context_t *context, char *line, void *tag);
-typedef void (*deh_md5_hash_t)(md5_context_t *context);
-
-struct deh_section_s
-{
- char *name;
-
- // Called on startup to initialize code
-
- deh_section_init_t init;
-
- // This is called when a new section is started. The pointer
- // returned is used as a tag for the following calls.
-
- deh_section_start_t start;
-
- // This is called for each line in the section
-
- deh_line_parser_t line_parser;
-
- // This is called at the end of the section for any cleanup
-
- deh_section_end_t end;
-
- // Called when generating an MD5 sum of the dehacked state
-
- deh_md5_hash_t md5_hash;
-};
-
-#endif /* #ifndef DEH_DEFS_H */
-
-
--- /dev/null
+++ b/src/doom/deh_doom.c
@@ -1,0 +1,74 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 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.
+//
+//-----------------------------------------------------------------------------
+//
+// Top-level dehacked definitions for Doom dehacked.
+//
+//-----------------------------------------------------------------------------
+
+#include <stdlib.h>
+#include "deh_defs.h"
+#include "deh_main.h"
+
+char *deh_signatures[] =
+{
+ "Patch File for DeHackEd v2.3",
+ "Patch File for DeHackEd v3.0",
+ NULL
+};
+
+// deh_ammo.c:
+extern deh_section_t deh_section_ammo;
+// deh_cheat.c:
+extern deh_section_t deh_section_cheat;
+// deh_frame.c:
+extern deh_section_t deh_section_frame;
+// deh_misc.c:
+extern deh_section_t deh_section_misc;
+// deh_ptr.c:
+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_thing.c:
+extern deh_section_t deh_section_thing;
+// deh_weapon.c:
+extern deh_section_t deh_section_weapon;
+
+//
+// List of section types:
+//
+
+deh_section_t *deh_section_types[] =
+{
+ &deh_section_ammo,
+ &deh_section_cheat,
+ &deh_section_frame,
+ &deh_section_misc,
+ &deh_section_pointer,
+ &deh_section_sound,
+ &deh_section_text,
+ &deh_section_thing,
+ &deh_section_weapon,
+ NULL
+};
+
--- a/src/doom/deh_io.c
+++ /dev/null
@@ -1,211 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Dehacked I/O code (does all reads from dehacked files)
-//
-//-----------------------------------------------------------------------------
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "i_system.h"
-#include "z_zone.h"
-
-#include "deh_defs.h"
-#include "deh_io.h"
-
-struct deh_context_s
-{
- FILE *stream;
- char *filename;
- int linenum;
- boolean last_was_newline;
- char *readbuffer;
- int readbuffer_size;
-};
-
-// Open a dehacked file for reading
-// Returns NULL if open failed
-
-deh_context_t *DEH_OpenFile(char *filename)
-{
- FILE *fstream;
- deh_context_t *context;
-
- fstream = fopen(filename, "r");
-
- if (fstream == NULL)
- return NULL;
-
- context = Z_Malloc(sizeof(*context), PU_STATIC, NULL);
- context->stream = fstream;
-
- // Initial read buffer size of 128 bytes
-
- context->readbuffer_size = 128;
- context->readbuffer = Z_Malloc(context->readbuffer_size, PU_STATIC, NULL);
- context->filename = filename;
- context->linenum = 0;
- context->last_was_newline = true;
-
- return context;
-}
-
-// Close dehacked file
-
-void DEH_CloseFile(deh_context_t *context)
-{
- fclose(context->stream);
- Z_Free(context->readbuffer);
- Z_Free(context);
-}
-
-// Reads a single character from a dehacked file
-
-int DEH_GetChar(deh_context_t *context)
-{
- int result;
-
- // Read characters, but ignore carriage returns
- // Essentially this is a DOS->Unix conversion
-
- do
- {
- if (feof(context->stream))
- {
- // end of file
-
- result = -1;
- }
- else
- {
- result = fgetc(context->stream);
- }
-
- } while (result == '\r');
-
- // Track the current line number
-
- if (context->last_was_newline)
- {
- ++context->linenum;
- }
-
- context->last_was_newline = result == '\n';
-
- return result;
-}
-
-// Increase the read buffer size
-
-static void IncreaseReadBuffer(deh_context_t *context)
-{
- char *newbuffer;
- int newbuffer_size;
-
- newbuffer_size = context->readbuffer_size * 2;
- newbuffer = Z_Malloc(newbuffer_size, PU_STATIC, NULL);
-
- memcpy(newbuffer, context->readbuffer, context->readbuffer_size);
-
- Z_Free(context->readbuffer);
-
- context->readbuffer = newbuffer;
- context->readbuffer_size = newbuffer_size;
-}
-
-// Read a whole line
-
-char *DEH_ReadLine(deh_context_t *context)
-{
- int c;
- int pos;
-
- for (pos = 0;;)
- {
- c = DEH_GetChar(context);
-
- if (c < 0)
- {
- // end of file
-
- return NULL;
- }
-
- // cope with lines of any length: increase the buffer size
-
- if (pos >= context->readbuffer_size)
- {
- IncreaseReadBuffer(context);
- }
-
- if (c == '\n')
- {
- // end of line: a full line has been read
-
- context->readbuffer[pos] = '\0';
- break;
- }
- else if (c != '\0')
- {
- // normal character; don't allow NUL characters to be
- // added.
-
- context->readbuffer[pos] = (char) c;
- ++pos;
- }
- }
-
- return context->readbuffer;
-}
-
-void DEH_Warning(deh_context_t *context, char *msg, ...)
-{
- va_list args;
-
- va_start(args, msg);
-
- fprintf(stderr, "%s:%i: warning: ", context->filename, context->linenum);
- vfprintf(stderr, msg, args);
- fprintf(stderr, "\n");
-
- va_end(args);
-}
-
-void DEH_Error(deh_context_t *context, char *msg, ...)
-{
- va_list args;
-
- va_start(args, msg);
-
- fprintf(stderr, "%s:%i: ", context->filename, context->linenum);
- vfprintf(stderr, msg, args);
- fprintf(stderr, "\n");
-
- va_end(args);
-
- I_Error("Error parsing dehacked file");
-}
-
-
--- a/src/doom/deh_io.h
+++ /dev/null
@@ -1,40 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Dehacked I/O code (does all reads from dehacked files)
-//
-//-----------------------------------------------------------------------------
-
-#ifndef DEH_IO_H
-#define DEH_IO_H
-
-#include "deh_defs.h"
-
-deh_context_t *DEH_OpenFile(char *filename);
-void DEH_CloseFile(deh_context_t *context);
-int DEH_GetChar(deh_context_t *context);
-char *DEH_ReadLine(deh_context_t *context);
-void DEH_Error(deh_context_t *context, char *msg, ...);
-void DEH_Warning(deh_context_t *context, char *msg, ...);
-
-#endif /* #ifndef DEH_IO_H */
-
--- a/src/doom/deh_main.c
+++ /dev/null
@@ -1,423 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Main dehacked code
-//
-//-----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "doomtype.h"
-#include "d_iwad.h"
-#include "m_argv.h"
-
-#include "deh_defs.h"
-#include "deh_io.h"
-
-static char *deh_signatures[] =
-{
- "Patch File for DeHackEd v2.3",
- "Patch File for DeHackEd v3.0",
-};
-
-// deh_ammo.c:
-extern deh_section_t deh_section_ammo;
-// deh_cheat.c:
-extern deh_section_t deh_section_cheat;
-// deh_frame.c:
-extern deh_section_t deh_section_frame;
-// deh_misc.c:
-extern deh_section_t deh_section_misc;
-// deh_ptr.c:
-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_thing.c:
-extern deh_section_t deh_section_thing;
-// deh_weapon.c:
-extern deh_section_t deh_section_weapon;
-
-// If true, we can do long string replacements.
-
-boolean deh_allow_long_strings = false;
-
-// If true, we can do cheat replacements longer than the originals.
-
-boolean deh_allow_long_cheats = false;
-
-// If false, dehacked cheat replacements are ignored.
-
-boolean deh_apply_cheats = true;
-
-//
-// List of section types:
-//
-
-static deh_section_t *section_types[] =
-{
- &deh_section_ammo,
- &deh_section_cheat,
- &deh_section_frame,
- &deh_section_misc,
- &deh_section_pointer,
- &deh_section_sound,
- &deh_section_text,
- &deh_section_thing,
- &deh_section_weapon,
-};
-
-void DEH_Checksum(md5_digest_t digest)
-{
- md5_context_t md5_context;
- unsigned int i;
-
- MD5_Init(&md5_context);
-
- for (i=0; i<arrlen(section_types); ++i)
- {
- if (section_types[i]->md5_hash != NULL)
- {
- section_types[i]->md5_hash(&md5_context);
- }
- }
-
- MD5_Final(digest, &md5_context);
-}
-
-// Called on startup to call the Init functions
-
-static void InitializeSections(void)
-{
- unsigned int i;
-
- for (i=0; i<arrlen(section_types); ++i)
- {
- if (section_types[i]->init != NULL)
- {
- section_types[i]->init();
- }
- }
-}
-
-// Given a section name, get the section structure which corresponds
-
-static deh_section_t *GetSectionByName(char *name)
-{
- unsigned int i;
-
- for (i=0; i<arrlen(section_types); ++i)
- {
- if (!strcasecmp(section_types[i]->name, name))
- {
- return section_types[i];
- }
- }
-
- return NULL;
-}
-
-// Is the string passed just whitespace?
-
-static boolean IsWhitespace(char *s)
-{
- for (; *s; ++s)
- {
- if (!isspace(*s))
- return false;
- }
-
- return true;
-}
-
-// Strip whitespace from the start and end of a string
-
-static char *CleanString(char *s)
-{
- char *strending;
-
- // Leading whitespace
-
- while (*s && isspace(*s))
- ++s;
-
- // Trailing whitespace
-
- strending = s + strlen(s) - 1;
-
- while (strlen(s) > 0 && isspace(*strending))
- {
- *strending = '\0';
- --strending;
- }
-
- return s;
-}
-
-// This pattern is used a lot of times in different sections,
-// an assignment is essentially just a statement of the form:
-//
-// Variable Name = Value
-//
-// The variable name can include spaces or any other characters.
-// The string is split on the '=', essentially.
-//
-// Returns true if read correctly
-
-boolean DEH_ParseAssignment(char *line, char **variable_name, char **value)
-{
- char *p;
-
- // find the equals
-
- p = strchr(line, '=');
-
- if (p == NULL && p-line > 2)
- {
- return false;
- }
-
- // variable name at the start
- // turn the '=' into a \0 to terminate the string here
-
- *p = '\0';
- *variable_name = CleanString(line);
-
- // value immediately follows the '='
-
- *value = CleanString(p+1);
-
- return true;
-}
-
-static boolean CheckSignatures(deh_context_t *context)
-{
- size_t i;
- char *line;
-
- // Read the first line
-
- line = DEH_ReadLine(context);
-
- if (line == NULL)
- {
- return false;
- }
-
- // Check all signatures to see if one matches
-
- for (i=0; i<arrlen(deh_signatures); ++i)
- {
- if (!strcmp(deh_signatures[i], line))
- {
- return true;
- }
- }
-
- return false;
-}
-
-// Parses a comment string in a dehacked file.
-
-static void DEH_ParseComment(char *comment)
-{
- // Allow comments containing this special value to allow string
- // replacements longer than those permitted by DOS dehacked.
- // This allows us to use a dehacked patch for doing string
- // replacements for emulating Chex Quest.
- //
- // If you use this, your dehacked patch may not work in Vanilla
- // Doom.
-
- if (strstr(comment, "*allow-long-strings*") != NULL)
- {
- deh_allow_long_strings = true;
- }
-
- // Allow magic comments to allow longer cheat replacements than
- // those permitted by DOS dehacked. This is also for Chex
- // Quest.
-
- if (strstr(comment, "*allow-long-cheats*") != NULL)
- {
- deh_allow_long_cheats = true;
- }
-}
-
-// Parses a dehacked file by reading from the context
-
-static void DEH_ParseContext(deh_context_t *context)
-{
- deh_section_t *current_section = NULL;
- char section_name[20];
- void *tag = NULL;
- char *line;
-
- // Read the header and check it matches the signature
-
- if (!CheckSignatures(context))
- {
- DEH_Error(context, "This is not a valid dehacked patch file!");
- }
-
- deh_allow_long_strings = false;
- deh_allow_long_cheats = false;
-
- // Read the file
-
- for (;;)
- {
- // read a new line
-
- line = DEH_ReadLine(context);
-
- // end of file?
-
- if (line == NULL)
- return;
-
- while (line[0] != '\0' && isspace(line[0]))
- ++line;
-
- if (line[0] == '#')
- {
- // comment
-
- DEH_ParseComment(line);
- continue;
- }
-
- if (IsWhitespace(line))
- {
- if (current_section != NULL)
- {
- // end of section
-
- if (current_section->end != NULL)
- {
- current_section->end(context, tag);
- }
-
- //printf("end %s tag\n", current_section->name);
- current_section = NULL;
- }
- }
- else
- {
- if (current_section != NULL)
- {
- // parse this line
-
- current_section->line_parser(context, line, tag);
- }
- else
- {
- // possibly the start of a new section
-
- sscanf(line, "%19s", section_name);
-
- current_section = GetSectionByName(section_name);
-
- if (current_section != NULL)
- {
- tag = current_section->start(context, line);
- //printf("started %s tag\n", section_name);
- }
- else
- {
- //printf("unknown section name %s\n", section_name);
- }
- }
- }
- }
-}
-
-// Parses a dehacked file
-
-int DEH_LoadFile(char *filename)
-{
- deh_context_t *context;
-
- printf(" loading %s\n", filename);
-
- context = DEH_OpenFile(filename);
-
- if (context == NULL)
- {
- fprintf(stderr, "DEH_LoadFile: Unable to open %s\n", filename);
- return 0;
- }
-
- DEH_ParseContext(context);
-
- DEH_CloseFile(context);
-
- return 1;
-}
-
-// Checks the command line for -deh argument
-
-void DEH_Init(void)
-{
- char *filename;
- int p;
-
- InitializeSections();
-
- //!
- // @category mod
- //
- // Ignore cheats in dehacked files.
- //
-
- if (M_CheckParm("-nocheats") > 0)
- {
- deh_apply_cheats = false;
- }
-
- //!
- // @arg <files>
- // @category mod
- //
- // Load the given dehacked patch(es)
- //
-
- p = M_CheckParm("-deh");
-
- if (p > 0)
- {
- ++p;
-
- while (p < myargc && myargv[p][0] != '-')
- {
- filename = D_TryFindWADByName(myargv[p]);
- DEH_LoadFile(filename);
- ++p;
- }
- }
-}
-
-
--- a/src/doom/deh_main.h
+++ /dev/null
@@ -1,54 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Dehacked entrypoint and common code
-//
-//-----------------------------------------------------------------------------
-
-#ifndef DEH_MAIN_H
-#define DEH_MAIN_H
-
-#include "doomtype.h"
-#include "doomfeatures.h"
-#include "md5.h"
-#include "deh_str.h"
-
-// These are the limits that dehacked uses (from dheinit.h in the dehacked
-// source). If these limits are exceeded, it does not generate an error, but
-// a warning is displayed.
-
-#define DEH_VANILLA_NUMSTATES 966
-#define DEH_VANILLA_NUMSFX 107
-
-void DEH_Init(void);
-int DEH_LoadFile(char *filename);
-
-boolean DEH_ParseAssignment(char *line, char **variable_name, char **value);
-
-void DEH_Checksum(md5_digest_t digest);
-
-extern boolean deh_allow_long_strings;
-extern boolean deh_allow_long_cheats;
-extern boolean deh_apply_cheats;
-
-#endif /* #ifndef DEH_MAIN_H */
-
--- a/src/doom/deh_mapping.c
+++ /dev/null
@@ -1,133 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Dehacked "mapping" code
-// Allows the fields in structures to be mapped out and accessed by
-// name
-//
-//-----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "doomtype.h"
-#include "i_system.h"
-#include "deh_mapping.h"
-
-//
-// Set the value of a particular field in a structure by name
-//
-
-boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
- void *structptr, char *name, int value)
-{
- int i;
-
- for (i=0; mapping->entries[i].name != NULL; ++i)
- {
- deh_mapping_entry_t *entry = &mapping->entries[i];
-
- if (!strcasecmp(entry->name, name))
- {
- void *location;
-
- if (entry->location == NULL)
- {
- DEH_Warning(context, "Field '%s' is unsupported", name);
- return false;
- }
-
- location = (uint8_t *)structptr + ((uint8_t *)entry->location - (uint8_t *)mapping->base);
-
- // printf("Setting %p::%s to %i (%i bytes)\n",
- // structptr, name, value, entry->size);
-
- switch (entry->size)
- {
- case 1:
- * ((uint8_t *) location) = value;
- break;
- case 2:
- * ((uint16_t *) location) = value;
- break;
- case 4:
- * ((uint32_t *) location) = value;
- break;
- default:
- DEH_Error(context, "Unknown field type for '%s' (BUG)", name);
- return false;
- }
-
- return true;
- }
- }
-
- // field with this name not found
-
- DEH_Warning(context, "Field named '%s' not found", name);
-
- return false;
-}
-
-void DEH_StructMD5Sum(md5_context_t *context, deh_mapping_t *mapping,
- void *structptr)
-{
- int i;
-
- // Go through each mapping
-
- for (i=0; mapping->entries[i].name != NULL; ++i)
- {
- deh_mapping_entry_t *entry = &mapping->entries[i];
- void *location;
-
- if (entry->location == NULL)
- {
- // Unsupported field
-
- continue;
- }
-
- // Add in data for this field
-
- location = (uint8_t *)structptr + ((uint8_t *)entry->location - (uint8_t *)mapping->base);
-
- switch (entry->size)
- {
- case 1:
- MD5_UpdateInt32(context, *((uint8_t *) location));
- break;
- case 2:
- MD5_UpdateInt32(context, *((uint16_t *) location));
- break;
- case 4:
- MD5_UpdateInt32(context, *((uint32_t *) location));
- break;
- default:
- I_Error("Unknown dehacked mapping field type for '%s' (BUG)",
- entry->name);
- break;
- }
- }
-}
-
--- a/src/doom/deh_mapping.h
+++ /dev/null
@@ -1,90 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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.
-//
-//-----------------------------------------------------------------------------
-//
-// Dehacked "mapping" code
-// Allows the fields in structures to be mapped out and accessed by
-// name
-//
-//-----------------------------------------------------------------------------
-
-#ifndef DEH_MAPPING_H
-#define DEH_MAPPING_H
-
-#include "doomtype.h"
-#include "deh_io.h"
-#include "md5.h"
-
-#define DEH_BEGIN_MAPPING(mapping_name, structname) \
- static structname deh_mapping_base; \
- static deh_mapping_t mapping_name = \
- { \
- &deh_mapping_base, \
- {
-
-#define DEH_MAPPING(deh_name, fieldname) \
- {deh_name, &deh_mapping_base.fieldname, \
- sizeof(deh_mapping_base.fieldname)},
-
-#define DEH_UNSUPPORTED_MAPPING(deh_name) \
- {deh_name, NULL, -1},
-
-#define DEH_END_MAPPING \
- {NULL, NULL, -1} \
- } \
- };
-
-
-
-#define MAX_MAPPING_ENTRIES 32
-
-typedef struct deh_mapping_s deh_mapping_t;
-typedef struct deh_mapping_entry_s deh_mapping_entry_t;
-
-struct deh_mapping_entry_s
-{
- // field name
-
- char *name;
-
- // location relative to the base in the deh_mapping_t struct
- // If this is NULL, it is an unsupported mapping
-
- void *location;
-
- // field size
-
- int size;
-};
-
-struct deh_mapping_s
-{
- void *base;
- deh_mapping_entry_t entries[MAX_MAPPING_ENTRIES];
-};
-
-boolean DEH_SetMapping(deh_context_t *context, deh_mapping_t *mapping,
- void *structptr, char *name, int value);
-void DEH_StructMD5Sum(md5_context_t *context, deh_mapping_t *mapping,
- void *structptr);
-
-#endif /* #ifndef DEH_MAPPING_H */
-
--- a/src/doom/deh_text.c
+++ /dev/null
@@ -1,127 +1,0 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2005 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 "z_zone.h"
-
-#include "deh_defs.h"
-#include "deh_io.h"
-#include "deh_main.h"
-
-// Given a string length, find the maximum length of a
-// string that can replace it.
-
-static int TXT_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 *from_text, *to_text;
- int fromlen, tolen;
- int i;
-
- if (sscanf(line, "Text %i %i", &fromlen, &tolen) != 2)
- {
- DEH_Warning(context, "Parse error on section start");
- return NULL;
- }
-
- // Only allow string replacements that are possible in Vanilla Doom.
- // Chocolate Doom is unforgiving!
-
- if (!deh_allow_long_strings && tolen > TXT_MaxStringLength(fromlen))
- {
- DEH_Error(context, "Replacement string is longer than the maximum "
- "possible in doom.exe");
- return NULL;
- }
-
- from_text = Z_Malloc(fromlen + 1, PU_STATIC, NULL);
- to_text = Z_Malloc(tolen + 1, PU_STATIC, NULL);
-
- // read in the "from" text
-
- for (i=0; i<fromlen; ++i)
- {
- int c;
-
- c = DEH_GetChar(context);
-
- from_text[i] = c;
- }
-
- from_text[fromlen] = '\0';
-
- // read in the "to" text
-
- for (i=0; i<tolen; ++i)
- {
- int c;
-
- c = DEH_GetChar(context);
-
- to_text[i] = c;
- }
- to_text[tolen] = '\0';
-
- DEH_AddStringReplacement(from_text, to_text);
-
- return NULL;
-}
-
-static void DEH_TextParseLine(deh_context_t *context, char *line, void *tag)
-{
- // not used
-}
-
-deh_section_t deh_section_text =
-{
- "Text",
- NULL,
- DEH_TextStart,
- DEH_TextParseLine,
- NULL,
- NULL,
-};
-