docs(R4-V0): pins P1-P7 resolved — the autonomous-byte gate IS retail's echo discriminator; heading_diff mirror Ghidra-confirmed

P1 (BLOCKER -> RESOLVED, no adaptation needed): retail's
CPhysics::SetObjectMovement (0x00509690) drops any movement event whose
wire AUTONOMOUS byte is set when the addressed object IsThePlayer -
BEFORE unpack_movement's unconditional head-interrupt ever runs. ACE's
mt-0 MoveToState echo is IsAutonomous=1 HARDCODED (MovementData.cs:162)
and only exists when the client itself sends a MoveToState (the
2026-05-14 'echo kills auto-walk' trace was the pre-#75 build whose
overlay leaked outbound packets - post-#75 there is no echo at moveto
start). acdream parses isAutonomous (UpdateMotion.cs:129) and consumes
it NOWHERE; MotionSequenceGate cites 0x00509690 in its own doc but
omitted this final branch. V-commits port the missing gate tail and the
verbatim head-cancel lands cleanly; the informal GameWindow
no-cancel-on-non-MoveTo note retires.

P3 (Ghidra-confirmed live, textual verdict independently identical):
heading_diff 0x00528fb0 HAS the TurnLeft mirror - 360-diff whenever the
turn command != TurnRight; the extraction's 'arg unused' was a BN
x87-setcc artifact (the W6b class). P2 Ghidra-confirmed:
get_desired_heading = fwd-towards 0 / fwd-away 180 / back-towards
180 / back-away 0. ghidra-confirmations.md holds both raw decompiles.
P4-P7 pinned per V0-pins.md. RemoteMoveToDriver's stale chase/flee
class-doc claim corrected (retail and ACE AGREE on the predicates).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-03 11:02:13 +02:00
parent 988304e13b
commit 386b1ce550
3 changed files with 384 additions and 3 deletions

View file

@ -0,0 +1,58 @@
# R4-V0 — Ghidra ground-truth decompiles (patchmem.gpr, fetched live 2026-07-03)
Authoritative resolutions for the two pins the BN pseudo-C garbled. Fetched
via the Ghidra MCP while the V0 pin workflow ran; these OVERRIDE any textual
adjudication that disagrees.
## P3 — `heading_diff` 0x00528fb0: the TurnLeft mirror EXISTS
```c
float __cdecl heading_diff(float param_1, float param_2, ulong param_3)
{
float fVar1;
fVar1 = param_1 - param_2;
if (ABS(param_1 - param_2) < F_EPSILON) {
fVar1 = 0.0f;
}
if (fVar1 < -F_EPSILON) {
fVar1 = fVar1 + 360.0f; // ___real_43b40000
}
if ((F_EPSILON < fVar1) && (param_3 != 0x6500000d)) {
fVar1 = 360.0f - fVar1; // the mirror — NOT-TurnRight only
}
return fVar1;
}
```
Adjudication of the research contradiction:
- `r4-moveto-decomp.md` §5g ("turn-command arg UNUSED") is **WRONG** — the
arg gates the mirror.
- `r4-ace-moveto.md`'s suspicion (an x87-garbled `360diff` TurnLeft branch)
is **CONFIRMED**: the mirror applies whenever the turn command is not
TurnRight (0x6500000d), i.e. the TurnLeft direction measures the
complementary angle. Port verbatim with the epsilon literal
0.000199999995f (F_EPSILON).
## P2 — `MovementParameters::get_desired_heading` 0x0052aad0: ACE-shaped constants CONFIRMED
```c
float __thiscall MovementParameters::get_desired_heading(
MovementParameters* this, ulong command, int movingAway)
{
if ((command == 0x44000007) || (command == 0x45000005)) { // Run/WalkForward
if (movingAway == 0)
return 0.0f;
}
else {
if (command != 0x45000006) // not WalkBackward
return 0.0f;
if (movingAway != 0)
return 0.0f;
}
return 180.0f; // ___real_43340000
}
```
Truth table: forward+towards → 0°; forward+away → 180°;
backward+towards → 180°; backward+away → 0°; any other command → 0°.