fix(D210): chrToPatrol leaves act_patrol.lastvisible60 uninitialised on PC

Sibling of D209 (A1 raw-byte union-alias class). chrToPatrol writes
act_init.padding[0x13] (union byte 0x4c) = -1, which is act_patrol.lastvisible60
on N64. act_patrol starts with a patrol_path* that widens 4->8 on x86-64, so
0x4c now lands in waydata and lastvisible60 (@0x50) stays uninitialised. The
patrol 'haven't seen the player recently' gate (chraction.c:~9347) then reads
garbage on the first ticks after entering PATROL.

Fix: write the named field under #ifdef PORT; N64 line verbatim under #else.
ABI/pointer-width only, no game-logic change.

Found by the post-D209 A1 sweep; the only new instance (act_anim/act_dead
padding aliases are pointer-free -> layout-stable).

Build clean; bunker1 + facility verify PASS (both patrol-heavy), no crash.
findings D210 + porting-notes A1 + findings-index regen.
This commit is contained in:
James Dansereau committed 2026-09-08 20:51:18 -04:00
1 parent 97a09665a1
commit b47eea65e3
4 files changed
+25

No files matched your search

+11
View File
@@ -3869,7 +3869,18 @@ void set_actor_on_path(ChrRecord *self, struct patrol_path *path)
self->act_patrol.forward = 1;
self->act_patrol.waydata.age = randomGetNext() % 0x64U;
self->act_patrol.waydata.unk03 = 0;
/* D210 (A1 raw-byte-alias class, sibling of D209): `act_init.padding[0x13]`
* (union-relative byte 0x4c) is `act_patrol.lastvisible60` on N64. On PC
* `act_patrol` widened by 4 (the `path` pointer), so byte 0x4c now lands
* in `waydata.segdisttotal` and `lastvisible60` (@0x50) is left
* uninitialised -> the "hasn't seen the player recently" patrol check at
* chraction.c:~9347 reads garbage on the first tick after entering PATROL.
* Write the named field. */
#ifdef PORT
self->act_patrol.lastvisible60 = -1;
#else
self->act_init.padding[0x13] = -1;
#endif
self->act_patrol.speed = 0.0f;
chrlvSetNextActPatrolStepPadPos(self);