forked from Ports/goldeneye-pc-port
docs(D148/D160/D173): re-confirm propDef stride ruled-out; rule out PadRecord.stan and act_anim aliasing for puppet-position bug (#61)
Investigation pass on the cutscene-reliability cluster (D148/D160/D173), part of the 1.0 acceptance-bar #4 push. No build/runtime toolchain was available in this worktree (no gcc/cmake on PATH, MSYS2 MINGW64 not active), so this is a static-analysis-only pass; no code changes. D160 (Dam end-cutscene / D148 label): independently re-derived (not just re-cited) that hypothesis (a), a propDef sizepropdef() stride desync, is ruled out — CutsceneRecord (propDef type 46) is all-scalar, 28B, zero pointer/union fields, so the D122/D126/D132/D209 pointer- width-growth class cannot apply. Confirms the existing M-31 audit recorded in porting-notes.md. Hypotheses (b)/(c) (AI trigger flow / invisible puppet render) remain unconfirmed — still need the shipped GE_D160=1 trace driven live. D173 (third-person Bond puppet floats / spins in cutscenes): checked the two most D209-shaped candidates for a puppet Y-position aliasing bug and ruled out both. (1) PadRecord.stan is a ROM-serialized pointer field zeroed by tools_pc/d88_emit.py's emit_pad() with a "dead-on-load" comment; verified against the N64 source asset tables (UsetupdamZ.c) that every PadRecord literal initializes stan to 0 on N64 too, so the PC zeroing is byte-identical to ground truth, not a converter bug. (2) The anim-root-motion Y-accumulation chain was already exhaustively audited during D193/D209 (M-80/M-81) and the padding[]-union sweep that found D209/D210 explicitly cleared act_anim/act_dead as layout-stable. Root cause not found; the D209-style struct-aliasing pattern does not appear to be the shared explanation here, unlike the hope stated in the dispatch brief. Flagged next steps: a live Cradle capture, and locating the actual two-actor Cuba end-credits code path (not found this session). Added a generalizable porting-notes.md quirk: before assuming a zeroed ROM-serialized pointer-width tail slot is a converter miss, check the N64 source literal — some fields are legitimately always NULL on both platforms. Claude-Session: https://claude.ai/code/session_016TaKy6AAsVUTfjkhrX6CjG
This commit is contained in:
1 parent
650ac57fc6
commit
7e99344741
2 files changed
+22
-2
No files matched your search
@@ -340,6 +340,26 @@ through a converter or a runtime bswap fixup reads scrambled.
|
||||
elsewhere. The Dam rappel cutscene (D148) reached this wall: data path proven intact;
|
||||
residual cause is runtime AI-script control-flow / `CAMERAMODE_POSEND` cinematic
|
||||
render (D75 family). `GE_D160=1` diagnostic ships; needs a live Dam-to-exit playthrough.
|
||||
**M-106 addendum:** independently re-derived (not just re-cited) — `CutsceneRecord`
|
||||
(propDef type 46) has zero pointer/union fields, so it cannot exhibit this class at
|
||||
all; confirms the M-31 stride audit rather than superseding it. D148/D160's residual
|
||||
cause is still unlocated (needs the live trace); see D173 for a related negative
|
||||
result on the puppet-position side.
|
||||
- **D132/D126 corollary — a zeroed ROM-serialized pointer-width tail slot is not
|
||||
automatically a converter bug; check the N64 source literal first (M-106).**
|
||||
Before assuming an offline converter wrongly zeroed a widened pointer field
|
||||
(the D122/D126/D132 "dead-on-load" pattern), grep the asset `.c` source tables
|
||||
(`assets/obseg/**/*.c`) for that field's literal initialiser. `PadRecord.stan`
|
||||
(`src/bondtypes.h:1744-1751`) looked exactly like a D126/D132 miss — a ROM-
|
||||
serialized tail pointer, zeroed by `tools_pc/d88_emit.py`'s `emit_pad()` — but
|
||||
every `PadRecord` in every checked setup table (`UsetupdamZ.c` etc.) initialises
|
||||
`stan` to literal `0`; N64 never carried a live pointer there either, so the PC
|
||||
zeroing is byte-identical to ground truth, not a regression. The tell that saves
|
||||
the trip: if the *source*, not just the ROM binary, always writes `0`/`NULL` for
|
||||
a field, it was never "dead-on-load" in the D123-corollary sense (a field that
|
||||
reads a real small int/id before being overwritten) — it's simply always
|
||||
runtime-computed, on both platforms, and a NULL seed into whatever consumes it
|
||||
is the original game's normal case, not a port defect.
|
||||
- **D151 — a ROM-serialized `s32` slot decoded by the struct as `[u16 hi][u16 lo]`
|
||||
reads zero on LE.** N64 code frequently splits a 32-bit setup-stream word into
|
||||
`u16 reserved; u16 realvalue;` where the useful value is always small and lands
|
||||
|
||||
Reference in new issue
Block a user