Skip to content

overlay: FPS / VI / ms-per-VI readout (rcore rev 8, link 2.2) - #6

Merged
TechnicallyComputers merged 1 commit into
mainfrom
feat/frame-stats
Oct 8, 2026
Merged

TechnicallyComputers merged 1 commit into
mainfrom
feat/frame-stats

Conversation

@TechnicallyComputers

Copy link
Copy Markdown
Member

The overlay's single "60 FPS" was the VI rate (one tick per run_frame), so a 30 fps N64 game read 60. It is now three labelled rows:

FPS    30.0     the game's own pictures a second
VI     59.9     frames the core finished and presented a second
ms/VI  5.10     the runner's measured run_frame time per frame (headroom vs 16.7)

Changes

  • rcore rev 8: rcore_frame appends game_frame (0 = the core cannot tell). Read only when struct_size covers it.
  • Link 2.2: FrameDone appends game_frame and work_ns. It is the first message to grow. A 2.2 runner sends the 2.1 size (24 bytes) to a 2.1 hub, and a 2.2 hub reads a 2.1 runner's message with both fields 0. CoreLink::frame_stats() keeps the running totals.
  • Overlay: Osd::note_counters(now, {frames, game, work_ns}).
    • Each rate covers the last second. FPS is anchored on the samples where the game's count moved, so it doesn't jitter by ±1.
    • Digits refresh 4×/s. Labels are dim and values white. A reading the core or link can't supply shows --.
    • note_frame() still works for a host with no counters (VI only).
  • Docs: CORE_ABI.md (rev 8), CORE_LINK.md (2.2), OVERLAY.md.

Checked

  • ctest: 30/30. That includes overlay (counters, uneven arrival, turbo, reset, pause, label colours, and FPS within 29.9–30.05 for a 29.97 game) and the new link_frame_stats test (fake core, game 5 of 10, work measured).
  • n64lle core with this runner on Pokemon Stadium (fixture package, 600 grants) gives frame stats: game 522 work measured. 522 matches the VI model's own VI_RATE swaps=522 ("a new buffer every 2 fields = 29.91 fps").
  • retro-overlay-test --dump renders the readout and was inspected. It was not captured on a live hub window: the window was behind other windows and there is no Xvfb here, so the on-screen check is still owed.

Not tested

  • The 2.1 interop path in both directions. The size logic is what's described above; no 2.1 peer was run against it.

Companion PRs: n64lle (fills game_frame) and Retro-Launcher (the hub feeds note_counters; bumps this submodule).

Release note: n64lle's fetch_release.py requires the runner's draft revision to equal the core's, so Runtime and n64lle releases with rev 8 must be cut together.

🤖 Generated with Claude Code

The readout's one "60 FPS" number was the VI rate: one tick per run_frame.
It is now three labelled rows:

  FPS    the game's own pictures a second (rcore_frame::game_frame, rev 8)
  VI     frames the core finished and presented a second (frames done)
  ms/VI  the runner's measured run_frame time per frame (link 2.2 work_ns)

- rcore.h rev 8: rcore_frame appends game_frame (0 = the core cannot tell).
- Link 2.2: FrameDone grows game_frame and work_ns, the first grown message.
  A 2.2 runner sends it at its 2.1 size to a 2.1 hub (send_msg_sized); a 2.2
  hub reads a 2.1 runner's with both zero. CoreLink::frame_stats() sums them.
- Osd::note_counters takes running totals; rates span the last second, FPS
  anchored on the samples where the game's count moved so a window edge does
  not read 29.5 / 30.5 for a 30 fps game. Digits refresh 4x a second; labels
  dim, values white; "--" for a reading the core or link cannot supply.
  note_frame() remains for a host with no counters (VI only).
- Tests: overlay (counters, uneven arrival, turbo, reset, pause, labels),
  link_frame_stats (fake core game 5 of 10, work measured). --dump renders
  both readouts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P8WyraAmnCpC7UwtCEWdw5
@TechnicallyComputers
TechnicallyComputers merged commit 218e74e into main Oct 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant