D243 M-154 fix: guard tick-probe render_pos read against the -1 tombstone

First live abseil run crashed inside the new probe (AV, fault addr
0xFFFFFFFFFFFFFFFF, PC in playerTick bondview2.c:10419) on the first
tick after CREATE: bodyModel->render_pos is assigned by
instcalcmatrices() during the draw pass (model.c:2453), i.e. AFTER the
probe point, so on tick 1 post-CREATE it still holds the reused
AnimModelSlot's stale 0xFF tombstone (-1). The game only dereferences
it post-chrTick, so it is legitimately unset here; the M-153-era
fields never touched it, which is why the earlier capture survived.

Guard the raw= read against NULL and (RenderPosView*)-1; rp=%p stays
unconditional so the -1 -> real transition frame is captured (a D243
data point in itself). Probe-only; zero game-code impact. Smoke: 30 s
bare boot clean, 4,059 chrdraw lines.
This commit is contained in:
James Dansereau committed 2026-09-16 16:57:39 -04:00
1 parent 90c87fa227
commit 85aa1a74e9
1 file changed
+9 -1
+9 -1
View File
@@ -10414,7 +10414,15 @@ s32 playerTick(PropRecord *prop)
* view-matrix cycling in f488pos). */
RenderPosView *d243mrp = (pp->bodyModel != NULL) ? pp->bodyModel->render_pos : NULL;
double d243mrx = 0.0, d243mry = 0.0, d243mrz = 0.0;
if (d243mrp != NULL) {
/* M-154 fix (crash on first abseil run): render_pos is assigned
* by instcalcmatrices() during the draw pass (model.c:2453), i.e.
* AFTER this probe point -- on the first tick after CREATE it
* still holds the reused AnimModelSlot's stale value, observed as
* the 0xFF tombstone (-1) at the Dam abseil. The game only ever
* dereferences it post-chrTick, so it is legitimately unset here.
* Log the pointer itself (the -1 -> real transition frame is
* diagnostic) but never dereference NULL or the -1 tombstone. */
if (d243mrp != NULL && d243mrp != (RenderPosView *) -1) {
Mtxf *d243mraw = (Mtxf *) d243mrp;
d243mrx = d243mraw->m[3][0];
d243mry = d243mraw->m[3][1];