315. Main fps counter
Add a simple periodic FPS counter to main.py.
Lesson 315 of 356 · tests/chapter_10_performance/test_315_main_fps_counter.py
File to update
main.pyWhy this step exists
Before optimizing pygame rendering or emulator speed, the manual runner should show a simple end-to-end FPS signal in the terminal.
The FPS counter should measure the complete manual frame path
Console.step_until_next_frame()
Console.render_framebuffer()
draw_framebuffer(...)
pygame.display.flip()Suggested implementation example
import time
FPS_REPORT_INTERVAL_SECONDS = 1.0
...
running = True
last_fps_report_time = time.perf_counter()
frames_since_last_report = 0
while running:
...
executed = console.step_until_next_frame()
framebuffer = console.render_framebuffer()
draw_framebuffer(window, framebuffer, SCALE)
pygame.display.flip()
frames_since_last_report += 1
now = time.perf_counter()
elapsed = now - last_fps_report_time
if elapsed >= FPS_REPORT_INTERVAL_SECONDS:
fps = frames_since_last_report / elapsed
print(f"fps={fps:.1f}")
frames_since_last_report = 0
last_fps_report_time = nowImportant
This is intentionally simple. It does not separate emulation time from render time. It only gives a visible terminal signal before optimization work.
Why source-shape tests? main.py opens pygame and runs a manual loop. Automated tests must not call main(), open a window, or require a commercial ROM.
Out of scope
- optimizing pygame drawing
- frame pacing / speed cap
- profiling individual subsystems
- launching PyPy
- calling main() from pytest
Run this lesson
uv run pytest tests/chapter_10_performance/test_315_main_fps_counter.py -v