diff --git a/docs/internal/upstream/pr13-fps-telemetry.md b/docs/internal/upstream/pr13-fps-telemetry.md index 2ae437d1..e7c3f587 100644 --- a/docs/internal/upstream/pr13-fps-telemetry.md +++ b/docs/internal/upstream/pr13-fps-telemetry.md @@ -3,7 +3,9 @@ Parked from NyperYuhgard's PSXrecomp PR #13, commit [`b49548e7b8f494c9584eb09039a8c325d7375b46`](https://github.com/mstan/psxrecomp/commit/b49548e7b8f494c9584eb09039a8c325d7375b46). -This branch retains only the title-neutral simulated-vblank FPS and realtime-speed -telemetry. It was adapted to current master and guards window-title access in -headless/windowless operation. The overlay-cache inventory from the same upstream -commit is parked separately. +This branch retains only the simulated-vblank FPS and realtime-speed telemetry. +It was adapted to current master, guards window-title access in +headless/windowless operation, and is disabled by default. Set +`PSX_FPS_TELEMETRY=1` before launch to opt in to the title-bar counter and +matching stderr line. The overlay-cache inventory from the same upstream commit +is parked separately. diff --git a/runtime/src/main.cpp b/runtime/src/main.cpp index c1515eda..5b54243e 100644 --- a/runtime/src/main.cpp +++ b/runtime/src/main.cpp @@ -355,6 +355,16 @@ static int s_netplay_depth24_present_skip = 0; static uint32_t s_fmv_skip_last_mdec = 0; static int s_fmv_skip_hold = 0; +/* Lightweight title/stderr FPS telemetry is developer-facing and opt-in. + * Keep release window titles clean unless explicitly requested. */ +static bool fps_telemetry_enabled() { + static const bool enabled = [] { + const char* value = std::getenv("PSX_FPS_TELEMETRY"); + return value && value[0] && value[0] != '0'; + }(); + return enabled; +} + static void smooth_60_reset(void) { g_smooth_60_state.previous_source.clear(); g_smooth_60_state.source_hash = 0; @@ -3334,14 +3344,14 @@ static void sdl_vblank_present(void) { * than presents so turbo and skipped-frame modes still report game speed. * Skip during netplay post-load barrier — admit is stalled and the window * is not updating, so a climbing FPS line is misleading. */ - if (!psx_netplay_in_load_barrier()) { + if (fps_telemetry_enabled() && !psx_netplay_in_load_barrier()) { extern uint64_t s_frame_count; const Uint64 now = SDL_GetPerformanceCounter(); const Uint64 frequency = SDL_GetPerformanceFrequency(); if (!s_fps_last_time) { s_fps_last_time = now; s_fps_last_frame = s_frame_count; - if (sdl_window) { + if (sdl_window && s_fps_base_title.empty()) { const char *title = SDL_GetWindowTitle(sdl_window); if (title) s_fps_base_title = title; } diff --git a/runtime/tests/test_fps_telemetry_opt_in.py b/runtime/tests/test_fps_telemetry_opt_in.py new file mode 100644 index 00000000..a38562da --- /dev/null +++ b/runtime/tests/test_fps_telemetry_opt_in.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +"""Structural guard: FPS title/stderr telemetry stays explicitly opt-in.""" + +from pathlib import Path + + +main_cpp = (Path(__file__).parents[1] / "src" / "main.cpp").read_text( + encoding="utf-8" +) + +required = ( + 'std::getenv("PSX_FPS_TELEMETRY")', + "fps_telemetry_enabled() && !psx_netplay_in_load_barrier()", + "sdl_window && s_fps_base_title.empty()", +) +for needle in required: + if needle not in main_cpp: + raise AssertionError(f"missing FPS telemetry opt-in guard: {needle}") + +print("PASS: FPS telemetry remains opt-in and title-stable")