foxygit / doom Log in
commit 8258632f22992446473a55bf31a9c8d5f53fe4a6
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Tue Oct 31 01:01:48 2006 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Tue Oct 31 01:01:48 2006 +0000

    Simulate overflowing the Doom frame table in dehacked patches (DOS
    dehacked's behavior). Overwrite the weaponinfo table instead when
    changes are made to the last element in states[]. Thanks to grazza for
    pointing out that Chococlate Doom did not emulate this bug.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 744
---
 src/deh_frame.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/src/deh_frame.c b/src/deh_frame.c
index 2204579b..398fa014 100644
--- a/src/deh_frame.c
+++ b/src/deh_frame.c
@@ -28,6 +28,7 @@

 #include "doomdef.h"
 #include "doomtype.h"
+#include "d_items.h"
 #include "info.h"

 #include "deh_defs.h"
@@ -73,6 +74,43 @@ static void *DEH_FrameStart(deh_context_t *context, char *line)
     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;
@@ -98,9 +136,16 @@ static void DEH_FrameParseLine(deh_context_t *context, char *line, void *tag)

     ivalue = atoi(value);

-    // set the appropriate field
+    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);
+        DEH_SetMapping(context, &state_mapping, state, variable_name, ivalue);
+    }
 }

 static void DEH_FrameMD5Sum(md5_context_t *context)