Jump to content

  • Log In with Google      Sign In   
  • Create Account


simple SDL framerate?


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
30 replies to this topic

#1 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 01 July 2014 - 07:54 PM

Hello, I have been doing alot of stuff in Allegro, I want to learn about SDL. I have been having a hard time getting the right type of framerate counter in my SDL program. This is what I did in Allegro:

/* Framerate Processes */
volatile int ticks = 0;
void ticker()
{
	ticks++;
}
END_OF_FUNCTION(ticker)
volatile int game_time = 0;
void game_time_ticker()
{
	game_time++;
}
END_OF_FUNCTION(game_time_ticker)
const int updates_per_second = 60;

/* This is the deltatime, used for timing */
double dt;

inside the main function in my Allegro program, I did this (code has been butchered so you see things related to framerate):

int main(void) {
/* Initialize Allegro */
	allegro_init();
	install_timer();
	/* Initialize Framerate */
	LOCK_VARIABLE(ticks);
	LOCK_FUNCTION(ticker);
	install_int_ex(ticker, BPS_TO_TIMER(updates_per_second));
	LOCK_VARIABLE(game_time);
	LOCK_FUNCTION(game_time_ticker);
	install_int_ex(game_time_ticker, BPS_TO_TIMER(10)); /* The game is 1/10 seconds */
	int fps = 0;
	int frames_done = 0;
	int old_time = 0;
	int frames_array[10];
	int frame_index = 0;
	int ii;
	for(ii = 0; ii < 10; ii++)
		frames_array[ii] = 0;
/* Other stuff*/
	other_stuff();
/* Run Game Loop */
	while ( quit == false ) {
		while(ticks == 0) {
			rest(1);
		}
		while(ticks > 0)
		{
			int old_ticks = ticks;
			ticks--;
			if(old_ticks <= ticks)
				break; 
		}
		if(game_time >= old_time + 1)
		{
			fps -= frames_array[frame_index];
			frames_array[frame_index] = frames_done;
			fps += frames_done;
 
			frame_index = (frame_index + 1) % 10;
 
			frames_done = 0;
			old_time += 1;
		}
		/* do stuff */
		do_stuff();
		/* set dt */
                render_var( 16, 184, TEXT_LEFT, "FPS:", fps, true );
		dt = 1.0f/(updates_per_second*1.0f);
		frames_done++;
	}
/* Finish up */
	return 0;
}
END_OF_MAIN()

