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)