Commit Graph
941 Commits
Author SHA1 Message Date
James Dansereau 462675cf47 optionsoverlay.c: Turok-style regroup - DISPLAY/GRAPHICS split, BOND FILE absorbs music/FX, designated rows, overflow log, file-scope title annotation (D353) 2026-09-27 13:32:39 -04:00
James Dansereau 8e9bee6ef0 watchsettings.c: D350-bridge robustness - hold-not-drop at stage transitions, chooser spinlock, queue coalescing, warning logs (D352) 2026-09-27 13:32:18 -04:00
James Dansereau 1303c0ebe1 D350: expose watch-backed Bond settings in PC options and F10
Add a game-thread bridge and field-scoped per-file persistence for PC UI edits, with an explicit file chooser; keep watch-only edits session-only. Fix D351 row initializer offsets for units and auto-hide. Document verification and review follow-ups.
2026-09-27 13:20:21 -04:00
James Dansereau 98a24a07f4 Docs: close D343 (NTSC verified; PAL/JP not capturable locally) 2026-09-27 12:30:14 -04:00
James Dansereau 050c3981d6 D348: mini slider glyph beside the file-select PC Options label
No settings icon exists in the game art (mainfolderimages holds only
copy/del/select-arrow/X/check/dot), so a miniature slider control is drawn
instead: three menu-box tracks with offset knobs in the 14px gap after Erase
(10px wide, 2px margins), INK_DIM tracks, knobs matching the label ink
(white / gold while hot). Tracks the dynamic label x (JP-safe), text position
unchanged; hot region extended to include the glyph. PCDUMP pixel-verified.
2026-09-27 12:24:56 -04:00
James Dansereau 7e07d9e018 D347: F10 overlay controller value-adjust + hold-to-repeat
D-pad left/right and stick-X now adjust the selected row's value (A/X/B/Y
kept); 18/4-frame hold-to-repeat added to value adjust and up/down nav,
matching the options screen's D345(e)/(f) cadence. Port-only; user
controller test verified.
2026-09-27 12:18:36 -04:00
James Dansereau 7ff9ddbe14 D345/D346: options-screen pointer + keyboard nav fixes; settings wording pass
D345 (a-g): re-assert window on menu change; cursorToItem skips snap while
the 1:1 pointer is live; W/S emit stick in menus under NaturalPitch;
F10-style discrete row stepping + arrow left/right value adjust replace raw
drift (first pass shipped broken, fixed); screen-placed cursor parks in the
left gutter off the row text.

D346 (+b): labels/values aligned to Nightdive/Turok + PD-port conventions
(title-case On/Off, Frame rate cap, Anti-aliasing/None, Anisotropic
filtering, units in values not labels, deadzone as %, self-explanatory
auto-FOV toggles); VIEW section merged into VIDEO (MAX_PROWS 12->15,
ROW_DY 20->18). Display-only: config keys and stored values untouched.

Port-only; no src/game edits. User playtest verified.
2026-09-27 12:12:32 -04:00
James Dansereau 835035916d D343: PC Options joins the file-select bottom bar; Copy/Erase shift left
Rule-2 layout edit (user sign-off 2026-09-27): Copy 247/225 -> 222/200,
Erase 357/335 -> 304/282 under #ifdef PORT; their click boxes follow.
"PC Options" is drawn by the port hook right after Erase's measured text
end (min x 352), so wider localised labels push it right. The top-right
label is gone.
2026-09-27 11:01:58 -04:00
James Dansereau 13473d5ec6 D343: PC options as a GE front-end screen (MENU_PC_OPTIONS)
Replaces the M2 panel. Built like the Cheat Options screen: open dossier
(tabs + blank CLASSIFIED page), black Zurich ink via frontPrintText, GE's
highlight box, PREVIOUS tab as back, the game's crosshair. Page 0 is a
numbered section list; each section lists the F10 overlay's rows with a
value column (ON in the cheat red) and slider bars.

