Merge PR #123 from dolent: opt-in crosshair when not aiming (D436)

Video.CrosshairPersistent, F10 Game page after Show crosshair. Merged with
the 2026-10-01 review conditions: both display-mode presets set it off,
tip added, gunDrawSight change is draw-only (Rule 2 sign-off by the
maintainer, 2026-10-06). Default off is pixel-identical (Dam gate PASS).
This commit is contained in:
James Dansereau committed 2026-10-06 21:22:17 -04:00
commit afd86cd7f8
5 files changed
+64

No files matched your search

+1
View File
@@ -425,3 +425,4 @@ D533,FIXED,"The probe-doc drift that would have failed CI, plus three tracked-fi
D534,FIXED,Pre-release review of the 2026-10-05 local batch —,FIXED 2026-10-05 (verify.sh/capture_p7.sh INT/TERM trap; release-notes linux-gate wording; dead security-and-fidelity-status.md links; future-dated 2026-10-07 labels normalised; D526 probe dangling-e…
D540,FIXED,Fog rework (Deck playtest):,FIXED 2026-10-05 (port:
D450,FIXED,"Unplugging and replugging a controller was not picked up (user, GameSir-G7 Pro; 2026-09-29).","FIXED — port-only: the render thread's gfx_sdl_handle_events drains the same SDL queue as video.c's host pump but had no case for SDL_CONTROLLERDEVICEADDED/REMOVED, so it usually swallowed them and i…"
D436,FIXED,"Persistent (hipfire) crosshair, opt-in:",FIXED (shipped 2026-09-29; rule-2 sign-off:
1 # GENERATED by tools_pc/gen_findings_index.py -- do not hand-edit.
425 D534
426 D540
427 D450
428 D436
+44
View File
@@ -835,6 +835,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
| D407 | **Tanks cannot be boarded/exited on PC — the v0.4.0 use/reload split (D378/D393) removed the B-button tap the engine's tank handlers in `bondview2.c` consume (user report 2026-09-28, Runway/Streets)** — full `## D407` entry at file tail | PARTIAL (fix landed in v0.4.0, port-only): present `GE_CONT_B` on the use (E / pad A) rising edge only while `g_PlayerIsInTank == 1` or `g_BondCanEnterTank != 0`; E keeps its D378 no-reload-fallback semantics elsewhere, N64 layout unaffected. D407(b) same cycle: front PC Options page-edge highlight clamp + mouse-wheel / W-S paging (wheel queue consumed on the menu, D223); its wheel mapping shipped inverted and was fixed to match W/S (wheel up = step up). D407(c): board-animation lockout, menu-accept B gate in tank states, in-tank aim routed through the legacy velocity stick + `Input.TankAimScale` knob. RESOLVED 2026-09-28: all port-only (src/game zero-diff), 10 TANKDBG probes stripped, release binary verified clean, user live tank drive signed off (board + exit OK, aim feel good). |
| D408 | **`Game.SkipIntro` skips the post-mission failure dossier: with it on, entering a level then aborting (watch Z+A) or dying (KIA) returns straight to the menus — no REPORT / "Mission status: KILLED IN ACTION / ABORTED" screen** (user report 2026-09-28; save/AllUnlocked ruled out) — full `## D408` entry at file tail | OPEN (cosmetic, not root-caused past the handoff site). v0.4.0 decision: SkipIntro stays EXPERIMENTAL / not recommended for regular users — F10 row relabelled "Skip intro (EXPERIMENTAL)". |
| D450 | **Unplugging and replugging a controller was not picked up (user, GameSir-G7 Pro; 2026-09-29).** — full `## D450` entry at file tail | FIXED — port-only: the render thread's `gfx_sdl_handle_events` drains the same SDL queue as video.c's host pump but had no case for `SDL_CONTROLLERDEVICEADDED/REMOVED`, so it usually swallowed them and `inputRescanPads` never ran. Both pumps now post a request; the rescan runs at the top of `inputUpdate`, on the thread that reads the pads. |
| D436 | **Persistent (hipfire) crosshair, opt-in: `Video.CrosshairPersistent` / F10 > Gameplay > HUD > "Crosshair when not aiming" draws the native sight at `crosshair_angle` outside aim mode (2026-09-29).** — full `## D436` entry at file tail | FIXED (shipped 2026-09-29; rule-2 sign-off: user direction; presentation-only masked condition in `gunDrawSight` + `port/src/video.c`). Default off byte-identical; aim mode unchanged; netplay SH identical mixed off/on. |
Phase 2 replaced the Phase-1 demo loop with the real `mainproc()` on real OS
@@ -18313,3 +18314,46 @@ show 0-255 and step by 5; the existing value swatch is the live preview; new tip
**Migration (`video.c videoInit`):** an ini holding a former preset 1..7 becomes
Custom with that preset's RGB, so no saved colour changes (checked: 3 -> 8 with
64/64/255). Display-mode presets and resets still use 0 (Original).
## D436 — persistent (hipfire) crosshair, opt-in: the native sight drawn outside aim mode (2026-09-29)
**Status:** SHIPPED (offered from the netplay line): port-only logic + one presentation-only `#ifdef PORT` condition in `src/game/gunfire.c` `gunDrawSight` (rule-2 sign-off: user direction 2026-09-29, "constant on screen crosshair that could be enabled or disabled"; same class and same function as upstream's D373/D381 hide/colour/size/style hooks). Default off = N64.
**Spec:** `docs/dev/RESEARCH-FREE-AIM.md` option A'. The N64 sets `GUNSIGHTREASON_NOTAIMING` every tick from `moveData.aiming` (`bondview2.c:5753`) and `gunDrawSight` draws only when `gunsightmode == 0`. Every shot, hipfire included, leaves from the screen point `crosshair_angle`, recomputed every tick in both modes (auto-aim pull, stick lag), so the native sprite drawn there in hipfire shows the true aim point. `gunsightmode` has no reader but `gunDrawSight` (draw-only state).
**Implementation:**
- `port/src/video.c`: `Video.CrosshairPersistent` (0/1) next to the other crosshair options; `portCrosshairPersistent()`.
- `src/game/gunfire.c` `gunDrawSight`: under `#ifdef PORT` the visibility test becomes `(gunsightmode & ~(persistent ? NOTAIMING : 0)) == 0 && !mpmenuon`. Every other reason still hides the sprite: `GUNSIGHTREASON_1` (the "Sight on screen" option in solo, the lobby-agreed `sight` flag in MP/netplay), `NOCONTROL` (cutscenes), `DAMAGE` (the damage/death sequence) and the MP menu. In aim mode nothing changes (one sprite, the game's own). Non-PORT builds keep the original condition byte-identical.
- `port/src/optionsoverlay.c`: HUD row "Crosshair when not aiming" (Off/On) after "Show crosshair", plus its reset default (0). The front-end PC Options screen picks the row up through `optionsRowCount()`.
**Netplay / fairness:** render-only and per machine (nothing is written; `texSelect` + a texrect, the same variance upstream's "Show crosshair" off already introduces). A hipfire sight that visibly slides onto auto-aim targets is extra information in a match; today it follows the lobby's agreed per-player `sight` flag (a player whose sight is off sees nothing either way). Whether the lobby should pin the persistent mode too is a **user decision** (RESEARCH-FREE-AIM decision 3).
**Verification** (headless, silent, llvmpipe, mp-sandbox data, `GE_FIXEDSTEP=1 GE_TICKINPUT=1 GE_RSEED=12345`; sandboxes `build-pc/xh-*`):
| Check | Result |
|---|---|
| F10 > Gameplay > HUD auto-opened (`GE_OPTIONSOVERLAY=3 GE_OPTIONSOVERLAY_SECTION=__HdrHUD`), frame 240 | row renders between "Show crosshair" and "Crosshair colour", value Off; page self-check count 12 <= 14 |
| Solo `-level_09` hipfire, option ON, frame 1800 (unseeded first pass) | the red sight at the centre of the view, ammo/gun unchanged (PNG viewed) |
| Solo `-level_09` hipfire, option OFF, frame 1800 | no sight (PNG viewed) |
| Solo `-level_09`, option OFF, frames 600/1200/1800, new binary vs the pre-change binary (ad7b63d9) | **BYTE-IDENTICAL** all three; frame 1800 md5 `1561622c8eed` = the golden in CONTROLLER-PAGES-RESULTS |
| Solo `-level_09` hipfire, OFF vs ON, frames 600/1200/1800 | 2 561 px differ, bbox x 391-475 y 278-373 on the 869x652 canvas (the sprite at the view centre); nothing else |
| Solo `-level_09`, R held from frame 700 (aim mode), OFF vs ON, frames 1200/1800 | **identical** (one sprite, the game's own; no double draw) |
| Sanity: OFF hipfire vs OFF aim mode, frame 1800 | the same 2 561 px / bbox as the row above: the persistent sprite is pixel-for-pixel the aim-mode sprite |
| Netplay 2P loopback (Temple, MULTIPLAYER-DEV script), both peers OFF | SH identical on 4 615 common ticks, 0 DESYNC |
| Both peers ON | SH identical on 4 616 ticks, 0 DESYNC |
| **Mixed: A OFF, B ON** | SH identical on 4 610 common ticks, 0 DESYNC (render-only confirmed) |
**Not verified:** a real play session (feel, the sight over the watch while paused: the N64 draws its own aim-mode sight the same way, so it is fidelity-consistent), split-screen and the own-view transform (the D13 texrect signature should match the same sprite; check on the next couch/own-view pass).
**Confidence: [H]** for correctness and neutrality (measured); [M] for the user-facing wording of the row.
**v0.5.0 integration (2026-10-06, maintainer request "roll the always on crosshair option in"):**
merged as dolent's original commit (#123, true merge, so the PR shows Merged).
The review conditions from 2026-10-01 are met as follows: D436 is free in this
tree (no relabel needed); both display-mode presets (Modern / Original N64) set
`Video.CrosshairPersistent` 0 (`port/src/video.c` preset table), so Original N64
stays N64; the row got a tip; the `gunDrawSight` condition is presentation only
(draw test, no gameplay reader of `gunsightmode`) and is signed off by the
maintainer with this request (Rule 2). Placement: Game page, right after "Show
crosshair". **Owed (maintainer, by eye):** hipfire on/off, sniper zoom, and
split-screen 2P with the option on.