Skip to content

Add configurable FPS cap to CPU Sleep frame rate control, and fix the broken deadline math in LimitFrameRate - #8632

Open
romanstingler wants to merge 1 commit into
diasurgical:masterfrom
romanstingler:feature/fps-cap
Open

Add configurable FPS cap to CPU Sleep frame rate control, and fix the broken deadline math in LimitFrameRate#8632
romanstingler wants to merge 1 commit into
diasurgical:masterfrom
romanstingler:feature/fps-cap

Conversation

@romanstingler

Copy link
Copy Markdown
Contributor

This PR adds a user-facing FPS Cap option under Settings → Graphics that lets players pick a target frame rate (30 / 60 / 75 / 120 / 144 / 165 / 240 / 360) when Frame Rate Control is set to Limit FPS.

While implementing, I noticed the existing LimitFrameRate() math was wrong, even with the option enabled, the cap oscillated between the target and the native framerate instead of holding steady. This PR rewrites the deadline logic with a simple, correct steady-interval scheduler.

What's new (feature)

  • New GraphicsOptions::fpsCap option (default: 60), with allowed values 30, 60, 75, 120, 144, 165, 240, 360.
  • Slot inserted right below Frame Rate Control in the graphics menu so the relationship is obvious.
  • Tooltip: "Target frame rate used when Frame Rate Control is set to Limit FPS."
  • Flagged CantChangeInGame (matches the neighbouring Frame Rate Control row).

What's fixed

LimitFrameRate() previously:

v = tc % frameDelay;
SDL_Delay((v / 1000) + 1);          // waits the elapsed time, not the remaining time
frameDeadline = tc + v + frameDelay; // deadline drifts forward every iteration

Two bugs:

  1. The delay was v = tc % frameDelay, i.e. the time already elapsed in the current frame interval, instead of the time remaining until the next interval boundary. The scheduler ended up roughly doubling the intended wait.
  2. frameDeadline was recomputed each frame as tc + v + frameDelay, causing a per-iteration drift of v microseconds. Net effect: the cap never settled and oscillated between fast and slow framerates, with reported FPS well above the target.

Replaced with a steady-interval scheduler that advances frameDeadline by frameDelay per frame and waits frameDeadline - tc

Limitations / known gotchas

The FPS Cap only takes effect when Frame Rate Control is set to Limit FPS (CPU Sleep). With Vertical Sync on, the limiter returns early and the new option is a no-op, the cap is gated by design.

image image image image

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