Game code (Rule 2, user sign-off 2026-09-27): MENU_PC_OPTIONS enum value
and five one-line dispatch cases, all #ifdef PORT. The file-select label
now enters the screen via frontChangeMenu. The M2 button hand-off in
input.c is gone; F10/Select don't open the overlay on this screen.
2026-09-27 10:58:27 -04:00
James Dansereau e4cf012410 D343/D344: record user verification on PC 2026-09-27 10:41:25 -04:00
James Dansereau fd82dda717 D343 M2: GE-styled options panel on file select; D344 docs
The file-select Options label opens a panel drawn in the same hook:
sections as tabs, rows from the F10 overlay's table via an exported row
API, the game's crosshair as pointer (input.c passes the stick, hands the
buttons to the panel). Quit to desktop now goes through videoRequestQuit.
Also repairs two escaped-newline typos in the D343 docs.
2026-09-27 10:38:16 -04:00
James Dansereau 461ea871c2 D344: orderly quit so exit never lands inside the GL driver; GE_QUITFRAME
Quit (quit event, window close, Alt+F4, from either SDL pump) used to
exit(0) immediately while the render thread could be mid-frame in the
driver: the likely trigger of the host's 0x119 bugchecks. Now quits are
requested; the render thread glFinish()es, unbinds the context and parks
at a frame boundary, and the host exits after (max 2 s). GE_QUITFRAME=<n>
gives the harness a clean self-quit; golden_gate.sh uses it.
2026-09-27 10:38:16 -04:00
James Dansereau c07af11fae D343: record user playtest (all but a physical controller confirmed) 2026-09-27 10:07:22 -04:00
James Dansereau 413014b8f6 D343: file-select Options label opens the settings overlay; F10 idle-timer fix
One Rule-2 #ifdef PORT draw hook in constructor_menu05_fileselect (user
sign-off 2026-09-27). The label's hit test and open request live in
optionsoverlay.c; the open is applied on the input thread. While the
overlay is open on file select, g_MenuTimer is held at 0 so the screen no
longer drops to the legal screen after 30 s.
2026-09-27 10:01:27 -04:00
James Dansereau bd8ade5c1e D307: note camera reaction timing is tick-based and faithful 2026-09-27 00:31:57 -04:00
James Dansereau 60f12f2bba D245 follow-up: water base-level crop never ran (coloured dashes)
The crop tested loaded_texture.line_size_bytes, which is the whole
LoadBlock (1400 B), so the water still uploaded 32x43 while UVs were
normalised to 32 rows; the mip rows showed as coloured dashes. Test the
tile line size instead. User-verified on Frigate; golden 3/3.
2026-09-27 00:31:24 -04:00
James Dansereau 4ba1454ba8 D342: file-select folders vanished after backing out of a file
The PC wallet model (0x1664C B, 0x17000 reservation) loads at the start of
ptr_logo_and_walletbond_DL, but the file-select scratch DL and the
briefing text still used the N64 offset +0xA000 -- inside the model.
After main menu -> back the model is not reloaded, so the overwritten
folder bodies/photos disappeared. Both now use +0x17000 (same 0x6e000
budget). User-verified; golden gate 3/3. D341 also user-verified.
2026-09-27 00:16:18 -04:00
James Dansereau 5c643e3acb D341: intro gun-barrel blood drip drew static garbage
Two fast3d defects. (1) The 1-cycle blood texture rectangle sampled a
stale tile-1 CI8 declaration: the title leaves G_TL_LOD set and the D236
detail-base rule redirected texunit 0 to tile 1. LOD tile selection is
2-cycle-only on the RDP, so texrects outside 2-cycle now sample their own
tile. (2) The drip image is regenerated in place in the dyn pool (reached
via the KSEG0 mirror); the address-only cache key froze it on its first
image. Dyn-pool textures now key on a content hash. Headless-verified,
golden 3/3. A/B: GE_DYNTEXHASH_OFF.
2026-09-26 19:20:06 -04:00
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