v0.4.0 wrap-up: D407 RESOLVED — tank board-ordering fix, board-animation lockout, menu-accept B gate, in-tank aim routing + Input.TankAimScale; PC Options wheel direction fixed (D407(b)); all 10 TANKDBG probes stripped (src/game zero-diff); D408 logged (SkipIntro skips the failure dossier — Skip intro marked EXPERIMENTAL); release notes + readme stats

This commit is contained in:
James Dansereau committed 2026-09-28 09:28:28 -04:00
1 parent 76e9202dfd
commit 4f66db12d6
6 files changed
+104 -40

No files matched your search

+11 -2
View File
@@ -61,7 +61,8 @@ frame cadence. Fixed at the root; the game now holds a rock-stable 60 fps
is now **profile**. (D353–D356)
- The **F10 in-game overlay** was refreshed GE-style: category headers,
full controller support (value-adjust with hold-to-repeat), fixed pointer/
keyboard navigation, and new rows: **Show FPS**, **Skip intro**, pad
keyboard navigation, and new rows: **Show FPS**, **Skip intro
(experimental)**, pad
**Invert look / Southpaw / Deadzone / Trigger threshold**. (D237/D345–
D347/D360–D370)
- The front end gained a **PC Options screen** beside the file-select bar,
@@ -144,7 +145,10 @@ distances). (D402/D283)
- **Tanks** (Runway, Streets) can be boarded and exited again — the new
use/reload button split had removed the B-button tap the engine's tank
handlers use; B is presented again in tank states, and use keeps its
no-reload-fallback semantics everywhere else. (D407)
no-reload-fallback semantics everywhere else. A short input lockout during
the sit-down animation means a double-tap can't cancel boarding, and in-tank
mouse aim has its own **`Tank aim speed`** setting (`Input.TankAimScale`,
default 100) so the turret matches your on-foot feel. (D407)
- File-select background / gun-barrel comb rendering fixed. (D397)
- Stale-texture artifacts after level transitions fixed. (D235)
- Distant-geometry dropout on the biggest open levels (Streets, Egyptian)
@@ -249,6 +253,11 @@ All settings available in v0.4.0, in both options screens (front-end
- **`All unlocked` is experimental** (see above); the fresh-install
corruption case is fixed, but saves made while it is on are not
guaranteed recoverable by switching it off. (D387)
- **`Skip intro` is experimental — not recommended for regular use yet.**
With it on, a failed or aborted mission skips the post-mission failure
report screen and returns straight to the menus (the mission still records
correctly). An older audio quirk on some saves is also still being chased.
(D408/D216)
## Roadmap since v0.3.0 (research, not yet features)
+2 -2
View File
@@ -237,8 +237,8 @@ asset pipeline, first frames), and **Claude Code** (Sonnet 5, Opus 5 for the
hardest bugs) joining for the collaborative phase (the 21-level sweep, the
ABI finding catalog, SDL input, front end), handing work back and forth
through shared written notes, directed by one person part-time. In short:
43 days (16 Aug – 28 Sep), 995 commits, 285 findings root-caused and logged
(`D1`–`D407`).
43 days (16 Aug – 28 Sep), 997 commits, 286 findings root-caused and logged
(`D1`–`D408`).
The full write-up (timeline, handoff mechanism, effort breakdown, an honest
"what worked / what didn't"): [`docs/dev/agentic-development.md`](docs/dev/agentic-development.md).
+1
View File
@@ -284,3 +284,4 @@ D404,RESOLVED,"""Aim style: Centred (PC)"" (Input.AimMode=1, D333/D337) has no e
D405,CLOSED,"fast3d/OpenGL: MSAA above the driver max black-screens; two glBindFramebuffer calls pass an index where a GL name is required (PR #106, italoarruda, 2026-09-25…","CLOSED (2026-09-28). Merged from PR #106 (code file only; security-reviewed clean - port-layer GL state fixes, no external input, no allocations)."
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)."
1 # GENERATED by tools_pc/gen_findings_index.py -- do not hand-edit.
284 D405
285 D406
286 D407
287 D408
+18 -5
View File
@@ -691,7 +691,8 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
| D404 | **"Aim style: Centred (PC)" (`Input.AimMode=1`, D333/D337) has no effect when aiming with a gamepad; the row's own doc comment over-promises ("applies to every aim input … pad trigger") but the centred path is mouse-only (Steam Deck, 2026-09-27).** Full `## D404` entry at file tail. | RESOLVED (2026-09-28, port-layer only): the toggle now genuinely works on a pad. First logged as a communication bug and closed by relabel ("Aim style (mouse)"), then reopened on user challenge the same day: the pad path emits stick *deflection* into the game's crosshair integrator, so the pad was actually always in the **N64** model (a flick travels the crosshair; edge-scroll + spring-back only made a hold *feel* direct), and the "stick has no crosshair to travel" rationale was wrong. Fix: new `padDirectCompute()` in `input.c` (the pad twin of `hipDirectCompute`'s CENTRED branch -- same dead/watch/pause/cutscene gates, minus the mouse-grab gate; revised same day to the N64 path's verbatim quadratic curve -- `sign(v)\u00b7clamp(defl/70,\u00b11)\u00b2 \u00b7 (fov/60) \u00b7 3.5 deg/poll` (bondview2.c canNaturalTurn/canNaturalPitch), full-stick parity with the N64 path, pending retest on the refreshed build); the natural-pitch pad branch routes CENTRED through it and keeps N64's classic deflection behaviour (also the default, so no pad default changes). Labels reverted to device-neutral ("Aim style" / "Aim range"). **Steam Deck (2026-09-27/28): "centered aim is broken on deck too" -- fixed for real; the first-pass linear gain was measured as a dramatic sensitivity loss (2026-09-28) and replaced with the N64 path's verbatim quadratic curve (fov/60 base, 3.5 deg/poll top rate); retest on the refreshed build: user "good". RESOLVED.** |
| D405 | **fast3d/OpenGL: MSAA above the driver max black-screens; two `glBindFramebuffer` calls pass an index where a GL name is required** (PR #106, italoarruda, 2026-09-25; label rebased from the PR's D323, which collides with our D323 LOD finding) — full `## D405` entry at file tail | **CLOSED (2026-09-28).** Merged from PR #106 (code file only; security-reviewed clean - port-layer GL state fixes, no external input, no allocations). `resolve_msaa_color_buffer` clamps `msaa_level` to `GL_MAX_SAMPLES`; the resolve/copy paths bind `current_framebuffer ? framebuffers[i].fbo : 0` (the default framebuffer is GL name 0). Both Windows (opengl32) and Linux use this backend. Post-merge sweep 21/21 PASS + MSAA=16 boot check render-verified; link ritual clean. |
| 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). Build + link clean, zero TANKDBG strings in the binary; the user's first live tank drive (board + exit) is owed for sign-off. |
| 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)". |
Phase 2 replaced the Phase-1 demo loop with the real `mainproc()` on real OS
@@ -15504,10 +15505,22 @@ included; D281 keeps the shipped mitigation + disclosure, zero-saves root cause
**Root cause (port-layer input regression from the v0.4.0 wave, not game logic):** on the N64 a B tap drives both object use and the tank handlers in `bondview2.c` (`bondviewProcessInput`): B tap while `g_PlayerIsInTank == 1` exits the tank; B tap while `g_BondCanEnterTank != 0` (set by the `PROPDEF_TANK` proximity test in `bondviewCalcUpdatePlayerCollision`) boards it. The v0.4.0 input rework (D378: E = `bond_interact_object()` use with no reload fallback; D393: pad A = use / X = reload / Y = weapon cycle) routed the PC use action to that dedicated interact call and stopped presenting `GE_CONT_B`, so both tank branches lost their trigger: the tank stayed solid (collision) but its state machine was unreachable.
**Fix (port-layer only, `port/src/input.c` `inputComputePad`; `src/game` zero-diff — the four static `TANKDBG` probes used to diagnose this were stripped before the release):** present `GE_CONT_B` on the use (E / pad A) rising edge only while `g_PlayerIsInTank == 1 || g_BondCanEnterTank != 0`. E keeps its D378 no-reload-fallback semantics everywhere else; the N64 layout presents B natively and is unaffected.
**Fix (port-layer only, `port/src/input.c` `inputComputePad`; `src/game` zero-diff — the ten `TANKDBG` probes used to diagnose this (7 in `bondview2.c`, 3 in `input.c`, all `#ifdef PORT`) were stripped for the release):** present `GE_CONT_B` on the use (E / pad A) rising edge only while `g_PlayerIsInTank == 1 || g_BondCanEnterTank != 0`. E keeps its D378 no-reload-fallback semantics everywhere else; the N64 layout presents B natively and is unaffected.
**D407(b) (same cycle, front-end follow-ups from the D406 Deck validation; `frontoptions.c` + `input.c`):** (1) on the front PC Options screen, past the top/bottom edge of the visible rows the mouse highlight was dropped entirely — it now clamps to the page-edge row, so a mouse-only user keeps a row selected at the page edge (wheel / S then turns the page). (2) the mouse wheel pages the row list on that screen (wheel down = step down); the wheel queue is consumed on the menu so a scroll cannot leak into the next stage's weapon cycle (D223). (3) W/S also drive pad up/down on that screen.
**D407(c) (same cycle, tank follow-ups from live playtest):** (1) **Board-animation lockout** — the game's B handler is a toggle: while `g_PlayerIsInTank` is set, a B tap is the EXIT path. Boarding commits a ~45-frame sit blend during which `g_EnterTankAudioState` stays `TANK_RUN_STATE_NOT_RUNNING`; a key bounce or impatient re-press of E in that window hit the exit a few frames later and silently cancelled the whole animation (playtest 2026-09-28: every attempt was a board→exit microcycle — "tries to do something, cancels out"). The port now suppresses B from E while `g_PlayerIsInTank == 1 && g_EnterTankAudioState == TANK_RUN_STATE_NOT_RUNNING` (`s_tankBoardLock`); once seated, E = exit again. (2) **Menu-accept B gate** — the level-triggered "pad A / E presents B outside playable stages" mapping is disabled in tank states, so a held E while seated cannot re-edge the game's own exit toggle. (3) **Tank aim routing + `Input.TankAimScale`** — in-tank the game aims the turret from raw stick deflection only (`bondview2.c`: |stick| > 60 → `aimTurn`/`speedVerta`), so the direct-write aim models (centred / GEPD) are bypassed while `g_PlayerIsInTank == 1` and the legacy velocity stick is emitted instead; new `Input.TankAimScale` (default 100, range 10–300) scales only the mouse→stick gain on that in-tank path — on-foot aim, hipfire and keyboard/pad input are untouched.
**Verification:** NTSC build + link clean; zero `TANKDBG` strings in the release binary; 40 s front-end boot steady ~60 fps with zero errors (2026-09-28). The user's first live tank drive (Runway or Streets) is owed for board + exit sign-off — if board/exit misbehaves, or E double-triggers against the tank prop (port-side interact call + native B-bit handler), re-open D407.
**D407(b) (same cycle, front-end follow-ups from the D406 Deck validation; `frontoptions.c` + `input.c`):** (1) on the front PC Options screen, past the top/bottom edge of the visible rows the mouse highlight was dropped entirely — it now clamps to the page-edge row, so a mouse-only user keeps a row selected at the page edge (wheel / S then turns the page). (2) the mouse wheel pages the row list on that screen (wheel down = step down); the wheel queue is consumed on the menu so a scroll cannot leak into the next stage's weapon cycle (D223). (3) W/S also drive pad up/down on that screen. **(2026-09-28 fix, user report):** the (2) mapping shipped inverted — `wheelBack` (SDL wheel-up) drove `-STICK_MAX` and `wheelFwd` (wheel-down) `+STICK_MAX`, but this screen's convention is `+STICK_MAX` = up (the W/Up keys in `pcOptionsKeyboardPad`). Swapped so wheel up = step up, wheel down = step down; scoped to `MENU_PC_OPTIONS` only — in-stage weapon cycling (D223: wheel down = next weapon) and the F10 overlay's own scroll are untouched.
**Status:** PARTIAL — fix landed in v0.4.0 (port-only); the user's live board/exit sign-off is owed on the first tank drive.
**Verification:** NTSC build + link clean; zero `TANKDBG` strings in the release binary (re-verified after probe strip, 2026-09-28); 40 s front-end boot steady ~60 fps with zero errors. **Live sign-off (user, 2026-09-28):** first tank drive — board + exit work, no double-trigger against the tank prop, and the in-tank aim feel is good at `TankAimScale = 100` ("felt fine, glad to have the setting").
**Status:** RESOLVED (2026-09-28) — board-ordering fix + board-animation lockout + menu-accept B gate + tank aim routing + `Input.TankAimScale`, all port-only (`src/game` zero-diff), user-signed off on a live tank drive; probes stripped, release binary verified clean.
## D408 — `Game.SkipIntro` skips the post-mission failure dossier: failed/aborted missions return straight to the menus with no REPORT screen (user report 2026-09-28, during v0.4.0 wrap-up playtest)
**Symptom:** with `Game.SkipIntro = 1`, entering a solo mission and then either aborting (watch menu Z+A) or dying (KIA) returns the player straight to the front-end menus — the post-mission failure dossier is never shown. On a normal boot that screen is `MENU_MISSION_FAILED` (`front.c` `constructor_menu0C_missionfailed`: "REPORT / Mission status: KILLED IN ACTION" or "ABORTED", with the objective list and next/prev tabs to the mission-complete report). Initial suspicion was the user's save or `Game.AllUnlocked` (D257/D387); **user confirmed 2026-09-28 that it is a SkipIntro quirk** — save state and AllUnlocked are not involved.
**Traced so far (handoff site, mechanism not fully pinned):** the stage-end handoff lives in `menu_init()`'s `MENU_RUN_STAGE` case (`front.c:~8909`, called from `lv.c:1322` only once `g_CurrentStageToLoad == LEVELID_TITLE`): non-replay solo stages fall through to `frontChangeMenu(MENU_MISSION_FAILED, 1)` (Cuba → cast display, multi → MP options, ramrom replay → legal screen). Under SkipIntro that handoff evidently never runs on the fail/abort return path — the exact point where the boot shortcut's state diverges (which flag/menu value the skipped intro stages would normally have left behind) is not yet identified. The abort path itself (`options.c:798`: `set_missionstate(MISSION_STATE_0); bossRunTitleStage(); mission_failed_or_aborted = TRUE; deleteCurrentSelectedFolder()`) and the KIA path (`bondview2.c bondviewKillCurrentPlayer`, `g_isBondKIA = 1`) are game logic and behave per the decomp; nothing in `port/` intercepts `MENU_MISSION_FAILED`.
**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.
+66 -26
View File
@@ -98,6 +98,7 @@ extern int gameScriptedCameraActive(void);
extern bool bond_interact_object(void); /* chrprop.c: use target, no reload fallback */
extern s32 g_PlayerIsInTank; /* bondview.c: tank state (D407) */
extern s32 g_BondCanEnterTank; /* bondview.c: tank board gate (D407) */
extern s32 g_EnterTankAudioState; /* bondview2.c: tank entry/running state (D407) */
/* gun.c: native weapon-switch entry points (not exposed in gun.h). */
extern ITEM_IDS get_next_weapon_in_cycle_for_hand(GUNHAND hand, s32 direction);
extern void gunRequestHandWeaponChange(enum GUNHAND hand, s32 nextWeapon, s32 cycleDirection);
@@ -370,6 +371,12 @@ static int gepdSens = 38; /* D194 Input.GepdSens: GEPD SENSITIVITY set
(20 -> 25 "a bit slow" -> 30 user-calibrated match point
-> 38: user asked defaults ~20-35% faster than that) */
static int aimBand = 20; /* aim mode: usable stick range above the 60 gate */
/* D407: mouse->stick gain multiplier (%, 100 = unchanged) applied ONLY while
* aiming in tank. In-tank aim must use the legacy velocity-stick path (the
* game's turret code reads raw stick deflection only), whose px->screen feel
* differs from the direct-write on-foot models; this knob lets the user dial
* the turret to taste without touching on-foot aim. */
static int tankAimScale = 100;
/* D194/D238: default 100 -> 40 (M-123 user calibration). The old gain
* (MOUSE_TURN_GAIN=6 stick/px) saturated the game's quadratic natural-turn
* curve at ~13 px/poll, i.e. hipfire ran at full 315 deg/s for any normal
@@ -1612,27 +1619,53 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
int useNow = scriptIsActive() ? s_scriptUse : (actHeld(ks, IA_CANCEL) || padUse);
int reloadNow = scriptIsActive() ? s_scriptReload : (actHeld(ks, IA_RELOAD) || padReload);
int playable = inputCanUseGameplayActions(menuMode);
if (playable) {
if (useNow && !s_useHeldPrev) {
bool empty = bond_interact_object();
if (configGetInputLog()) sysLogPrintf(LOG_NOTE, "GE_INPUTLOG dedicated use (no target=%d)", empty);
}
} else if (scriptIsActive() ? s_scriptUse : actHeld(ks, IA_CANCEL)) {
/* A on the pad is still native accept outside playable stages. */
button |= GE_CONT_B;
}
/* D407: on the N64 the B bit also drives bondview2.c's tank
* handlers (board when g_BondCanEnterTank, exit while
* g_PlayerIsInTank). The D378/D393 split above routes E/pad A to a
* dedicated interact call without presenting B, which left tank
* board/exit dead on PC (the tank blocks movement but can never be
* entered -- Runway, Streets). Present B only in the tank states so
* E keeps its no-reload-fallback semantics everywhere else. */
if (useNow && !s_useHeldPrev
&& (g_PlayerIsInTank == 1 || g_BondCanEnterTank != 0))
{
* E keeps its no-reload-fallback semantics everywhere else.
* In the tank states the dedicated interact call is ALSO skipped:
* on the N64 the use/reload fallback (lv.c:796) runs on the B bit
* AFTER the board handler in the same tick, so pre-activating the
* tank prop on the input side (propobjInteract ->
* RUNTIMEBITFLAG_ACTIVATED, propobj.c) reorders the N64 sequence
* and flaps g_BondCanEnterTank between input sampling and the
* board check (user: still can't board, 2026-09-28). */
int tankState = (g_PlayerIsInTank == 1 || g_BondCanEnterTank != 0);
/* D407 (cont.): board-animation lockout. The game's B-tap handler
* (bondview2.c) is a toggle: while g_PlayerIsInTank is set, a B tap
* is the EXIT path. Boarding commits a ~45-frame (0.75 s) sit blend
* during which g_EnterTankAudioState stays TANK_RUN_STATE_NOT_RUNNING;
* only once it finishes does the engine SFX start. A key bounce or a
* player re-pressing E in that silent window ("nothing is happening")
* hits the exit a few frames later and silently cancels the whole
* animation -- 2026-09-28 playtest: every attempt was a
* board->exit microcycle, so no seat, no engine, and the tank camera
* transition reverted ("tries to do something, cancels out"). An N64
* player simply presses once and waits; give the keyboard the same
* guarantee in the port layer: suppress B from E while the entry
* animation is running. Once seated, E = exit again. */
static int s_tankBoardLock = 0;
s_tankBoardLock = (g_PlayerIsInTank == 1 &&
g_EnterTankAudioState == TANK_RUN_STATE_NOT_RUNNING);
if (playable) {
if (useNow && !s_useHeldPrev && !tankState) {
bool empty = bond_interact_object();
if (configGetInputLog()) sysLogPrintf(LOG_NOTE, "GE_INPUTLOG dedicated use (no target=%d)", empty);
}
} else if ((scriptIsActive() ? s_scriptUse : actHeld(ks, IA_CANCEL)) && !tankState) {
/* A on the pad is still native accept outside playable stages.
* D407: NOT in tank states -- there B must come only from the
* locked edge path below. This mapping is level-triggered on E;
* in-tank (playable=false) it would re-present B on any E press,
* bypassing the board-animation lockout and re-edging the game's
* own exit toggle (2026-09-28: unprobed board->exit microcycles). */
button |= GE_CONT_B;
}
if (useNow && !s_useHeldPrev && tankState && !s_tankBoardLock)
button |= GE_CONT_B;
if (reloadNow && !s_reloadHeldPrev && playable) {
attempt_reload_item_in_hand(GUNRIGHT);
attempt_reload_item_in_hand(GUNLEFT);
@@ -1817,14 +1850,20 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
/* D194 GEPD-mirror aim: direct crosshair/camera writes, no
* look stick (see aimGepdCompute). Keyboard turn (sx/sy set
* above) still works. Otherwise fall through to the legacy
* velocity stick below. */
if (aimModeGet() == AIMMODE_CENTRED) {
* velocity stick below.
* D407 follow-up: in-tank the game aims the turret from raw
* stick deflection ONLY (bondview2.c HONEY/SOLITARE branch:
* |stick_x|/|stick_y| > 60 -> aimTurn/speedVerta), so the
* direct-write models must be bypassed there and the legacy
* velocity stick emitted instead. */
int tankAimStick = (g_PlayerIsInTank == 1);
if (!tankAimStick && aimModeGet() == AIMMODE_CENTRED) {
/* D333: FPS-style centred aim -- the camera takes the
* mouse (same path as hipfire, which also declines on
* the watch/pause/cutscene gates) and no stick is
* emitted, so the crosshair settles at centre. */
hipDirectCompute(edx * lookDtScale, dyLook * lookDtScale);
} else if (pdMouseAimEnabled()) {
} else if (!tankAimStick && pdMouseAimEnabled()) {
/* PD model: accumulate only. The game's own integrator is
* driven by the port-supplied turn through the
* sub_GAME_7F067FBC hook (see Input.PdMouseAim above). */
@@ -1833,9 +1872,10 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
* crosshair model -- without this the camera stops
* following the crosshair at the screen edge. */
aimGepdEdgeScroll();
} else if (!aimGepdCompute(edx * lookDtScale, dyLook * lookDtScale)) {
} else if (tankAimStick || !aimGepdCompute(edx * lookDtScale, dyLook * lookDtScale)) {
double aimEdx = edx * lookDtScale, aimDyLook = dyLook * lookDtScale;
double aimSens = (mouseAimSpeed / 100.0) * (mouseSensitivity / 100.0);
if (tankAimStick) aimSens *= tankAimScale / 100.0; /* D407 */
double gamma = aimCurveGamma / 100.0;
double normX = fabs(aimEdx) * aimSens / AIM_FULL_SPEED_PX;
double normY = fabs(aimDyLook) * aimSens / AIM_FULL_SPEED_PX;
@@ -1927,16 +1967,16 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
{
pcOptionsKeyboardPad(ks, mb, optionsBindingInputBlocked(), &button, &sx, &sy);
/* D407(b): on this screen the mouse wheel scrolls the row list
* (wheel down = step down). Front-end menus otherwise leave the
* wheel queue unconsumed in menu mode -- clear it here so a
* scroll can't leak into the next stage's weapon cycle (D223). */
* -- wheel up = step UP, wheel down = step DOWN (same sign
* convention as the W/S keys above: +STICK_MAX = up). The
* original mapping had them swapped (2026-09-28 user report).
* Front-end menus otherwise leave the wheel queue unconsumed in
* menu mode -- clear it here so a scroll can't leak into the
* next stage's weapon cycle (D223). */
if (!optionsBindingInputBlocked())
{
int wheel = 0;
if (wheelBack > 0) { wheel = +1; wheelBack = 0; }
else if (wheelFwd > 0) { wheel = -1; wheelFwd = 0; }
if (wheel != 0)
sy = (wheel < 0) ? STICK_MAX : -STICK_MAX;
if (wheelBack > 0) { sy = STICK_MAX; wheelBack = 0; } /* wheel up */
else if (wheelFwd > 0) { sy = -STICK_MAX; wheelFwd = 0; } /* wheel down */
}
}
menuPrevActive = menuMode;
@@ -2166,7 +2206,6 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
sysLogPrintf(LOG_NOTE, "GE_INPUTLOG cont%d: btn=%04x stick=(%d,%d)",
idx, button, sx, sy);
}
return button;
}
@@ -2705,6 +2744,7 @@ PD_CONSTRUCTOR static void inputConfigInit(void)
configRegisterInt("Input.AimModeSens", &gepdSens, 1, 500);
configRegisterInt("Input.GepdSens", &gepdSens, 1, 500); /* deprecated alias */
configRegisterInt("Input.AimBand", &aimBand, 5, 40);
configRegisterInt("Input.TankAimScale", &tankAimScale, 10, 300); /* D407 */
configRegisterInt("Input.MouseTurnSpeed", &mouseTurnSpeed, 1, 500);
configRegisterInt("Input.SensLink", &sensLink, 0, 1);
configRegisterInt("Input.MenuPointerSpeed", &menuPointerSpeed, 10, 500);
+6 -5
View File
@@ -298,11 +298,12 @@ static struct Row rows[] = {
{ .key="Bond.LookAhead", .label="Look ahead", .kind=ROW_TOGGLE,
.names=kOnOff, .found=1, .uiMax=1, .cfgMax=1, .saveScoped=1 },
/* D216/Game.SkipIntro: user report (v0.2.1 testing) that it breaks audio
* -- pulled from the menu until root-caused. Not exposed to players; the
* config var + lv.c hook stay in place (dead unless an existing ini has
* it set, which no menu path can do any more). Do not re-add without
* fixing the underlying issue first. */
{ .key="Game.SkipIntro", .label="Skip intro", .kind=ROW_TOGGLE, .step=1, .names=kOnOff },
* -- pulled from the menu until root-caused; re-exposed since. D408
* (2026-09-28): still EXPERIMENTAL -- with it on, a failed/aborted
* mission skips the post-mission failure dossier (MENU_MISSION_FAILED)
* and returns straight to the menus. Not recommended for regular users;
* keep the loud label until both quirks are root-caused. */
{ .key="Game.SkipIntro", .label="Skip intro (EXPERIMENTAL)", .kind=ROW_TOGGLE, .step=1, .names=kOnOff },
/* D232: the community "no damage flash" toggle (suppresses the red/green
* hit-flash overlay in bondview2). */
{ .key="Game.NoHitFlash", .label="No hit flash", .kind=ROW_TOGGLE, .step=1, .names=kOnOff },