shithub: choc

Download patch

ref: 8258632f22992446473a55bf31a9c8d5f53fe4a6
parent: 4ed8566a0b2803a9eb29216afaa48e57b86fc9e7
author: Simon Howard <[email protected]>
date: Mon Oct 30 20:01:48 EST 2006

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

--- 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 @@
     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 @@
 
     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)