[Solved] Frame rate cap and calculation of

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

[Solved] Frame rate cap and calculation of

Post by short »

Hey guys, I'm having difficulty following two of lazyfoo's tutorial's together. Independently I can either cap the fps on my pong game or I can view the fps, but doing both at the same time is presenting difficulties.

Here is my relevant code: (I removed some irrelevant code as to make it easier to find my mistake)

Code: Select all

int main(int argc, char* args[])
{
	 bool quit = false;
	 float frame = 0.0;

	 Timer fps;
	 Timer update;

	 update.start();

	 if( init() == false)	  // initialize SDL subsystem, if they failed exit with error code 0x01
	 {
		  return 1;
	 }
	 if(load_Files() == false) // if failed exit with error code 0x01
	 {
		  return 1;
	 }
	 while(quit == false)
	 {  
		  fps.start();
		  apply_surface(0, 0, background, screen); 


		  if(fps.get_ticks() > 1000)
		  {
			   std::stringstream caption;
			   caption << "Average Frames Per Second: " << frame / ( fps.get_ticks() / 1000.f ); 
			   if(pushFont(caption.str().c_str(),100,100,message,screen,font,textColor) == false) // this fn writes the font to the screen.
			   {
					return 1; // error rendering text.
			   }

			   //Restart the update timer 
			   update.start(); 
		  }
		  if(fps.get_ticks() < (1000 / FRAMES_PER_SECOND))
		  { 
			   //Sleep the remaining frame time 
			   SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
		  } 

		  //Swap the current and back buffer.
		  if(SDL_Flip(screen) == -1)
		  {
			   return 1;
		  }

		  frame++;

	 }

	 cleanUp();
	 return 0; // no errors
}
If i put the fps.start(); before the while(quit == false) I get 130fps showing up.

If i put the fps.start(); inside the while(quit == false) main loop (like lazyfoo's tutorial shows for one of the tutorials) I never get anything showing up on my screen.

Where is my logic off?
Last edited by short on Wed Jun 10, 2009 12:16 pm, edited 2 times in total.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
Lucas
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 16
Joined: Sun May 24, 2009 11:28 am
Favorite Gaming Platforms: PC, SNES, Dreamcast
Programming Language of Choice: C++
Location: UK

Re: fps capping and viewing question

Post by Lucas »

First of all I'm only learning from Lazy Foo' myself so don't take any of what I say as a definite solution.

You need to start your fps.start(); before the main game loop.

Every time you go back to the start of your loop you are resetting the startTicks variable which was defined in the class, so by the time you reach your if(fps.get_ticks() > 1000) statement your fps.get_ticks() function is still returning a number lower than 1000, and thus not displaying anything.

That would be my answer as to why you don't display anything if you put fps.start() inside the main loop, but like I said I'm still learning myself and haven't tried to do this myself yet.

Edit:
Couldn't you just create another timer to do the if(fps.get_ticks() > 1000) check?
What is the update timer doing?
I don't see any invisible walls...
User avatar
Bakkon
Chaos Rift Junior
Chaos Rift Junior
Posts: 384
Joined: Wed May 20, 2009 2:38 pm
Programming Language of Choice: C++
Location: Indiana

Re: fps capping and viewing question

Post by Bakkon »

Have you tried doing fps.start() before and inside the main while loop?
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: fps capping and viewing question

Post by short »

yes, yes I have. Outside the main loop I get ~130fps. Inside the mainloop fps.get_ticks() never gets over 1000 so I don't see the fps.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: fps capping and viewing question

Post by short »

Ok, I'm trying a new approach. Here is my main game loop:

Code: Select all

while(quit == false) //main loop.
	 {  
		  start_ticks = SDL_GetTicks();
		  updateScreen();
		  
		  handleUserInput(&quit); // keyboard and mouse input.

		  fps_cap(&start_ticks); // cap the fps
	 }
and here is my fps_cap fn:

Code: Select all

void fps_cap(Uint32 * start_ticks)
{
	 int end_ticks = SDL_GetTicks();
	 int sleep_delay = (1000 / FRAMES_PER_SECOND) - (end_ticks- *start_ticks);
     
	 if (sleep_delay > 0) 
	 {
		  SDL_Delay(sleep_delay);
	 }
	 myLog->writeToFile(intToString((1000/(SDL_GetTicks() - *start_ticks))).c_str());
	 myLog->writeToFile("\n");
}
Everything before the myLog->.... I feel like the way I calculate the frames per second is correct, but when I go to display the average fps I am at a loss. What should I be outputting (either on the screen, or in my case a txt file)?



edit: Solved, this code works perfectly... I am at least pretty sure.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
eatcomics
ES Beta Backer
ES Beta Backer
Posts: 2528
Joined: Sat Mar 08, 2008 7:52 pm
Location: Illinois

Re: fps capping and viewing question

Post by eatcomics »

Bakkon wrote:Have you tried doing fps.start() before and inside the main while loop?
You know... Your avatar would be much more impressive if you had taken the picture while you were in the driver's seat... driving... That would be a fun pic to look at :lol: /offtopic
Image
User avatar
Bakkon
Chaos Rift Junior
Chaos Rift Junior
Posts: 384
Joined: Wed May 20, 2009 2:38 pm
Programming Language of Choice: C++
Location: Indiana

Re: [Solved] Frame rate cap and calculation of

Post by Bakkon »

Dunno what I was thinking in my original post. Think I was sleep deprived.

Using LazyFoo's code:

Code: Select all

int main( int argc, char* args[] )
{
    //Quit flag
    bool quit = false;

    //Keep track of the frame count
    int frame = 0;

    //Timer used to calculate the frames per second
    Timer fps;

    //Timer used to update the caption
    Timer update;
    
    //Timer used to restrain FPS
    Timer delay;

    //Initialize
    if( init() == false )
    {
        return 1;
    }

    //Load the files
    if( load_files() == false )
    {
        return 1;
    }

    //Start the update timer
    update.start();

    //Start the frame timer
    fps.start();

    //While the user hasn't quit
    while( quit == false )
    {
        //Start the delay timer
    	delay.start();
    	
        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }

        //Apply the background
        apply_surface( 0, 0, image, screen );

        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

        //Increment the frame counter
        frame++;
        
        //Restrain the FPS
        if( delay.get_ticks() < 1000 / FRAMES_PER_SECOND )
			SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - delay.get_ticks() );

        //If a second has passed since the caption was last updated
        if( update.get_ticks() > 1000 )
        {
            //The frame rate as a string
            std::stringstream caption;

            //Calculate the frames per second and create the string
            caption << "Average FPS: " << frame / ( fps.get_ticks() / 1000.f );

            //Reset the caption
            SDL_WM_SetCaption( caption.str().c_str(), NULL );

            //Restart the update timer
            update.start();
        }
    }

    //Clean up
    clean_up();

    return 0;
}
Something like this. :)
Post Reply