Calculating Framerate in SDL

So I'm going through LazyFoo.net's tutorials and I wanted to make my program keep a constant framerate of 60FPS while displaying the framerate on the top caption of the window.

I can achieve it! ...but only one at a time.

The code acts differently depending on where I place two of my timers. (They are classes)

This code makes the framerate unregulated but provides a framerate counter that's accurate.
1
2
3
4
5
6
7
8
9
10
    //Start the frame and update timers.
    update.start();
    fps.start();

    while(quit == false){
       while( SDL_PollEvent(&event)){
           if( event.type == SDL_QUIT ){
               //Quit the program
               quit = true;
           }


And this code makes the framerate regulated but the counter stays at 0.
1
2
3
4
5
6
7
8
9
10
11
while(quit == false){

       //Start the frame and update timers.
       update.start();
       fps.start();

       while( SDL_PollEvent(&event)){
           if( event.type == SDL_QUIT ){
               //Quit the program
               quit = true;
           }


If I separate both of the timer classes the program crashes.

Now I can see where my problem may lie. In my timer class, if I "start" it, it resets the ticker thingamabob. Later on in the code, after 1000 ticks on the update (for the caption) class's timer, it returns the amount of time and then resets it. But if I put it at the start of the loop, it keeps resetting before it can even count thus always being 0.

The update timer also relies on the fps class' timer to make it's calculations. Oops! So if the fps class (which also ACTUALLY regulates the framerate) is outside of the loop, there is no control, and if it is inside, there is, but the update class has to be with it or else it crashes.

I don't know what I should do to solve this. Any suggestions?

I'll post all my code below for the timer class and main .cpp file. (minus the irrelevant beginning to keep my post within' length limit. I'll email or upload the full source upon request) The ellipses lines will denote cut out code.

EDIT: Added source code download: http://www.mediafire.com/?4p0kjx7akdr607c Press left and right arrows to add and subtract balls.

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

.........................
    
    //Framerate control stuff
    const int FRAMES_PER_SECOND = 60;
    int frame = 0; //Keep track of how many frames were printed to screen.
    float framerate = 0;
    bool cap = true; //Cap the framerate
    Timer fps; //Framerate regulator.
    Timer update; //Timer used to update the caption.

.........................
    
    //String Stream for adding ints to strings
    std::stringstream ss;
    
    //Variables for the screen.
    double gravity = 0.25;
    int presstimer = 0;
    int ballcount = 3500;
    int balllimit = 5000;    
    std::string title;
    
    //Create the balls.
    ball b[balllimit];

    
.........................
    
    
    //*************************************************************************
    //All initialization over! Begin game code and displaying.
    //*************************************************************************
    
    //Start the frame and update timers.
    update.start();
    fps.start();

    while(quit == false){
       while( SDL_PollEvent(&event)){
           if( event.type == SDL_QUIT ){
               //Quit the program
               quit = true;
           }
           //If a key is pressed
           if( event.type == SDL_KEYDOWN ){
               switch( event.key.keysym.sym ){
                    case SDLK_ESCAPE: quit = true;
                    case SDLK_RETURN: cap = ( !cap );
               }
           }
       }
    
    //Check for key presses
    Uint8 *keystates = SDL_GetKeyState( NULL );

    if( keystates[ SDLK_RIGHT ] ){
        if(ballcount<balllimit and presstimer <= 0){
            ballcount += 1;    //Create ball and refresh stuff
            b[ballcount-1].init(SCREEN_WIDTH, SCREEN_HEIGHT);
            presstimer = 5;             
        }
    }
    if( keystates[ SDLK_LEFT ] ){
            if(ballcount>0 and presstimer <= 0){
            ballcount -= 1;    //Destroy ball but don't bother refreshing
            presstimer = 5;
        }
    }
    
    //Tick the press timer.
    //Press timer is to allow a delay between ball spawning
    //when holding the button down
    if(presstimer>0)presstimer -= 1;

    //*************************************************************************
    
.........................
    
    //Update screen
    if( SDL_Flip( screen ) == -1 ){
        return 1;
    }
    
    
    
    //Increment frame counter
    frame++;
    
    //If framerate is capped, wait until next frame.
    if((cap == true) && (fps.get_ticks() < 1000 / FRAMES_PER_SECOND))
    {
    SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks());
    }
    
    //Calculate the framerate.
    if( update.get_ticks() > 1000 ){
        framerate = frame / (fps.get_ticks() / 1000);
        //Restart the update timer.
        update.start();
    }
    
    //Update the Window Caption with new ball count and framerate
    ss.str(std::string());      //Clear the caption
    ss << "Ball Bounce - " << ballcount << " Balls";
    ss << " | " << framerate << "FPS";
    title = ss.str();
    SDL_WM_SetCaption(title.c_str(), NULL );
    
.........................
             
    //End of game loop
    }

    
.........................
    
}


time.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class Timer
{
      private:
      //Clock time when the timer started.
      int startTicks;
      
      //The ticks stored when the timer was paused.
      int pausedTicks;
      
      //The timer status.
      bool paused;
      bool started;
      
      public:
      //Initializes variables.
      Timer();
      
      //The various clock actions.
      void start();
      void stop();
      void pause();
      void unpause();
      
      //Gets the timer's time.
      int get_ticks();
      
      //Checks the status of the timer.
      bool is_started();
      bool is_paused();
};

Timer::Timer()
{
      //Initialize the variables.
      startTicks = 0;
      pausedTicks = 0;
      paused = false;
      started = false;
}

void Timer::start()
{
     started = true;
     
     //Unpause the timer
     paused = false;
     
     //Get the current clock time
     startTicks = SDL_GetTicks();
}

void Timer::stop()
{
     //Stop the timer.
     started = false;
     
     //Unpause the timer
     paused = false;
}


int Timer::get_ticks()
{
    //If the timer is running
    if( started == true ){
        //If the timer is paused
        if( paused == true ){
            //Return number of ticks when timer was paused.
            return pausedTicks;
        }
        else{
             //Return the current time minus the start time
             return SDL_GetTicks() - startTicks;
        }
    }
    
    //If the timer isn't running...
    return 0;
}

void Timer::pause()
{
     //If the timer is running and isn't already paused...
     if(( started == true ) && ( paused == false ))
     {
          //Pause the timer.
          paused = true;
          
          //Calculate the paused ticks
          pausedTicks = SDL_GetTicks() - startTicks;
     }
}


void Timer::unpause()
{
     //If the timer is paused...
     if( paused == true ){
         //Unpause the timer.
         paused = false;
         
         //Reset the starting ticks.
         startTicks = SDL_GetTicks() - pausedTicks;
         
         //Reset the paused ticks.
         pausedTicks = 0;
     }
}

bool Timer::is_started(){
     return started;
}

bool Timer::is_paused(){
     return paused;
}


Thanks in advance!


EDIT: Added source code download. http://www.mediafire.com/?4p0kjx7akdr607c Press left and right arrows to add and subtract balls.
Last edited on
Topic archived. No new replies allowed.