P0 — research + pins: full CSequence-family verbatim extraction (1756 lines, per-function raw pseudo-C + cleaned flow, decomp line anchors), ACE cross-reference (9 ranked divergences; headline: retail frame_number is x87 long double — ACE's float is the worst case, our double the best available; ACE's frame-boundary epsilon is an ACE fabrication, NOT retail), current-sequencer map, and the R1 gap map (20 gaps, 13 keeps, P0-P6 port order). Pinned the one decomp ambiguity (leftover-time carry after advance_to_next_animation — ACE reading adopted; cdb confirmation protocol recorded, non-blocking). P1 — AnimSequenceNode verbatim (gap G1/G2/G16/G18): - direction-aware BARE-INT boundary pair (get_starting_frame 0x00525c80 / get_ending_frame 0x00525cb0): reverse starts at high+1, ends at low — NO epsilon; - multiply_framerate (0x00525be0) swaps low/high on negative factor; - set_animation_id (0x00525d60) retail clamp order (high<0 -> num-1; low>=num -> num-1; high>=num -> num-1; low>high -> high=low); - ctors with retail defaults (30f/-1/-1; AnimData copy + clamp); - get_pos_frame null out-of-range (retail; ACE returns identity), floor double overload; get_part_frame same discipline; - NO per-node IsLooping/Velocity/Omega — loop membership is list structure, physics accumulators live on the sequence (G16). 22 conformance tests (clamp table, boundary mirror table, swap round-trip, bounds/floor semantics). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.9 KiB
R1-P0 — pseudocode pins and ambiguity resolutions
The verbatim extraction lives in r1-csequence-decomp.md (1,756 lines, per-
function raw pseudo-C + cleaned translation, line anchors into
docs/research/named-retail/acclient_2013_pseudo_c.txt). This note records
the corrections and pins the R1 port codes against, per the gap map
(r1-gap-map.md).
Corrections to the extraction (verified against raw decomp + ACE)
- §21
update_internalcleaned flow is garbled in two places. The authoritative skeleton is ACESequence.cs:351-443(verified verbatim, matches the raw decomp branch layout at 0x005255d0-0x005259ca): overshoot check → clampframe_numbertoget_high_frame()(fwd) /get_low_frame()(rev) + computeframeTimeElapsedleftover +animDone = true→ per-frame crossing loop →if (!animDone) return→ AnimDone gate (anim_list.head != first_cyclic) →advance_to_next_animation→ carry leftover → loop. - Hook direction constants: forward crossings pass +1
(0x0052578c, counter
++after), reverse pass −1 (0x0052590c, counter--after). Retail encoding == ACE/DatReaderWriterAnimationHookDir(Backward=−1 / Both=0 / Forward=1) — no remap.
PINNED ambiguity — leftover-time carry after node advance
Raw decomp at 0x0052598a-0x0052598d APPEARS to zero the elapsed argument
after advance_to_next_animation before looping; ACE carries the leftover
(timeElapsed = frameTimeElapsed, Sequence.cs:436-442).
PIN: the ACE reading (carry the leftover). Rationale: (a) Binary Ninja
routinely loses x87 stack-slot reassignments (the same artifact class as the
garbled setcc returns in is_newer); (b) zeroing would make a lag spike
unable to fast-forward through multiple queued nodes in one tick, visibly
freezing links under hitches — behavior nobody has ever reported on retail;
(c) the loop structure (while(true) with the leftover recomputed per
node) only makes sense with a carry.
Confirmation pending (not blocking): cdb breakpoints on
acclient!CSequence::update + acclient!CSequence::advance_to_next_animation
with hit counters (pattern tools/cdb/l2g-observer.cdb) under an induced
stall — an advance/update ratio > 1 in a single update proves the carry.
Fold into the next live retail session; if it DISPROVES the carry, the fix
is one line in update_internal + rerun of the P4 conformance suite.
P0 addenda for later stages
- The same cdb session should also capture
append_animation/remove_cyclic_animsargument logs (P2/P5 goldens) — one session serves all of R1. frame_numberis x87long double(acclient.h:30747); C#doubleis the closest available → divergence-register row lands with the P2 commit (G15).- ACE's
PhysicsGlobals.EPSILONsubtraction inget_starting/get_ending_frameis an ACE fabrication (compensating for ACE'sfloat FrameNumber) — retail returns bare ints. Do NOT copy (G1).