Glad to hear its working! The reason you're getting 63 fps instead of 60 is most likely due to the integer division in determining the sleep time (ideally you want 16 and 2/3 ms of time for each frame, though due to integer division, 1000/60 equates to 16ms of sleep time). I've written up what
should be a fix for this problem, which alternates sleeping for different amounts of time in order to achieve the desired framerate.
Code: Select all
const int FRAMERATE = 60;
bool firstPass = true;
int mainFrameTime, alternateFrameTime, alternateFrameInterval;
while(true)
{
input();
logic();
input->start();
render();
input->update();
}
void Input::update()
{
if(firstPass)
{
firstPass = false;
calcFrameTimes(FRAMERATE, mainFrameTime, alternateFrameTime, alternateFrameInterval);
}
tick = currentTime - lastTime;
if(tick > 50)
tick=0;
/* if(paused)
tick=0;*/
int frameTime;
if(frames % alternateFrameInterval == 0)
{
frameTime = alternateFrameTime;
}
else
{
frameTime = mainFrameTime;
}
if(tick < frameTime)
{
// If we had extra time during the frame, and have to delay to compensate,
// then the total time for this frame will be the value associated with
// our desired framerate (tick + (frameTime - tick)), which can be simplified
// to frameTime
deltas += frameTime;
SDL_Delay(frameTime - tick);
}
else
{
deltas += tick;
}
lastTime = currentTime;
CEGUI::System::getSingleton().injectTimePulse(static_cast<float>(tick*0.001));
frames++;
if(deltas > 1000)
{
fps = frames;
frames = 0;
deltas = 0 ;
}
}
void calcFrameTimes(int targetFramerate, int &mainFrameTime, int &alternateFrameTime, int &alternateFrameInterval)
{
// Calculate the actual frame time, and the approximate (integer divided) frame time
float realFrameTime = 1000.0f / targetFramerate;
int approxFrameTime = 1000 / targetFramerate;
// Find the fractional part of the real frame time, and use it to determine how many
// frames should be rendered at the high frame time, and how many at the low frame time
float frameTimeDiff = realFrameTime - approxFrameTime;
int framesAtHigherTime = (int)(frameTimeDiff * targetFramerate + 0.5f);
int framesAtLowerTime = targetFramerate - framesAtHigherTime;
if(framesAtHigherTime >= framesAtLowerTime)
{
mainFrameTime = approxFrameTime + 1;
alternateFrameTime = approxFrameTime;
// Number of times to use the main amount before using the alternate amount, plus 1
alternateFrameInterval = (int)(((float)framesAtHigherTime / framesAtLowerTime) + 0.5f) + 1;
}
else
{
mainFrameTime = approxFrameTime;
alternateFrameTime = approxFrameTime + 1;
// Number of times to use the main amount before using the alternate amount, plus 1
alternateFrameInterval = (int)(((float)framesAtLowerTime / framesAtHigherTime) + 0.5f) + 1;
}
}
I haven't thoroughly tested out this system yet, though it seems to be returning good values. Try giving it a shot, and let me know how it goes!
-Aaron