Jump to content

  • Log In with Google      Sign In   
  • Create Account


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 ISDCaptain01   Members   -  Reputation: 1315

Like
1Likes
Like

Posted 19 September 2013 - 03:52 PM

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);

	//Load in all the sprites 
	loadsprite();

    //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
		updatescroller();

		//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?



Sponsor:

#2 SillyCow   Members   -  Reputation: 843

Like
1Likes
Like

Posted 19 September 2013 - 04:22 PM

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;
       //limit and stabalize your FPS:
       UpdateSlidingWindowAsMentionedAbove(currentTime());
       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, 19 September 2013 - 04:35 PM.

My new android game : Enemies of the Crown

My previous android game : Killer Bees


#3 Alpha_ProgDes   Crossbones+   -  Reputation: 4680

Like
0Likes
Like

Posted 19 September 2013 - 06:35 PM

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


Beginner in Game Development? Read here.
 
Super Mario Bros clone tutorial written in XNA 4.0 [MonoGame, ANX, and MonoXNA] by Scott Haley
 
If you have found any of the posts helpful, please show your appreciation by clicking the up arrow on those posts Posted Image
 
Spoiler




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS