mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-24 00:02:45 +02:00
feat: D436 -- persistent crosshair, opt-in (Video.CrosshairPersistent; F10 > Gameplay > HUD > "Crosshair when not aiming")
The native sight is drawn at crosshair_angle outside aim mode too: one masked condition in gunDrawSight (#ifdef PORT, beside the D373/D381 hooks) ignores GUNSIGHTREASON_NOTAIMING when the option is on; every other reason and the MP menu still hide it. Default off is byte-identical (frames 600/1200/1800); hipfire on/off differ only in the sprite region; aim mode on/off identical. Findings D436. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e8c2ce213
commit
17891cc468
5 files changed
+51
No files matched your search
@@ -285,3 +285,4 @@ D405,CLOSED,"fast3d/OpenGL: MSAA above the driver max black-screens; two glBindF
|
||||
D406,RESOLVED,front-end PC Options screen:,"RESOLVED (2026-09-28, port-layer only, Steam Deck-validated):"
|
||||
D407,PARTIAL,Tanks cannot be boarded/exited on PC —,"PARTIAL (fix landed in v0.4.0, port-only):"
|
||||
D408,OPEN,Game.SkipIntro skips the post-mission failure dossier:,"OPEN (cosmetic, not root-caused past the handoff site)."
|
||||
D436,FIXED,"Persistent (hipfire) crosshair, opt-in:",FIXED (shipped 2026-09-29; rule-2 sign-off:
|
||||
|
@@ -693,6 +693,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D406 | **front-end PC Options screen: long sections (INPUT, 17 visible rows) run off the bottom of the 440x330 paper, and rows past the silent 14-row page cap (Crouch mode, Reset to defaults, Bindings…) are unreachable from the front screen** (user report 2026-09-28, v0.4.0 pre-push review) — full `## D406` entry at file tail | RESOLVED (2026-09-28, port-layer only, Steam Deck-validated): in-section pagination in `frontoptions.c` (11 rows/page; the vertical stepper crosses page boundaries both ways; dim 'Page p/N' marker + bottom hint on every page; slider bars start past long labels; F10 overlay untouched). D406b/c/d same-cycle refinements (label/track overlap, hint visibility/wording, hint position). |
|
||||
| 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)". |
|
||||
| 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
|
||||
@@ -15524,3 +15525,35 @@ included; D281 keeps the shipped mitigation + disclosure, zero-saves root cause
|
||||
**v0.4.0 decision (user, 09-28):** `Game.SkipIntro` stays **EXPERIMENTAL — not recommended for regular users yet**, alongside its older unrooted audio-break report (D216 status note). The F10 row is relabelled "Skip intro (EXPERIMENTAL)" (`port/src/optionsoverlay.c`, mirroring the D387 AllUnlocked labelling precedent); the config var, default (off), and `lv.c` hook are unchanged.
|
||||
|
||||
**Status:** OPEN — cosmetic (no crash, no data loss; the mission still records as failed/aborted and the menus are fully functional). Root-causing needs a side-by-side of front-end state (`current_menu`, `g_CurrentStageToLoad`, `mission_failed_or_aborted`, `g_isBondKIA`) on the fail return with SkipIntro off vs on — candidate for v0.5.0 alongside the D216 audio half.
|
||||
|
||||
## 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.
|
||||
@@ -331,6 +331,7 @@ static struct Row rows[] = {
|
||||
/* D226: scales the ammo counter, pickup/status text and dialogue. */
|
||||
{ .key="Game.HudScale", .label="HUD scale", .kind=ROW_SLIDER, .step=5, .unit="%" },
|
||||
{ .key="Video.CrosshairHide", .label="Show crosshair", .kind=ROW_TOGGLE, .step=1, .names=kOnOffRev },
|
||||
{ .key="Video.CrosshairPersistent", .label="Crosshair when not aiming", .kind=ROW_TOGGLE, .step=1, .names=kOnOff }, /* D436 */
|
||||
{ .key="Video.CrosshairColor", .label="Crosshair colour", .kind=ROW_ENUM, .step=1, .names=kCrosshairColor },
|
||||
{ .key="Video.CrosshairRed", .label="Red", .kind=ROW_SLIDER, .step=1, .shownWhen="Video.CrosshairColor", .shownValue=8 },
|
||||
{ .key="Video.CrosshairGreen", .label="Green", .kind=ROW_SLIDER, .step=1, .shownWhen="Video.CrosshairColor", .shownValue=8 },
|
||||
@@ -1316,6 +1317,7 @@ static const struct { const char *key; double def; } kResetDefaults[] = {
|
||||
{ "Video.DrawDistance", 250 }, /* midpoint: 50/100 */
|
||||
{ "Video.LodDistance", 250 }, /* midpoint: 50/100 */
|
||||
{ "Video.CrosshairHide", 0 }, /* = 0 (on, N64) */
|
||||
{ "Video.CrosshairPersistent", 0 }, /* D436: off = N64 (aim mode only) */
|
||||
{ "Video.CrosshairColor", 0 }, /* = 0 (authored red sprite) */
|
||||
{ "Video.CrosshairRed", 255 },
|
||||
{ "Video.CrosshairGreen", 255 },
|
||||
|
||||
@@ -106,6 +106,8 @@ s32 portNoHitFlash = 0;
|
||||
* (gunfire.c gunDrawSight, #ifdef PORT). Default keeps the original
|
||||
* authored red sprite; hide is opt-in. */
|
||||
s32 portCrosshairHide = 0;
|
||||
static int cfgCrosshairPersistent = 0; /* D436: 1 = draw the sight outside aim mode too */
|
||||
int portCrosshairPersistent(void) { return cfgCrosshairPersistent; }
|
||||
static int cfgCrosshairColor = 0; /* 0 = authored sprite; 1..7 = presets; 8 = custom RGB */
|
||||
static int cfgCrosshairRed = 255, cfgCrosshairGreen = 255, cfgCrosshairBlue = 255;
|
||||
static int cfgCrosshairSize = 100; /* 100% retains the original 32x32 drawing */
|
||||
@@ -413,6 +415,7 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
|
||||
configRegisterInt("Game.SkipIntro", &portSkipIntro, 0, 1);
|
||||
configRegisterInt("Game.NoHitFlash", &portNoHitFlash, 0, 1);
|
||||
configRegisterInt("Video.CrosshairHide", &portCrosshairHide, 0, 1); /* v0.4.0 M2 (D373) */
|
||||
configRegisterInt("Video.CrosshairPersistent", &cfgCrosshairPersistent, 0, 1); /* D436 */
|
||||
configRegisterInt("Video.CrosshairColor", &cfgCrosshairColor, 0, 8); /* 8 = custom; old ini values unchanged */
|
||||
configRegisterInt("Video.CrosshairRed", &cfgCrosshairRed, 0, 255);
|
||||
configRegisterInt("Video.CrosshairGreen", &cfgCrosshairGreen, 0, 255);
|
||||
|
||||
@@ -6518,7 +6518,19 @@ void gunDrawSight(s32 *gdl) {
|
||||
f32 xypos[2];
|
||||
f32 halfedxy[2];
|
||||
|
||||
#ifdef PORT
|
||||
/* D436: opt-in persistent sight. With Video.CrosshairPersistent the
|
||||
* NOTAIMING reason is ignored so the sprite is also drawn in hipfire, at
|
||||
* the same crosshair_angle the shots use. Every other reason (Sight
|
||||
* option / MP sight policy, cutscene, damage) and the MP menu still hide
|
||||
* it. Default off = the N64 test. */
|
||||
extern int portCrosshairPersistent(void);
|
||||
s32 sightmode = g_CurrentPlayer->gunsightmode
|
||||
& ~(portCrosshairPersistent() ? GUNSIGHTREASON_NOTAIMING : 0);
|
||||
if ((sightmode == 0) && (g_CurrentPlayer->mpmenuon == FALSE)) {
|
||||
#else
|
||||
if ((g_CurrentPlayer->gunsightmode == 0) && (g_CurrentPlayer->mpmenuon == FALSE)) {
|
||||
#endif
|
||||
#ifdef PORT
|
||||
if (portCrosshairHide)
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user