acdream/docs/research/2026-07-02-r1-csequence/P0-pins.md
Erik 1371c2a14c feat(R1-P0/P1): CSequence research base + verbatim AnimSequenceNode
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>
2026-07-02 19:45:56 +02:00

55 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)
1. **§21 `update_internal` cleaned flow is garbled in two places.** The
authoritative skeleton is ACE `Sequence.cs:351-443` (verified verbatim,
matches the raw decomp branch layout at 0x005255d0-0x005259ca):
overshoot check → clamp `frame_number` to `get_high_frame()` (fwd) /
`get_low_frame()` (rev) + compute `frameTimeElapsed` leftover +
`animDone = true` → per-frame crossing loop → `if (!animDone) return`
AnimDone gate (`anim_list.head != first_cyclic`) →
`advance_to_next_animation` → carry leftover → loop.
2. **Hook direction constants**: forward crossings pass +1
(0x0052578c, counter `++` after), reverse pass 1 (0x0052590c, counter
`--` after). Retail encoding == ACE/DatReaderWriter `AnimationHookDir`
(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_anims` argument logs (P2/P5 goldens) — one session serves
all of R1.
- `frame_number` is x87 `long double` (acclient.h:30747); C# `double` is the
closest available → divergence-register row lands with the P2 commit
(G15).
- ACE's `PhysicsGlobals.EPSILON` subtraction in
`get_starting/get_ending_frame` is an ACE fabrication (compensating for
ACE's `float FrameNumber`) — retail returns bare ints. Do NOT copy (G1).