I cannot for the life of me figure out how to do the equivalent in SDL, every attempt (that i've deleted as well) always came down to using SDL_Delay(1000/framerate) in the end, and while the speed seemed good, every 1 second the game would stop for one frame, and that really bothered me.

 

I've spent a couple days looking for a simple SDL framerate example, haven't been able to find any. If you can point me in the right direction (not lazyfoo's, i've tried his, and he is C++ whereas I want to do it in C), that would be great, thanks.



Sponsor:

#2 Sik_the_hedgehog   Crossbones+   -  Reputation: 1608

Like
2Likes
Like

Posted 01 July 2014 - 08:41 PM

Assuming you're using SDL 2, look up these two functions:

  • SDL_GetPerformanceCounter
  • SDL_GetPerformanceFrequency

This will give you a high resolution timer you can use to calculate how much time has ellapsed since the last time you checked. With some math you can turn that into frames per second (just make sure to not discard frames that haven't fully ellapsed yet).


Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

#3 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 01 July 2014 - 08:45 PM

Thanks, but do you know what I can look up for SDL 1.2 as well? Thanks



#4 Sik_the_hedgehog   Crossbones+   -  Reputation: 1608

Like
3Likes
Like

Posted 01 July 2014 - 08:54 PM

Not really, if I recall correctly there were timers but their resolution was like 1ms (and the documentation warned that it was usually less), that may be enough for framerate if you account for rounding errors I guess.

 

SDL 1.2 is deprecated and not maintained anymore though, you're better off avoiding it if possible. SDL 2.0 is actively maintained and supports modern platforms (including mobile), and fixes several issues that 1.2 used to have. It also has functions to render stuff using the GPU (SDL 1.2 couldn't do that). The biggest loss is lack of CD Audio support, but does anybody still use that for games?


Edited by Sik_the_hedgehog, 01 July 2014 - 08:55 PM.

Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

#5 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 01 July 2014 - 09:08 PM

The Dreamcast and Wii (not sure about PSP) don't have SDL 2 yet, so for now I just need some SDL 1.2 code.



#6 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 02 July 2014 - 01:27 PM

Here I translated this C++ timing system to ANSI C. Does not work as correctly as I though (doesn't work at all):

http://pastebin.com/Lfixw615



#7 georger.araujo   Members   -  Reputation: 814

Like
2Likes
Like

Posted 02 July 2014 - 03:25 PM

I've spent a couple days looking for a simple SDL framerate example, haven't been able to find any. If you can point me in the right direction (not lazyfoo's, i've tried his, and he is C++ whereas I want to do it in C), that would be great, thanks.

 

I just read LazyFoo's code. His LTimer class is a VERY simple POD type, you should be able to just slap up a C struct and rewrite the member functions as global functions that take a LTimer * parameter, and you're good to go.



#8 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 02 July 2014 - 04:48 PM

isn't that what I did in the pastebin?



#9 georger.araujo   Members   -  Reputation: 814

Like
2Likes
Like

Posted 02 July 2014 - 06:03 PM

isn't that what I did in the pastebin?

 

No, it's not. What you did was declare the member variables as global variables and have the global functions manipulate them, treating them like static members of a class. That won't work because in LazyFoo's original code, the member variables are not static at all - each instance of the class has its own member variables, and there are two instances of Timer in main().



#10 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 02 July 2014 - 08:02 PM

Well i'm lost here. It was alot easier making a fps limiter and deltatimer in Allegro than it is in SDL. I know in the long run it'll come out good, but i'm really lost on this.


Edited by DrNicholas, 02 July 2014 - 08:02 PM.


#11 Bacterius   Crossbones+   -  Reputation: 8580

Like
2Likes
Like

Posted 02 July 2014 - 09:48 PM

Basically, wrap the C++ class members (startTicks, etc...) into a struct, and have each function take a pointer to such a struct and operate on it (akin to the "this" parameter in C++). This is the simplest example of an "object" in C.


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#12 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 02 July 2014 - 10:22 PM

I see. Perhaps I haven't conveyed everything correctly. I apologize if I haven't. Take a look at these:

 

timer.h: http://pastebin.com/9tqwGasJ
timer.c: http://pastebin.com/3mW61LEf
main.c: http://pastebin.com/hwmrbEax

 

these work nice, just like lazyfoo's system. The system's themselves aren't bad, I can get a good delta time, and I see the game running at the same speed on an old Dell Dimension 4550 or a newer custom FX-8350 machine with the dt I use. The problem I am having is locking the game to a framerate. Say it runs at 300fps on one pc and 100fps on the other, even though your monitors refresh rate may not be that high. Say I want to record footage from it using fraps, if the framerate was locked at 60, wouldn't it show me 60 in the corner (before it's recording, i think it changes if you are recording at a different frame rate)? Do you know what I mean?



#13 L. Spiro   Crossbones+   -  Reputation: 13318

Like
0Likes
Like

Posted 02 July 2014 - 11:50 PM

You need to look into fixed-time updated and separating rendering and game logic.
 
Fixed-Time-Step Implementation
FIX YOUR TIMESTEP!

Forget about using timers.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#14 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 03 July 2014 - 11:44 AM

I had those in my favorites already. I've used those before, but that doesn't still solve the issue of limiting the games framerate. Fraps tells me the timestep game runs at about 3000fps. I am trying to make it so I can have a capped and uncapped framerate, do you know what I mean? It works perfectly fine in Allegro, but not SDL (I am not talking about delta time, that works fine in both cases). Any time I limit the framerate in SDL with SDL_Delay(), everything seems to "tick" as it moves, even if it is moving with a delta time.



#15 L. Spiro   Crossbones+   -  Reputation: 13318

Like
0Likes
Like

Posted 03 July 2014 - 12:54 PM

But what is the point in that?
Who cares if it runs at 300/3000/100/60 FPS? It’s not correct for you to limit that.
If users want to cap the frame-rate they can force v-sync.
 

Say it runs at 300fps on one pc and 100fps on the other, even though your monitors refresh rate may not be that high.

So? Then it runs faster than the refresh rate, 300 on 1 and 100 on another.
What is the problem? Why are you trying to fix break this?

 

 

L. Spiro


It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#16 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 03 July 2014 - 01:10 PM

That was a hypothetical scenario. I just want to cap the game's framerate without having this "tick" issue SDL is giving me (Allegro or SFML did not give said issue). You know how console games tend to be capped at anywhere from 30 to 60fps? That's what I want to do. Half-Life 2 is normally uncapped at 300fps when I boot it up, but I can cap it at 30, 60, or any other fps I desire. That's what I want to do.



#17 L. Spiro   Crossbones+   -  Reputation: 13318

Like
0Likes
Like

Posted 03 July 2014 - 01:43 PM

Game consoles are “capped” because they have v-sync enabled and you can’t disable it.

Again, if the user wants a cap on his or her PC, he or she can enable v-sync.

 

 

L. Spiro


Edited by L. Spiro, 03 July 2014 - 01:44 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#18 georger.araujo   Members   -  Reputation: 814

Like
2Likes
Like

Posted 03 July 2014 - 02:58 PM

That was a hypothetical scenario. I just want to cap the game's framerate without having this "tick" issue SDL is giving me (Allegro or SFML did not give said issue). You know how console games tend to be capped at anywhere from 30 to 60fps? That's what I want to do. Half-Life 2 is normally uncapped at 300fps when I boot it up, but I can cap it at 30, 60, or any other fps I desire. That's what I want to do.

 

You seem to be confusing the concepts of frame rate and game speed (see the article I linked to below).

 

Ticks in SDL are a solution rather than an issue. As for SFML, did you use sf::RenderWindow::setFramerateLimit() or sf::RenderWindow::setVerticalSyncEnabled()? The first calls sf::sleep(), the latter does what @L. Spiro mentioned. Either way, you need to understand what's going on under the hood.

 

Consider reading deWiTTERS Game Loop, a well-known article about this topic; in particular, I think the Constant Game Speed with Maximum FPS section could help.



#19 DrNicholas   Members   -  Reputation: 130

Like
0Likes
Like

Posted 03 July 2014 - 03:35 PM

I am really confused now. I'm not sure every console game has vsynch enabled, maybe a buffer, but i'm not sure. You and I may have a different definition of framerate, look at this:

timestep_fps.PNG

fraps shows me the framerate the game is supposedly outputting. Take a look at this:

ocarina_fps.jpg

Ocarina of Time was capped by Nintendo to operate at 20fps. I'm pretty certain not every game on the Nintendo 64 is 20fps. Here's a picture of Half-Life 2 uncapped:

hl2_uncapped.jpg

I can cap it's framerate to 30 if I want, and I can visually tell it's not as smooth as if it were capped at 60fps (or uncapped in general):

hl2_capped.jpg

and it's not vsynched

hl2_novsynch.jpg

So I am really confused all by what you are telling me. Maybe i'm not saying the right words. How is that measurement capped? If I make a game, i'll make a setting so it's capped at 30, 60, or uncapped.

 

georger.araujo, I saw you replied while I was typing this. I will take a look after I post this.



#20 L. Spiro   Crossbones+   -  Reputation: 13318

Like
1Likes
Like

Posted 03 July 2014 - 04:44 PM

I'm not sure every console game has vsynch enabled

Every console and mobile device has v-sync forced enabled.
All frame-rate capping is done by syncing to v-blank.

Frame-rate (FPS): Number of times the game is drawn per second. The yellow number in your images.

The question still remains as to why you want to do it on PC (you don’t have a choice on consoles or mobile devices, just a few options as to which cap you can use).

Do you think it is just cool?

Do you think it makes your product “pro”?

 

When a game company puts a cap on the frame-rate there is a reason.

For example, we developed a bunch of games for Xbox 360 and PlayStation 3.  We aimed at 60 FPS (the max you can do) but in some games in some areas we had to reduce to 30 FPS (every 2nd v-blank).  For Infinite Undiscovery and Radiata Stories there was too much to draw within a single v-blank so again the whole games had to use 2 v-blanks (30 FPS).

 

If Nintendo made a game run at 20 FPS it is because they needed more time to render, not because, “Oh, FPS caps are the cool new thing.”

 

 

Half-Life 2 is doing the same thing.  Their reason (something you lack) is because their games were fairly heavy on the CPU (and GPU) back then and would consume a lot of power.  Forcing the FPS down reduces power consumption and heat generation, but that won’t apply to your games.  You are not a huge team of experienced veterans making a multi-million-dollar AAA title.

 

And even if you did have a reason to use a cap, it is implemented via v-blank.  It is always implemented in relation to v-blanks to prevent tearing.

 

 

 

If your SDL does not give you v-blank access, give up and move on to the next task.  Any other way of doing it will lead to the same problems you had before (after some time there is a 1-frame jitter), and you don’t even have an actual reason to do it in the first place.  Your time is better spent anywhere else on your project.

 

 

L. Spiro


Edited by L. Spiro, 03 July 2014 - 04:44 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums




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