forked from Ports/goldeneye-pc-port
M-26: [B/C] level_sweep STALLED verdict, raw mouse input opt-in
- level_sweep.sh: frames rendered then frozen with process alive -> STALLED (froze at N/M frames) instead of a false PASS (the Silo -level_20 fly-down / D117-D134 load case). Retried once like NO-FRAMES. - input.c: Input.MouseRawInput=1 (default 0) sets SDL relative system-scale + warp hints off in inputInit -> no OS pointer accel on aim. - docs: M-26-QOL-REVIEW.md + HANDOFF section.
This commit is contained in:
1 parent
db1834ca9b
commit
710d02f802
4 files changed
+111
-12
No files matched your search
@@ -311,6 +311,27 @@ behavior exactly.
|
||||
idle machine the user drove Silo live past ~1800 frames, VI pacemaker
|
||||
healthy, no stall. See `docs/M-25-QOL-REVIEW.md`.
|
||||
|
||||
## Done this session (M-26) — port-layer QoL batch (A/B/C/E)
|
||||
|
||||
Low-risk QoL, `port/` only, zero `src/` change. All defaults reproduce
|
||||
prior behaviour. Full review: **`docs/M-26-QOL-REVIEW.md`**.
|
||||
|
||||
- **A — save-on-exit + `[Window]` persistence.** `atexit(portAtExit)` in
|
||||
`main.c` (`videoSaveWindowState()` + `configSave()`), fires on every
|
||||
clean quit (`exit(0)` in `videoPumpEvents`); `abort()` paths skip it.
|
||||
New `[Window]` ini section (`Width/Height/X/Y/Maximized`, sentinels =
|
||||
old behaviour) in `video.c`; `Video.Fullscreen` now round-trips.
|
||||
- **B — `level_sweep.sh` STALLED verdict.** Frames rendered then froze
|
||||
with the process still alive → `STALLED (froze at N/M frames)` instead
|
||||
of a bogus PASS (the Silo case). Retried once like NO-FRAMES.
|
||||
- **C — raw mouse input.** `Input.MouseRawInput=1` (default 0) sets the
|
||||
SDL relative-scale / warp hints off in `inputInit` — no OS pointer accel.
|
||||
- **E — `--help` / `--version`** in `main.c` before `crashInit()`: build
|
||||
id, usage, the 21-level `-level_XX` table.
|
||||
- **Verified:** build green (`ntsc-final`); `-level_09` + `-level_20`
|
||||
boot crash-free 6/6 GE_PCDUMP frames (unregressed); `ge007.ini` gains a
|
||||
populated `[Window]` block on exit.
|
||||
|
||||
## Next task (M-24 — Opus 5)
|
||||
|
||||
**Scope call (user, M-23):** D139 (stage unload) + D140 (pause menu / watch)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# M-26 QoL review — save-on-exit, window persistence, raw mouse, --help, STALLED verdict
|
||||
|
||||
Port-layer only. Zero `src/` / game-logic change. Every default reproduces
|
||||
prior behaviour exactly (all new knobs default-off / default-current).
|
||||
|
||||
## A — `atexit()` save-on-exit + `[Window]` persistence
|
||||
|
||||
- `port/src/main.c`: `atexit(portAtExit)` registered right after
|
||||
`configLoad()`. `portAtExit` = `videoSaveWindowState()` then
|
||||
`configSave()`. The `exit(0)` in `videoPumpEvents` (SDL_QUIT / ESC /
|
||||
window-close) is reachable, so the handler fires on every clean quit.
|
||||
Crash / `sysFatalError` paths call `abort()` → handler does **not** run
|
||||
(intended — don't persist a broken state).
|
||||
- `port/src/video.c`: new `[Window]` config section — `Width`, `Height`,
|
||||
`X`, `Y`, `Maximized`. Sentinels reproduce the old hardcoded behaviour:
|
||||
`Width/Height = 0` → native (640×480 / 640×400), `X/Y = -1` → SDL
|
||||
centres the window. `videoInit` uses them for the `GfxWindowInitSettings`.
|
||||
- `videoSaveWindowState()` reads `wmAPI->get_fullscreen_state` /
|
||||
`get_maximized_state` / `get_dimensions` (all already in the SDL2 wapi
|
||||
backend) and writes geometry back into the cfg vars. A maximized or
|
||||
fullscreen window keeps its last *restored* size/pos on disk and only
|
||||
updates the flag. `Video.Fullscreen` now round-trips too.
|
||||
- **Verified:** `-level_09` / `-level_20` boot crash-free (6/6 GE_PCDUMP
|
||||
frames each, unregressed); `ge007.ini` gains a populated `[Window]`
|
||||
block on exit; relaunch reads it back with no unknown-key warnings.
|
||||
|
||||
## B — `level_sweep.sh` STALLED verdict
|
||||
|
||||
Pure shell (not built). A level that renders a few frames then freezes
|
||||
while the process stays alive (the Silo `-level_20` fly-down case,
|
||||
D117/D134 machine-load sensitivity) previously reported **PASS** because
|
||||
`last=$(ls ppm/*.ppm | tail -1)` was non-empty. Now the watchdog records
|
||||
`stalled=1` when the frame count is frozen for `STALL_SECS`, and `alive=1`
|
||||
if the process was still running when the watchdog gave up →
|
||||
`STALLED (froze at N/M frames)`. A complete dump set is still a real PASS.
|
||||
STALLED is retried once (like NO-FRAMES) before it's believed.
|
||||
|
||||
## C — raw mouse input (`Input.MouseRawInput`, default 0)
|
||||
|
||||
`port/src/input.c inputInit`: when `MouseRawInput=1`, sets
|
||||
`SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE=0` and
|
||||
`SDL_HINT_MOUSE_RELATIVE_MODE_WARP=0` before `SDL_SetRelativeMouseMode` —
|
||||
removes OS pointer acceleration / warp emulation from aim. Off by default
|
||||
so nothing changes unless the user opts in.
|
||||
|
||||
## E — `--help` / `--version`
|
||||
|
||||
`port/src/main.c`, handled before `crashInit()`:
|
||||
- `--version` → rom id / target platform / build hash, exit 0.
|
||||
- `--help` / `-h` → the above + usage + the 21 solo-level `-level_XX`
|
||||
table (matches `tools_pc/level_sweep.sh` / `playtest.sh --list`), exit 0.
|
||||
|
||||
## Not done (Tier 2/3 from the board)
|
||||
|
||||
F (minidump), G (PNG screenshots), H (rumble), I/J (in-render overlay /
|
||||
toasts) — left for a dedicated session.
|
||||
@@ -129,6 +129,7 @@ static int mouseTurnSpeed = 100; /* hipfire yaw sensitivity, percent */
|
||||
static int mouseInvertY = 0; /* 1 = mouse-down looks up */
|
||||
static int mouseYScale = 100; /* extra vertical (pitch) sensitivity, % */
|
||||
static int mouseSmoothing = 0; /* 0 = raw; 1..90 = low-pass strength (%) */
|
||||
static int mouseRawInput = 0; /* 1 = bypass OS pointer accel for aim */
|
||||
|
||||
/* Gamepad tuning -- defaults reproduce the old hardcoded constants exactly. */
|
||||
static int padDeadzone = STICK_DEADZONE; /* left-stick deadzone, raw 0..32767 */
|
||||
@@ -202,6 +203,14 @@ int inputInit(void)
|
||||
/* Relative mouse mode for mouse-look. ESC still quits (video.c). */
|
||||
mouseGrabbed = mouseEnabled;
|
||||
if (mouseEnabled) {
|
||||
if (mouseRawInput) {
|
||||
/* Feed the raw device delta straight through: no OS pointer
|
||||
* acceleration, no warp-based emulation. Must be set before
|
||||
* relative mode is enabled. */
|
||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, "0");
|
||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "0");
|
||||
sysLogPrintf(LOG_INFO, "input: raw mouse input (no OS pointer accel)");
|
||||
}
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
/* Drain the initial jump. */
|
||||
SDL_GetRelativeMouseState(NULL, NULL);
|
||||
@@ -477,6 +486,7 @@ PD_CONSTRUCTOR static void inputConfigInit(void)
|
||||
configRegisterInt("Input.MouseInvertY", &mouseInvertY, 0, 1);
|
||||
configRegisterInt("Input.MouseYScale", &mouseYScale, 1, 500);
|
||||
configRegisterInt("Input.MouseSmoothing", &mouseSmoothing, 0, 90);
|
||||
configRegisterInt("Input.MouseRawInput", &mouseRawInput, 0, 1);
|
||||
configRegisterInt("Input.PadDeadzone", &padDeadzone, 0, 30000);
|
||||
configRegisterInt("Input.PadTriggerPct", &padTriggerPct, 1, 99);
|
||||
configRegisterInt("Input.PadLookInvertY", &padLookInvertY, 0, 1);
|
||||
|
||||
+24
-12
@@ -66,18 +66,22 @@ run_level() {
|
||||
# known -- exit as soon as the whole dump set is on disk (PASS), or the frame
|
||||
# count has been frozen for STALL_SECS (level rendered a bit then wedged), or
|
||||
# the process exits on its own (clean exit / crash).
|
||||
local waited=0 fcnt=0 prev=0 stall=0
|
||||
local waited=0 fcnt=0 prev=0 stall=0 stalled=0
|
||||
while [ $waited -lt $SWEEP_SECS ] && kill -0 $pid 2>/dev/null; do
|
||||
sleep 1; waited=$((waited + 1))
|
||||
fcnt=$(ls ppm/*.ppm 2>/dev/null | wc -l)
|
||||
[ "$fcnt" -ge "$EXPECT_FRAMES" ] && break
|
||||
if [ "$fcnt" -gt 0 ] && [ "$fcnt" -eq "$prev" ]; then
|
||||
stall=$((stall + 1)); [ $stall -ge $STALL_SECS ] && break
|
||||
stall=$((stall + 1))
|
||||
if [ $stall -ge $STALL_SECS ]; then stalled=1; break; fi
|
||||
else
|
||||
stall=0
|
||||
fi
|
||||
prev=$fcnt
|
||||
done
|
||||
# was the process still alive when we gave up (vs. a clean exit / crash)?
|
||||
local alive=0
|
||||
kill -0 $pid 2>/dev/null && alive=1
|
||||
taskkill //F //IM ge007.x86_64.exe > /dev/null 2>&1
|
||||
wait $pid 2>/dev/null
|
||||
sleep 2
|
||||
@@ -95,7 +99,14 @@ run_level() {
|
||||
last=$(ls ppm/*.ppm 2>/dev/null | tail -1)
|
||||
if [ -n "$last" ]; then
|
||||
pcnt=$(python tools_pc/pixcount.py "$last" 2>/dev/null | grep -oE 'non-clear [0-9]+ \([0-9.]+%\)')
|
||||
# frames rendered then froze while the process stayed alive -> STALLED,
|
||||
# not a real PASS (the Silo -level_20 fly-down case, D117/D134 load
|
||||
# sensitivity). A complete dump set is still a genuine PASS.
|
||||
if [ "$stalled" = 1 ] && [ "$alive" = 1 ] && [ "$fcnt" -lt "$EXPECT_FRAMES" ]; then
|
||||
echo "STALLED (froze at $fcnt/$EXPECT_FRAMES frames) $pcnt"
|
||||
else
|
||||
echo "PASS $pcnt"
|
||||
fi
|
||||
else
|
||||
echo "NO-FRAMES"
|
||||
fi
|
||||
@@ -105,18 +116,19 @@ for entry in $LV; do
|
||||
name=${entry%%:*}; num=${entry##*:}
|
||||
status=$(run_level "$name" "$num")
|
||||
|
||||
# NO-FRAMES is the flaky outcome (D117 + host load) -- retry once before
|
||||
# believing it. A CRASH is deterministic enough to report as-is.
|
||||
if [ "$status" = "NO-FRAMES" ]; then
|
||||
# NO-FRAMES and STALLED are the flaky outcomes (D117 + host load) -- retry
|
||||
# once before believing them. A CRASH is deterministic enough to report as-is.
|
||||
case "$status" in
|
||||
NO-FRAMES|STALLED*)
|
||||
sleep 3
|
||||
retry=$(run_level "$name" "$num")
|
||||
if [ "$retry" = "NO-FRAMES" ]; then
|
||||
status="NO-FRAMES (2 attempts)"
|
||||
else
|
||||
status="$retry [passed on retry]"
|
||||
[ -f $LOGS/$name.crash.log ] || true
|
||||
fi
|
||||
fi
|
||||
case "$retry" in
|
||||
NO-FRAMES) status="NO-FRAMES (2 attempts)" ;;
|
||||
STALLED*) status="$retry (2 attempts)" ;;
|
||||
*) status="$retry [passed on retry]" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$name ($num): $status" | tee -a $OUT
|
||||
done
|
||||
|
||||
Reference in new issue
Block a user