Mech::Reset: restore the POSTURE clears the port had dropped (#142)

Oracle: "crouch wasn't resetting on respawn ... mechs always spawn standing".
Correct -- Mech::Reset (@0049fb74) stands the mech up and the port cleared
none of it:

    *(this+0x398) = 0             duckState
    Set_Alarm_Level(this+0x39c,0) legStateAlarm  -> standing
    Set_Alarm_Level(this+0x714,0) bodyStateAlarm -> standing
    *(this+0x650/0x654/0x658) = 0 death + leg/body reset latches
    *(this+0x5ac) = 1.0f          idleStrideScale

A pilot who died CROUCHED came back crouched -- leg parked in 'sqd' -- and now
that the cockpit strip works, showing the up-arrow "press to rise" frame on a
standing mech.

Benched (crouchrespawn.sh): A squats, dies while down, respawns -> legLvl 0
(standing) after Mech::Reset.  Weak but the failure mode (stuck legLvl=1) is
absent.  NB the first attempt was void: force-damage kept A dying before it
could crouch (legLvl 22/24 = death clips), so the run tested a STANDING death.
Switched to self-damage so the mech is stopped long enough to crouch.

Also carries the #142 gauge work: the crouch strip is a BUTTON-STATE indicator
(grey unavailable / orange down-arrow ready / orange up-arrow crouched),
decoded by rendering BDUCK.PCC rather than inferring it; and the gauge
factory's missing-image path no longer uses the no-op DebugStream.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCJQkvq6G2JNrpVbA75tVZ
This commit is contained in:
Joe DiPrima
2026-08-08 00:11:00 -05:00
co-authored by Claude Opus 5
parent 03c4d55672
commit 1f0923747b
4 changed files with 168 additions and 3 deletions
+66 -3
View File
@@ -2172,6 +2172,26 @@ void
poseSyncLatch = 0; // @0x77c
graphicAlarm.SetLevel(0); // clear >=9 (the vital-kill trigger)
// --- STAND THE MECH UP. Restored 2026-08-07 (#142, Oracle: "crouch wasn't
// resetting on respawn"). These are in the binary's own Reset sweep and the
// port had dropped all of them, so a pilot who died CROUCHED respawned
// crouched -- leg parked in 'sqd', the cockpit strip still showing the
// up-arrow "press to rise" frame. Verbatim from FUN_0049fb74:
// *(this+0x398) = 0 duckState -- not crouching
// FUN_0041bbd8(this+0x39c, 0) legStateAlarm -> 0 (standing)
// FUN_0041bbd8(this+0x714, 0) bodyStateAlarm -> 0 (standing)
// *(this+0x650/0x654/0x658) = 0 death + leg/body reset latches
// *(this+0x5ac) = 1.0f idleStrideScale
duckState = 0; // @0x398
duckRequest = 0; // port-only pending flag (#142)
legStateAlarm.SetLevel(0); // @0x39c -- stand
bodyStateAlarm.SetLevel(0); // @0x714 -- stand
stabilityAlarm.SetLevel(1); // risen (the rise path's value)
deathAnimationLatched = 0; // @0x650
legResetLatch = 0; // @0x654
bodyResetLatch = 0; // @0x658
idleStrideScale = 1.0f; // @0x5ac = 0x3f800000
// --- HEAL every damage zone: full structure, intact skin, no burning ---
for (int z = 0; z < damageZoneCount; ++z)
{
@@ -4514,10 +4534,53 @@ void
// back to 0/1 by the next visit, so "am I still moving?" has to be
// asked fresh, and the strip settled whenever the answer is no.
{
// SETTLE to the binary's VALUE RANGE: duckState is 0 or 1, never
// 2. Corrected 2026-08-07 after checking FUN_004a9b5c -- the
// mech4 master perf is fully indexed and exported (5645 bytes,
// no dark region inside) and never references +0x398. So the
// binary has NO code reader of duckState at all: the gauge
// attribute is the only consumer, and the only writers are the
// handler (=1) and Mech::Reset (=0). Frame 2 of bduck.pcc was
// unreachable in the original too.
//
// The strip is therefore a TWO-STATE indicator -- standing and
// crouched -- and the "crouch animation" is the MECH's 'sqd'
// clip, not the symbol stepping. An earlier revision here made
// duckState a 3-state posture (0/1/2); that was an invention on
// top of a stand-in and it put the crouched pose on the wrong
// frame.
// #142: report EVERY change of the value the cockpit strip is fed,
// so 'which frames actually got shown, and for how long' stops
// being guesswork. Ungated: one line per posture change.
static int s_lastDuck = -1;
// THE STRIP IS A BUTTON-STATE INDICATOR, not a pose animation.
// Decoded 2026-08-07 by RENDERING THE ASSET itself
// (content/GAUGE/BDUCK.PCC -- PCX, 108x102, three 36x102 frames;
// see scratchpad/night13/bduck_frames.png):
//
// frame 0 GREY mech standing, GREY down-arrow -- UNAVAILABLE
// frame 1 ORANGE standing, YELLOW down -- ready to crouch
// frame 2 ORANGE CROUCHED, YELLOW up -- press to rise
//
// There is NO mid-transition pose. The arrow tells the pilot
// what the next press will do, and the grey frame says the
// button is inert -- which is the visual half of the
// must-be-stopped rule (Lynx: "when a mech STOPS").
//
// Two earlier readings were wrong: a 2-state flag (which
// ignores frame 2's up-arrow entirely) and a stand/moving/
// crouched pose animation (there is no mid pose). Both were
// inferred from code and logs; only the ART settled it, and it
// also explains the field report -- a stopped mech that COULD
// crouch was drawing the grey "unavailable" frame.
const int lvlNow = (int)legStateAlarm.GetLevel();
if (lvlNow != 2 && lvlNow != 3) // not playing 'sqd'/'squ'
duckState = (lvlNow == 1) ? 2 : 0; // crouched : standing
// else: hold 1, the middle frame, while the clip runs.
if (lvlNow != 2 && lvlNow != 3) // hold through the clip
{
if (lvlNow == 1) duckState = 2; // crouched
else if (squatCapable != 0 && mapPosture == 1)
duckState = 1; // ready
else duckState = 0; // inert
}
}
// (3b) AIRBORNE AUTO-RISE -- recovered 2026-08-06 by the #60