Commit Graph
973 Commits
Author SHA1 Message Date
James Dansereau f242992360 D245: water tiled at the wrong size + s16 sky/water vertices; D242 closed
The IsWater 32x32 CI8 image (drawn through an RGBA16 tile, D229) was
imported with its mip chain as 32x43 and normalised as 16 wide, so the
pattern ran at 2x and wrapped every 43 rows instead of the N64's 32:
fold steps made it jump. Import the base level only and use CI8
geometry in the tri path. Sky/water fans now go through a port-only
G_FLOATVTX_EXT (float clip positions + S/T) instead of s16 Vtx, removing
the tc shift and wScale quantisation jitter. User-verified vs 1964;
golden 3/3; Win + Linux build. A/B: GE_D245_OLDVTX / GE_D245_OLDTEX.
2026-09-26 18:56:52 -04:00
James Dansereau d5f41d6a37 D242: headless death auto-advances without input; KIA screen needs a menu-launch check 2026-09-26 18:22:39 -04:00
James Dansereau d061ca3d12 D303: model converter copied 1/4 of each star muzzle flash's vertices
The op-22 DisplayListPrimaryRecord count is the number of star-flash
arms; dorottex (and PD's modelRenderNodeStarGunfire) read count*4
vertices. d43_emit/d43_convert sized the array as count vertices, so
3/4 of every muzzle star came from neighbouring sidecar bytes and drew
as long spikes (M16 "shooting up"). Size it 16*4*count. Emitter
round-trip checks all pass; M16 renders a clean star headless.

Also TEMP GE_STARTWEAPON (bondview_r.c) for weapon repros. Re-run
tools_pc/d43_emit.py to regenerate data/pcmodels-*.
2026-09-26 18:15:17 -04:00
James Dansereau 00b0006971 D307: security cameras read the mount pad as their look-at pad
CCTVRecord's own s32 `pad` (the look-at pad) shadows the inherited
ObjectRecord `pad` (mount pad) under IDO. The PC struct renamed it
`lookpad` to satisfy GCC, which silently re-pointed setupCctv's reads at
the mount pad, so every camera's look vector was its lens offset and the
lens faced the wall. Read `lookpad` on PC (#ifdef PORT, A1 class);
matches PD's setupCreateCctv (lookatpadnum). User-verified vs 1964,
golden gate 3/3. Porting-notes gains the duplicate-member rename trap.
2026-09-26 18:00:40 -04:00
James Dansereau 40b6994504 Findings: 1964 comparisons — D174/D308 faithful; D307/D303/D245 confirmed port bugs; D242 N64 reference 2026-09-26 17:46:57 -04:00
James Dansereau 116a9db798 Findings: close D183 D298 D202 D315; D220 merged into D303; D242/D303 to 1964 list 2026-09-26 17:39:29 -04:00
James Dansereau 035d54dd66 Findings bookkeeping: user status calls + stale-row cleanup (M-201)
User-confirmed fixed/closed: D289 D285 D160 D156 D152 D235; approved
closes D286 D296 D85, D323 parked as an enhancement; D218 shipped as
DrawDistance. Shipped QoL rows D180-D216 and D333-D338 marked fixed;
D318/D320/D321 fixed via D329; D236 sub-passes D265-D280 closed.
D186/D339/D202/D207/D174/D308 annotated with user direction.
2026-09-26 17:36:48 -04:00
James Dansereau 506cd7ed11 D207/D241: shot-sound handle probe; live captures refute drop/starvation
TEMP GE_D207S (gunfire.c, #ifdef PORT, read-only) logs every player
shot-sound decision (H1/H2/SKIP). Four user captures incl. a 7-weapon
stress test at 60 fps: 0 SKIP, 0 voice drops, audio production at rate.
The one captured drop-out ran under GE_AUDIOTRACE, whose audio-path file
I/O is a likely cause. Still open as intermittent.
2026-09-26 17:26:06 -04:00
James Dansereau b8e34c7fac D287: user-confirmed fixed (idle-unfocused click-in, mouse checks) 2026-09-26 16:55:58 -04:00
James Dansereau 8f838316c0 Q7: declare atoi/lround for port TUs; D207: ZHOLD/ZREL harness, findings
optionsoverlay.c called atoi and lround through implicit int declarations
(GE's stub stdlib.h/math.h shadow the CRT, D324 class); atoi joins the
other K&R decls in port/shim/stdlib.h, lround gets a local prototype.
Windows + Linux builds clean of both warnings.

GE_INPUTSCRIPT gains ZHOLD/ZREL (sustained fire) for automatic-weapon
audio repros. D207/D241: headless burst-fire at 60 vs 30 fps with the
alarm forced logged zero voice drops at both caps; owed a real-play
capture. Golden gate 3/3.
2026-09-26 16:53:54 -04:00
James Dansereau 0097469810 D291/D306: close Dam intro truck glitch as faithful; add repro probes
D291 (user-captured) is D306: Dam intro camera 5, truck over the walkway
camera; reproduces at FovScale 100. All PC-specific leads refuted with
evidence: FOV, depth precision/DrawDistance, depth state (every truck
triangle is opaque z-tested), near-plane handling, wheel transforms. The
image is a depth-correct view of the authored model from under the truck.
GE_ZF's earlier "real fighting" was a +-255 z quantisation artefact.

TEMP tools: GE_INTROCAM=<n> pins the level intro's first camera
(bondview_r.c, #ifdef PORT, PRNG draw still consumed); GE_D306C depth-state
census in gfx_pc.cpp. Golden gate 3/3.
2026-09-26 15:54:46 -04:00
James Dansereau f1207e915b D252: re-sync compiled explosion DLs on every stage load; D314 confirmed
gimgSyncCompiledGlobalDLs (D68 shim) only copied texLoad's resolved
texture pointers into the compiled globalDL shadows while a slot still
held the 0xABCD IMAGESEG marker, i.e. only for the first stage (title).
Every later stage kept pointers into the title's freed texture pool, so
explosion smoke/fire/debris rendered as rainbow garbage once the stage
overwrote that memory (Facility: past the lockers). Learn the slots once,
re-sync them every stage. User-verified; golden gate 3/3.

Also: TEMP GE_D252POOL texpool/sync probe; GE_D157 F12 burst and caps
(uncapped colour match made live play 4-6 fps). D314 F10 flicker
user-confirmed fixed. Findings M-201, porting-notes C2.
2026-09-26 11:43:30 -04:00
James Dansereau aedc98e247 D252/D314/D291: explosion-debris investigation, overlay wheel race fix, Dam truck notes
- D252 (M-200): the 'rainbow confetti' is the explosion debris
  (explosionInitFlyingParticles). Statically clean for colour; 4 headless
  repros including the user's grenade-launcher trigger are all clean. Still OPEN.
- d320repro (TEMP): new explode= and cheat= actions for headless explosion
  captures; documented in GE-ENV-PROBES.
- D314: optionsOverlayScroll (host thread) rebuilt s_visIdx/s_visN and wrote
  s_sel while the scheduler thread draws the overlay. Wheel notches are now
  queued atomically and applied in HandleInput (D287 pattern). Emit and
  HandleInput share the scheduler thread. Headless file/mission select is
  pixel-stable; likely fixed together with D287, needs a user check.
- D291: truck AI mapped (ai_9 / 0x040a, path 7); headless walk did not reach it.
2026-09-25 23:20:38 -04:00
James Dansereau d07ed0f2d0 D287: apply SDL mouse-mode/cursor changes on the window thread only
input.c called SDL_SetRelativeMouseMode / SDL_ShowCursor from the scheduler
thread (every controller poll) and from the host thread's focus/click
handling at the same time. SDL's mouse API is not thread-safe; on Windows
relative mode starts/stops the raw-input thread, and clicking back into the
window after being unfocused is exactly when both threads flip it - the D287
freeze trigger. Callers now record the wanted state; inputApplyMouseRequests()
applies it on the host thread from videoPumpEvents(). Queue-deadlock leads
ruled out statically. Win+Linux build clean, golden 3/3; freeze re-test owed.
2026-09-25 22:37:46 -04:00
James Dansereau 2ed84ed38b Q7 audit fixes: missing returns in front.c menus, getenv prototype, dram.c shift UB
- front.c: constructor_menu07_missionsel / constructor_menu0D_missioncomplete
  fall off the end while the caller uses the Gfx* result; return DL under
  AVOID_UB (porting-notes D6). Old/new objects disassemble identically at -O2,
  so no behaviour change on this compiler; clang/arm64 no longer rely on luck.
- libultra/audio/event.c: include <stdlib.h> under PORT so getenv() is not an
  implicit int-returning declaration (D324 class).
- dram.c: DRAM_SIZE >> 32 on a 32-bit unsigned long (Win64) was UB.
Golden gate 3/3.
2026-09-25 22:30:48 -04:00
James Dansereau edddf87429 D322: prefer DirectSound over SDL2's WASAPI backend on Windows
Four simultaneous drain monitors on the same USB interface: WASAPI (512 and
2048 samples) fell to 81-88% drain for ~30-50 s every ~317 s and lost 1.4% of
playback, while DirectSound stayed at exact real time. Each WASAPI shortfall
overflowed the audio queue and dropped blocks (the periodic garbled bursts).
audioInit() now hints directsound,wasapi; SDL_AUDIODRIVER still overrides.
Golden gate 3/3; 60 s GE_D204 run clean after load.
2026-09-25 22:25:13 -04:00
James Dansereau 2a20a93318 D322: periodic 'garbled' bursts are the host audio device, not the port
A no-game SDL drain monitor (new tools_pc/sdl_drain_monitor.c, opens SDL
exactly like port/src/audio.c) shows the maintainer's Focusrite USB interface
draining at 88-95% for ~15 s every ~312 s, matching the in-game overflow
bursts' period. Level loads, combat, the SDL pull pattern and a
pacemaker-vs-vsync beat were ruled out. Remaining D322 items: the 8-voice SFX
cap (D207/D241) and #87's progressive decay. porting-notes: measure the host
device before chasing periodic audio glitches.
2026-09-25 19:15:22 -04:00
James Dansereau 82548a0fe9 findings: 2026-09-25 release playtest close-outs + D322 capture
D311 FIXED (root cause D336; 0 anomaly lines incl. Caverns combat), D288
CLOSED, D294 and D330 user-confirmed, D235 still unreproduced. D322: pools
healthy (leak hypothesis refuted); SFX soft-cap saturation in firefights
(D207/D241) plus a new periodic SDL output-queue overflow every ~314 s that
starts at the title screen, so it should reproduce headless.
2026-09-25 18:40:26 -04:00
James Dansereau 7baf490020 tools_pc: golden_gate.sh — one-command per-patch golden gate
Pins data/ge007.ini to a defaults-only 640x480 window (restored on any exit),
captures Bunker 1 at 640-1120:240 and runs framediff.py against the golden
baseline. --level/--dump give a capture-only smoke run (exit 0 = frames
captured and no crash). Full framediff output goes to scratch/.
2026-09-25 16:46:03 -04:00
James Dansereau 251fcc4194 docs: fold drop-in ROM Part B backlog (issue #85) into release-dropin-rom-plan 2026-09-25 10:47:59 -04:00
James Dansereau 684dee9127 D231: park mute-on-focus-loss/screenshot QoL (deprioritized; branch retired from GitHub) 2026-09-25 10:45:11 -04:00
James Dansereau 709959c66a docs: cut-content research round 2 — decomp-only discoveries + full music alignment
New findings not covered by TCRF's articles (full detail in local
backlog/cut-content/RESEARCH.md):

- The shipped game's M16 pickup text still reads 'an AR33 assault rifle'
  (LpropobjE PROPOBJ_STR_2A, propobj.c:10471); unused 'US AR33' strings and
  PROP_CHRM16 comments survive too.
- Klobb rename scar verified: GUN_STR_6B is the only out-of-alphabetical-order
  weapon name in LgunE.c, exactly as TCRF's prerelease page describes.
- cartrifle + wristdart: full pickup/prop resources, no ITEM_ enum, no weapon
  stats — cut weapons missing from TCRF's unused-items list (wrist dart = the
  AMMO_DARTS hardware; decomp comments it '(BETA)').
- All four Bonds mapped: CUFF_/BOND_ Connery/Dalton/Moore enums + the
  actor-switch code in bondview2.c with every branch flattened to Brosnan;
  no former-actor models exist in the ROM (80 C*Z chr models enumerated).
- Cuba (LlenE.c) is the only orphan level with recoverable text: cut Natalya
  dialogue, title card, alternate credits cast.
- Orphan-level geometry confirmed present in ROM (obseg.h segment decls);
  what's missing is mission setup, not geometry.
- Music enum vs Notes-page GS index aligned slot-for-slot through 0x2C with
  four local mismatches past it (49/52/54/59) pending in-game audition.
2026-09-25 10:44:44 -04:00
James Dansereau 019ec2f233 D226: cap HUD scale at 150% (user playtest: works, little benefit above 150) 2026-09-24 11:40:43 -04:00
James Dansereau 062f605520 plan: reconcile v0.4.0 rows (D226, D237, D238, D294, D311) + session additions (D336-D339, #105 note) 2026-09-24 11:29:21 -04:00
James Dansereau cd651000ca D226: findings write-up (implemented, verified) 2026-09-24 11:29:03 -04:00
James Dansereau 3072035417 D226: HUD scale option (Game.HudScale 75-200%) — fast3d G_HUDSCALE_EXT rect scaling about per-element anchors
Ammo (per-hand corner), bottom messages/title card (bottom-left) and top
dialogue (text origin) scale with crisp glyphs; dialogue and bottom
messages are width-capped because their line breaks are authored. 100%
emits nothing (golden 3/3). Captures verified at 150/200%; Win + Linux.
2026-09-24 11:28:29 -04:00
James Dansereau 0de97b9c67 D311: likely root-caused by D336 (head-bob alias read); headless Caverns clean at 2x pool; close after a live combat session 2026-09-24 11:13:42 -04:00
James Dansereau 36de85e789 D339 (#92): GE_PERFSTAT perf probe + measured CPU budget (CPU likely not the low-end bottleneck; GPU suspect)
Env-gated per-frame timing: render phases, tris/batches, game-thread busy,
GL_TIME_ELAPSED GPU timer. Measured ~2.1 ms/frame total CPU on the heaviest
levels here; the GPU timer is only meaningful when GPU-bound. Target-hardware
numbers needed before a low-end preset. Golden 3/3; Win + Linux builds.
2026-09-24 11:11:47 -04:00
James Dansereau 02c361c909 D337/D338: user feel check ('Seems good'); legacy AimStyle migration exercised live 2026-09-24 10:57:15 -04:00
James Dansereau 827ab54288 D338: Aim range option — PC (default, full-screen GEPD feel) or N64 (original 65% stick limits, camera turn from ~49%)
Scales the mouse accumulator's screen mapping and edge-scroll threshold; aim
entry adopts through the game's screen mapping so it never jumps. Measured:
PC 98%/72%, N64 65%/49%. Golden 3/3; Win + Linux builds.
2026-09-24 10:52:42 -04:00
James Dansereau 2d2f56b050 docs: GE_AIMLOG + scripted mouse/aim tokens in the probe catalogue (D337) 2026-09-24 10:40:26 -04:00
James Dansereau 1a33cc09b5 D337: fold aim modes (N64 via PD integration default, Centred (PC) opt-in); Q/L + Toggle aim routing; per-device mouse integration; scripted-mouse aim harness
- Input.AimMode 0=N64 (D332 PD-integration, default) / 1=Centred (PC); legacy
  AimStyle/PdMouseAim migrated; hidden Input.AimLegacyGepd fallback.
- Mouse aim routing follows RMB/Aim, Q/L (the game's second aim button), and
  insightaimmode (Toggle aim, pad): removes the accidental Q 'FPS aim'.
- The PD game hook only feeds the mouse while the mouse is the active aim
  device, so pad/keyboard stick aim is not swallowed.
- Harness: GE_INPUTSCRIPT MDX/MDY/RHOLD/LHOLD/RREL + GE_AIMLOG; measured old
  vs new: same screen range and edge-scroll, jitter equal headlessly.
Golden 3/3; Win + Linux builds.
2026-09-24 10:40:16 -04:00
James Dansereau d3b4b9cd0a D336: user-confirmed (Facility>Frigate, Runway>Frigate; 0 D156 in a 14-level session) 2026-09-24 10:12:03 -04:00
James Dansereau 91564f79b6 docs: porting-notes on dead placeholders after inlining a split struct (D336); probe catalogue 2026-09-24 09:58:09 -04:00
James Dansereau f73599f449 TEMP diagnostics: GE_D235_NEXT (load a different stage after abort) and D85TEX per-stage texture-pool size/range line 2026-09-24 09:57:55 -04:00
James Dansereau c5f0d1b741 D335a follow-up: reset the scissor after the pillarboxed front end so the squeezed scissor can't carry into the first stage frames 2026-09-24 09:57:55 -04:00
James Dansereau 38354e1c7e D336: fix Frigate 'everything breaks but the gun' — head-bob anim read uninitialised alias fields (A1, D100 follow-up)
bheadAdjustAnimation read player->field_5C0 / animFlipFlag, which on N64
are raw-offset aliases of the inline player.model (model.animframe1 /
model.gunhand). Since D100 made model a real inline struct on PC they were
separate, never-written fields: Bond's head-bob start frame came from
uninitialised player-struct bytes (2e32 etc.), poisoning his model anim
(D156) and wrecking the scene. The D294 2x room pool only moved the player
struct onto dirtier memory. Read/write the real model fields.

Found with gdb hardware watchpoints (field never written). Headless repro
Runway -> Frigate -> turn now clean, D156 0; golden 3/3; Win + Linux.
2026-09-24 09:57:55 -04:00
James Dansereau b74d2738fd backlog: D335b F10 overlay pillarbox (polish) 2026-09-23 15:40:54 -04:00
James Dansereau 8e07bced9d D334/D335: 16:9 smoke sweep over 16 more levels — all render, no crashes, no slabs 2026-09-23 15:40:09 -04:00
James Dansereau 89a9875542 README: drop the fixed gun-barrel widescreen note (D335a) 2026-09-23 15:29:57 -04:00
James Dansereau 9232ea180f D335: wrap end credits; fix D335a gun-barrel bar leak (full-canvas scissor under the pillarbox)
Verified at 16:9: -level_54 ending subtitles/cast roll keep their shape;
gun-barrel backdrop now clips at the 4:3 edge. Emitted only for windows
wider than 4:3. Win + Linux builds clean.
2026-09-23 15:29:48 -04:00
James Dansereau 66b33f7f45 D226: design refinement — HUD scale needs a fast3d span transform (boxes + text + icons), not per-glyph scaling 2026-09-23 15:00:38 -04:00
James Dansereau 91bd0f84b7 D237: F10 overlay category headers (DISPLAY/VIEW/MOUSE/CONTROLLER/GAME) + SkipIntro, Show FPS, pad invert/deadzone/trigger rows
New non-selectable ROW_HEADER kind: navigation, wheel and clicks step over
headers. Wheel scroll already existed. Port-only; Win + Linux builds clean;
overlay capture verified.
2026-09-23 14:59:37 -04:00
James Dansereau 7a541da877 plan: widescreen done (D334/D335) 2026-09-23 14:57:07 -04:00
James Dansereau ae1b39ff25 README: native widescreen replaces the stretched-4:3 known issue and roadmap entry (D334/D335) 2026-09-23 14:56:50 -04:00
James Dansereau f62bceaf88 D335: native widescreen, HUD + front end (Option B Phase 3)
HUD elements now keep 4:3 proportions via fast3d's EXT aspect modes (the PD
pattern): watch, gauge bars, messages/title card, upper text and countdown
CENTER; ammo RIGHT (right hand) / LEFT (left hand). The front end is
pillarboxed (whole menu_jump_constructor_handler CENTER) and the menu
pointer is mapped into the pillarbox. port/include/hudaspect.h emits only
when native widescreen is on and the window is wider than 4:3, so 4:3 and
native-off stay byte-identical. Rule-2 approved.

Verified with 16:9/21:9 captures (HUD, watch, title card, legal, file
select, gun barrel); golden 3/3; Win + Linux builds. Gun-barrel circle
leaks into the bars while sliding in -> GRAPHICS-BACKLOG D335a.
2026-09-23 14:56:29 -04:00
James Dansereau d5d9a36a6f D334: native widescreen, world side (Option B Phase 2) — Video.NativeWidescreen
Generalise GE's own N64 16:9 mode (aspect = vp_ratio*0.75*16/9, the TV
pre-squash) to the real window aspect: the port's canvas->window stretch is
that TV, so the world renders undistorted at any aspect (Hor+, vertical FOV
kept). All of GE's 16:9 special cases generalised under #ifdef PORT (camera
aspect NTSC+EU, crosshair sprite width, rocket viewmodel offset); Rule-2
approved. Phase-4 vertical FOV boost is skipped while native is on (would
double-count); room-pool aspect term kept. Default on; F10 row.

4:3 identity (golden 3/3); native 16:9 centre == 4:3 frame (diff 4.3 vs
12.4 stretched); 21:9 clean on Bunker/Facility/Dam; Win + Linux builds.
HUD still stretched (Phase 3 next).
2026-09-23 14:44:46 -04:00
James Dansereau 639a112b9b D333 (#104): Input.AimStyle — N64 / PD damp / centred FPS-style aim on RMB
One F10 selector ("RMB aim style") instead of stacking toggles. CENTRED
routes RMB-held mouse motion to hipDirectCompute (FOV-scaled) and emits no
aim stick, so the game's aim integrator keeps the crosshair centred: the
behaviour the reporter found on Q (game L button), now on RMB. PD DAMP is
D332 (PR #96); legacy Input.PdMouseAim=1 migrates to it. Default N64 =
unchanged. Port-only.

Windows + Linux builds clean; bunker1 golden 3/3. Feel check owed.
2026-09-23 14:34:24 -04: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
James Dansereau 3a7c5d06c5 plan: fix D235 commit ref after amend 2026-09-23 13:34:24 -04:00