mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
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.
This commit is contained in:
1 parent
835035916d
commit
7ff9ddbe14
6 files changed
+287
-32
No files matched your search
@@ -222,3 +222,5 @@ D341,FIXED,"Intro gun-barrel blood drip draws as static blocks/lines instead of
|
||||
D342,FIXED,"File select: folder bodies and Bond photos vanish after selecting a file and backing out (user, v0.4.0, 2026-09-26).","FIXED (M-201, user-verified):"
|
||||
D343,PARTIAL,"File select: PC ""Options"" label opens the settings overlay (v0.4.0 feature, M1 of the route-B options screen, 2026-09-27); also fixes F10 on file select jumpin…","LANDED (M1): one Rule-2 #ifdef PORT draw hook (user sign-off 2026-09-27); headless + user-verified (mouse, F10, >30 s, widescreen); physical controller check owed."
|
||||
D344,FIXED,Host PC bugchecks (BSOD 0x119 VIDEO_SCHEDULER_INTERNAL_ERROR) during game test runs; probable cause:,"FIXED (probable cause; orderly quit + GE_QUITFRAME), headless + user-verified; no dump, watch for recurrence."
|
||||
D345,FIXED,"Front-end crosshair snaps away from the pointer on screen/page changes (file select → mode select setCursorPOSforMode(0), front.c:2516; every MENU_PC_OPTIONS p…","Port-only, user-verified (parts a–g):"
|
||||
D346,PARTIAL,PC-settings wording pass:,Port-only display change landed (optionsoverlay.c rows[]/valueText + one colour match in frontoptions.c); both UIs (F10 overlay + options screen) share the table.
|
||||
|
@@ -630,6 +630,8 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D342 | **File select: folder bodies and Bond photos vanish after selecting a file and backing out (user, v0.4.0, 2026-09-26).** — full `## D342` entry at file tail | FIXED (M-201, user-verified): scratch placed at the N64 offset +0xA000 of `ptr_logo_and_walletbond_DL` landed inside the larger PC wallet model; moved past its 0x17000 reservation. |
|
||||
| D343 | **File select: PC "Options" label opens the settings overlay (v0.4.0 feature, M1 of the route-B options screen, 2026-09-27); also fixes F10 on file select jumping to the legal screen after 30 s.** — full `## D343` entry at file tail | LANDED (M1): one Rule-2 `#ifdef PORT` draw hook (user sign-off 2026-09-27); headless + user-verified (mouse, F10, >30 s, widescreen); physical controller check owed. |
|
||||
| D344 | **Host PC bugchecks (BSOD 0x119 VIDEO_SCHEDULER_INTERNAL_ERROR) during game test runs; probable cause: quit called exit() while the render thread could be inside the GL driver (2026-09-27).** — full `## D344` entry at file tail | FIXED (probable cause; orderly quit + GE_QUITFRAME), headless + user-verified; no dump, watch for recurrence. |
|
||||
| D345 | **Front-end crosshair snaps away from the pointer on screen/page changes (file select → mode select `setCursorPOSforMode(0)`, front.c:2516; every `MENU_PC_OPTIONS` page hop), and the options screen's keyboard navigation was missing/mis-modelled (2026-09-27).** — full `## D345` entry at file tail | Port-only, user-verified (parts a–g): (a) `input.c` re-assert window on menu change; (b) `cursorToItem` skips its snap while the pointer is live; (d) W/S emit stick in menus under NaturalPitch; (e/f) F10-style discrete row stepping + arrow left/right value adjust replace raw drift (first pass shipped broken, fixed); (g) screen-placed cursor parks in the left gutter, off the row text. Game-side one-liner (pad users) parked pending Rule-2 sign-off. |
|
||||
| D346 | **PC-settings wording pass: option labels/values aligned to Nightdive/Turok + PD-port conventions (title-case On/Off, "Frame rate cap", "Anti-aliasing"/"None", units in values not labels, self-explanatory auto-FOV toggles); VIEW section merged into VIDEO (2026-09-27).** — full `## D346` entry at file tail | Port-only display change landed (`optionsoverlay.c` rows[]/valueText + one colour match in `frontoptions.c`); both UIs (F10 overlay + options screen) share the table. Config keys/values untouched. Deadzone % display uses raw-step grid (cosmetic follow-up noted). |
|
||||
|
||||
Phase 2 replaced the Phase-1 demo loop with the real `mainproc()` on real OS
|
||||
threads, compiled GE's real `src/sched.c`, and brought in PD's fast3d software
|
||||
@@ -13607,3 +13609,96 @@ Implemented as `Input.PdMouseAim` (**default off**, because it changes aim feel)
|
||||
|
||||
**Status: FIXED (probable cause), user-verified.**
|
||||
|
||||
|
||||
## D345 — File select → mode select: crosshair snaps to the Agent row and stays there until the mouse moves (2026-09-27)
|
||||
|
||||
**Report:** with mouse input, entering a folder page (file select → mode select) resets the crosshair away from the pointer; it stays at the snapped position until the next mouse movement.
|
||||
|
||||
**Evidence:** `front.c:2516` — the file-select→mode-select entry path calls `setCursorPOSforMode(0)` unconditionally, teleporting `cursor_h/v_pos` to (126, 226), the first row. Its two sibling re-entry paths (`front.c:4502`, `:4646`) already use `setCursorPOSforMode(gamemode)`. The port's 1:1 menu pointer (`port/src/input.c`, D165/D169) writes `cursor_h/v_pos` from the absolute mouse position **only on frames where the OS mouse moved** (idle-mouse cede so WASD/arrow navigation can drive the cursor through the game's integrator). A click-to-enter leaves the mouse idle, so the game's snap persists until the next movement. `menuPrevActive` (`input.c:1359`) tracks menu-vs-not only, so the "just entered a menu" baseline-adopt branch does not fire on menu-to-menu transitions. Poll order is input → interface (D343), so the same-frame snap wins over any same-frame re-assert.
|
||||
|
||||
**Fix (port-only, `port/src/input.c`):** carry pointer ownership across front-end screen changes.
|
||||
- New statics: `menuPointerLastMenuId`, `menuPointerTransitionFrames`, `menuPointerLastAbsWrite` (perf-counter stamp of the last absolute write).
|
||||
- Every pad-0 poll: if `current_menu` changed, open a 3-poll re-assert window (the transition poll's write loses to the game's same-frame snap; poll+1 sticks).
|
||||
- In the 1:1 pointer block, force the absolute write when `(mouse moved) OR (window open AND mouse used within MENU_POINTER_REASSERT_MS = 1500 ms)`. Click-to-enter → cursor lands back under the pointer on the new page. Stale idle mouse (WASD navigation) → no yank; the cede-to-keyboard behaviour is preserved.
|
||||
- The F10 overlay does not change `current_menu`, so opening/closing it opens no window (correct: same screen, pointer already under the mouse). Entering `MENU_PC_OPTIONS` does change it and re-asserts — desirable, flagged for playtest.
|
||||
|
||||
**D345(b) — the new PC options screen (user report: "doesn't work on our new PC settings menu").** `MENU_PC_OPTIONS` has its own cursor teleporter: `cursorToItem()` (`port/src/frontoptions.c:178`) snaps the crosshair to a page's first item, called from screen-entry init, section entry, and back. The section/back hops happen *inside* frontoptions.c (no `current_menu` change), so the D345(a) window never sees them; every page hop re-snapped the crosshair away from the pointer. Fix (port-only): input.c now exports `inputMenuPointerLive()` (in a menu + abs pointer available + mouse used within `MENU_POINTER_REASSERT_MS`; refreshed every pad-0 poll, forced 0 while the F10 overlay owns the mouse), and `cursorToItem()` skips its snap when it is set — the cursor is already under the OS pointer. Keyboard/D-pad users (stale mouse) keep the snap. Also added `#include <SDL.h>` to `port/include/input.h` (its API uses SDL types; previously only includers that had SDL already compiled — cf. video.h).
|
||||
|
||||
**D345(c) — options screen: W/S did not move through the lists (user playtest).** Cheat-screen-style menus integrate stick input into `cursor_h/v_pos` by calling `frontUpdateControlStickPosition()` from their interface (`interface_menu15_cheat`, front.c:7700); `frontOptionsMenuInterface()` never did, so keyboard/D-pad vertical input had nothing to drive the cursor (A/D worked because frontoptions.c reads those as buttons directly). Fix (port-only): `frontOptionsMenuInterface()` now calls `frontUpdateControlStickPosition()` after `buildPages()`, before the highlight reads the cursor — mirroring the cheat screen. No-op while the 1:1 pointer owns the cursor (it emits a zero stick).
|
||||
|
||||
**D345(d) — W/S still dead after (c): NaturalPitch mode starves the stick (user playtest via playtest_v040.bat, confirmed running the fixed binary by exe/log timestamps).** With `NaturalPitch = 1` (default; in the user's ini), the keyboard forward/back mapping emits **C-up/C-down buttons** instead of stick (`input.c:1037-1042`, the D194/D238 in-stage aim scheme) -- and no front-end screen navigates on C-buttons, so W/S (and Up/Down arrows) produced zero stick in every menu. Fix (port-only): the natural-pitch branch now requires `!menuMode`, so menus always get the stick mapping (N64 front end is stick-driven). Watch/pause is unaffected: it runs at `current_menu == RUN_STAGE` (menuMode 0) and keeps the C-button mapping, N64-style. This also restores W/S vertical navigation on file select / cheat screen for NaturalPitch users (mouse users never noticed).
|
||||
|
||||
**D345(e) — user preference: F10-style discrete keyboard navigation on the options screen ("behave like the F10 menu but keep the mouse option").** Replaced the D345(c) raw stick drift with one-row-at-a-time stepping in `frontOptionsMenuInterface()`: W/S / Up-Down arrows (stick, via D345(d)) or pad stick/D-pad (`U_JPAD`/`D_JPAD`) move the highlight ±1 row, clamped at the ends, hold-to-repeat on the screen's existing 18/4-frame cadence (separate `s_vrepeatDir/Timer` state so it can run alongside left/right value adjust). Each step snaps the crosshair via new ungated `cursorToItemRaw()` (explicit keyboard nav owns the cursor even right after mouse use); `cursorToItem()` keeps the D345(b) pointer-live gate for page transitions. Mouse is untouched: any movement re-owns the cursor and the highlight hit-test follows it next frame. Stepper is skipped while a slider drag holds A. The D345(c) `frontUpdateControlStickPosition()` call is removed (it fought the pointer over `cursor_v_pos`).
|
||||
|
||||
**D345(f) — D345(e) shipped broken (user: "W/S still just move the crosshair").** The D345(e) edit added the stepper but its two *removals* never landed: the D345(c) `frontUpdateControlStickPosition()` call (after `buildPages()`) and its extern stayed in `frontoptions.c`, so W/S ran raw cursor drift on top of the row stepper. The build didn't catch it: with the extern gone from my intended edit but present in the file, compilation only produced an implicit-declaration warning, which this project compiles through. Fix: removed the call + extern (verified by grep, not just the edit tool's success message), and added stick-X to the left/right value block so Left/Right arrows adjust values like F10 (A/D letters already worked via C-buttons). Lesson recorded: after any edit that both adds and removes, grep-verify the removals against the file.
|
||||
|
||||
**Not changed:** the game-side snap itself (`front.c:2516`) is untouched — no Rule-2 sign-off needed for this fix. The optional one-liner `setCursorPOSforMode(gamemode >= 0 ? gamemode : 0)` (matching its siblings) remains a separate parked item; its main beneficiary is pad users, who have no re-assert at all.
|
||||
|
||||
**User-verified (2026-09-27):** folder-page snap gone (mouse); options screen entry/section hops keep the pointer under the mouse; sliders/toggles fine; F10-style W/S + arrow navigation with hold-to-repeat works; left/right arrows adjust values; crosshair parks in the gutter off the row text. Resolved for time being.
|
||||
|
||||
**Verification:** builds clean (`build-pc.sh ntsc-final`; only pre-existing warnings). Headless smoke: `GE_STARTMENU=5 GE_INPUTLOG=1 GE_QUITFRAME=400` — 412 `menuptr` lines, cursor stable, orderly self-quit (`render parked after 3 ms`). The playtest items listed here were subsequently covered by the user verification above.
|
||||
|
||||
## D346 — PC-settings wording pass: Nightdive/Turok + PD-port conventions (2026-09-27)
|
||||
|
||||
User request: make all PC setting labels/values consistent with the PD port and
|
||||
Nightdive remasters (Turok) where possible. Both settings UIs (the F10 overlay
|
||||
and `MENU_PC_OPTIONS`) share one table — `rows[]` in `port/src/optionsoverlay.c`
|
||||
— so a single pass covers both. Display-only: config keys, stored values, and
|
||||
adjustment behavior are untouched (existing inis read/write identically).
|
||||
|
||||
**Label changes** (`rows[]`, optionsoverlay.c):
|
||||
|
||||
| Before | After | Rationale |
|
||||
|---|---|---|
|
||||
| `DISPLAY` (section) | `VIDEO` | Nightdive section naming ("Video"); pairs with the existing `VIEW` section |
|
||||
| `Frame cap` | `Frame rate cap` | Turok 3's exact wording; values already Nightdive-style (`Uncapped` / `120 FPS`) |
|
||||
| `MSAA` | `Anti-aliasing` | Nightdive standard; jargon-free |
|
||||
| `Anisotropic` | `Anisotropic filtering` | Nightdive standard |
|
||||
| `FOV scale %` / `Draw distance %` / `LOD distance %` / `HUD scale %` / `Trigger threshold %` | `%` dropped from labels, moved to the value (`100%`, `150%`, …) | Nightdive shows units in the value column, not the label |
|
||||
| `Crop overscan bars` | `Crop overscan` | trimmed; "bars" was internal phrasing |
|
||||
| `Draw dist. auto` / `LOD dist. auto` | `Draw dist. follows FOV` / `LOD dist. follows FOV` | the old labels didn't say what follows what (they couple the distance to `Video.FovScale`, video.c:203-231) |
|
||||
| `Mouse invert Y` / `Pad invert look Y` | `Invert look (mouse)` / `Invert look (controller)` | Nightdive per-device convention; now a consistent pair |
|
||||
|
||||
**Value changes:** `OFF/ON` → `Off/On` (kOnOff); `NEAREST/BILINEAR/3-POINT` →
|
||||
`Nearest/Bilinear/3-Point`; `CENTRED (PC)` → `Centred (PC)`; MSAA `OFF` →
|
||||
`None` (Nightdive AA vocabulary). The options screen's ON-colour match in
|
||||
`frontoptions.c:454` updated `"ON"` → `"On"` to follow.
|
||||
|
||||
**Mechanism:** two display-only fields appended to `struct Row` (`unit`,
|
||||
`dispDiv`; C zero-fill keeps every existing positional initializer valid) and a
|
||||
small branch at the integer-slider tail of `valueText()`: optional raw→display
|
||||
divide, then unit suffix. Used by: FovScale/DrawDistance/LodDistance/HudScale/
|
||||
PadTriggerPct (`%`), Anisotropy (`x`), PadDeadzone (`%`, dispDiv 300 — raw
|
||||
0..30000 stick units → % of full travel; default 7000 now reads "23%" instead
|
||||
of "7000").
|
||||
|
||||
**Kept deliberately:** `VSync`, `Fullscreen`, `Resolution`, `Texture filter`
|
||||
(universal); `Aim style`/`Aim range` + their `N64`/`PC` values (GE-specific,
|
||||
already clear); `No hit flash` (community-mod name; inverting the polarity to
|
||||
"Hit flash: Off" would change what On means — not a wording fix); `Skip intro`,
|
||||
`Show FPS`, `All unlocked`, `Quit to desktop` (plain English, no reference
|
||||
counterpart worth matching).
|
||||
|
||||
**Known cosmetic follow-up (not done):** the deadzone slider's raw step is 500
|
||||
stick units, so its % display advances ~1.7% per press (23→24→25→27…). A clean
|
||||
1%-per-press grid would mean changing `step` to 300 — a behavior change to the
|
||||
adjustment feel, out of scope for a wording pass; flagged for a future input-QoL
|
||||
item.
|
||||
|
||||
**D346b — VIEW section merged into VIDEO (user request, same day).** The old
|
||||
`VIEW` header row was deleted from `rows[]`; its rows (FOV scale, Native
|
||||
widescreen, Widescreen auto FOV, Crop overscan, draw/LOD distance pairs) now
|
||||
follow the display/quality rows in one Nightdive-style "Video" section. The
|
||||
options screen's page model is one-header-one-page with a row cap, so the cap
|
||||
moved 12→15 (`MAX_PROWS`) and the row pitch 20→18 px (`ROW_DY`, frontoptions.c)
|
||||
to keep the worst case (15 rows: "Draw dist. follows FOV" off reveals both its
|
||||
toggle and the slider) on one page — last row text at y=317, inside the 330
|
||||
paper; its 22px highlight box overflows by 1px in that state only (clipped,
|
||||
invisible). Hit bands stay contiguous at the tighter pitch (band = [y-3, y+15),
|
||||
next starts y+15). F10 overlay unaffected (own pitch, scrolls). Section list is
|
||||
now 4 entries: Video / Mouse / Aim / Controller / Game.
|
||||
|
||||
**Verification:** `build-pc.sh ntsc-final` clean (no new warnings); headless
|
||||
boot into the options screen (`GE_STARTMENU=26 GE_QUITFRAME=300`) orderly
|
||||
self-quit, zero crash lines. All strings plain ASCII (JP-region safe, #87).
|
||||
Port-only: no `src/game` edits, N64 build untouched.
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
#include <SDL.h> /* API types (SDL_GameControllerButton/Axis); cf. video.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -67,6 +68,11 @@ short inputPadAxis(int idx, SDL_GameControllerAxis a);
|
||||
* ignored -- GE only cycles forward on a bare A edge. */
|
||||
void inputPostWheel(int notches);
|
||||
|
||||
/* D345(b): 1 while the 1:1 menu pointer owns cursor_h/v_pos (in a menu,
|
||||
* abs pointer available, mouse used within the re-assert window). Port
|
||||
* screens that teleport the crosshair should skip their snap when set. */
|
||||
int inputMenuPointerLive(void);
|
||||
|
||||
/* Re-enumerate gamepads after a hotplug (SDL_CONTROLLERDEVICEADDED/REMOVED). */
|
||||
void inputRescanPads(void);
|
||||
|
||||
|
||||
+83
-9
@@ -42,13 +42,13 @@
|
||||
#include "envflag.h"
|
||||
#include "optionsoverlay.h"
|
||||
#include "frontoptions.h"
|
||||
#include "input.h"
|
||||
|
||||
/* front.c functions this screen shares with the cheat screen (not all are in
|
||||
* front.h). */
|
||||
extern Gfx *frontSetupMenuBackground(Gfx *DL);
|
||||
extern Gfx *frontAddPreviousTabText(Gfx *DL);
|
||||
extern s32 frontCheckCursorOnPreviousTab(void);
|
||||
extern void frontUpdateControlStickPosition(void);
|
||||
extern Gfx *frontDrawCursor(Gfx *DL);
|
||||
extern Gfx *frontPrintText(Gfx *gdl, s32 *x, s32 *y, s8 *text, s32 second_font_table,
|
||||
s32 first_font_table, s32 arg6, s32 view_x, s32 view_y,
|
||||
@@ -69,7 +69,11 @@ extern struct rectbbox folder_option_ERASE_bound; /* front.c:439 */
|
||||
#define TITLE_Y 0x2B
|
||||
#define ROW_X 0x37 /* the cheat list's x */
|
||||
#define ROW_Y0 0x41 /* cheat list starts 0x35; +12 for the title line */
|
||||
#define ROW_DY 0x14 /* the cheat list's row pitch */
|
||||
/* D346b: 20 -> 18 px so the merged Video section (14 rows default, 15 with
|
||||
* "Draw dist. follows FOV" off) fits the paper on one page. Hit bands stay
|
||||
* contiguous at any pitch >= 6; the 22px highlight box still clears the next
|
||||
* row (y+14 < y+17). */
|
||||
#define ROW_DY 18
|
||||
#define NUM_X 0x37 /* "1." on the section list */
|
||||
#define SEC_X 0x4B
|
||||
#define VAL_R 372 /* values right-aligned here */
|
||||
@@ -85,7 +89,7 @@ extern struct rectbbox folder_option_ERASE_bound; /* front.c:439 */
|
||||
#define HIT_PAD 4
|
||||
|
||||
#define MAX_PAGES 8
|
||||
#define MAX_PROWS 12 /* the paper fits 12 rows, like the cheat list */
|
||||
#define MAX_PROWS 15 /* D346b: 12 -> 15 for the merged Video section (see ROW_DY) */
|
||||
|
||||
static const char kLabel[] = "PC Options"; /* ASCII only: issue #87 / D295 */
|
||||
static const char kLabelNL[] = "PC Options\n";
|
||||
@@ -96,6 +100,9 @@ static int s_page = 0; /* current section */
|
||||
static int s_hl = -1; /* highlighted row / section, -1 = none */
|
||||
static int s_dragRow = -1; /* global row index being dragged */
|
||||
static int s_repeatDir = 0, s_repeatTimer = 0;
|
||||
/* D345(e): hold-to-repeat state for vertical row stepping (separate from
|
||||
* the left/right value-adjust repeat; both can be held at once). */
|
||||
static int s_vrepeatDir = 0, s_vrepeatTimer = 0;
|
||||
|
||||
static int s_pageHdr[MAX_PAGES];
|
||||
static int s_pageN = 0;
|
||||
@@ -174,11 +181,29 @@ static int itemCount(void)
|
||||
return s_level == 0 ? s_pageN : s_rowN;
|
||||
}
|
||||
|
||||
/* Put the crosshair on item k, unconditionally. */
|
||||
static void cursorToItemRaw(int k)
|
||||
{
|
||||
/* D345(g): snap into the left gutter (x=44), not onto the row text
|
||||
* (the old ROW_X+20 centred the sprite over the label/highlight box).
|
||||
* 44 stays inside [ROW_HIT_X0..1] so the highlight hit-test still
|
||||
* resolves row k, and clears the number column (NUM_X=55) / highlight
|
||||
* boxes (from x=53/73). The PREVIOUS-tab hitbox (x>390 && y>223) is
|
||||
* far away. Mouse users are unaffected: the pointer sits under the
|
||||
* real mouse, never at this snap position. */
|
||||
cursor_h_pos = 44.0f;
|
||||
cursor_v_pos = (f32)(rowY(k) + 6);
|
||||
}
|
||||
|
||||
/* Put the crosshair on item k (entering a page / going back). */
|
||||
static void cursorToItem(int k)
|
||||
{
|
||||
cursor_h_pos = (f32)(ROW_X + 20);
|
||||
cursor_v_pos = (f32)(rowY(k) + 6);
|
||||
/* D345(b): while the 1:1 pointer owns the crosshair (mouse recently
|
||||
* used), it is already under the OS pointer -- snapping would yank it
|
||||
* to the top-left item and it would stay there until the next mouse
|
||||
* movement. Keyboard/D-pad users (stale mouse) keep the snap. */
|
||||
if (inputMenuPointerLive()) return;
|
||||
cursorToItemRaw(k);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -209,6 +234,7 @@ void frontOptionsMenuInit(void)
|
||||
s_hl = -1;
|
||||
s_dragRow = -1;
|
||||
s_repeatDir = 0;
|
||||
s_vrepeatDir = 0;
|
||||
buildPages();
|
||||
cursorToItem(0);
|
||||
sysLogPrintf(LOG_INFO, "frontoptions: opened");
|
||||
@@ -242,6 +268,11 @@ void frontOptionsMenuInterface(void)
|
||||
|
||||
buildPages(); /* an auto toggle may have hidden or shown % rows */
|
||||
|
||||
/* D345(f): NO raw stick integration on this screen (the D345(c) call to
|
||||
* frontUpdateControlStickPosition() was removed): vertical input is the
|
||||
* discrete row stepper below, horizontal is the left/right block -- F10
|
||||
* model. Raw drift fought the pointer over cursor_h/v_pos. */
|
||||
|
||||
/* Highlight: as the cheat screen, recomputed while A is not held. */
|
||||
if (joyGetButtons(PLAYER_1, A_BUTTON | Z_TRIG) == 0) {
|
||||
tab_prev_highlight = FALSE;
|
||||
@@ -298,8 +329,11 @@ void frontOptionsMenuInterface(void)
|
||||
* with hold-to-repeat. */
|
||||
if (s_level == 1 && s_hl >= 0 && s_hl < s_rowN) {
|
||||
int dir = 0;
|
||||
if (joyGetButtons(PLAYER_1, L_JPAD | L_CBUTTONS)) dir = -1;
|
||||
if (joyGetButtons(PLAYER_1, R_JPAD | R_CBUTTONS)) dir = +1;
|
||||
/* D345(f): stick X joins the D-pad/C-buttons, so Left/Right arrows
|
||||
* (and the pad's left stick) adjust values like F10's left/right. */
|
||||
s8 vsx = joyGetStickX(PLAYER_1);
|
||||
if (joyGetButtons(PLAYER_1, L_JPAD | L_CBUTTONS) || vsx < -5) dir = -1;
|
||||
if (joyGetButtons(PLAYER_1, R_JPAD | R_CBUTTONS) || vsx > 5) dir = +1;
|
||||
if (dir != 0) {
|
||||
int fire = 0;
|
||||
if (dir != s_repeatDir) {
|
||||
@@ -323,7 +357,47 @@ void frontOptionsMenuInterface(void)
|
||||
set_item_visibility_in_objinstance(walletinst[0], SW_TABS, 1);
|
||||
set_item_visibility_in_objinstance(walletinst[0], SW_BLANK, 1);
|
||||
set_item_visibility_in_objinstance(walletinst[0], SW_CLASSIFIED, 1);
|
||||
frontUpdateControlStickPosition();
|
||||
|
||||
/* D345(e): F10-style discrete vertical navigation. W/S / Up-Down arrows
|
||||
* (stick via D345(d)) or the pad's stick/D-pad step the highlight one
|
||||
* row at a time -- clamped at the ends, hold-to-repeat with the same
|
||||
* 18/4-frame cadence as left/right -- and snap the crosshair onto the
|
||||
* new row (ungated: explicit keyboard navigation owns the cursor even
|
||||
* right after mouse use). Replaces the raw stick drift of D345(c),
|
||||
* which fought the pointer over cursor_v_pos. The mouse is untouched:
|
||||
* any movement re-owns the cursor and the highlight hit-test above
|
||||
* follows it next frame. Skipped while a slider drag holds A. */
|
||||
if (s_dragRow < 0) {
|
||||
int vdir = 0;
|
||||
s8 vsy = joyGetStickY(PLAYER_1);
|
||||
if (joyGetButtons(PLAYER_1, U_JPAD) || vsy > 5) vdir = -1; /* up */
|
||||
else if (joyGetButtons(PLAYER_1, D_JPAD) || vsy < -5) vdir = +1; /* down */
|
||||
if (vdir != 0) {
|
||||
int fire = 0;
|
||||
if (vdir != s_vrepeatDir) {
|
||||
fire = 1;
|
||||
s_vrepeatTimer = 18;
|
||||
} else if (--s_vrepeatTimer <= 0) {
|
||||
fire = 1;
|
||||
s_vrepeatTimer = 4;
|
||||
}
|
||||
if (fire) {
|
||||
int n = itemCount();
|
||||
if (n > 0) {
|
||||
int q = (s_hl < 0 ? 0 : s_hl) + vdir;
|
||||
if (q < 0) q = 0;
|
||||
if (q >= n) q = n - 1;
|
||||
if (q != s_hl) {
|
||||
s_hl = q;
|
||||
cursorToItemRaw(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
s_vrepeatDir = vdir;
|
||||
} else {
|
||||
s_vrepeatDir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Gfx *frontOptionsMenuDraw(Gfx *DL)
|
||||
@@ -381,7 +455,7 @@ Gfx *frontOptionsMenuDraw(Gfx *DL)
|
||||
|
||||
optionsRowValueText(i, buf, sizeof(buf) - 1);
|
||||
if (buf[0]) {
|
||||
u32 col = (strcmp(buf, "ON") == 0) ? INK_ON : INK;
|
||||
u32 col = (strcmp(buf, "On") == 0) ? INK_ON : INK; /* D346: kOnOff is now title-case */
|
||||
strcat(buf, "\n");
|
||||
DL = inkR(DL, VAL_R, y, buf, col);
|
||||
}
|
||||
|
||||
+63
-2
@@ -265,6 +265,9 @@ extern s32 lvlGetCurrentStageToLoad(void);
|
||||
#define MENU_CURSOR_LO 20.0
|
||||
#define MENU_CURSOR_HI_H 300.0
|
||||
#define MENU_CURSOR_HI_V 220.0
|
||||
/* D345: after a front-end screen change, re-assert the 1:1 pointer for a few
|
||||
* frames if the mouse was used within this many ms (see inputComputePad). */
|
||||
#define MENU_POINTER_REASSERT_MS 1500.0
|
||||
#define MENU_CURSOR_MID_H 160.0
|
||||
#define MENU_CURSOR_MID_V 120.0
|
||||
|
||||
@@ -538,6 +541,20 @@ static int hipfirePitchSpeed = 100; /* D166: hipfire pitch pulse rate, percen
|
||||
static int menuPrevActive = 0;
|
||||
static double hipPitchPhase = 0.0; /* D166: hipfire pitch pulse phase 0..1 */
|
||||
static int lastMenuMouseX = -1, lastMenuMouseY = -1; /* WI-2: last abs cursor seen in a menu */
|
||||
/* D345: carry pointer ownership across front-end screen changes. The game
|
||||
* teleports cursor_h/v_pos on some transitions (file select -> mode select
|
||||
* calls setCursorPOSforMode(0), front.c:2516); the absolute write below only
|
||||
* fires while the OS mouse moves, so with an idle mouse the snap persists
|
||||
* until the next movement. lastMenuId detects the change; transitionFrames is
|
||||
* a short countdown during which a recent-mouse re-assert is allowed;
|
||||
* lastAbsWrite is the perf-counter stamp of the last absolute write (mouse
|
||||
* recency). */
|
||||
static int menuPointerLastMenuId = -1;
|
||||
static int menuPointerTransitionFrames = 0;
|
||||
static Uint64 menuPointerLastAbsWrite = 0;
|
||||
/* D345(b): 1 while the 1:1 pointer can own cursor_h/v_pos this poll
|
||||
* (menu, mouse enabled + grabbed). Refreshed every pad-0 poll. */
|
||||
static int s_menuPointerLive = 0;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -949,6 +966,7 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
optionsOverlayHandleInput();
|
||||
if (stick_x) *stick_x = 0;
|
||||
if (stick_y) *stick_y = 0;
|
||||
s_menuPointerLive = 0; /* D345(b): the overlay owns the mouse */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -959,6 +977,17 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
int menuMode = (current_menu != GE_MENU_RUN_STAGE &&
|
||||
current_menu != GE_MENU_INVALID);
|
||||
|
||||
/* D345: detect front-end screen changes (any current_menu flip,
|
||||
* including into MENU_PC_OPTIONS / the F10 overlay's parent state)
|
||||
* and open a short re-assert window. Runs every poll so the
|
||||
* countdown drains even when the pointer block below is skipped
|
||||
* (mouse disabled, unfocused window, legacy velocity mode). */
|
||||
if ((int)current_menu != menuPointerLastMenuId) {
|
||||
menuPointerLastMenuId = (int)current_menu;
|
||||
menuPointerTransitionFrames = 3; /* this poll + two more */
|
||||
}
|
||||
if (menuPointerTransitionFrames > 0) menuPointerTransitionFrames--;
|
||||
|
||||
/* D194: aim mode drives the view from GRABBED relative deltas (see
|
||||
* aimAbsCompute) -- the cursor stays hidden and clipped to the window
|
||||
* for the whole hold. The earlier free-cursor experiment (suspend the
|
||||
@@ -1005,7 +1034,13 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
* because the stick's Y axis is what carries continuous analog
|
||||
* pitch there instead. Strafe and turn are unchanged -- both
|
||||
* schemes read them the same way. */
|
||||
if (naturalPitchMode) {
|
||||
/* D345(d): natural pitch is an in-stage aim scheme -- the N64 front
|
||||
* end navigates on the analog stick only, so in menus W/S (and the
|
||||
* Up/Down arrows) must emit stick even with NaturalPitch=1, or no
|
||||
* front-end screen (file select, cheat, MENU_PC_OPTIONS) can be
|
||||
* driven vertically from the keyboard. Watch/pause keeps the C-button
|
||||
* mapping: it is current_menu==RUN_STAGE (menuMode 0), N64-style. */
|
||||
if (naturalPitchMode && !menuMode) {
|
||||
if (actHeld(ks, IA_FORWARD)) button |= GE_CONT_E; /* C-up = forward */
|
||||
if (actHeld(ks, IA_BACK)) button |= GE_CONT_D; /* C-down = back */
|
||||
} else {
|
||||
@@ -1205,7 +1240,17 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
lastMenuMouseX = mx;
|
||||
lastMenuMouseY = my;
|
||||
}
|
||||
if (mx != lastMenuMouseX || my != lastMenuMouseY) {
|
||||
/* D345: re-assert right after a screen change when the
|
||||
* mouse was the recent navigation device (click-to-
|
||||
* enter). A stale idle mouse (WASD/arrow navigation)
|
||||
* keeps the cede-to-keyboard behaviour: no yank. */
|
||||
Uint64 pcNow = SDL_GetPerformanceCounter();
|
||||
int mouseRecent = (menuPointerLastAbsWrite != 0) &&
|
||||
((double)(pcNow - menuPointerLastAbsWrite) /
|
||||
(double)SDL_GetPerformanceFrequency() * 1000.0) <
|
||||
MENU_POINTER_REASSERT_MS;
|
||||
if ((mx != lastMenuMouseX || my != lastMenuMouseY) ||
|
||||
(menuPointerTransitionFrames > 0 && mouseRecent)) {
|
||||
double fx = (double)mx / (double)ww;
|
||||
/* D335: under native widescreen the front end is
|
||||
* pillarboxed to a centred 4:3 region
|
||||
@@ -1226,6 +1271,7 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
cursor_v_pos = (float)(loV + fy * (hiV - loV));
|
||||
sx = 0; /* pointer owns the cursor this poll */
|
||||
sy = 0;
|
||||
menuPointerLastAbsWrite = pcNow;
|
||||
}
|
||||
lastMenuMouseX = mx;
|
||||
lastMenuMouseY = my;
|
||||
@@ -1357,6 +1403,7 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
if (mb & SDL_BUTTON(SDL_BUTTON_RIGHT)) button |= GE_CONT_B;
|
||||
}
|
||||
menuPrevActive = menuMode;
|
||||
s_menuPointerLive = (menuMode && mouseEnabled && !mouseGrabbed) ? 1 : 0;
|
||||
|
||||
mouseDX = 0.0;
|
||||
mouseDY = 0.0;
|
||||
@@ -1506,6 +1553,20 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
return button;
|
||||
}
|
||||
|
||||
int inputMenuPointerLive(void)
|
||||
{
|
||||
/* D345(b): true while the 1:1 menu pointer owns cursor_h/v_pos -- in a
|
||||
* menu, the abs pointer is available, and the mouse was used recently.
|
||||
* Port screens that teleport the crosshair (frontoptions.c cursorToItem)
|
||||
* skip their snap when this is set: the cursor is already under the OS
|
||||
* pointer. Keyboard/D-pad users (stale mouse) still get the snap. */
|
||||
if (!s_menuPointerLive || menuPointerLastAbsWrite == 0) return 0;
|
||||
Uint64 now = SDL_GetPerformanceCounter();
|
||||
return ((double)(now - menuPointerLastAbsWrite) /
|
||||
(double)SDL_GetPerformanceFrequency() * 1000.0) <
|
||||
MENU_POINTER_REASSERT_MS;
|
||||
}
|
||||
|
||||
static void applyGrab(int want)
|
||||
{
|
||||
want = want && mouseEnabled;
|
||||
|
||||
+38
-21
@@ -71,9 +71,11 @@ extern s16 viGetY(void);
|
||||
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 };
|
||||
static const char *const kAimMode[] = { "N64", "CENTRED (PC)", NULL }; /* D337 */
|
||||
/* D346: wording pass -- Nightdive/Turok + PD-port conventions: title-case
|
||||
* On/Off, no all-caps value strings. Display-only; config stores 0/1 either way. */
|
||||
static const char *const kOnOff[] = { "Off", "On", NULL };
|
||||
static const char *const kTexFilter[] = { "Nearest", "Bilinear", "3-Point", NULL };
|
||||
static const char *const kAimMode[] = { "N64", "Centred (PC)", NULL }; /* D337 */
|
||||
static const char *const kAimRange[] = { "PC", "N64", NULL }; /* D338 */
|
||||
static const int kMsaaSeq[] = { 1, 2, 4, 8 };
|
||||
/* D186: the sim's own tick pacemaker is hardcoded to the console's native VI
|
||||
@@ -123,29 +125,36 @@ struct Row {
|
||||
* disappears while its "auto" toggle is on). Resolved to hidePtr at init. */
|
||||
const char *hiddenIfOn;
|
||||
int *hidePtr;
|
||||
|
||||
/* D346: value-text decoration (display only). unit is appended to integer
|
||||
* slider values ("%"/"x"); dispDiv>0 divides the raw value before display
|
||||
* (e.g. deadzone raw 0..30000 -> % of full stick). NULL/0 = plain int. */
|
||||
const char *unit;
|
||||
int dispDiv;
|
||||
};
|
||||
|
||||
static struct Row rows[] = {
|
||||
{ "__HdrDisplay", "DISPLAY", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "__HdrDisplay", "VIDEO", 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 },
|
||||
{ "Video.FpsCap", "Frame cap", ROW_FPSCAP, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.MSAA", "MSAA", ROW_MSAA, 0, NULL, 1, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.FpsCap", "Frame rate cap", ROW_FPSCAP, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.MSAA", "Anti-aliasing", 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 },
|
||||
{ "Video.Anisotropy", "Anisotropic filtering",ROW_SLIDER, 1, NULL, 0, 0, 0, 0,0,0,0,0, NULL, "x" },
|
||||
/* D346b: the old VIEW section (FOV / widescreen / draw distance) is merged
|
||||
* into VIDEO -- one Nightdive-style "video" section; rows keep order. */
|
||||
{ "Video.FovScale", "FOV scale", ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0, NULL, "%" },
|
||||
/* D334: native widescreen (world projected at the window aspect, Hor+).
|
||||
* While on, "Widescreen auto FOV" has no effect (it was the stretch-era
|
||||
* vertical-FOV compensation). */
|
||||
{ "Video.NativeWidescreen", "Native widescreen",ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.WidescreenAuto", "Widescreen auto FOV",ROW_TOGGLE,1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.SafeAreaCrop", "Crop overscan bars", ROW_TOGGLE,1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.DrawDistance", "Draw distance %", ROW_SLIDER, 25, NULL, 0, 0, 0, 0,0,0,0,0, "Video.DrawDistanceAutoFov" },
|
||||
{ "Video.DrawDistanceAutoFov","Draw dist. auto", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.LodDistance", "LOD distance %", ROW_SLIDER, 25, NULL, 0, 0, 0, 0,0,0,0,0, "Video.LodDistanceAutoFov" },
|
||||
{ "Video.LodDistanceAutoFov", "LOD dist. auto", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.SafeAreaCrop", "Crop overscan", ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.DrawDistance", "Draw distance", ROW_SLIDER, 25, NULL, 0, 0, 0, 0,0,0,0,0, "Video.DrawDistanceAutoFov", "%" },
|
||||
{ "Video.DrawDistanceAutoFov","Draw dist. follows FOV",ROW_TOGGLE,1,kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Video.LodDistance", "LOD distance", ROW_SLIDER, 25, NULL, 0, 0, 0, 0,0,0,0,0, "Video.LodDistanceAutoFov", "%" },
|
||||
{ "Video.LodDistanceAutoFov", "LOD dist. follows FOV",ROW_TOGGLE,1,kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* Aim row edits Input.AimModeSens -- the knob the default GEPD aim path
|
||||
* actually uses (Input.MouseAimSpeed only feeds the legacy velocity-stick
|
||||
* fallback, so it was inert here). D304: both this row and the turn-speed
|
||||
@@ -177,7 +186,7 @@ static struct Row rows[] = {
|
||||
/* { "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.MouseInvertY", "Invert look (mouse)",ROW_TOGGLE, 1, kOnOff, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* Input.PdMouseAim (findings D332): the Perfect Dark port's mouse-aim
|
||||
* model. The port only accumulates the mouse; the game's own crosshair
|
||||
* integrator is driven by the port-supplied turn with PD's near-zero damp
|
||||
@@ -195,9 +204,9 @@ static struct Row rows[] = {
|
||||
* style is CENTRED (PC), where the crosshair doesn't travel. */
|
||||
{ "Input.AimRange", "Aim range", ROW_ENUM, 1, kAimRange, 0, 0, 0, 0,0,0,0,0, "Input.AimMode" },
|
||||
{ "__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 },
|
||||
{ "Input.PadLookInvertY", "Invert look (controller)",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, NULL, "%", 300 },
|
||||
{ "Input.PadTriggerPct", "Trigger threshold",ROW_SLIDER, 1, NULL, 0, 0, 0, 0,0,0,0,0, NULL, "%" },
|
||||
/* 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
|
||||
@@ -210,7 +219,7 @@ static struct Row rows[] = {
|
||||
{ "__HdrGame", "GAME", ROW_HEADER, 0, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
/* D226: scales the ammo counter, pickup / status messages and dialogue
|
||||
* about their screen anchors. 100% = original, nothing emitted. */
|
||||
{ "Game.HudScale", "HUD scale %", ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0 },
|
||||
{ "Game.HudScale", "HUD scale", ROW_SLIDER, 5, NULL, 0, 0, 0, 0,0,0,0,0, NULL, "%" },
|
||||
{ "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 },
|
||||
@@ -922,7 +931,7 @@ static void valueText(const struct Row *r, char *out, int n)
|
||||
}
|
||||
}
|
||||
if (r->kind == ROW_MSAA) {
|
||||
if ((int)lround(v) <= 1) snprintf(out, n, "OFF");
|
||||
if ((int)lround(v) <= 1) snprintf(out, n, "None");
|
||||
else snprintf(out, n, "%dx", (int)lround(v));
|
||||
return;
|
||||
}
|
||||
@@ -940,7 +949,15 @@ static void valueText(const struct Row *r, char *out, int n)
|
||||
else snprintf(out, n, "%d FPS", fps);
|
||||
return;
|
||||
}
|
||||
snprintf(out, n, "%d", (int)lround(v));
|
||||
/* D346: integer sliders -- optional raw->display divide + unit suffix. */
|
||||
if (r->dispDiv > 0) {
|
||||
v = (double)(int)lround(v / (double)r->dispDiv);
|
||||
}
|
||||
if (r->unit) {
|
||||
snprintf(out, n, "%d%s", (int)lround(v), r->unit);
|
||||
} else {
|
||||
snprintf(out, n, "%d", (int)lround(v));
|
||||
}
|
||||
}
|
||||
|
||||
static Gfx *drawText(Gfx *gdl, s32 x, s32 y, const char *str, u32 colour)
|
||||
|
||||
Reference in new issue
Block a user