From 37865c5d5b53fd0427b6f22d0a13f830a74c3064 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 7 Sep 2008 21:03:09 +0000 Subject: Move dehacked code to doom/. Split dehacked string replacement code into common code and remove dependencies on deh_main.h. Subversion-branch: /branches/raven-branch Subversion-revision: 1210 --- src/Makefile.am | 14 +- src/deh_ammo.c | 111 -------------- src/deh_cheat.c | 148 ------------------ src/deh_defs.h | 68 --------- src/deh_frame.c | 169 -------------------- src/deh_io.c | 212 ------------------------- src/deh_io.h | 40 ----- src/deh_main.c | 408 ------------------------------------------------- src/deh_main.h | 66 -------- src/deh_mapping.c | 133 ---------------- src/deh_mapping.h | 90 ----------- src/deh_misc.c | 237 ---------------------------- src/deh_misc.h | 92 ----------- src/deh_ptr.c | 151 ------------------ src/deh_sound.c | 113 -------------- src/deh_str.c | 180 ++++++++++++++++++++++ src/deh_str.h | 46 ++++++ src/deh_text.c | 254 ------------------------------ src/deh_thing.c | 140 ----------------- src/deh_weapon.c | 109 ------------- src/doom/Makefile.am | 18 ++- src/doom/deh_ammo.c | 111 ++++++++++++++ src/doom/deh_cheat.c | 148 ++++++++++++++++++ src/doom/deh_defs.h | 68 +++++++++ src/doom/deh_frame.c | 169 ++++++++++++++++++++ src/doom/deh_io.c | 212 +++++++++++++++++++++++++ src/doom/deh_io.h | 40 +++++ src/doom/deh_main.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++++ src/doom/deh_main.h | 53 +++++++ src/doom/deh_mapping.c | 133 ++++++++++++++++ src/doom/deh_mapping.h | 90 +++++++++++ src/doom/deh_misc.c | 237 ++++++++++++++++++++++++++++ src/doom/deh_misc.h | 92 +++++++++++ src/doom/deh_ptr.c | 151 ++++++++++++++++++ src/doom/deh_sound.c | 113 ++++++++++++++ src/doom/deh_text.c | 126 +++++++++++++++ src/doom/deh_thing.c | 140 +++++++++++++++++ src/doom/deh_weapon.c | 109 +++++++++++++ src/i_pcsound.c | 2 +- src/i_sdlmusic.c | 2 +- src/i_sdlsound.c | 2 +- src/i_system.c | 2 +- src/i_video.c | 2 +- src/m_config.c | 2 +- src/m_misc.c | 2 +- src/net_client.c | 1 + src/s_sound.c | 2 +- src/v_video.c | 2 +- 48 files changed, 2654 insertions(+), 2564 deletions(-) delete mode 100644 src/deh_ammo.c delete mode 100644 src/deh_cheat.c delete mode 100644 src/deh_defs.h delete mode 100644 src/deh_frame.c delete mode 100644 src/deh_io.c delete mode 100644 src/deh_io.h delete mode 100644 src/deh_main.c delete mode 100644 src/deh_main.h delete mode 100644 src/deh_mapping.c delete mode 100644 src/deh_mapping.h delete mode 100644 src/deh_misc.c delete mode 100644 src/deh_misc.h delete mode 100644 src/deh_ptr.c delete mode 100644 src/deh_sound.c create mode 100644 src/deh_str.c create mode 100644 src/deh_str.h delete mode 100644 src/deh_text.c delete mode 100644 src/deh_thing.c delete mode 100644 src/deh_weapon.c create mode 100644 src/doom/deh_ammo.c create mode 100644 src/doom/deh_cheat.c create mode 100644 src/doom/deh_defs.h create mode 100644 src/doom/deh_frame.c create mode 100644 src/doom/deh_io.c create mode 100644 src/doom/deh_io.h create mode 100644 src/doom/deh_main.c create mode 100644 src/doom/deh_main.h create mode 100644 src/doom/deh_mapping.c create mode 100644 src/doom/deh_mapping.h create mode 100644 src/doom/deh_misc.c create mode 100644 src/doom/deh_misc.h create mode 100644 src/doom/deh_ptr.c create mode 100644 src/doom/deh_sound.c create mode 100644 src/doom/deh_text.c create mode 100644 src/doom/deh_thing.c create mode 100644 src/doom/deh_weapon.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a91de106..9e751dd9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,19 +61,7 @@ z_zone.c z_zone.h # source files needed for FEATURE_DEHACKED FEATURE_DEHACKED_SOURCE_FILES= \ -deh_ammo.c \ -deh_cheat.c \ -deh_defs.h \ -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 +deh_str.c deh_str.h # source files needed for FEATURE_MULTIPLAYER diff --git a/src/deh_ammo.c b/src/deh_ammo.c deleted file mode 100644 index eb26ef75..00000000 --- a/src/deh_ammo.c +++ /dev/null @@ -1,111 +0,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 "Ammo" sections in dehacked files -// -//----------------------------------------------------------------------------- - -#include -#include -#include - -#include "doomtype.h" -#include "deh_defs.h" -#include "deh_io.h" -#include "deh_main.h" -#include "p_local.h" - -static void *DEH_AmmoStart(deh_context_t *context, char *line) -{ - int ammo_number = 0; - - if (sscanf(line, "Ammo %i", &ammo_number) != 1) - { - DEH_Warning(context, "Parse error on section start"); - return NULL; - } - - if (ammo_number < 0 || ammo_number >= NUMAMMO) - { - DEH_Warning(context, "Invalid ammo number: %i", ammo_number); - return NULL; - } - - return &maxammo[ammo_number]; -} - -static void DEH_AmmoParseLine(deh_context_t *context, char *line, void *tag) -{ - char *variable_name, *value; - int ivalue; - int ammo_number; - - if (tag == NULL) - return; - - ammo_number = ((int *) tag) - maxammo; - - // Parse the assignment - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - - DEH_Warning(context, "Failed to parse assignment"); - return; - } - - ivalue = atoi(value); - - // maxammo - - if (!strcasecmp(variable_name, "Per ammo")) - clipammo[ammo_number] = ivalue; - else if (!strcasecmp(variable_name, "Max ammo")) - maxammo[ammo_number] = ivalue; - else - { - DEH_Warning(context, "Field named '%s' not found", variable_name); - } -} - -static void DEH_AmmoMD5Hash(md5_context_t *context) -{ - int i; - - for (i=0; i - -#include "doomtype.h" - -#include "deh_defs.h" -#include "deh_io.h" -#include "deh_main.h" -#include "am_map.h" -#include "st_stuff.h" - -typedef struct -{ - char *name; - cheatseq_t *seq; -} deh_cheat_t; - -static deh_cheat_t allcheats[] = -{ - {"Change music", &cheat_mus }, - {"Chainsaw", &cheat_choppers }, - {"God mode", &cheat_god }, - {"Ammo & Keys", &cheat_ammo }, - {"Ammo", &cheat_ammonokey }, - {"No Clipping 1", &cheat_noclip }, - {"No Clipping 2", &cheat_commercial_noclip }, - {"Invincibility", &cheat_powerup[0] }, - {"Berserk", &cheat_powerup[1] }, - {"Invisibility", &cheat_powerup[2] }, - {"Radiation Suit", &cheat_powerup[3] }, - {"Auto-map", &cheat_powerup[4] }, - {"Lite-Amp Goggles", &cheat_powerup[5] }, - {"BEHOLD menu", &cheat_powerup[6] }, - {"Level Warp", &cheat_clev }, - {"Player Position", &cheat_mypos }, - {"Map cheat", &cheat_amap }, -}; - -static deh_cheat_t *FindCheatByName(char *name) -{ - size_t i; - - for (i=0; i= cheat->seq->sequence_len) - { - DEH_Warning(context, "Cheat sequence longer than supported by " - "Vanilla dehacked"); - break; - } - - cheat->seq->sequence[i] = unsvalue[i]; - ++i; - - // Absolute limit - don't exceed - - if (i >= MAX_CHEAT_LEN - cheat->seq->parameter_chars) - { - DEH_Error(context, "Cheat sequence too long!"); - return; - } - } - - cheat->seq->sequence[i] = '\0'; -} - -deh_section_t deh_section_cheat = -{ - "Cheat", - NULL, - DEH_CheatStart, - DEH_CheatParseLine, - NULL, - NULL, -}; - diff --git a/src/deh_defs.h b/src/deh_defs.h deleted file mode 100644 index a6650544..00000000 --- a/src/deh_defs.h +++ /dev/null @@ -1,68 +0,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 initialise 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 */ - - diff --git a/src/deh_frame.c b/src/deh_frame.c deleted file mode 100644 index 3972f8df..00000000 --- a/src/deh_frame.c +++ /dev/null @@ -1,169 +0,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 "Frame" sections in dehacked files -// -//----------------------------------------------------------------------------- - -#include - -#include "doomtype.h" -#include "d_items.h" -#include "info.h" - -#include "deh_defs.h" -#include "deh_io.h" -#include "deh_main.h" -#include "deh_mapping.h" - -DEH_BEGIN_MAPPING(state_mapping, state_t) - DEH_MAPPING("Sprite number", sprite) - DEH_MAPPING("Sprite subnumber", frame) - DEH_MAPPING("Duration", tics) - DEH_MAPPING("Next frame", nextstate) - DEH_MAPPING("Unknown 1", misc1) - DEH_MAPPING("Unknown 2", misc2) - DEH_UNSUPPORTED_MAPPING("Codep frame") -DEH_END_MAPPING - -static void *DEH_FrameStart(deh_context_t *context, char *line) -{ - int frame_number = 0; - state_t *state; - - if (sscanf(line, "Frame %i", &frame_number) != 1) - { - DEH_Warning(context, "Parse error on section start"); - return NULL; - } - - if (frame_number < 0 || frame_number >= NUMSTATES) - { - DEH_Warning(context, "Invalid frame number: %i", frame_number); - return NULL; - } - - if (frame_number >= DEH_VANILLA_NUMSTATES) - { - DEH_Warning(context, "Attempt to modify frame %i: this will cause " - "problems in Vanilla dehacked.", frame_number); - } - - state = &states[frame_number]; - - return state; -} - -// Simulate a frame overflow: Doom has 967 frames in the states[] array, but -// DOS dehacked internally only allocates memory for 966. As a result, -// attempts to set frame 966 (the last frame) will overflow the dehacked -// array and overwrite the weaponinfo[] array instead. -// -// This is noticable in Batman Doom where it is impossible to switch weapons -// away from the fist once selected. - -static void DEH_FrameOverflow(deh_context_t *context, char *varname, int value) -{ - if (!strcasecmp(varname, "Duration")) - { - weaponinfo[0].ammo = value; - } - else if (!strcasecmp(varname, "Codep frame")) - { - weaponinfo[0].upstate = value; - } - else if (!strcasecmp(varname, "Next frame")) - { - weaponinfo[0].downstate = value; - } - else if (!strcasecmp(varname, "Unknown 1")) - { - weaponinfo[0].readystate = value; - } - else if (!strcasecmp(varname, "Unknown 2")) - { - weaponinfo[0].atkstate = value; - } - else - { - DEH_Error(context, "Unable to simulate frame overflow: field '%s'", - varname); - } -} - -static void DEH_FrameParseLine(deh_context_t *context, char *line, void *tag) -{ - state_t *state; - char *variable_name, *value; - int ivalue; - - if (tag == NULL) - return; - - state = (state_t *) tag; - - // Parse the assignment - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - - DEH_Warning(context, "Failed to parse assignment"); - return; - } - - // all values are integers - - ivalue = atoi(value); - - if (state == &states[NUMSTATES - 1]) - { - DEH_FrameOverflow(context, variable_name, ivalue); - } - else - { - // set the appropriate field - - DEH_SetMapping(context, &state_mapping, state, variable_name, ivalue); - } -} - -static void DEH_FrameMD5Sum(md5_context_t *context) -{ - int i; - - for (i=0; i -#include -#include -#include - -#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; ; ++pos) - { - c = DEH_GetChar(context); - - if (c < 0) - { - // end of file - - return NULL; - } - - if (c == '\0') - { - 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 - { - context->readbuffer[pos] = (char) c; - } - } - - 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"); -} - - diff --git a/src/deh_io.h b/src/deh_io.h deleted file mode 100644 index 061a5a0e..00000000 --- a/src/deh_io.h +++ /dev/null @@ -1,40 +0,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 */ - diff --git a/src/deh_main.c b/src/deh_main.c deleted file mode 100644 index 9d528b0a..00000000 --- a/src/deh_main.c +++ /dev/null @@ -1,408 +0,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 -#include -#include -#include - -#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; - -// -// 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; imd5_hash != NULL) - { - section_types[i]->md5_hash(&md5_context); - } - } - - MD5_Final(digest, &md5_context); -} - -// Called on startup to call the Init functions - -static void InitialiseSections(void) -{ - unsigned int i; - - for (i=0; iinit != 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; iname, 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; iend != 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; - - InitialiseSections(); - - //! - // @arg - // @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; - } - } -} - - diff --git a/src/deh_main.h b/src/deh_main.h deleted file mode 100644 index 388c56de..00000000 --- a/src/deh_main.h +++ /dev/null @@ -1,66 +0,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" - -// 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); - -// deh_text.c: -// -// Used to do dehacked text substitutions throughout the program - -#ifdef FEATURE_DEHACKED - -char *DEH_String(char *s); - -#else - -#define DEH_String(x) (x) - -#endif - -extern boolean deh_allow_long_strings; -extern boolean deh_allow_long_cheats; - -#endif /* #ifndef DEH_MAIN_H */ - diff --git a/src/deh_mapping.c b/src/deh_mapping.c deleted file mode 100644 index b215b128..00000000 --- a/src/deh_mapping.c +++ /dev/null @@ -1,133 +0,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 -#include -#include - -#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; - } - } -} - diff --git a/src/deh_mapping.h b/src/deh_mapping.h deleted file mode 100644 index 4862dec9..00000000 --- a/src/deh_mapping.h +++ /dev/null @@ -1,90 +0,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 */ - diff --git a/src/deh_misc.c b/src/deh_misc.c deleted file mode 100644 index b57d0ef0..00000000 --- a/src/deh_misc.c +++ /dev/null @@ -1,237 +0,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 "Misc" sections in dehacked files -// -//----------------------------------------------------------------------------- - -#include -#include - -#include "doomtype.h" -#include "deh_defs.h" -#include "deh_io.h" -#include "deh_main.h" -#include "deh_misc.h" - -// Dehacked: "Initial Health" -// This is the initial health a player has when starting anew. -// See G_PlayerReborn in g_game.c - -int deh_initial_health = DEH_DEFAULT_INITIAL_HEALTH; - -// Dehacked: "Initial bullets" -// This is the number of bullets the player has when starting anew. -// See G_PlayerReborn in g_game.c - -int deh_initial_bullets = DEH_DEFAULT_INITIAL_BULLETS; - -// Dehacked: "Max Health" -// This is the maximum health that can be reached using medikits -// alone. See P_TouchSpecialThing in p_inter.c - -int deh_max_health = DEH_DEFAULT_MAX_HEALTH; - -// Dehacked: "Max Armor" -// This is the maximum armor which can be reached by picking up -// armor helmets. See P_TouchSpecialThing in p_inter.c - -int deh_max_armor = DEH_DEFAULT_MAX_ARMOR; - -// Dehacked: "Green Armor Class" -// This is the armor class that is given when picking up the green -// armor or an armor helmet. See P_TouchSpecialThing in p_inter.c -// -// DOS dehacked only modifies the behavior of the green armor shirt, -// the armor class set by armor helmets is not affected. - -int deh_green_armor_class = DEH_DEFAULT_GREEN_ARMOR_CLASS; - -// Dehacked: "Blue Armor Class" -// This is the armor class that is given when picking up the blue -// armor or a megasphere. See P_TouchSpecialThing in p_inter.c -// -// DOS dehacked only modifies the MegaArmor behavior and not -// the MegaSphere, which always gives armor type 2. - -int deh_blue_armor_class = DEH_DEFAULT_BLUE_ARMOR_CLASS; - -// Dehacked: "Max soulsphere" -// The maximum health which can be reached by picking up the -// soulsphere. See P_TouchSpecialThing in p_inter.c - -int deh_max_soulsphere = DEH_DEFAULT_MAX_SOULSPHERE; - -// Dehacked: "Soulsphere health" -// The amount of health bonus that picking up a soulsphere -// gives. See P_TouchSpecialThing in p_inter.c - -int deh_soulsphere_health = DEH_DEFAULT_SOULSPHERE_HEALTH; - -// Dehacked: "Megasphere health" -// This is what the health is set to after picking up a -// megasphere. See P_TouchSpecialThing in p_inter.c - -int deh_megasphere_health = DEH_DEFAULT_MEGASPHERE_HEALTH; - -// Dehacked: "God mode health" -// This is what the health value is set to when cheating using -// the IDDQD god mode cheat. See ST_Responder in st_stuff.c - -int deh_god_mode_health = DEH_DEFAULT_GOD_MODE_HEALTH; - -// Dehacked: "IDFA Armor" -// This is what the armor is set to when using the IDFA cheat. -// See ST_Responder in st_stuff.c - -int deh_idfa_armor = DEH_DEFAULT_IDFA_ARMOR; - -// Dehacked: "IDFA Armor Class" -// This is what the armor class is set to when using the IDFA cheat. -// See ST_Responder in st_stuff.c - -int deh_idfa_armor_class = DEH_DEFAULT_IDFA_ARMOR_CLASS; - -// Dehacked: "IDKFA Armor" -// This is what the armor is set to when using the IDKFA cheat. -// See ST_Responder in st_stuff.c - -int deh_idkfa_armor = DEH_DEFAULT_IDKFA_ARMOR; - -// Dehacked: "IDKFA Armor Class" -// This is what the armor class is set to when using the IDKFA cheat. -// See ST_Responder in st_stuff.c - -int deh_idkfa_armor_class = DEH_DEFAULT_IDKFA_ARMOR_CLASS; - -// Dehacked: "BFG Cells/Shot" -// This is the number of CELLs firing the BFG uses up. -// See P_CheckAmmo and A_FireBFG in p_pspr.c - -int deh_bfg_cells_per_shot = DEH_DEFAULT_BFG_CELLS_PER_SHOT; - -// Dehacked: "Monsters infight" -// This controls whether monsters can harm other monsters of the same -// species. For example, whether an imp fireball will damage other -// imps. The value of this in dehacked patches is weird - '202' means -// off, while '221' means on. -// -// See PIT_CheckThing in p_map.c - -int deh_species_infighting = DEH_DEFAULT_SPECIES_INFIGHTING; - -static struct -{ - char *deh_name; - int *value; -} misc_settings[] = { - {"Initial Health", &deh_initial_health}, - {"Initial Bullets", &deh_initial_bullets}, - {"Max Health", &deh_max_health}, - {"Max Armor", &deh_max_armor}, - {"Green Armor Class", &deh_green_armor_class}, - {"Blue Armor Class", &deh_blue_armor_class}, - {"Max Soulsphere", &deh_max_soulsphere}, - {"Soulsphere Health", &deh_soulsphere_health}, - {"Megasphere Health", &deh_megasphere_health}, - {"God Mode Health", &deh_god_mode_health}, - {"IDFA Armor", &deh_idfa_armor}, - {"IDFA Armor Class", &deh_idfa_armor_class}, - {"IDKFA Armor", &deh_idkfa_armor}, - {"IDKFA Armor Class", &deh_idkfa_armor_class}, - {"BFG Cells/Shot", &deh_bfg_cells_per_shot}, -}; - -static void *DEH_MiscStart(deh_context_t *context, char *line) -{ - return NULL; -} - -static void DEH_MiscParseLine(deh_context_t *context, char *line, void *tag) -{ - char *variable_name, *value; - int ivalue; - size_t i; - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - - DEH_Warning(context, "Failed to parse assignment"); - return; - } - - ivalue = atoi(value); - - if (!strcasecmp(variable_name, "Monsters Infight")) - { - // See notes above. - - if (ivalue == 202) - { - deh_species_infighting = 0; - } - else if (ivalue == 221) - { - deh_species_infighting = 1; - } - else - { - DEH_Warning(context, - "Invalid value for 'Monsters Infight': %i", ivalue); - } - - return; - } - - for (i=0; i -#include -#include - -#include "doomtype.h" -#include "info.h" - -#include "deh_defs.h" -#include "deh_io.h" -#include "deh_main.h" - -static actionf_t codeptrs[NUMSTATES]; - -static int CodePointerIndex(actionf_t *ptr) -{ - int i; - - for (i=0; i= NUMSTATES) - { - DEH_Warning(context, "Invalid frame number: %i", frame_number); - return NULL; - } - - return &states[frame_number]; -} - -static void DEH_PointerParseLine(deh_context_t *context, char *line, void *tag) -{ - state_t *state; - char *variable_name, *value; - int ivalue; - - if (tag == NULL) - return; - - state = (state_t *) tag; - - // Parse the assignment - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - DEH_Warning(context, "Failed to parse assignment"); - return; - } - -// printf("Set %s to %s for state\n", variable_name, value); - - // all values are integers - - ivalue = atoi(value); - - // set the appropriate field - - if (!strcasecmp(variable_name, "Codep frame")) - { - if (ivalue < 0 || ivalue >= NUMSTATES) - { - DEH_Warning(context, "Invalid state '%i'", ivalue); - } - else - { - state->action = codeptrs[ivalue]; - } - } - else - { - DEH_Warning(context, "Unknown variable name '%s'", variable_name); - } -} - -static void DEH_PointerMD5Sum(md5_context_t *context) -{ - int i; - - for (i=0; i -#include - -#include "doomfeatures.h" -#include "doomtype.h" -#include "deh_defs.h" -#include "deh_main.h" -#include "deh_mapping.h" -#include "sounds.h" - -DEH_BEGIN_MAPPING(sound_mapping, sfxinfo_t) - DEH_UNSUPPORTED_MAPPING("Offset") - DEH_MAPPING("Zero/One", singularity) - DEH_MAPPING("Value", priority) - DEH_MAPPING("Zero 1", link) - DEH_MAPPING("Zero 2", pitch) - DEH_MAPPING("Zero 3", volume) - DEH_MAPPING("Zero 4", data) - DEH_MAPPING("Neg. One 1", usefulness) - DEH_MAPPING("Neg. One 2", lumpnum) -DEH_END_MAPPING - -static void *DEH_SoundStart(deh_context_t *context, char *line) -{ - int sound_number = 0; - - if (sscanf(line, "Sound %i", &sound_number) != 1) - { - DEH_Warning(context, "Parse error on section start"); - return NULL; - } - - if (sound_number < 0 || sound_number >= NUMSFX) - { - DEH_Warning(context, "Invalid sound number: %i", sound_number); - return NULL; - } - - if (sound_number >= DEH_VANILLA_NUMSFX) - { - DEH_Warning(context, "Attempt to modify SFX %i. This will cause " - "problems in Vanilla dehacked.", sound_number); - } - - return &S_sfx[sound_number]; -} - -static void DEH_SoundParseLine(deh_context_t *context, char *line, void *tag) -{ - sfxinfo_t *sfx; - char *variable_name, *value; - int ivalue; - - if (tag == NULL) - return; - - sfx = (sfxinfo_t *) tag; - - // Parse the assignment - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - DEH_Warning(context, "Failed to parse assignment"); - return; - } - - // all values are integers - - ivalue = atoi(value); - - // Set the field value - - DEH_SetMapping(context, &sound_mapping, sfx, variable_name, ivalue); - -} - -deh_section_t deh_section_sound = -{ - "Sound", - NULL, - DEH_SoundStart, - DEH_SoundParseLine, - NULL, - NULL, -}; - diff --git a/src/deh_str.c b/src/deh_str.c new file mode 100644 index 00000000..d2cc3ae6 --- /dev/null +++ b/src/deh_str.c @@ -0,0 +1,180 @@ +// 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 +#include + +#include "doomtype.h" +#include "deh_str.h" + +#include "z_zone.h" + +typedef struct +{ + char *from_text; + char *to_text; +} deh_substitution_t; + +static deh_substitution_t **hash_table = NULL; +static int hash_table_entries; +static int hash_table_length = -1; + +// This is the algorithm used by glib + +static unsigned int strhash(char *s) +{ + char *p = s; + unsigned int h = *p; + + if (h) + { + for (p += 1; *p; p++) + h = (h << 5) - h + *p; + } + + return h; +} + +// Look up a string to see if it has been replaced with something else +// This will be used throughout the program to substitute text + +char *DEH_String(char *s) +{ + int entry; + + // Fallback if we have not initialised the hash table yet + + if (hash_table_length < 0) + return s; + + entry = strhash(s) % hash_table_length; + + while (hash_table[entry] != NULL) + { + if (!strcmp(hash_table[entry]->from_text, s)) + { + // substitution found! + + return hash_table[entry]->to_text; + } + + entry = (entry + 1) % hash_table_length; + } + + // no substitution found + + return s; +} + +static void InitHashTable(void) +{ + // init hash table + + hash_table_entries = 0; + hash_table_length = 16; + hash_table = Z_Malloc(sizeof(deh_substitution_t *) * hash_table_length, + PU_STATIC, NULL); + memset(hash_table, 0, sizeof(deh_substitution_t *) * hash_table_length); +} + +static void DEH_AddToHashtable(deh_substitution_t *sub); + +static void IncreaseHashtable(void) +{ + deh_substitution_t **old_table; + int old_table_length; + int i; + + // save the old table + + old_table = hash_table; + old_table_length = hash_table_length; + + // double the size + + hash_table_length *= 2; + hash_table = Z_Malloc(sizeof(deh_substitution_t *) * hash_table_length, + PU_STATIC, NULL); + memset(hash_table, 0, sizeof(deh_substitution_t *) * hash_table_length); + + // go through the old table and insert all the old entries + + for (i=0; i 6) + { + IncreaseHashtable(); + } + + // find where to insert it + + entry = strhash(sub->from_text) % hash_table_length; + + while (hash_table[entry] != NULL) + { + entry = (entry + 1) % hash_table_length; + } + + hash_table[entry] = sub; + ++hash_table_entries; +} + +void DEH_AddStringReplacement(char *from_text, char *to_text) +{ + deh_substitution_t *sub; + + // Initialise the hash table if this is the first time + + if (hash_table_length < 0) + { + InitHashTable(); + } + + sub = Z_Malloc(sizeof(*sub), PU_STATIC, 0); + + sub->from_text = from_text; + sub->to_text = to_text; + + DEH_AddToHashtable(sub); +} + diff --git a/src/deh_str.h b/src/deh_str.h new file mode 100644 index 00000000..986536de --- /dev/null +++ b/src/deh_str.h @@ -0,0 +1,46 @@ +// 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 string replacements +// +//----------------------------------------------------------------------------- + +#ifndef DEH_STR_H +#define DEH_STR_H + +#include "doomfeatures.h" + +// Used to do dehacked text substitutions throughout the program + +#ifdef FEATURE_DEHACKED + +char *DEH_String(char *s); +void DEH_AddStringReplacement(char *from_text, char *to_text); + +#else + +#define DEH_String(x) (x) + +#endif + +#endif /* #ifndef DEH_STR_H */ + diff --git a/src/deh_text.c b/src/deh_text.c deleted file mode 100644 index 853e30e4..00000000 --- a/src/deh_text.c +++ /dev/null @@ -1,254 +0,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 - -#include "doomtype.h" - -#include "z_zone.h" - -#include "deh_defs.h" -#include "deh_io.h" -#include "deh_main.h" - -typedef struct -{ - char *from_text; - char *to_text; -} deh_substitution_t; - -static deh_substitution_t **hash_table; -static int hash_table_entries; -static int hash_table_length = -1; - -// This is the algorithm used by glib - -static unsigned int strhash(char *s) -{ - char *p = s; - unsigned int h = *p; - - if (h) - { - for (p += 1; *p; p++) - h = (h << 5) - h + *p; - } - - return h; -} - -// Look up a string to see if it has been replaced with something else -// This will be used throughout the program to substitute text - -char *DEH_String(char *s) -{ - int entry; - - // Fallback if we have not initialised the hash table yet - - if (hash_table_length < 0) - return s; - - entry = strhash(s) % hash_table_length; - - while (hash_table[entry] != NULL) - { - if (!strcmp(hash_table[entry]->from_text, s)) - { - // substitution found! - - return hash_table[entry]->to_text; - } - - entry = (entry + 1) % hash_table_length; - } - - // no substitution found - - return s; -} - -static void DEH_AddToHashtable(deh_substitution_t *sub); - -static void IncreaseHashtable(void) -{ - deh_substitution_t **old_table; - int old_table_length; - int i; - - // save the old table - - old_table = hash_table; - old_table_length = hash_table_length; - - // double the size - - hash_table_length *= 2; - hash_table = Z_Malloc(sizeof(deh_substitution_t *) * hash_table_length, - PU_STATIC, NULL); - memset(hash_table, 0, sizeof(deh_substitution_t *) * hash_table_length); - - // go through the old table and insert all the old entries - - for (i=0; i 6) - { - IncreaseHashtable(); - } - - // find where to insert it - - entry = strhash(sub->from_text) % hash_table_length; - - while (hash_table[entry] != NULL) - { - entry = (entry + 1) % hash_table_length; - } - - hash_table[entry] = sub; - ++hash_table_entries; -} - -// 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_TextInit(void) -{ - // init hash table - - hash_table_entries = 0; - hash_table_length = 16; - hash_table = Z_Malloc(sizeof(deh_substitution_t *) * hash_table_length, - PU_STATIC, NULL); - memset(hash_table, 0, sizeof(deh_substitution_t *) * hash_table_length); -} - -static void *DEH_TextStart(deh_context_t *context, char *line) -{ - deh_substitution_t *sub; - 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; - } - - sub = Z_Malloc(sizeof(deh_substitution_t), PU_STATIC, NULL); - sub->from_text = Z_Malloc(fromlen + 1, PU_STATIC, NULL); - sub->to_text = Z_Malloc(tolen + 1, PU_STATIC, NULL); - - // read in the "from" text - - for (i=0; ifrom_text[i] = c; - } - - sub->from_text[fromlen] = '\0'; - - // read in the "to" text - - for (i=0; ito_text[i] = c; - } - sub->to_text[tolen] = '\0'; - - DEH_AddToHashtable(sub); - - return NULL; -} - -static void DEH_TextParseLine(deh_context_t *context, char *line, void *tag) -{ - // not used -} - -deh_section_t deh_section_text = -{ - "Text", - DEH_TextInit, - DEH_TextStart, - DEH_TextParseLine, - NULL, - NULL, -}; - diff --git a/src/deh_thing.c b/src/deh_thing.c deleted file mode 100644 index 5400ae60..00000000 --- a/src/deh_thing.c +++ /dev/null @@ -1,140 +0,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 "Thing" sections in dehacked files -// -//----------------------------------------------------------------------------- - -#include -#include - -#include "doomtype.h" - -#include "deh_defs.h" -#include "deh_main.h" -#include "deh_mapping.h" - -#include "info.h" - -DEH_BEGIN_MAPPING(thing_mapping, mobjinfo_t) - DEH_MAPPING("ID #", doomednum) - DEH_MAPPING("Initial frame", spawnstate) - DEH_MAPPING("Hit points", spawnhealth) - DEH_MAPPING("First moving frame", seestate) - DEH_MAPPING("Alert sound", seesound) - DEH_MAPPING("Reaction time", reactiontime) - DEH_MAPPING("Attack sound", attacksound) - DEH_MAPPING("Injury frame", painstate) - DEH_MAPPING("Pain chance", painchance) - DEH_MAPPING("Pain sound", painsound) - DEH_MAPPING("Close attack frame", meleestate) - DEH_MAPPING("Far attack frame", missilestate) - DEH_MAPPING("Death frame", deathstate) - DEH_MAPPING("Exploding frame", xdeathstate) - DEH_MAPPING("Death sound", deathsound) - DEH_MAPPING("Speed", speed) - DEH_MAPPING("Width", radius) - DEH_MAPPING("Height", height) - DEH_MAPPING("Mass", mass) - DEH_MAPPING("Missile damage", damage) - DEH_MAPPING("Action sound", activesound) - DEH_MAPPING("Bits", flags) - DEH_MAPPING("Respawn frame", raisestate) -DEH_END_MAPPING - -static void *DEH_ThingStart(deh_context_t *context, char *line) -{ - int thing_number = 0; - mobjinfo_t *mobj; - - if (sscanf(line, "Thing %i", &thing_number) != 1) - { - DEH_Warning(context, "Parse error on section start"); - return NULL; - } - - // dehacked files are indexed from 1 - --thing_number; - - if (thing_number < 0 || thing_number >= NUMMOBJTYPES) - { - DEH_Warning(context, "Invalid thing number: %i", thing_number); - return NULL; - } - - mobj = &mobjinfo[thing_number]; - - return mobj; -} - -static void DEH_ThingParseLine(deh_context_t *context, char *line, void *tag) -{ - mobjinfo_t *mobj; - char *variable_name, *value; - int ivalue; - - if (tag == NULL) - return; - - mobj = (mobjinfo_t *) tag; - - // Parse the assignment - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - - DEH_Warning(context, "Failed to parse assignment"); - return; - } - -// printf("Set %s to %s for mobj\n", variable_name, value); - - // all values are integers - - ivalue = atoi(value); - - // Set the field value - - DEH_SetMapping(context, &thing_mapping, mobj, variable_name, ivalue); -} - -static void DEH_ThingMD5Sum(md5_context_t *context) -{ - int i; - - for (i=0; i -#include - -#include "doomtype.h" - -#include "d_items.h" - -#include "deh_defs.h" -#include "deh_main.h" -#include "deh_mapping.h" - -DEH_BEGIN_MAPPING(weapon_mapping, weaponinfo_t) - DEH_MAPPING("Ammo type", ammo) - DEH_MAPPING("Deselect frame", upstate) - DEH_MAPPING("Select frame", downstate) - DEH_MAPPING("Bobbing frame", readystate) - DEH_MAPPING("Shooting frame", atkstate) - DEH_MAPPING("Firing frame", flashstate) -DEH_END_MAPPING - -static void *DEH_WeaponStart(deh_context_t *context, char *line) -{ - int weapon_number = 0; - - if (sscanf(line, "Weapon %i", &weapon_number) != 1) - { - DEH_Warning(context, "Parse error on section start"); - return NULL; - } - - if (weapon_number < 0 || weapon_number >= NUMWEAPONS) - { - DEH_Warning(context, "Invalid weapon number: %i", weapon_number); - return NULL; - } - - return &weaponinfo[weapon_number]; -} - -static void DEH_WeaponParseLine(deh_context_t *context, char *line, void *tag) -{ - char *variable_name, *value; - weaponinfo_t *weapon; - int ivalue; - - if (tag == NULL) - return; - - weapon = (weaponinfo_t *) tag; - - if (!DEH_ParseAssignment(line, &variable_name, &value)) - { - // Failed to parse - - DEH_Warning(context, "Failed to parse assignment"); - return; - } - - ivalue = atoi(value); - - DEH_SetMapping(context, &weapon_mapping, weapon, variable_name, ivalue); -} - -static void DEH_WeaponMD5Sum(md5_context_t *context) -{ - int i; - - for (i=0; i +#include +#include + +#include "doomtype.h" +#include "deh_defs.h" +#include "deh_io.h" +#include "deh_main.h" +#include "p_local.h" + +static void *DEH_AmmoStart(deh_context_t *context, char *line) +{ + int ammo_number = 0; + + if (sscanf(line, "Ammo %i", &ammo_number) != 1) + { + DEH_Warning(context, "Parse error on section start"); + return NULL; + } + + if (ammo_number < 0 || ammo_number >= NUMAMMO) + { + DEH_Warning(context, "Invalid ammo number: %i", ammo_number); + return NULL; + } + + return &maxammo[ammo_number]; +} + +static void DEH_AmmoParseLine(deh_context_t *context, char *line, void *tag) +{ + char *variable_name, *value; + int ivalue; + int ammo_number; + + if (tag == NULL) + return; + + ammo_number = ((int *) tag) - maxammo; + + // Parse the assignment + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + + DEH_Warning(context, "Failed to parse assignment"); + return; + } + + ivalue = atoi(value); + + // maxammo + + if (!strcasecmp(variable_name, "Per ammo")) + clipammo[ammo_number] = ivalue; + else if (!strcasecmp(variable_name, "Max ammo")) + maxammo[ammo_number] = ivalue; + else + { + DEH_Warning(context, "Field named '%s' not found", variable_name); + } +} + +static void DEH_AmmoMD5Hash(md5_context_t *context) +{ + int i; + + for (i=0; i + +#include "doomtype.h" + +#include "deh_defs.h" +#include "deh_io.h" +#include "deh_main.h" +#include "am_map.h" +#include "st_stuff.h" + +typedef struct +{ + char *name; + cheatseq_t *seq; +} deh_cheat_t; + +static deh_cheat_t allcheats[] = +{ + {"Change music", &cheat_mus }, + {"Chainsaw", &cheat_choppers }, + {"God mode", &cheat_god }, + {"Ammo & Keys", &cheat_ammo }, + {"Ammo", &cheat_ammonokey }, + {"No Clipping 1", &cheat_noclip }, + {"No Clipping 2", &cheat_commercial_noclip }, + {"Invincibility", &cheat_powerup[0] }, + {"Berserk", &cheat_powerup[1] }, + {"Invisibility", &cheat_powerup[2] }, + {"Radiation Suit", &cheat_powerup[3] }, + {"Auto-map", &cheat_powerup[4] }, + {"Lite-Amp Goggles", &cheat_powerup[5] }, + {"BEHOLD menu", &cheat_powerup[6] }, + {"Level Warp", &cheat_clev }, + {"Player Position", &cheat_mypos }, + {"Map cheat", &cheat_amap }, +}; + +static deh_cheat_t *FindCheatByName(char *name) +{ + size_t i; + + for (i=0; i= cheat->seq->sequence_len) + { + DEH_Warning(context, "Cheat sequence longer than supported by " + "Vanilla dehacked"); + break; + } + + cheat->seq->sequence[i] = unsvalue[i]; + ++i; + + // Absolute limit - don't exceed + + if (i >= MAX_CHEAT_LEN - cheat->seq->parameter_chars) + { + DEH_Error(context, "Cheat sequence too long!"); + return; + } + } + + cheat->seq->sequence[i] = '\0'; +} + +deh_section_t deh_section_cheat = +{ + "Cheat", + NULL, + DEH_CheatStart, + DEH_CheatParseLine, + NULL, + NULL, +}; + diff --git a/src/doom/deh_defs.h b/src/doom/deh_defs.h new file mode 100644 index 00000000..a6650544 --- /dev/null +++ b/src/doom/deh_defs.h @@ -0,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 initialise 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 */ + + diff --git a/src/doom/deh_frame.c b/src/doom/deh_frame.c new file mode 100644 index 00000000..3972f8df --- /dev/null +++ b/src/doom/deh_frame.c @@ -0,0 +1,169 @@ +// 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 "Frame" sections in dehacked files +// +//----------------------------------------------------------------------------- + +#include + +#include "doomtype.h" +#include "d_items.h" +#include "info.h" + +#include "deh_defs.h" +#include "deh_io.h" +#include "deh_main.h" +#include "deh_mapping.h" + +DEH_BEGIN_MAPPING(state_mapping, state_t) + DEH_MAPPING("Sprite number", sprite) + DEH_MAPPING("Sprite subnumber", frame) + DEH_MAPPING("Duration", tics) + DEH_MAPPING("Next frame", nextstate) + DEH_MAPPING("Unknown 1", misc1) + DEH_MAPPING("Unknown 2", misc2) + DEH_UNSUPPORTED_MAPPING("Codep frame") +DEH_END_MAPPING + +static void *DEH_FrameStart(deh_context_t *context, char *line) +{ + int frame_number = 0; + state_t *state; + + if (sscanf(line, "Frame %i", &frame_number) != 1) + { + DEH_Warning(context, "Parse error on section start"); + return NULL; + } + + if (frame_number < 0 || frame_number >= NUMSTATES) + { + DEH_Warning(context, "Invalid frame number: %i", frame_number); + return NULL; + } + + if (frame_number >= DEH_VANILLA_NUMSTATES) + { + DEH_Warning(context, "Attempt to modify frame %i: this will cause " + "problems in Vanilla dehacked.", frame_number); + } + + state = &states[frame_number]; + + return state; +} + +// Simulate a frame overflow: Doom has 967 frames in the states[] array, but +// DOS dehacked internally only allocates memory for 966. As a result, +// attempts to set frame 966 (the last frame) will overflow the dehacked +// array and overwrite the weaponinfo[] array instead. +// +// This is noticable in Batman Doom where it is impossible to switch weapons +// away from the fist once selected. + +static void DEH_FrameOverflow(deh_context_t *context, char *varname, int value) +{ + if (!strcasecmp(varname, "Duration")) + { + weaponinfo[0].ammo = value; + } + else if (!strcasecmp(varname, "Codep frame")) + { + weaponinfo[0].upstate = value; + } + else if (!strcasecmp(varname, "Next frame")) + { + weaponinfo[0].downstate = value; + } + else if (!strcasecmp(varname, "Unknown 1")) + { + weaponinfo[0].readystate = value; + } + else if (!strcasecmp(varname, "Unknown 2")) + { + weaponinfo[0].atkstate = value; + } + else + { + DEH_Error(context, "Unable to simulate frame overflow: field '%s'", + varname); + } +} + +static void DEH_FrameParseLine(deh_context_t *context, char *line, void *tag) +{ + state_t *state; + char *variable_name, *value; + int ivalue; + + if (tag == NULL) + return; + + state = (state_t *) tag; + + // Parse the assignment + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + + DEH_Warning(context, "Failed to parse assignment"); + return; + } + + // all values are integers + + ivalue = atoi(value); + + if (state == &states[NUMSTATES - 1]) + { + DEH_FrameOverflow(context, variable_name, ivalue); + } + else + { + // set the appropriate field + + DEH_SetMapping(context, &state_mapping, state, variable_name, ivalue); + } +} + +static void DEH_FrameMD5Sum(md5_context_t *context) +{ + int i; + + for (i=0; i +#include +#include +#include + +#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; ; ++pos) + { + c = DEH_GetChar(context); + + if (c < 0) + { + // end of file + + return NULL; + } + + if (c == '\0') + { + 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 + { + context->readbuffer[pos] = (char) c; + } + } + + 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"); +} + + diff --git a/src/doom/deh_io.h b/src/doom/deh_io.h new file mode 100644 index 00000000..061a5a0e --- /dev/null +++ b/src/doom/deh_io.h @@ -0,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 */ + diff --git a/src/doom/deh_main.c b/src/doom/deh_main.c new file mode 100644 index 00000000..9d528b0a --- /dev/null +++ b/src/doom/deh_main.c @@ -0,0 +1,408 @@ +// 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 +#include +#include +#include + +#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; + +// +// 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; imd5_hash != NULL) + { + section_types[i]->md5_hash(&md5_context); + } + } + + MD5_Final(digest, &md5_context); +} + +// Called on startup to call the Init functions + +static void InitialiseSections(void) +{ + unsigned int i; + + for (i=0; iinit != 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; iname, 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; iend != 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; + + InitialiseSections(); + + //! + // @arg + // @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; + } + } +} + + diff --git a/src/doom/deh_main.h b/src/doom/deh_main.h new file mode 100644 index 00000000..8a0587ff --- /dev/null +++ b/src/doom/deh_main.h @@ -0,0 +1,53 @@ +// 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; + +#endif /* #ifndef DEH_MAIN_H */ + diff --git a/src/doom/deh_mapping.c b/src/doom/deh_mapping.c new file mode 100644 index 00000000..b215b128 --- /dev/null +++ b/src/doom/deh_mapping.c @@ -0,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 +#include +#include + +#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; + } + } +} + diff --git a/src/doom/deh_mapping.h b/src/doom/deh_mapping.h new file mode 100644 index 00000000..4862dec9 --- /dev/null +++ b/src/doom/deh_mapping.h @@ -0,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 */ + diff --git a/src/doom/deh_misc.c b/src/doom/deh_misc.c new file mode 100644 index 00000000..b57d0ef0 --- /dev/null +++ b/src/doom/deh_misc.c @@ -0,0 +1,237 @@ +// 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 "Misc" sections in dehacked files +// +//----------------------------------------------------------------------------- + +#include +#include + +#include "doomtype.h" +#include "deh_defs.h" +#include "deh_io.h" +#include "deh_main.h" +#include "deh_misc.h" + +// Dehacked: "Initial Health" +// This is the initial health a player has when starting anew. +// See G_PlayerReborn in g_game.c + +int deh_initial_health = DEH_DEFAULT_INITIAL_HEALTH; + +// Dehacked: "Initial bullets" +// This is the number of bullets the player has when starting anew. +// See G_PlayerReborn in g_game.c + +int deh_initial_bullets = DEH_DEFAULT_INITIAL_BULLETS; + +// Dehacked: "Max Health" +// This is the maximum health that can be reached using medikits +// alone. See P_TouchSpecialThing in p_inter.c + +int deh_max_health = DEH_DEFAULT_MAX_HEALTH; + +// Dehacked: "Max Armor" +// This is the maximum armor which can be reached by picking up +// armor helmets. See P_TouchSpecialThing in p_inter.c + +int deh_max_armor = DEH_DEFAULT_MAX_ARMOR; + +// Dehacked: "Green Armor Class" +// This is the armor class that is given when picking up the green +// armor or an armor helmet. See P_TouchSpecialThing in p_inter.c +// +// DOS dehacked only modifies the behavior of the green armor shirt, +// the armor class set by armor helmets is not affected. + +int deh_green_armor_class = DEH_DEFAULT_GREEN_ARMOR_CLASS; + +// Dehacked: "Blue Armor Class" +// This is the armor class that is given when picking up the blue +// armor or a megasphere. See P_TouchSpecialThing in p_inter.c +// +// DOS dehacked only modifies the MegaArmor behavior and not +// the MegaSphere, which always gives armor type 2. + +int deh_blue_armor_class = DEH_DEFAULT_BLUE_ARMOR_CLASS; + +// Dehacked: "Max soulsphere" +// The maximum health which can be reached by picking up the +// soulsphere. See P_TouchSpecialThing in p_inter.c + +int deh_max_soulsphere = DEH_DEFAULT_MAX_SOULSPHERE; + +// Dehacked: "Soulsphere health" +// The amount of health bonus that picking up a soulsphere +// gives. See P_TouchSpecialThing in p_inter.c + +int deh_soulsphere_health = DEH_DEFAULT_SOULSPHERE_HEALTH; + +// Dehacked: "Megasphere health" +// This is what the health is set to after picking up a +// megasphere. See P_TouchSpecialThing in p_inter.c + +int deh_megasphere_health = DEH_DEFAULT_MEGASPHERE_HEALTH; + +// Dehacked: "God mode health" +// This is what the health value is set to when cheating using +// the IDDQD god mode cheat. See ST_Responder in st_stuff.c + +int deh_god_mode_health = DEH_DEFAULT_GOD_MODE_HEALTH; + +// Dehacked: "IDFA Armor" +// This is what the armor is set to when using the IDFA cheat. +// See ST_Responder in st_stuff.c + +int deh_idfa_armor = DEH_DEFAULT_IDFA_ARMOR; + +// Dehacked: "IDFA Armor Class" +// This is what the armor class is set to when using the IDFA cheat. +// See ST_Responder in st_stuff.c + +int deh_idfa_armor_class = DEH_DEFAULT_IDFA_ARMOR_CLASS; + +// Dehacked: "IDKFA Armor" +// This is what the armor is set to when using the IDKFA cheat. +// See ST_Responder in st_stuff.c + +int deh_idkfa_armor = DEH_DEFAULT_IDKFA_ARMOR; + +// Dehacked: "IDKFA Armor Class" +// This is what the armor class is set to when using the IDKFA cheat. +// See ST_Responder in st_stuff.c + +int deh_idkfa_armor_class = DEH_DEFAULT_IDKFA_ARMOR_CLASS; + +// Dehacked: "BFG Cells/Shot" +// This is the number of CELLs firing the BFG uses up. +// See P_CheckAmmo and A_FireBFG in p_pspr.c + +int deh_bfg_cells_per_shot = DEH_DEFAULT_BFG_CELLS_PER_SHOT; + +// Dehacked: "Monsters infight" +// This controls whether monsters can harm other monsters of the same +// species. For example, whether an imp fireball will damage other +// imps. The value of this in dehacked patches is weird - '202' means +// off, while '221' means on. +// +// See PIT_CheckThing in p_map.c + +int deh_species_infighting = DEH_DEFAULT_SPECIES_INFIGHTING; + +static struct +{ + char *deh_name; + int *value; +} misc_settings[] = { + {"Initial Health", &deh_initial_health}, + {"Initial Bullets", &deh_initial_bullets}, + {"Max Health", &deh_max_health}, + {"Max Armor", &deh_max_armor}, + {"Green Armor Class", &deh_green_armor_class}, + {"Blue Armor Class", &deh_blue_armor_class}, + {"Max Soulsphere", &deh_max_soulsphere}, + {"Soulsphere Health", &deh_soulsphere_health}, + {"Megasphere Health", &deh_megasphere_health}, + {"God Mode Health", &deh_god_mode_health}, + {"IDFA Armor", &deh_idfa_armor}, + {"IDFA Armor Class", &deh_idfa_armor_class}, + {"IDKFA Armor", &deh_idkfa_armor}, + {"IDKFA Armor Class", &deh_idkfa_armor_class}, + {"BFG Cells/Shot", &deh_bfg_cells_per_shot}, +}; + +static void *DEH_MiscStart(deh_context_t *context, char *line) +{ + return NULL; +} + +static void DEH_MiscParseLine(deh_context_t *context, char *line, void *tag) +{ + char *variable_name, *value; + int ivalue; + size_t i; + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + + DEH_Warning(context, "Failed to parse assignment"); + return; + } + + ivalue = atoi(value); + + if (!strcasecmp(variable_name, "Monsters Infight")) + { + // See notes above. + + if (ivalue == 202) + { + deh_species_infighting = 0; + } + else if (ivalue == 221) + { + deh_species_infighting = 1; + } + else + { + DEH_Warning(context, + "Invalid value for 'Monsters Infight': %i", ivalue); + } + + return; + } + + for (i=0; i +#include +#include + +#include "doomtype.h" +#include "info.h" + +#include "deh_defs.h" +#include "deh_io.h" +#include "deh_main.h" + +static actionf_t codeptrs[NUMSTATES]; + +static int CodePointerIndex(actionf_t *ptr) +{ + int i; + + for (i=0; i= NUMSTATES) + { + DEH_Warning(context, "Invalid frame number: %i", frame_number); + return NULL; + } + + return &states[frame_number]; +} + +static void DEH_PointerParseLine(deh_context_t *context, char *line, void *tag) +{ + state_t *state; + char *variable_name, *value; + int ivalue; + + if (tag == NULL) + return; + + state = (state_t *) tag; + + // Parse the assignment + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + DEH_Warning(context, "Failed to parse assignment"); + return; + } + +// printf("Set %s to %s for state\n", variable_name, value); + + // all values are integers + + ivalue = atoi(value); + + // set the appropriate field + + if (!strcasecmp(variable_name, "Codep frame")) + { + if (ivalue < 0 || ivalue >= NUMSTATES) + { + DEH_Warning(context, "Invalid state '%i'", ivalue); + } + else + { + state->action = codeptrs[ivalue]; + } + } + else + { + DEH_Warning(context, "Unknown variable name '%s'", variable_name); + } +} + +static void DEH_PointerMD5Sum(md5_context_t *context) +{ + int i; + + for (i=0; i +#include + +#include "doomfeatures.h" +#include "doomtype.h" +#include "deh_defs.h" +#include "deh_main.h" +#include "deh_mapping.h" +#include "sounds.h" + +DEH_BEGIN_MAPPING(sound_mapping, sfxinfo_t) + DEH_UNSUPPORTED_MAPPING("Offset") + DEH_MAPPING("Zero/One", singularity) + DEH_MAPPING("Value", priority) + DEH_MAPPING("Zero 1", link) + DEH_MAPPING("Zero 2", pitch) + DEH_MAPPING("Zero 3", volume) + DEH_MAPPING("Zero 4", data) + DEH_MAPPING("Neg. One 1", usefulness) + DEH_MAPPING("Neg. One 2", lumpnum) +DEH_END_MAPPING + +static void *DEH_SoundStart(deh_context_t *context, char *line) +{ + int sound_number = 0; + + if (sscanf(line, "Sound %i", &sound_number) != 1) + { + DEH_Warning(context, "Parse error on section start"); + return NULL; + } + + if (sound_number < 0 || sound_number >= NUMSFX) + { + DEH_Warning(context, "Invalid sound number: %i", sound_number); + return NULL; + } + + if (sound_number >= DEH_VANILLA_NUMSFX) + { + DEH_Warning(context, "Attempt to modify SFX %i. This will cause " + "problems in Vanilla dehacked.", sound_number); + } + + return &S_sfx[sound_number]; +} + +static void DEH_SoundParseLine(deh_context_t *context, char *line, void *tag) +{ + sfxinfo_t *sfx; + char *variable_name, *value; + int ivalue; + + if (tag == NULL) + return; + + sfx = (sfxinfo_t *) tag; + + // Parse the assignment + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + DEH_Warning(context, "Failed to parse assignment"); + return; + } + + // all values are integers + + ivalue = atoi(value); + + // Set the field value + + DEH_SetMapping(context, &sound_mapping, sfx, variable_name, ivalue); + +} + +deh_section_t deh_section_sound = +{ + "Sound", + NULL, + DEH_SoundStart, + DEH_SoundParseLine, + NULL, + NULL, +}; + diff --git a/src/doom/deh_text.c b/src/doom/deh_text.c new file mode 100644 index 00000000..caac59a3 --- /dev/null +++ b/src/doom/deh_text.c @@ -0,0 +1,126 @@ +// 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 + +#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 +#include + +#include "doomtype.h" + +#include "deh_defs.h" +#include "deh_main.h" +#include "deh_mapping.h" + +#include "info.h" + +DEH_BEGIN_MAPPING(thing_mapping, mobjinfo_t) + DEH_MAPPING("ID #", doomednum) + DEH_MAPPING("Initial frame", spawnstate) + DEH_MAPPING("Hit points", spawnhealth) + DEH_MAPPING("First moving frame", seestate) + DEH_MAPPING("Alert sound", seesound) + DEH_MAPPING("Reaction time", reactiontime) + DEH_MAPPING("Attack sound", attacksound) + DEH_MAPPING("Injury frame", painstate) + DEH_MAPPING("Pain chance", painchance) + DEH_MAPPING("Pain sound", painsound) + DEH_MAPPING("Close attack frame", meleestate) + DEH_MAPPING("Far attack frame", missilestate) + DEH_MAPPING("Death frame", deathstate) + DEH_MAPPING("Exploding frame", xdeathstate) + DEH_MAPPING("Death sound", deathsound) + DEH_MAPPING("Speed", speed) + DEH_MAPPING("Width", radius) + DEH_MAPPING("Height", height) + DEH_MAPPING("Mass", mass) + DEH_MAPPING("Missile damage", damage) + DEH_MAPPING("Action sound", activesound) + DEH_MAPPING("Bits", flags) + DEH_MAPPING("Respawn frame", raisestate) +DEH_END_MAPPING + +static void *DEH_ThingStart(deh_context_t *context, char *line) +{ + int thing_number = 0; + mobjinfo_t *mobj; + + if (sscanf(line, "Thing %i", &thing_number) != 1) + { + DEH_Warning(context, "Parse error on section start"); + return NULL; + } + + // dehacked files are indexed from 1 + --thing_number; + + if (thing_number < 0 || thing_number >= NUMMOBJTYPES) + { + DEH_Warning(context, "Invalid thing number: %i", thing_number); + return NULL; + } + + mobj = &mobjinfo[thing_number]; + + return mobj; +} + +static void DEH_ThingParseLine(deh_context_t *context, char *line, void *tag) +{ + mobjinfo_t *mobj; + char *variable_name, *value; + int ivalue; + + if (tag == NULL) + return; + + mobj = (mobjinfo_t *) tag; + + // Parse the assignment + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + + DEH_Warning(context, "Failed to parse assignment"); + return; + } + +// printf("Set %s to %s for mobj\n", variable_name, value); + + // all values are integers + + ivalue = atoi(value); + + // Set the field value + + DEH_SetMapping(context, &thing_mapping, mobj, variable_name, ivalue); +} + +static void DEH_ThingMD5Sum(md5_context_t *context) +{ + int i; + + for (i=0; i +#include + +#include "doomtype.h" + +#include "d_items.h" + +#include "deh_defs.h" +#include "deh_main.h" +#include "deh_mapping.h" + +DEH_BEGIN_MAPPING(weapon_mapping, weaponinfo_t) + DEH_MAPPING("Ammo type", ammo) + DEH_MAPPING("Deselect frame", upstate) + DEH_MAPPING("Select frame", downstate) + DEH_MAPPING("Bobbing frame", readystate) + DEH_MAPPING("Shooting frame", atkstate) + DEH_MAPPING("Firing frame", flashstate) +DEH_END_MAPPING + +static void *DEH_WeaponStart(deh_context_t *context, char *line) +{ + int weapon_number = 0; + + if (sscanf(line, "Weapon %i", &weapon_number) != 1) + { + DEH_Warning(context, "Parse error on section start"); + return NULL; + } + + if (weapon_number < 0 || weapon_number >= NUMWEAPONS) + { + DEH_Warning(context, "Invalid weapon number: %i", weapon_number); + return NULL; + } + + return &weaponinfo[weapon_number]; +} + +static void DEH_WeaponParseLine(deh_context_t *context, char *line, void *tag) +{ + char *variable_name, *value; + weaponinfo_t *weapon; + int ivalue; + + if (tag == NULL) + return; + + weapon = (weaponinfo_t *) tag; + + if (!DEH_ParseAssignment(line, &variable_name, &value)) + { + // Failed to parse + + DEH_Warning(context, "Failed to parse assignment"); + return; + } + + ivalue = atoi(value); + + DEH_SetMapping(context, &weapon_mapping, weapon, variable_name, ivalue); +} + +static void DEH_WeaponMD5Sum(md5_context_t *context) +{ + int i; + + for (i=0; i #endif -#include "deh_main.h" +#include "deh_str.h" #include "i_system.h" #include "s_sound.h" #include "m_argv.h" diff --git a/src/i_system.c b/src/i_system.c index 218acc59..c3b3211e 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -38,7 +38,7 @@ #include #endif -#include "deh_main.h" +#include "deh_str.h" #include "doomtype.h" #include "doomstat.h" #include "m_argv.h" diff --git a/src/i_video.c b/src/i_video.c index dc4a249e..4c70c48c 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -33,7 +33,7 @@ #include "icon.c" #include "config.h" -#include "deh_main.h" +#include "deh_str.h" #include "doomtype.h" #include "doomkeys.h" #include "i_joystick.h" diff --git a/src/m_config.c b/src/m_config.c index bea255d2..bb8d5020 100644 --- a/src/m_config.c +++ b/src/m_config.c @@ -32,7 +32,7 @@ #include #include "config.h" -#include "deh_main.h" +#include "deh_str.h" #include "doomtype.h" #include "doomkeys.h" #include "doomfeatures.h" diff --git a/src/m_misc.c b/src/m_misc.c index 88519b3c..db62fd42 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -45,7 +45,7 @@ #include "doomtype.h" #include "doomstat.h" -#include "deh_main.h" +#include "deh_str.h" #include "i_swap.h" #include "i_system.h" diff --git a/src/net_client.c b/src/net_client.c index 26cd2133..f85f2b94 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -29,6 +29,7 @@ #include "doomtype.h" #include "doomstat.h" #include "deh_main.h" +#include "deh_str.h" #include "g_game.h" #include "i_system.h" #include "i_timer.h" diff --git a/src/s_sound.c b/src/s_sound.c index f3f6bf1f..26bbb5fd 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -29,7 +29,7 @@ #include "i_system.h" #include "doomfeatures.h" -#include "deh_main.h" +#include "deh_str.h" #include "doomstat.h" #include "doomtype.h" diff --git a/src/v_video.c b/src/v_video.c index bea0171c..918e64e1 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -34,7 +34,7 @@ #include "doomtype.h" #include "doomdata.h" -#include "deh_main.h" +#include "deh_str.h" #include "m_bbox.h" #include "i_swap.h" #include "i_video.h" -- cgit v1.2.3