How to do windowed mode AND limit the framerate?

BlitzMax Forums/BlitzMax Beginners Area/How to do windowed mode AND limit the framerate?

Crinkle(Posted 2010) [#1]
Ok so i can see there is a handy little refresh rate variable now in the graphics command, but in order to get window mode you have to set this refresh rate (which is basically an fps_limiter) to 0, so theres no limit (no no, no no no no!)

so how can one stop ones program from doing as mine is and rendering between 30 and 522fps and seeming to be idling at 522fps and maxing out refreshes at a certain speed?


Czar Flavius(Posted 2010) [#2]
If you turn off vsync then the refresh rate won't limit the fps. Generally speaking, you don't care about the drawing rate but only the update rate. If you want 20 updates per second that's 50 ms between updates. Keep track of the last time you updated and then check the current Millisecs(). If 50 or more ms has passed then reset the last update time and now run your update function. Run a draw each loop regardless.

If you look at the doc for flip you can put 1 or 0 on the end and one these may limit your fps, so check that out.


ima747(Posted 2010) [#3]
You could also look into writing your game logic for variable timing with a tween value, or another method, so it can run above, or bellow your target frame rate and it will just make it smoother (or blockier if slower) but ins will perform at the same real world speed regardless... Can be a hassle to go back and add that in however if you're far along in development.


Muttley(Posted 2010) [#4]
http://gafferongames.com/game-physics/fix-your-timestep/


Crinkle(Posted 2010) [#5]
Ahh thanks for that, i found an ideal fix!

Local Lmt_FPS=60
Local Lmt_Frametime=1000/Lmt_Fps
Local Lmt_Frame_begin

[Main loop begins]

Lmt_Frame_begin=MilliSecs()

[Rest of code]
[Flip]

If (MilliSecs()-Lmt_Frame_begin)<Lmt_Frametime
Delay Lmt_Frametime-(MilliSecs()-Lmt_frame_begin)
EndIf

[End Main Loop]

The above seems to work, and locks it down, however for some reason its at 63fps in my program, never mind though, its close enough for government work!


H&K(Posted 2010) [#6]
1000/60 = 16

60*16 < 1000 by 2.5*16

Fps 63


Crinkle(Posted 2010) [#7]
What?? :s


Muttley(Posted 2010) [#8]
He means that you're using integer maths, but 1000/60 = 16.67

Do yourself a huge favour and start using SuperStrict right now. You'll thank yourself later.

To apply to your own code:

SuperStrict

Local Lmt_FPS:Float=60.0
Local Lmt_Frametime:Float=1000.0/Lmt_Fps
Local Lmt_Frame_begin:Float

[Main loop begins]

Lmt_Frame_begin=MilliSecs()

[Rest of code]
[Flip]

If (MilliSecs()-Lmt_Frame_begin)<Lmt_Frametime
Delay Lmt_Frametime-(MilliSecs()-Lmt_frame_begin)
EndIf

[End Main Loop]



jkrankie(Posted 2010) [#9]
If you just want to limit it without doing all the time step stuff, you can do a:

Graphics 800,600,0,60

Cheers
Charlie


Crinkle(Posted 2010) [#10]
I'll stay away from superstrict i dont know what it is supposed to do but it seems to make every line an error message!

jkrankie- i found that out yeah, first used a 0 for the refresh but that makes things go stupidly fast! :p


ImaginaryHuman(Posted 2010) [#11]
Does SetGraphicsDriver have a software refresh rate? (You gotta use it with Flip -1 also)


Czar Flavius(Posted 2010) [#12]
I'll stay away from superstrict i dont know what it is supposed to do but it seems to make every line an error message!
Because they contain errors! You need to declare each variable before you use it, and also the type of variable.

image = LoadImage("me.png")
DrawImage image 5, 5
WRONG.
Local image:TImage = LoadImage("me.png")
DrawImage image 5, 5

Correct.

Code with SuperStrict is faster and contains less bugs. It's off by default to make BlitzMax "easier" to learn, but this was a very bad decision by the powers above! The time it will take fixing your code is worth it. You can also use Strict as an alternative which means you don't need to specify the types of Ints (detected automatically) but still must the rest. As you've discovered, take special care when dividing with integers.

Local Lmt_FPS=60 change this to Const Lmt_FPS=60. It's a minor change but constants are a tiny bit faster.

As I stated in my first post, you need to worry about how often the game is updated a second, and not the number of times it is drawn. If you update the game and draw the game once per loop, then somebody with a higher refresh rate is going to run your game ridiculously fast. You need to make the number of updates (to player position, bullet position etc) distinct from drawing. So on 60fps you might have 1 update every 2 frames. On 120fps you would have 1 update every 4 frames. On 30fps (slower computer) you would update every frame. Then your game runs at the same speed on any computer.

its close enough for government work!
What does this mean??


Crinkle(Posted 2010) [#13]
do you mean if i use superstrict command then there will be a big performance increase regardless of what hardwar an end user has in their PC? I dont see the point if its only going to be 1 or 2 frames per second but maybe for 10 or so i'd reconsider.

If it just means trolling through more errors for things that are just "bad programming" i can live with that. It's hard enough as is so if things can be got just to work i'll be happy at the moment.

Also, what does it matter what a persons refresh rate on their pc is? If i set the delay in the main loop then the WHOLE program is only going to update once per frame which is controlled by a framerate limiter?


GW(Posted 2010) [#14]
I'll stay away from superstrict i dont know what it is supposed to do but it seems to make every line an error message!

LOL, that's the best line of the year!

My experience with vsync is that even if its on and your doing flip(1) or flip(-1). when you move the mouse, the Vsync goes from 60 to whatever the frequency of mouse events. It may be max2dd driver dependent.


Czar Flavius(Posted 2010) [#15]
Yes there will be a performance increase on the same hardware! I never tested the speed difference as I always use Strict as a matter of course. I suggest your next program you start with it on. It makes sense if you think about it. If you make a variable to store images, why would you want it to store strings the next moment and maybe integers later? Strict prevents those mistakes as well as typos.