Followers 0

# Trouble getting a stable framerate (C++/Allegro 4)

## 2 posts in this topic

I programmed a vertical shooter, but the frame keeps on jumping around from 30 fps to 190fps. It just leaves game so slow with a few seconds of smooth speed. How can I lock the framerate to one specific value? Heres some of my code

#include "warbirds.h"

//interrupt handeler
//Timer variables
volatile int counter;
volatile int ticks;
volatile int framerate;
volatile int resting;
volatile int rested;

//displays the stats
void displaystats()
{

//display some status information
textprintf_ex(buffer, font, 0, 410, WHITE, -1, "Life %d", health);
textprintf_ex(buffer, font, 0, 420, WHITE, -1, "Firing rate %d", firedelay);
textprintf_ex(buffer, font, 0, 440, WHITE, -1, "Counter %d", counter);
textprintf_ex(buffer, font, 0, 450, WHITE, -1, "Yoffset %d", yoffset);*/
textprintf_ex(buffer, font, 0, 460, WHITE, -1, "Framerate %d", framerate);

//display score
textprintf_ex(buffer, font, 22, 22, GRAY, -1, "SCORE: %d", score);
textprintf_ex(buffer, font, 20, 20, RED, -1, "SCORE: %d", score);
}

//calculate framerate every second
void timer1()
{
counter++;
framerate = ticks;
ticks = 0;
rest(2);
}
END_OF_FUNCTION(timer1)

int main()
{
int n;

//Intialize the game
initialize();

//indetify variables used by interupt funtion
LOCK_VARIABLE(counter);
LOCK_VARIABLE(framerate);
LOCK_VARIABLE(ticks);
LOCK_FUNCTION(timer1);

//create new interupt handler
install_int(timer1, 1000);

//Start the main game loop
while(!key[KEY_ESC])
{
//check if the player is interacting with the controls
checkinput();

//draw/update the map to the buffer

//update and draw the enemy and player
updateplayer();
updateenemyplanes();

//draw and update the bullets
updatebullets();

//draw and update the explosions
updateexplosions();

//draw and update bonuses and
//apply its effects on players if it collideds
updatebonuses();

//display health
displayprogress(health);

//display the stats
displaystats();

//check if the game needs to end
endgame(health, score);

//blit the double buffer
acquire_screen();
blit(buffer, screen, 0, 0, 0, 0, SCREEN_W-1, SCREEN_H-1);
release_screen();

ticks++;
firecount++;
}

//delete mappy level
MapFreeMem();

//delete bitmaps
destroy_bitmap(buffer);
destroy_bitmap(progress);
destroy_bitmap(bar);

for(n = 0; n < 6; n++)
{
destroy_bitmap(explosion_images[n]);
}
for(n = 0; n < 3; n++)
{
destroy_bitmap(player_images[n]);
//destroy_bitmap(bullet_images[n]);
destroy_bitmap(enemy_plane_images[n]);
}

//delete the sprite pointers
delete player;
for(n = 0; n < MAX_EXPLOSIONS; n++)
{
delete explosions[n];
}
for(n = 0; n < MAX_BULLETS; n++)
{
delete bullets[n];
}
for(n = 0; n < MAX_ENEMIES; n++)
{
delete enemy_planes[n];
}

allegro_exit();
return 0;

}
END_OF_MAIN()


Ive been playing around with the interrupt handler but its not changing much. How do I tackle this problem?

1

##### Share on other sites

limit your speed to a sliding window:

1. Keep a sliding window (queue) of your last 50 frames' times (or any other number)

2. If your current frame is too far ahead of it's time: You want 50 FPS, but a second has not passed since the last 50 frames, then sleep a little bit.

3. You will also want to check the last 2 frames, to set an upper bound for speed: It is ok for the game to accelerate to compensate for missed frames, but there should be a limit on the maximum rate. If you do not do this, and you have some long frames, then your game will jitter.

Regardless of these points, you should separate your logic code from your render code. Your logic should never fall behind as a result of frame drawing speed. If you use a single thread it should look something like this.

while(true){
bool wasUpdated=false;
int targetLogicTime=CalculateTimeFromSlidingWindowAsMentionedAbove();
while(currentTime()>targetLogicTime){
//calculate logic:
calculateStuff();//put all your logic code here
wasUpdated=true;
targetLogicTime=CalculateTimeFromSlidingWindowAsMentionedAbove();
}
if(wasUpdated){
drawStuff();//Draw everything here
}else{
sleep(1ms);//give the CPU time to rest to avoid busy waiting.
}
}

Basically, this loop makes sure:

1. Your frame rate doesn't explode

2. If your drawing rate goes down, your game rate stays the same (car still takes 60 seconds to drive from A to B regardless of frame rate)

3. You don't draw redundant frames (frames where nothing has changed)

4. If available, you give the CPU some time to rest. (Very important for desktop CPU temperature, and laptop/phone battery life).

You can get better performance if you do this on two threads, but that's a whole other story.

Edited by SillyCow
1

##### Share on other sites

I have one question that's tangential to what you're doing. Why aren't you using Allegro 5?

0

## Create an account

Register a new account