Commit Graph
4 Commits
Author SHA1 Message Date
Dan Turner 3785dcad33 macos: fix the pointer-truncation crash family, add PORT_ADDR_STRICT (D301-D308)
Census-driven: rebuilt the compiled set with -Wint-to-pointer-cast
-Wpointer-to-int-cast -Wint-conversion, giving 276 actionable sites, triaged
in three disjoint file groups. Group A (206 warnings) and most of C were
already-correct round trips; these are the real bugs.

- D301: chrCreateBloodStain() crashed on guard gunfire. Two defects —
  portN64ToHost(0) returned base+0 instead of NULL (defeating the decomp's
  `if (p != NULL)` failure checks), and Vertex.CollisionRelatedNode (a u32 vma
  kept 32-bit by PROMOTE32) was read with a bare cast.
- D302: six more truncations. Four are the "twin function" pattern — one of a
  near-duplicate solo/MP pair converted, the other missed. Includes bg.c:5213,
  where a truncated loop bound meant bgRoomCalcBB() never ran its body on
  arm64, leaving EVERY room in every level with an inverted bounding box.
  Silent, not a crash. Possible relevance to open D249.
- D303: texReadUncompressed() aligned its destination through u32. Latent —
  a probe over a full level boot showed the path is unreachable on PC
  (textures come from the pre-converted sidecars).
- D306: MSAA=8 produced a completely black screen. GL_MAX_SAMPLES is 4, and
  nothing clamped the request, so the renderbuffer was never allocated.
  video.c's own comment claimed MSAA "snaps down to the highest supported
  level"; it did not. Also fixed two index-vs-GL-name bugs in the same file.
- D308: the watch's Control page crashed. options.c cast a stack-local table
  pointer to (s32) before passing it as WatchContButtonPositions*, and
  watchRenderControllerOpaque forwarded the truncated value. Verified A/B
  against the user's exact repro — fault address byte-identical.
- D305: PORT_ADDR_STRICT, a debug gate (off by default, compiled out) that
  validates every u32->host conversion against the regions the port maps and
  reports offenders with a backtrace. Zero reports across 6 levels, 5 of them
  under full-control input.

Also records D307 (reticule jitter in aim mode) in the finding log as OPEN,
with the cause identified from live captures and no code change — an attempted
fix was reverted for not working.

Verified: clean build, 21/21 sweep, plus a targeted repro per fix.
2026-10-04 10:50:01 +01:00
Dan Turner 498be832c2 macos: packaging, sweep tooling, and two runtime fixes (D299, D300)
- tools_pc/bundle-mac.sh: a signed, double-clickable GoldenEye.app. Homebrew's
  libstdc++/libgcc_s and SDL2 are not system libraries, so they are bundled
  and rewritten to @executable_path/@loader_path. Note sdl2-compat (Homebrew's
  `sdl2`) finds its SDL3 backend through a RELATIVE rpath baked into the dylib,
  so SDL3 ships too and that rpath is repointed — copy it without that and
  sdl2-compat raises a modal error dialog from its initialiser and the app
  hangs before main(). prepare-assets/ goes in Contents/Resources/: codesign
  treats a directory under Contents/MacOS/ as nested code and fails the bundle.
- tools_pc/level_sweep_mac.sh: per-level crash-log sweep, symbolicated with
  atos, with a rendered-pixel check so "runs but renders nothing" is caught.
- D299: sndPlaySfx() rejected EVERY sound on arm64 — all in-level SFX were
  silent, while music played (separate player). Its guard predated the shifted
  window: `sp >= 0x400000000ULL` (16 GiB) is correct on x86_64 (DRAM at
  0x70000000) and rejects everything on arm64 (DRAM at ~0x1000_707b_5740).
  Fixed with a portAddrIsInWindow() helper rather than absolute bounds.
- D300: cleanupObjects() did `u32 *obj = (u32)g_CurrentSetup.propDefs`,
  truncating a host pointer to 32 bits. Crashed at stage unload — only
  reachable once a level actually ends.

Verified: 21/21 on both the no-input and full-control sweeps; SFX voices
allocate on every level.
2026-10-04 10:50:01 +01:00
Dan Turner d4cc71af0a macos: native Apple Silicon (arm64) support — address model, boot chain, 21/21 levels
Adds native arm64 macOS support on top of #88's Intel macOS layer.

The one structural change arm64 needs is an address model. The port realises
the N64's 32-bit address space *as host addresses* — DRAM at 0x70000000, cart
at 0x10000000, plus ~1700 linker-absolute symbols — which is only sound while
host addresses fit in 32 bits. Native arm64 cannot map below 4 GiB
(__PAGEZERO; a shrunken pagezero is SIGKILLed at exec; PIE is mandatory;
MAP_32BIT fails). So the whole space is relocated to a fixed host base,
PORT_ADDR_BASE (16 TiB), with portN64ToHost / portHostToN64 / PORT_N64PTR as
the conversion chokepoints. PORT_ADDR_BASE is 0 on every other platform, so
all of this is an identity there.

That relocation then surfaces a class of latent 64-bit bugs that are invisible
at base 0 — any place the decomp round-trips a pointer through a 32-bit
integer. The src/ changes here are that class: pointer-width/layout only, no
behaviour change, N64 branch textually unchanged, each documented in
docs/dev/findings.md (D298/M2).

Also: Mach-O absolute-symbol generation at the same base, #pragma weak ->
symbol equates, __x86_64__ -> PLATFORM_64BIT, Darwin crash handler/ucontext,
shm_open DRAM, the AppKit main-thread guard, and the sidecar generation that
was the real boot blocker.

Verified: 21/21 solo levels boot, render and run crash-free.
2026-10-04 10:50:01 +01:00
Dan Turner 05e5525db9 input: fix reticule jitter in aim mode — adopt the PD mouse-aim model (D332, PR #96)
Opt-in Input.PdMouseAim (F10 "PD mouse aim"): in aim mode the port only
accumulates the mouse position and the game's own crosshair integrator is
driven by it with PD's mouse damp (0.01), instead of GEPD's per-poll
overwrite fighting the weapon's ~0.8 per-tick damp (write*damp^k jitter).
Hook: #ifdef PORT block in sub_GAME_7F067FBC (aim-mode branch only),
identity when off; Rule-2 sign-off given by the maintainer.

Integrated locally from PR #96 with review fixes: finding renumbered
D337 -> D332; GE_PDMOUSEAIM lookup cached (GE_ENVSTR; it ran every poll
and aim tick); "live env" comments corrected. Windows build clean; bunker1
golden 3/3. Feel A/B owed.
2026-09-23 14:29:27 -04:00