fix frame timing

previosly timing was calculating the next frame based on now + duration
when the correct timing should have been last_frame + duration.

This would have the effect of slowing the game down the higher your CPU
usage.  A 0% CPU usage game would  play at the request frame rate,
but a 100% CPU usage game would play at only half the requested frame rate.

(RR is render time below)

Timing with the bug:
60FPs requested, 35FPs actual, 3 frames, 87ms.
|         29ms         |         29ms         |         29ms         |
| RR 12ms + 17ms sleep | RR 12ms + 17ms sleep | RR 12ms + 17ms sleep |

Timing after the fix:
60FPs, 60FPs actual, 3 frames, 51ms.
|       17ms      |       17ms      |       17ms      |
| RR 12ms + sleep | RR 12ms + sleep | RR 12ms + sleep |

After this fix you may need to change your games timing mechanics or
adjust your frame rate (to slow things back down). Your game will run
faster after this fix, even if you were using "100% CPU" before.
This commit is contained in:
Josh Goebel 2016-02-28 02:52:42 -05:00 committed by Scott Allen
parent c5445c7b9c
commit 993877b641
1 changed files with 18 additions and 5 deletions

View File

@ -106,12 +106,25 @@ bool Arduboy::nextFrame()
// pre-render
// technically next frame should be last frame + each frame but if we're
// running a slow render we would constnatly be behind the clock
// keep an eye on this and see how it works. If it works well the
// lastFrameStart variable could be eliminated completely
nextFrameStart = now + eachFrameMillis;
// next frame should start from last frame start + frame duration
nextFrameStart = lastFrameStart + eachFrameMillis;
// If we're running CPU at 100%+ (too slow to complete each loop within
// the frame duration) then it's possible that we get "behind"... Say we
// took 5ms too long, resulting in nextFrameStart being 5ms in the PAST.
// In that case we simply schedule the next frame to start immediately.
//
// If we were to let the nextFrameStart slide further and further into
// the past AND eventually the CPU usage dropped then frame management
// would try to "catch up" (by speeding up the game) to make up for all
// that lost time. That would not be good. We allow frames to take too
// long (what choice do we have?), but we do not allow super-fast frames
// to make up for slow frames in the past.
if (nextFrameStart < now) {
nextFrameStart = now;
}
lastFrameStart = now;
post_render = true;
return post_render;
}