CROUCH reconstruction (WIP): the master posture/duck machine, decoded + wired
Raw-disasm of the dark master-perf region (@0x4a9cf0-0x4aa0af): the myomer effectiveness factor (+0x79c, MAX over heatables' +0x31c, scales speedDemand -- feeder @004b8be3 unreconstructed, neutral 1.0 [T3]), the posture selector (+0x3f8: mode/novice/leg-state/myomer gates -- novices cannot crouch), and the DuckRequest consumer (standing -> SetLegAnimation(2) 'sqd', ducked -> SetLegAnimation(3) 'squ', ForceUpdate 8+1 ships the type-3 state record, stability alarm flips, request consumed). +0x1DC = mountSegment... er, the searchlight learned that one; here: mapPosture @0x3f8 + myomerEffectiveness @0x79c members land; value-space note (port normal mode == 1, binary 0). VERIFIED: request->consumer chain fires ([duck] SQUAT), the sqd clip plays (22kf/7joint, ends root -2.22 crouched -- clip data parsed from BTL4.RES, squ is its exact mirror; loader slot map re-verified byte-exact). OPEN: the parked crouch pose does not HOLD on screen (reverts ~1 frame after clip end with NO SetLegAnimation re-arm logged) -- the hold's render path is the remaining dig; [duck] re-arm tracer left in SetLegAnimation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
b75bb4a04c
commit
dd70061e0e
@@ -2118,6 +2118,9 @@ Mech::Mech(
|
||||
ramLastVictim = 0; // ram contact-edge state
|
||||
ramContactLinger = 0.0f;
|
||||
lastInflictingDamage = 0.0f; // task #60: killing-blow magnitude (set on hit)
|
||||
mapPosture = 0; // binary @0x3f8 (the ctor zero-block @0x4b3d18 zeroes the band)
|
||||
myomerEffectiveness = 1.0f; // binary @0x79c: 0-init + per-frame MAX; the port holds the
|
||||
// healthy 1.0 until the Myomers Performance feeder lands [T3]
|
||||
if (GroundReal() && GetCollisionVolumeCount() > 0
|
||||
&& collisionTemplate != 0 && collisionVolume != 0)
|
||||
{
|
||||
|
||||
@@ -1032,6 +1032,16 @@ protected:
|
||||
Scalar gimpStrideLength; // @0x350
|
||||
AlarmIndicator legStateAlarm; // @0x39c
|
||||
int legAnimationState; // @0x3b0
|
||||
int mapPosture; // binary @0x3f8 -- the map-legend/duck posture arbiter
|
||||
// (0 none / 1 may-duck / 2 holding-squat), computed per
|
||||
// master frame (FUN_004a9b5c @0x4a9f61-0x4aa007; the
|
||||
// CROUCH reconstruction, 2026-08-05)
|
||||
Scalar myomerEffectiveness; // binary @0x79c -- init 0 then MAX over the heatable
|
||||
// chain's +0x31c each master frame; scales the mapper
|
||||
// speedDemand (dead myomers cripple the walk) and gates
|
||||
// the crouch. FEEDER (Myomers Performance @004b8be3,
|
||||
// not in the export) UNRECONSTRUCTED -- the port holds
|
||||
// the healthy 1.0 [T3]; see the mech4 posture block.
|
||||
Scalar gimpSpeedMax; // @0x52c
|
||||
Scalar standSpeed; // @0x530
|
||||
Scalar walkStrideLength; // @0x534
|
||||
|
||||
@@ -220,6 +220,16 @@ enum MechAnimationState
|
||||
void
|
||||
Mech::SetLegAnimation(int state)
|
||||
{
|
||||
// DIAG (BT_DUCK_LOG): every leg re-arm with the caller's return address --
|
||||
// the crouch-clobber hunt (who re-arms after the squat parks?).
|
||||
if (getenv("BT_DUCK_LOG"))
|
||||
{
|
||||
char dbuf[96];
|
||||
sprintf(dbuf, "[duck] SetLegAnimation(%d) ra=btl4+0x%lx", state,
|
||||
(unsigned long)_ReturnAddress()
|
||||
- (unsigned long)GetModuleHandleA(0));
|
||||
DEBUG_STREAM << dbuf << std::endl << std::flush;
|
||||
}
|
||||
legAnimation.SelectSequence( // FUN_004277a8(this+0x65c, ...)
|
||||
animationClips[state], // *(this+0x5cc + state*4)
|
||||
// The real leg finished-callback PTR_LAB_0050d6f0 == FUN_004a6928
|
||||
|
||||
@@ -4348,6 +4348,95 @@ void
|
||||
// and the Standing case returns adv=0 (no motion). Only the LEGACY inline
|
||||
// clip-select path (BT_GAIT_SM=0) still needs the throttle gate (it would
|
||||
// loop the walk clip forever at idle).
|
||||
//
|
||||
// ---- MASTER POSTURE / CROUCH (raw disasm @0x4a9cf0-0x4aa0af, the dark
|
||||
// master-perf region FUN_004a9b5c; decoded + reconstructed 2026-08-05).
|
||||
// Binary order preserved: (1) the myomer factor -> speedDemand scale,
|
||||
// (2) the posture selector (+0x3f8), (3) the DuckRequest consumer.
|
||||
//
|
||||
{
|
||||
// (1) myomerEffectiveness (+0x79c): the binary inits 0 then MAXes
|
||||
// the heatable chain's +0x31c (healthy myomers publish ~1.0;
|
||||
// weapons park transient fireImpulse there) and multiplies the
|
||||
// mapper's speedDemand -- dead muscles = a crawling mech. The
|
||||
// WRITER (Myomers Performance @004b8be3) is not in the export and
|
||||
// stays unreconstructed, so the member holds the ctor's healthy
|
||||
// 1.0 and this multiply is a live no-op until that dig lands
|
||||
// (neutral-value deferral, the role=NULL pattern). [T3 feeder]
|
||||
{
|
||||
MechControlsMapper *postureMppr = MappingMapper();
|
||||
if (postureMppr != 0)
|
||||
postureMppr->speedDemand *= myomerEffectiveness;
|
||||
}
|
||||
|
||||
// (2) the posture selector (+0x3f8; feeds the map legend + the
|
||||
// duck arbiter). @0x4a9f61-0x4aa007: any non-zero movementMode
|
||||
// -> 0; !simLive -> 0 (a NOVICE cannot crouch -- the same +0x25c
|
||||
// lockout as the crit roll); leg alarm level 0/4 (standing /
|
||||
// turn-in-place idle) -> myomers alive ? 1 : 0 (|factor| <= 1e-4
|
||||
// == dead muscles, const @0x4ab16c); level 1 (parked in the
|
||||
// squat) -> 2; anything else -> 0.
|
||||
{
|
||||
extern int BTPlayerExperienceSimLive(void *owner_mech);
|
||||
const int postureLegLevel = (int)legStateAlarm.GetLevel();
|
||||
// VALUE-SPACE NOTE: the binary tests +0x40 != 0 (its normal
|
||||
// running state was 0); the task-#1 unification made our
|
||||
// normal the engine ExistingState == 1 (bench: mode=1 while
|
||||
// walking around). Same intent -- "no special mode (limbo 2,
|
||||
// airborne 3/4, dead 9, eject 10)".
|
||||
const int postureMode = MovementMode();
|
||||
if ((postureMode != 0 && postureMode != 1)
|
||||
|| !BTPlayerExperienceSimLive((void *)this))
|
||||
mapPosture = 0;
|
||||
else if (postureLegLevel == 0 || postureLegLevel == 4)
|
||||
mapPosture = (myomerEffectiveness <= 0.0001f
|
||||
&& myomerEffectiveness >= -0.0001f) ? 0 : 1;
|
||||
else if (postureLegLevel == 1)
|
||||
mapPosture = 2;
|
||||
else
|
||||
mapPosture = 0;
|
||||
}
|
||||
|
||||
// (3) the DuckRequest consumer (@0x4aa011-0x4aa0af), gated on the
|
||||
// latched request AND squatCapable ('squ'/'sqd' clips shipped).
|
||||
// Duck: SetLegAnimation(2) plays 'sqd'; LegClipFinished case-2
|
||||
// parks the pose + sets leg alarm 1. Rise: SetLegAnimation(3)
|
||||
// plays 'squ'; case-3 restores alarm 0. Both mark the type-3
|
||||
// state record dirty (ForceUpdate 8 then 1 -- it ships legState +
|
||||
// stability, so peers pose the squat for free) and flip the
|
||||
// stability alarm (ducked = 0, risen = 1). The request is
|
||||
// consumed whenever both gates passed, hit or miss.
|
||||
if (duckState != 0 && squatCapable != 0)
|
||||
{
|
||||
if (mapPosture == 1)
|
||||
{
|
||||
SetLegAnimation(2); // 'sqd' -- squat down
|
||||
ForceUpdate(8);
|
||||
ForceUpdate(1);
|
||||
stabilityAlarm.SetLevel(0);
|
||||
if (getenv("BT_DUCK_LOG") || getenv("BT_GAIT_LOG"))
|
||||
DEBUG_STREAM << "[duck] SQUAT (posture 1 -> leg clip 2)\n" << std::flush;
|
||||
}
|
||||
else if (mapPosture == 2)
|
||||
{
|
||||
SetLegAnimation(3); // 'squ' -- rise
|
||||
ForceUpdate(8);
|
||||
ForceUpdate(1);
|
||||
stabilityAlarm.SetLevel(1);
|
||||
if (getenv("BT_DUCK_LOG") || getenv("BT_GAIT_LOG"))
|
||||
DEBUG_STREAM << "[duck] RISE (posture 2 -> leg clip 3)\n" << std::flush;
|
||||
}
|
||||
else if (getenv("BT_DUCK_LOG"))
|
||||
DEBUG_STREAM << "[duck] request consumed, posture=" << mapPosture
|
||||
<< " (mode=" << MovementMode()
|
||||
<< " legLvl=" << (int)legStateAlarm.GetLevel()
|
||||
<< " simLive=" << 1 // re-read below costs a bridge call; posture already folded it
|
||||
<< " myo=" << myomerEffectiveness
|
||||
<< " squat=" << squatCapable << ")\n" << std::flush;
|
||||
duckState = 0; // consumed (@0x4aa0a9)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
static const int s_gaitTicksAlways = BTEnvOn("BT_GAIT_SM", 1);
|
||||
if (s_gaitTicksAlways || throttle != 0.0f)
|
||||
|
||||
Reference in New Issue
Block a user