forked from Ports/goldeneye-pc-port
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.
This commit is contained in:
1 parent
7a541da877
commit
91bd0f84b7
3 files changed
+58
-14
No files matched your search
@@ -133,7 +133,7 @@ D165,FIXED,"Front-end menu cursor doesn't feel like a mouse pointer (M-31, user
|
||||
D166,FIXED,Hipfire mouse pitch is digital while yaw is analog —,FIXED (port/src/input.c).…
|
||||
D235,OPEN,Wrong textures load after dying/restarting a level —,"OPEN — fix wired, headless reload clean (2026-09-23); bug NOT reproduced even with the fix off (GE_D235_OFF)."
|
||||
D236,CLOSED,"Surface 1: 2D billboard trees render as a wall/sheet of tree texture instead of discrete camera-facing tree sprites (M-106, user QA report).","CLOSED (M-198, pass 26, 425237f9; probes stripped 0503d335):"
|
||||
D237,OPEN,"QoL ask (M-106, user QA):",OPEN — not designed; port-only
|
||||
D237,FIXED,"QoL ask (M-106, user QA):","FIXED (2026-09-23): category headers + 5 more settings (SkipIntro, Show FPS, pad invert/deadzone/trigger); wheel scroll already existed."
|
||||
D238,OPEN,"QoL ask (M-106, user QA):",OPEN — not designed; port-only (port/src/input.c + config.c)
|
||||
D239,CLOSED,"QoL ask (M-106, user QA):",CLOSED — executed in the v0.2.0 prep pass (port-only)…
|
||||
D240,OPEN,"Player gunshot SFX timing/cadence reportedly does not match the N64 original's rate (M-106, user QA report).","OPEN — not root-caused; static call-site tracing only, no runtime verification possible in this environment."
|
||||
|
||||
|
@@ -540,7 +540,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D234 | **Dam: guard towers along the dam structure invisible except the first one (M-106, user QA report).** — full `## D234` entry at file tail | **VISUALLY VERIFIED FIXED (M-108), mechanism unexplained.** See the other D234 row for detail. |
|
||||
| D235 | **Wrong textures load after dying/restarting a level — not Facility-specific, seen on multiple levels (M-106, user QA report; clarified same session).** — full `## D235` entry at file tail | OPEN — fix wired, headless reload clean (2026-09-23); bug NOT reproduced even with the fix off (GE_D235_OFF). Needs the original die → mission select → restart trigger in a playtest to close. |
|
||||
| D236 | **Surface 1: 2D billboard trees render as a wall/sheet of tree texture instead of discrete camera-facing tree sprites (M-106, user QA report).** — full `## D236` entry at file tail | **CLOSED (M-198, pass 26, `425237f9`; probes stripped `0503d335`): root cause = `TEXTURETYPE_DETAIL` tile binding — fast3d drew the detail tile (opaque IA8 noise) instead of the base image; `gfx_lod_tile_offset` now samples tile 1 when the pair differs (`Video.DetailBaseTile`, default on). Live-verified Surface 1/2 + Depot; awaiting user play-test sign-off.** Historical trail — pass 24 (2026-09-21, static) DECODED THE TREE TEXTURE** (new `tools_pc/texdecode.py` ports image.c's LOOKUP/HUFFLOOKUP/RLELOOKUP codecs). **`tex1198` LOD 0 = 64×17 RGBA5551, 44.2% opaque, and its 1-bit alpha renders as an unmistakable treeline silhouette** — pass 23's identification confirmed by decode, not inference. **Rare authored a six-level LOD pyramid that PRESERVES the silhouette and its alpha coverage (44.2% → 43.1% → 38.8%), each level a separately-authored image with its own compmethod.** Since `XLU_SURF` has no alpha test (pass 22), averaging that 0/1 alpha into fractional mip alpha would smear the minified treeline into exactly the reported band — so 'authored LOD chain replaced by driver-generated mips' is now the leading mechanism, with hard ground truth behind it. Corrects pass 23: only `tex1198` is a treeline (`tex1199` 89.4% opaque denser foliage; `tex1200`/`tex1201` 100% opaque detail textures sharing the class). Two decoder bugs found while porting (missing per-image byte-align, `image.c:1096`; a GUESSED rather than ported RLE fudge) — both produced confident wrong pictures. **Pass 25 (live) answered all three questions: (1) YES 64×17 RGBA16 intact, pool ≡ offline decode; (2) YES alpha survives (44.2% opaque); (3) NO — no code path uploads authored chains as GL mips.** New: `tex1198`–`1201` are **never drawn from an idle spawn** (zero RGBA16 imports in 4800 frames) — the spawn wall is painted by other classes (cf D276/D280); the drawn tree-class card is **`tex149` IA8 32×64 hard cutout, byte-exact import, no authored chain**. Mip mechanism located: `texGetDepthAndSize` sizes LOADBLOCKs from the header `lods` field even for single-image textures (live A/B: 2808 B vs 2048 B real data), and the port's RC2 clip + `glGenerateMipmap`/trilinear (observed live) box-filters hard 0/F alpha into fractional mips → XLU smear. Pass 26 fix directions in entry (cheapest: no mip gen for no-chain textures). |
|
||||
| D237 | **QoL ask (M-106, user QA): F10 options overlay — make it scrollable with the mouse wheel, expose more settings into it (e.g. screen-flash / no-hit-flash…** — full `## D237` entry at file tail | OPEN — not designed; port-only |
|
||||
| D237 | **QoL ask (M-106, user QA): F10 options overlay — make it scrollable with the mouse wheel, expose more settings into it (e.g. screen-flash / no-hit-flash…** — full `## D237` entry at file tail | FIXED (2026-09-23): category headers + 5 more settings (SkipIntro, Show FPS, pad invert/deadzone/trigger); wheel scroll already existed. Hands-on pass owed. |
|
||||
| D238 | **QoL ask (M-106, user QA): mouse sensitivity rework toward normal PC-shooter feel.** — full `## D238` entry at file tail | OPEN — not designed; port-only (`port/src/input.c` + `config.c`) |
|
||||
| D239 | **QoL ask (M-106, user QA): click-to-lock vs always-grab parity.** — full `## D239` entry at file tail | CLOSED — executed in the v0.2.0 prep pass (port-only)… |
|
||||
| D240 | **Player gunshot SFX timing/cadence reportedly does not match the N64 original's rate (M-106, user QA report).** — full `## D240` entry at file tail | **OPEN — not root-caused; static call-site tracing only, no runtime verification possible in this environment.** Confidence LOW-MEDIUM that this is a *new* bug distinct from the D155/D186/D193/D204/D209 timing-keystone family (all of which gate the identical `deltaFrames→speedgraphframes→g_ClockTimer→g_GlobalTimer` chain this SFX trigger consumes).… |
|
||||
@@ -11333,6 +11333,8 @@ the Surface 1 spawn capture is unchanged across the strip.
|
||||
|
||||
**Status (from §F table):** OPEN — not designed; port-only
|
||||
|
||||
**IMPLEMENTED (2026-09-23, v0.4.0; port-only, `port/src/optionsoverlay.c`).** Wheel scroll already existed (D304 era). Added: (1) **category headers**, a new `ROW_HEADER` kind (not config-backed, never selectable; up/down/wheel step over headers via `overlayStepSel`, clicks on headers ignored, `rowAdjust` no-ops) drawn in the title accent: DISPLAY / VIEW / MOUSE / AIM / CONTROLLER / GAME; (2) **more settings**: `Game.SkipIntro`, `Video.DisplayFPS`, `Input.PadLookInvertY`, `Input.PadDeadzone` (slider, step 500), `Input.PadTriggerPct`. `Game.NoHitFlash` was already exposed. Verified: overlay capture shows the headers and the selection starting on the first real row; no unregistered-key warnings; Windows + Linux builds clean. Owed: a hands-on pass (wheel/arrows skip headers, the new sliders feel right).
|
||||
|
||||
## D238 — QoL ask (M-106, user QA): mouse sensitivity rework toward normal PC-shooter feel.
|
||||
|
||||
**QoL ask (M-106, user QA): mouse sensitivity rework toward normal PC-shooter feel.** Three parts: (1) a *separate* RMB aim-mode sensitivity in addition to hipfire turn; (2) ideally ONE single master mouse-sensitivity setting driving both, **linked by default**, with an option to set them independently later (today `Input.MouseAimSpeed` and `Input.MouseTurnSpeed` are two independent keys, defaults 16/100 — see `input.c:188-190`); (3) up/down should feel mostly the same as left/right (`Input.MouseYScale` exists but the axis asymmetry in the gain constants `AIM_GAIN`/`MOUSE_TURN_GAIN` + smoothing path is the likely culprit). User's reference for "feels better": GEPD Mouse Injector. Lump with the overall mouse/input fixes (D194/D165/D166 lineage; SOLITAIRE natural-pitch scheme switch may subsume part of this — see D166 M-87 note).
|
||||
|
||||
+54
-12
@@ -63,7 +63,8 @@ extern s16 viGetY(void);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
enum { ROW_TOGGLE, ROW_SLIDER, ROW_ENUM, ROW_MSAA, ROW_RES, ROW_ACTION, ROW_FPSCAP };
|
||||
enum { ROW_TOGGLE, ROW_SLIDER, ROW_ENUM, ROW_MSAA, ROW_RES, ROW_ACTION, ROW_FPSCAP,
|
||||
ROW_HEADER /* D237: non-selectable category label */ };
|
||||
|
||||
static const char *const kOnOff[] = { "OFF", "ON", NULL };
|
||||
static const char *const kTexFilter[] = { "NEAREST", "BILINEAR", "3-POINT", NULL };
|
||||
@@ -119,6 +120,7 @@ struct Row {
|
||||
};
|
||||
|
||||
static struct Row rows[] = {
|
||||
{ "__HdrDisplay", "DISPLAY", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.Fullscreen", "Fullscreen", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "__Resolution", "Resolution", ROW_RES, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.VSync", "VSync", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
@@ -126,6 +128,7 @@ static struct Row rows[] = {
|
||||
{ "Video.MSAA", "MSAA", ROW_MSAA, 0, NULL, 1, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.TextureFilter", "Texture filter", ROW_ENUM, 1, kTexFilter, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.Anisotropy", "Anisotropic", ROW_SLIDER, 1, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "__HdrView", "VIEW", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.FovScale", "FOV scale %", ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* D334: native widescreen (world projected at the window aspect, Hor+).
|
||||
* While on, "Widescreen auto FOV" has no effect (it was the stretch-era
|
||||
@@ -166,6 +169,7 @@ static struct Row rows[] = {
|
||||
/* { "Input.AimModeSens", "Mouse aim speed", ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0 }, */
|
||||
/* { "Input.MouseTurnSpeed", "Mouse turn speed", ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0 }, */
|
||||
/* { "Input.SensLink", "Link aim/turn sens",ROW_TOGGLE,1, kOnOff, 0, 0, 0, 0,0,0,0,0 }, */
|
||||
{ "__HdrMouse", "MOUSE / AIM", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Input.MouseSensitivity", "Mouse sensitivity",ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Input.MouseInvertY", "Mouse invert Y", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* Input.PdMouseAim (findings D332): the Perfect Dark port's mouse-aim
|
||||
@@ -179,6 +183,10 @@ static struct Row rows[] = {
|
||||
* PD DAMP = the PD model above, CENTRED = mouse turns the camera and the
|
||||
* crosshair stays centred. Input.PdMouseAim=1 migrates to PD DAMP. */
|
||||
{ "Input.AimStyle", "RMB aim style", ROW_ENUM, 1, kAimStyle, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "__HdrPad", "CONTROLLER", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Input.PadLookInvertY", "Pad invert look Y",ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Input.PadDeadzone", "Stick deadzone", ROW_SLIDER, 500, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Input.PadTriggerPct", "Trigger threshold %",ROW_SLIDER,1, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* D181/Game.ScreenShakeIntensity: user testing (v0.2.1) found the slider
|
||||
* "basically useless" -- viShake() is only called from explosion.c, so it
|
||||
* scales explosion shake alone; it never touches the always-on walking
|
||||
@@ -188,6 +196,9 @@ static struct Row rows[] = {
|
||||
* hook stay in place. */
|
||||
/* D232: the community "no damage flash" toggle (suppresses the red/green
|
||||
* hit-flash overlay in bondview2). */
|
||||
{ "__HdrGame", "GAME", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Game.SkipIntro", "Skip intro", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.DisplayFPS", "Show FPS", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Game.NoHitFlash", "No hit flash", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* 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
|
||||
@@ -323,6 +334,28 @@ static int overlayRowAtY(double oy)
|
||||
}
|
||||
|
||||
/* Rebuild the visible-row list and keep the selection in range. */
|
||||
/* D237: move a visible-list position by dir (+1/-1) to the next row that
|
||||
* is not a category header; stays put at the ends. */
|
||||
static int overlayStepSel(int pos, int dir)
|
||||
{
|
||||
int p = pos;
|
||||
for (;;) {
|
||||
int q = p + dir;
|
||||
if (q < 0 || q >= s_visN) {
|
||||
/* nothing selectable that way: if we started on a header, try
|
||||
* the other direction once so we never rest on one */
|
||||
if (rows[s_visIdx[p]].kind == ROW_HEADER && dir > 0) {
|
||||
return overlayStepSel(pos, -1);
|
||||
}
|
||||
return (rows[s_visIdx[p]].kind == ROW_HEADER) ? pos : p;
|
||||
}
|
||||
p = q;
|
||||
if (rows[s_visIdx[p]].kind != ROW_HEADER) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void overlayUpdateVisible(void)
|
||||
{
|
||||
s_visN = 0;
|
||||
@@ -340,6 +373,11 @@ static void overlayUpdateVisible(void)
|
||||
if (s_sel >= s_visN) {
|
||||
s_sel = s_visN - 1;
|
||||
}
|
||||
/* D237: never rest on a category header -- step to the nearest row
|
||||
* below it (or above, at the end of the list). */
|
||||
if (rows[s_visIdx[s_sel]].kind == ROW_HEADER) {
|
||||
s_sel = overlayStepSel(s_sel, +1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep the selected row on screen: shift the window ONLY when the selection
|
||||
@@ -421,7 +459,8 @@ static void overlayInit(void)
|
||||
configForEachOption(resolveCb, NULL);
|
||||
|
||||
for (int i = 0; i < NUM_ROWS; i++) {
|
||||
if (rows[i].kind == ROW_RES || rows[i].kind == ROW_ACTION) {
|
||||
if (rows[i].kind == ROW_RES || rows[i].kind == ROW_ACTION ||
|
||||
rows[i].kind == ROW_HEADER) {
|
||||
rows[i].found = 1; /* not config-backed */
|
||||
continue;
|
||||
}
|
||||
@@ -560,7 +599,7 @@ static void rowSet(struct Row *r, double v)
|
||||
|
||||
static void rowAdjust(struct Row *r, int dir)
|
||||
{
|
||||
if (!r->found) {
|
||||
if (!r->found || r->kind == ROW_HEADER) { /* D237: headers have no value */
|
||||
return;
|
||||
}
|
||||
double v = rowGet(r);
|
||||
@@ -649,11 +688,9 @@ void optionsOverlayScroll(int dir)
|
||||
return;
|
||||
}
|
||||
overlayUpdateVisible();
|
||||
s_sel += (dir > 0) ? -1 : 1; /* wheel-up -> move up the list */
|
||||
/* Clamp at both ends like a normal PC settings list -- wrapping made the
|
||||
* selection "repeat" from the far edge, which read as a duplicate. */
|
||||
if (s_sel < 0) s_sel = 0;
|
||||
if (s_sel >= s_visN) s_sel = s_visN - 1;
|
||||
/* wheel-up -> move up the list; clamps at both ends like a normal PC
|
||||
* settings list (wrapping read as a duplicate) and skips D237 headers. */
|
||||
s_sel = overlayStepSel(s_sel, (dir > 0) ? -1 : 1);
|
||||
}
|
||||
|
||||
/* Set a slider row from an overlay-space x inside its value bar, snapped to
|
||||
@@ -744,8 +781,8 @@ void optionsOverlayHandleInput(void)
|
||||
prevStart = startNow;
|
||||
|
||||
/* ---- keyboard / D-pad nav (clamped at the ends; scroll follows) ---- */
|
||||
if (up && !prevUp && s_sel > 0) s_sel--;
|
||||
if (dn && !prevDn && s_sel < s_visN - 1) s_sel++;
|
||||
if (up && !prevUp) s_sel = overlayStepSel(s_sel, -1); /* skips headers */
|
||||
if (dn && !prevDn) s_sel = overlayStepSel(s_sel, +1);
|
||||
overlayUpdateScroll();
|
||||
if (lf && !prevLf) rowAdjust(&rows[s_visIdx[s_sel]], -1);
|
||||
if (rt && !prevRt) rowAdjust(&rows[s_visIdx[s_sel]], +1);
|
||||
@@ -781,7 +818,7 @@ void optionsOverlayHandleInput(void)
|
||||
optionsOverlayToggle(); /* close + configSave */
|
||||
return;
|
||||
}
|
||||
if (hoverVis >= 0) {
|
||||
if (hoverVis >= 0 && rows[s_visIdx[hoverVis]].kind != ROW_HEADER) {
|
||||
s_sel = hoverVis; /* explicit click -> select */
|
||||
overlayUpdateScroll();
|
||||
if (ox >= bx0) {
|
||||
@@ -803,7 +840,8 @@ void optionsOverlayHandleInput(void)
|
||||
dragRow = -1;
|
||||
}
|
||||
/* right press in the value column: cycle back / decrement */
|
||||
if (rmb && !prevRmb && hoverVis >= 0 && !onClose && ox >= bx0) {
|
||||
if (rmb && !prevRmb && hoverVis >= 0 && !onClose && ox >= bx0 &&
|
||||
rows[s_visIdx[hoverVis]].kind != ROW_HEADER) {
|
||||
s_sel = hoverVis;
|
||||
overlayUpdateScroll();
|
||||
rowAdjust(&rows[s_visIdx[hoverVis]], -1);
|
||||
@@ -999,6 +1037,10 @@ Gfx *optionsOverlayEmit(void)
|
||||
u32 col = (p == s_sel) ? 0xffffffff : 0xc0c0c8ff;
|
||||
char val[48];
|
||||
|
||||
if (r->kind == ROW_HEADER) { /* D237 category label, no value */
|
||||
gdl = drawText(gdl, OV_X0, rowY, (char *)r->label, 0xffe040ff);
|
||||
continue;
|
||||
}
|
||||
gdl = drawText(gdl, OV_LABEL_X, rowY, (char *)r->label,
|
||||
r->found ? col : 0x808080ff);
|
||||
if (!r->found) {
|
||||
|
||||
Reference in new issue
Block a user