shithub: choc

Download patch

ref: 6a92bc54be4081c8821ca110947133b5f1f8516b
parent: f04325260a5a95ca4c60c3b57762e48beedc381e
author: Simon Howard <[email protected]>
date: Sat Feb 6 22:04:29 EST 2010

Initial code for HHE patch support.

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

--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -144,9 +144,9 @@
 @PROGRAM_PREFIX@doom_LDADD = doom/libdoom.a $(EXTRA_LIBS)
 
 if HAVE_WINDRES
-@PROGRAM_PREFIX@heretic_SOURCES=$(SOURCE_FILES) resource.rc
+@PROGRAM_PREFIX@heretic_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc
 else
-@PROGRAM_PREFIX@heretic_SOURCES=$(SOURCE_FILES)
+@PROGRAM_PREFIX@heretic_SOURCES=$(SOURCE_FILES_WITH_DEH)
 endif
 
 @PROGRAM_PREFIX@heretic_LDADD = heretic/libheretic.a $(EXTRA_LIBS)
--- a/src/heretic/Makefile.am
+++ b/src/heretic/Makefile.am
@@ -55,5 +55,14 @@
 i_sound.c                                            \
 i_ibm.c   
 
-libheretic_a_SOURCES=$(SOURCE_FILES)
+FEATURE_DEHACKED_SOURCE_FILES =            \
+deh_ammo.c                                 \
+deh_frame.c                                \
+deh_htic.c                                 \
+deh_sound.c                                \
+deh_thing.c                                \
+deh_weapon.c
+
+libheretic_a_SOURCES=$(SOURCE_FILES)                  \
+                     $(FEATURE_DEHACKED_SOURCE_FILES)
 
