the REVERSE DISABLED voice (#78): SimulationState 3/4 IS the trigger -- mirror the gimp level into the engine cell
User + old-timers were right; the earlier "no voice exists" verdict was wrong. The authored mech audio has state watchers on Entity.SimulationState==3/4 (the binary's one-cell mech+0x40) that start sequence notes 29,16,40 -- two klaxon hits then Warnings01 zone 8 (key 40-41) = the "reverse disabled" voice line the testers remember. The port's cell split (graphicAlarm vs engine simulationState, gotcha #23) meant the trigger value never arrived. - mechdmg: mirror gimp 3/4 into SetSimulationState at the leg-half crossing (guarded: never stomps disabled/fall/dead states). Voice verified playing end-to-end on the bench: SetupPatch bank2 patch113 note=40 -> Warnings01_z7.wav. - mech.cpp: BT_GIMP_SAFE_BASE_READ on all seven Simulation::ReadUpdateRecord sites -- gimp is monotonic per life; a record captured pre-gimp must not stomp the cell (the loopback otherwise perpetuates the stale value and restarts the warning on every damage event). - diagnostics (all env-gated): [statefire]/[startreq]/[animind]/[gimp-sim]/ [simstomp]/[indstomp] + StateIndicator::DebugAudioWatcherCount + raised spatial-log caps. These traced the whole chain and PROVED no SetState path stomps the cell. OPEN (follow-up): a RAW writer (bypasses SetState entirely; invisible to the indicator-level trap) resets the cell between damage events -- under the bench's 1 Hz metronome harness it restarted the sequence before the 1.8 s voice note; sporadic real-play damage is unaffected (one edge -> full sequence). Needs a cdb write-watchpoint session; candidates: a recon raw +0x2c-equivalent write or a struct copy spanning it. Also decoded en route: the AnimationState triggers on the limp states play EngineShiftRev01 (the downshift foley) -- working, and NOT the voice. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
7838df2924
commit
1671b7d4b2
@@ -2176,6 +2176,22 @@ Logical
|
||||
// airborne 3,4) tracks the master automatically; the case-0 / tail edge
|
||||
// tests below then see the old->current transition.
|
||||
//
|
||||
// #78 GIMP-MONOTONIC RECORD GUARD: the binary's mech+0x40 is one cell, so its
|
||||
// records always carried the live gimp level (3/4). The port's mirror write
|
||||
// (mechdmg) can be STOMPED by a record whose simulationState was captured
|
||||
// pre-gimp -- and the loopback then perpetuates the stale value forever
|
||||
// (write captures the stomped 1, read re-applies it): the "reverse disabled"
|
||||
// voice sequence restarted on every damage tick and never reached the voice
|
||||
// note. Gimp is monotonic within a life, so a record carrying <=1 while the
|
||||
// live state is 3/4 is stale by construction: patch the RECORD field to the
|
||||
// live value before the base read -- SetState then dedupes (no edge, no
|
||||
// restart) and the next WriteUpdateRecord captures 3/4, converging the loop.
|
||||
#define BT_GIMP_SAFE_BASE_READ(msg) \
|
||||
do { unsigned _cur = GetSimulationState(); \
|
||||
if ((_cur == 3 || _cur == 4) && (msg)->simulationState <= 1) \
|
||||
(msg)->simulationState = _cur; \
|
||||
Simulation::ReadUpdateRecord(msg); } while (0)
|
||||
|
||||
void
|
||||
Mech::ReadUpdateRecord(Simulation::UpdateRecord *message)
|
||||
{
|
||||
@@ -2280,7 +2296,7 @@ void
|
||||
// real payload (simulationState). BT_T2_CLOCK restores the old stamp (A/B).
|
||||
static const int s_t2clock = getenv("BT_T2_CLOCK") ? 1 : 0;
|
||||
const Time savedLastUpdate = lastUpdate;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
if (!s_t2clock) lastUpdate = savedLastUpdate;
|
||||
} // FUN_0041bd34
|
||||
bodyTargetSpeed = record->speedDemand; // @0x6b4 <- rec+0x10
|
||||
@@ -2310,7 +2326,7 @@ void
|
||||
// real payload (simulationState). BT_T2_CLOCK restores the old stamp (A/B).
|
||||
static const int s_t2clock = getenv("BT_T2_CLOCK") ? 1 : 0;
|
||||
const Time savedLastUpdate = lastUpdate;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
if (!s_t2clock) lastUpdate = savedLastUpdate;
|
||||
}
|
||||
bodyResetLatch = record->legResetLatch; // @0x658 <- rec+0x10
|
||||
@@ -2335,7 +2351,7 @@ void
|
||||
case 4: // orientation + angular-velocity re-sync
|
||||
{
|
||||
Mech__ResyncUpdateRecord *record = (Mech__ResyncUpdateRecord *)message;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
creationTime = Now(); // @0x778 -- the dead-reckon ref time
|
||||
{
|
||||
EulerAngles e(Radian(record->eulerX), Radian(record->eulerY),
|
||||
@@ -2374,7 +2390,7 @@ void
|
||||
// real payload (simulationState). BT_T2_CLOCK restores the old stamp (A/B).
|
||||
static const int s_t2clock = getenv("BT_T2_CLOCK") ? 1 : 0;
|
||||
const Time savedLastUpdate = lastUpdate;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
if (!s_t2clock) lastUpdate = savedLastUpdate;
|
||||
}
|
||||
heatAlarm.SetLevel(record->heatLevel); // @0x450 <- rec+0x10
|
||||
@@ -2405,7 +2421,7 @@ void
|
||||
// real payload (simulationState). BT_T2_CLOCK restores the old stamp (A/B).
|
||||
static const int s_t2clock = getenv("BT_T2_CLOCK") ? 1 : 0;
|
||||
const Time savedLastUpdate = lastUpdate;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
if (!s_t2clock) lastUpdate = savedLastUpdate;
|
||||
}
|
||||
heatAlarm.SetLevel(record->heatLevel);
|
||||
@@ -2438,7 +2454,7 @@ void
|
||||
// real payload (simulationState). BT_T2_CLOCK restores the old stamp (A/B).
|
||||
static const int s_t2clock = getenv("BT_T2_CLOCK") ? 1 : 0;
|
||||
const Time savedLastUpdate = lastUpdate;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
if (!s_t2clock) lastUpdate = savedLastUpdate;
|
||||
}
|
||||
heatAlarm.SetLevel(record->heatLevel);
|
||||
@@ -2466,7 +2482,7 @@ void
|
||||
// real payload (simulationState). BT_T2_CLOCK restores the old stamp (A/B).
|
||||
static const int s_t2clock = getenv("BT_T2_CLOCK") ? 1 : 0;
|
||||
const Time savedLastUpdate = lastUpdate;
|
||||
Simulation::ReadUpdateRecord(message);
|
||||
BT_GIMP_SAFE_BASE_READ(message);
|
||||
if (!s_t2clock) lastUpdate = savedLastUpdate;
|
||||
}
|
||||
airborneSelect = record->airborne; // @0x3f4 <- rec+0x10
|
||||
|
||||
Reference in New Issue
Block a user