--- /dev/null
+++ b/src/heretic/deh_ammo.c
@@ -1,0 +1,122 @@
+// 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "doomdef.h"
+#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);
+
+    if (!strcasecmp(variable_name, "Per ammo"))
+    {
+        // Heretic doesn't have a "per clip" ammo array, instead
+        // it is per weapon.  However, the weapon number lines
+        // up with the ammo number if we add one.
+
+        GetWeaponAmmo[ammo_number + 1] = 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<NUMAMMO; ++i)
+    {
+        MD5_UpdateInt32(context, maxammo[i]);
+    }
+
+    for (i=0; i<NUMWEAPONS; ++i)
+    {
+        MD5_UpdateInt32(context, GetWeaponAmmo[i]);
+    }
+}
+
+deh_section_t deh_section_ammo =
+{
+    "Ammo",
+    NULL,
+    DEH_AmmoStart,
+    DEH_AmmoParseLine,
+    NULL,
+    DEH_AmmoMD5Hash,
+};
+
--- /dev/null
+++ b/src/heretic/deh_frame.c
@@ -1,0 +1,131 @@
+// 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 <stdio.h>
+#include <stdlib.h>
+
+#include "doomtype.h"
+#include "info.h"
+
+#include "deh_defs.h"
+#include "deh_io.h"
+#include "deh_main.h"
+#include "deh_mapping.h"
+#include "deh_htic.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("Action pointer")
+DEH_END_MAPPING
+
+static void *DEH_FrameStart(deh_context_t *context, char *line)
+{
+    int frame_number = 0;
+    int mapped_frame_number;
+    state_t *state;
+
+    if (sscanf(line, "Frame %i", &frame_number) != 1)
+    {
+        DEH_Warning(context, "Parse error on section start");
+        return NULL;
+    }
+
+    // Map the HHE frame number (which assumes a Heretic 1.0 state table)
+    // to the internal frame number (which is is the Heretic 1.3 state table):
+
+    mapped_frame_number = DEH_MapHereticFrameNumber(frame_number);
+
+    if (mapped_frame_number < 0 || mapped_frame_number >= DEH_HERETIC_NUMSTATES)
+    {
+        DEH_Warning(context, "Invalid frame number: %i", frame_number);
+        return NULL;
+    }
+
+    state = &states[mapped_frame_number];
+
+    return state;
+}
+
+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);
+
+    // "Next frame" numbers need to undergo mapping.
+
+    if (!strcasecmp(variable_name, "Next frame"))
+    {
+        ivalue = DEH_MapHereticFrameNumber(ivalue);
+    }
+
+    DEH_SetMapping(context, &state_mapping, state, variable_name, ivalue);
+}
+
+static void DEH_FrameMD5Sum(md5_context_t *context)
+{
+    int i;
+
+    for (i=0; i<NUMSTATES; ++i)
+    {
+        DEH_StructMD5Sum(context, &state_mapping, &states[i]);
+    }
+}
+
+deh_section_t deh_section_frame =
+{
+    "Frame",
+    NULL,
+    DEH_FrameStart,
+    DEH_FrameParseLine,
+    NULL,
+    DEH_FrameMD5Sum,
+};
+
--- /dev/null
+++ b/src/heretic/deh_htic.c
@@ -1,0 +1,85 @@
+// Emacs style mode select   -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+//
+// Top-level dehacked definitions for Heretic dehacked (HHE).
+//
+//-----------------------------------------------------------------------------
+
+#include <stdlib.h>
+#include "deh_defs.h"
+#include "deh_main.h"
+#include "info.h"
+
+char *deh_signatures[] =
+{
+    "Patch File for HHE v1.1",
+    NULL
+};
+
+// deh_ammo.c:
+extern deh_section_t deh_section_ammo;
+// deh_frame.c:
+extern deh_section_t deh_section_frame;
+// deh_ptr.c:
+extern deh_section_t deh_section_pointer;
+// deh_sound.c
+extern deh_section_t deh_section_sound;
+// deh_text.c:
+extern deh_section_t deh_section_text;
+// deh_thing.c:
+extern deh_section_t deh_section_thing;
+// deh_weapon.c:
+extern deh_section_t deh_section_weapon;
+
+//
+// List of section types:
+//
+
+deh_section_t *deh_section_types[] =
+{
+    &deh_section_ammo,
+    &deh_section_frame,
+//    &deh_section_pointer, TODO
+    &deh_section_sound,
+//    &deh_section_text, TODO
+    &deh_section_thing,
+    &deh_section_weapon,
+    NULL
+};
+
+// HHE only worked with Heretic 1.0 and unfortunately was never updated
+// to support Heretic 1.3.  Between Heretic 1.0 and 1.3, two new frames
+// were added to the "states" table, to extend the "flame death"
+// animation displayed when the player is killed by fire.  Therefore,
+// we must map the HHE frame numbers (which assume a Heretic 1.0 frame
+// table) to corresponding indexes for the Heretic 1.3 frame table.
+
+int DEH_MapHereticFrameNumber(int frame)
+{
+    if (frame >= S_PLAY_FDTH19)
+    {
+        frame = (frame - S_PLAY_FDTH19) + S_BLOODYSKULL1;
+    }
+
+    return frame;
+}
+
--- /dev/null
+++ b/src/heretic/deh_htic.h
@@ -1,0 +1,45 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2010 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+//
+// Common header for Heretic dehacked (HHE) support.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef DEH_HTIC_H
+#define DEH_HTIC_H
+
+#include "info.h"
+
+// HHE doesn't know about the last two states in the state table, so
+// these are considered invalid.
+
+#define DEH_HERETIC_NUMSTATES (NUMSTATES - 2)
+
+// It also doesn't know about the last two things in the mobjinfo table
+// (which correspond to the states above)
+
+#define DEH_HERETIC_NUMMOBJTYPES (NUMMOBJTYPES - 2)
+
+int DEH_MapHereticFrameNumber(int frame);
+
+#endif /* #ifndef DEH_HTIC_H */
+
--- /dev/null
+++ b/src/heretic/deh_sound.c
@@ -1,0 +1,118 @@
+// 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 "Sound" sections in dehacked files
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "doomfeatures.h"
+#include "doomtype.h"
+#include "deh_defs.h"
+#include "deh_main.h"
+#include "deh_mapping.h"
+
+#include "doomdef.h"
+#include "i_sound.h"
+
+#include "sounds.h"
+
+DEH_BEGIN_MAPPING(sound_mapping, sfxinfo_t)
+    DEH_MAPPING_STRING("Name", name)
+    DEH_UNSUPPORTED_MAPPING("Special")
+    DEH_MAPPING("Value", priority)
+    DEH_MAPPING("Unknown 1", usefulness)
+    DEH_UNSUPPORTED_MAPPING("Unknown 2")
+    DEH_UNSUPPORTED_MAPPING("Unknown 3")
+    DEH_MAPPING("One/Two", numchannels)
+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;
+
+    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;
+    }
+
+    // Set the field value:
+
+    if (!strcasecmp(variable_name, "Name"))
+    {
+        DEH_SetStringMapping(context, &sound_mapping, sfx,
+                             variable_name, value);
+    }
+    else
+    {
+        DEH_SetMapping(context, &sound_mapping, sfx,
+                       variable_name, atoi(value));
+    }
+}
+
+deh_section_t deh_section_sound =
+{
+    "Sound",
+    NULL,
+    DEH_SoundStart,
+    DEH_SoundParseLine,
+    NULL,
+    NULL,
+};
+
--- /dev/null
+++ b/src/heretic/deh_thing.c
@@ -1,0 +1,149 @@
+// 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 <stdio.h>
+#include <stdlib.h>
+
+#include "doomtype.h"
+
+#include "deh_defs.h"
+#include "deh_main.h"
+#include "deh_mapping.h"
+#include "deh_htic.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("Burning frame",       crashstate)
+  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 1",              flags)
+  DEH_MAPPING("Bits 2",              flags2)
+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;
+    }
+
+    // HHE thing numbers are indexed from 1
+    --thing_number;
+
+    if (thing_number < 0 || thing_number >= DEH_HERETIC_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;
+    }
+
+    // all values are integers
+
+    ivalue = atoi(value);
+
+    // If the value to be set is a frame, the frame number must
+    // undergo transformation from a Heretic 1.0 index to a
+    // Heretic 1.3 index.
+
+    if (strstr(variable_name, "frame") != NULL)
+    {
+        ivalue = DEH_MapHereticFrameNumber(ivalue);
+    }
+
+    // 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<NUMMOBJTYPES; ++i)
+    {
+        DEH_StructMD5Sum(context, &thing_mapping, &mobjinfo[i]);
+    }
+}
+
+deh_section_t deh_section_thing =
+{
+    "Thing",
+    NULL,
+    DEH_ThingStart,
+    DEH_ThingParseLine,
+    NULL,
+    DEH_ThingMD5Sum,
+};
+
--- /dev/null
+++ b/src/heretic/deh_weapon.c
@@ -1,0 +1,130 @@
+// 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 "Weapon" sections in dehacked files
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "doomtype.h"
+
+#include "doomdef.h"
+
+#include "deh_defs.h"
+#include "deh_main.h"
+#include "deh_mapping.h"
+#include "deh_htic.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",     holdatkstate)
+  DEH_MAPPING("Unknown 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 * 2)
+    {
+        DEH_Warning(context, "Invalid weapon number: %i", weapon_number);
+        return NULL;
+    }
+
+    // Because of the tome of power, we have two levels of weapons:
+
+    if (weapon_number < NUMWEAPONS)
+    {
+        return &wpnlev1info[weapon_number];
+    }
+    else
+    {
+        return &wpnlev2info[weapon_number - NUMWEAPONS];
+    }
+}
+
+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);
+
+    // If this is a frame field, we need to map from Heretic 1.0 frame
+    // numbers to Heretic 1.3 frame numbers.
+
+    if (strstr(variable_name, "frame") != NULL)
+    {
+        ivalue = DEH_MapHereticFrameNumber(ivalue);
+    }
+
+    DEH_SetMapping(context, &weapon_mapping, weapon, variable_name, ivalue);
+}
+
+static void DEH_WeaponMD5Sum(md5_context_t *context)
+{
+    int i;
+
+    for (i=0; i<NUMWEAPONS ;++i)
+    {
+        DEH_StructMD5Sum(context, &weapon_mapping, &wpnlev1info[i]);
+        DEH_StructMD5Sum(context, &weapon_mapping, &wpnlev2info[i]);
+    }
+}
+
+deh_section_t deh_section_weapon =
+{
+    "Weapon",
+    NULL,
+    DEH_WeaponStart,
+    DEH_WeaponParseLine,
+    NULL,
+    DEH_WeaponMD5Sum,
+};
+