FreeBasic's Timer
Re: FreeBasic's Timer
deltarho
Google Chrome used to alter the resolution, it doesn't seem to do so now.
I have tested a while back.
java runtime used to alter the resolution, but I don't have it just now, so I cannot test.
I don't have firefox.
Google Chrome used to alter the resolution, it doesn't seem to do so now.
I have tested a while back.
java runtime used to alter the resolution, but I don't have it just now, so I cannot test.
I don't have firefox.
-
- Posts: 4156
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: FreeBasic's Timer
@fxm
That paragraph has been in timeBeginPeriod for a long time and should have been edited with Windows 10 or later.
With Windows 10 or later, suppose we have three processes using timer services, then the highest resolution requested from within that group will apply to that group. “For processes which have not called this function, Windows does not guarantee a higher resolution than the default system resolution.”
If no process uses timer services apart from your graphics program, then the rest of the system is unaffected.
Do you think that your graphics program on its own using timer services will reduce overall system performance? I seriously don't think so, and that is why Microsoft introduced the no global setting.
The Remarks section of timeBeginPeriod has always been badly written. I won't bore you, but there are other aspects of timeBeginPeriod changes in Windows 10 that have never been mentioned. I discovered them by experimenting.
What we have then is a choice between no 1000Hz timer and a threshold of 32ms with the option to change that scenario, or using the 1000Hz timer with a 3ms threshold with the option to change that scenario.
I strongly recommend the latter, as the user will get a very much reduced CPU load without having to do anything.
That paragraph has been in timeBeginPeriod for a long time and should have been edited with Windows 10 or later.
With Windows 10 or later, suppose we have three processes using timer services, then the highest resolution requested from within that group will apply to that group. “For processes which have not called this function, Windows does not guarantee a higher resolution than the default system resolution.”
If no process uses timer services apart from your graphics program, then the rest of the system is unaffected.
Do you think that your graphics program on its own using timer services will reduce overall system performance? I seriously don't think so, and that is why Microsoft introduced the no global setting.
The Remarks section of timeBeginPeriod has always been badly written. I won't bore you, but there are other aspects of timeBeginPeriod changes in Windows 10 that have never been mentioned. I discovered them by experimenting.
What we have then is a choice between no 1000Hz timer and a threshold of 32ms with the option to change that scenario, or using the 1000Hz timer with a 3ms threshold with the option to change that scenario.
I strongly recommend the latter, as the user will get a very much reduced CPU load without having to do anything.
Last edited by deltarho[1859] on May 28, 2023 22:11, edited 1 time in total.
Re: FreeBasic's Timer
But what is the compatibility of:
Declare Function _setTimer Lib "winmm" Alias "timeBeginPeriod"(Byval As Ulong = 1) As Long
_setTimer()
with older Windows ?
Declare Function _setTimer Lib "winmm" Alias "timeBeginPeriod"(Byval As Ulong = 1) As Long
_setTimer()
with older Windows ?
-
- Posts: 4156
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: FreeBasic's Timer
@dodicat
A few years ago, a person had one hell of a rant about web browsers and their messing with the timer resolution whether they needed to or not.
Sat in a park with our laptop running on battery will see the battery run down faster with a high timer resolution, he argued.
It follows that our battery will run down faster on Linux than Windows – 10ms versus 15.625ms.
The no global setting has helped in this respect, in addition to web browsers being better behaved.
Of course, there isn't much we can do about watching a film in the park, whether on Windows or Linux.
At home, a high timer resolution will suck more out of our A/C supply, but we are talking small amounts for one PC over a year. With every PC on the planet, it may add up to quite a lot.
A few years ago, a person had one hell of a rant about web browsers and their messing with the timer resolution whether they needed to or not.
Sat in a park with our laptop running on battery will see the battery run down faster with a high timer resolution, he argued.
It follows that our battery will run down faster on Linux than Windows – 10ms versus 15.625ms.
The no global setting has helped in this respect, in addition to web browsers being better behaved.
Of course, there isn't much we can do about watching a film in the park, whether on Windows or Linux.

At home, a high timer resolution will suck more out of our A/C supply, but we are talking small amounts for one PC over a year. With every PC on the planet, it may add up to quite a lot.
-
- Posts: 4156
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: FreeBasic's Timer
As I mentioned, timeBeginPeriod was introduced in Windows 2000.fxm wrote:But what is the compatibility of:
Declare Function _setTimer Lib "winmm" Alias "timeBeginPeriod"(Byval As Ulong = 1) As Long
_setTimer()
with older Windows ?
With a default of 1000Hz timer and a threshold of 3ms for Windows, I very much doubt that anyone will change that.
Re: FreeBasic's Timer
deltarho[1859] wrote: ↑May 28, 2023 21:36 What we have then is a choice between no 1000Hz timer and a threshold of 32ms with the option to change that scenario (by "timeBeginPeriod" + procedure call with 3 ms as second parameter), or using the 1000Hz timer with a 3ms threshold with the option to change that scenario (by "timeEndPeriod" + procedure call with 32 ms as second parameter).
I strongly recommend the latter, as the user will get a very much reduced CPU load without having to do anything.
-
- Posts: 4156
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: FreeBasic's Timer
For the life of me, I cannot see anyone in their right mind on Windows opting to choose a method which increases their CPU load with no change in the accuracy of the exercise.
At MSDN: "Call this function immediately before using timer services, and call the timeEndPeriod function immediately after you are finished using the timer services."
I ignored that on Windows 7 when I realized, on experimenting, that timeBeginPeriod(1) did not 'bite' until one clock tick had been executed – that is 15.625ms. That is why I called timeBeginPeriod(1) at the beginning of an application so that the 1ms resolution was available when needed. On Windows 10 it 'bites' immediately.
So, why didn't Microsoft mention the 15.625ms delay on Windows 7. The simple answer is: They did not know.
At MSDN: "Call this function immediately before using timer services, and call the timeEndPeriod function immediately after you are finished using the timer services."
I ignored that on Windows 7 when I realized, on experimenting, that timeBeginPeriod(1) did not 'bite' until one clock tick had been executed – that is 15.625ms. That is why I called timeBeginPeriod(1) at the beginning of an application so that the 1ms resolution was available when needed. On Windows 10 it 'bites' immediately.
So, why didn't Microsoft mention the 15.625ms delay on Windows 7. The simple answer is: They did not know.

Re: FreeBasic's Timer
Therefore, the source to be included ('delay_regulate_framerate.bi') containing all declarations and procedure bodies:
delay_regulate_framerate.bi:
Example using 'delay()' procedure:
Example using 'regulate()' procedure and 'framerate()' tooling procedure:
Previous example, but forcing the low basic resolution (16 ms) for the Windows OS cycle period:
delay_regulate_framerate.bi:
Code: Select all
' delay_regulate_framerate.bi
#if defined(__FB_WIN32__)
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 16)
Declare Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 16) As Double
Declare Function _setTimer Lib "winmm" Alias "timeBeginPeriod"(ByVal As Ulong = 1) As Long
Declare Function _resetTimer Lib "winmm" Alias "timeEndPeriod"(ByVal As Ulong = 1) As Long
Declare Sub delayHR(ByVal amount As Single, ByVal threshold As Ulong = 2 * 1)
Declare Function regulateHR(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 1) As Double
Sub delayHR(ByVal amount As Single, ByVal threshold As Ulong)
'' 'amount' : requested temporisation to apply, in milliseconds
'' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
Dim As Double t1 = Timer
Dim As Double t2
Dim As Double t3 = t1 + amount / 1000
If amount > threshold + 0.5 Then
_setTimer()
Sleep amount - threshold, 1
_resetTimer()
End If
Do
#if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
t2 = Timer
If t2 < t1 Then t1 -= 24 * 60 * 60 : t3 -= 24 * 60 * 60
Loop Until t2 >= t3
#else
Loop Until Timer >= t3
#endif
End Sub
Function regulateHR(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Double
'' 'MyFps' : requested FPS value, in frames per second
'' function return : applied delay (for debug), in milliseconds
'' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
Static As Double t1
Dim As Single tf = 1 / MyFps
Dim As Double t2 = Timer
#if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
If t2 < t1 Then t1 -= 24 * 60 * 60
#endif
Dim As Single dt = (tf - (t2 - t1)) * 1000
delayHR(dt, threshold)
t1 = Timer
Return dt
End Function
#elseif defined(__FB_LINUX__)
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 10)
Declare Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 10) As Double
#elseif defined(__FB_DOS__)
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 55)
Declare Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong = 2 * 55) As Double
#else
Declare Sub delay(ByVal amount As Single, ByVal threshold As Ulong = 2 * 16)
Declare Function regulate(ByVal MyFps As Ulong, ByVal Ulong As Single = 2 * 16) As Double
#endif
Declare Function framerate() As Ulong
'------------------------------------------------------------------------------
Sub delay(ByVal amount As Single, ByVal threshold As Ulong)
'' 'amount' : requested temporisation to apply, in milliseconds
'' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
Dim As Double t1 = Timer
Dim As Double t2
Dim As Double t3 = t1 + amount / 1000
If amount > threshold + 0.5 Then Sleep amount - threshold, 1
Do
#if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
t2 = Timer
If t2 < t1 Then t1 -= 24 * 60 * 60 : t3 -= 24 * 60 * 60
Loop Until t2 >= t3
#else
Loop Until Timer >= t3
#endif
End Sub
Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Double
'' 'MyFps' : requested FPS value, in frames per second
'' function return : applied delay (for debug), in milliseconds
'' 'thresold' : fixing threshold for fine-grain temporisation (by waiting loop), in milliseconds
Static As Double t1
Dim As Single tf = 1 / MyFps
Dim As Double t2 = Timer
#if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
If t2 < t1 Then t1 -= 24 * 60 * 60
#endif
Dim As Single dt = (tf - (t2 - t1)) * 1000
delay(dt, threshold)
t1 = Timer
Return dt
End Function
Function framerate() As Ulong
'' function return : measured FPS value (for debug), in frames per second
Static As Double t1
Dim As Double t2 = Timer
#if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
If t2 < t1 Then t1 -= 24 * 60 * 60
#endif
Dim As Ulong tf = 1 / (t2 - t1)
t1 = t2
Return tf
End Function
Example using 'delay()' procedure:
Code: Select all
#include "delay_regulate_framerate.bi"
Dim As Double t
Dim As Single t0 = 100
For N As Integer = 1 To 4
Print "Requesred delay :"; t0; " ms"
For I As Integer = 1 To 4
t = Timer
delay(t0)
Print Using" Measured delay : ###.### ms"; (Timer - t) * 1000
Next I
Print
t0 /= 10
Next N
Sleep
Example using 'regulate()' procedure and 'framerate()' tooling procedure:
Code: Select all
#include "delay_regulate_framerate.bi"
Screen 12
Dim As Ulong FPS = 60
Do
Static As Ulongint l
Static As Single dt
Screenlock
Cls
Color 11
Print Using "Requested FPS : ###"; FPS
Print
Print Using "Applied delay : ###.### ms"; dt
Print Using "Measured FPS : ###"; framerate()
Print
Print
Print
Color 14
Print "<+> : Increase FPS"
Print "<-> : Decrease FPS"
Print "<Escape> : Quit"
Line (0, 80)-(639, 96), 7, B
Line (0, 80)-(l, 96), 7, BF
Screenunlock
l = (l + 1) Mod 640
Dim As String s = Inkey
Select Case s
Case "+"
If FPS < 100 Then FPS += 1
Case "-"
If FPS > 10 Then FPS -= 1
Case Chr(27)
Exit Do
End Select
dt = regulate(FPS)
Loop
Previous example, but forcing the low basic resolution (16 ms) for the Windows OS cycle period:
Code: Select all
#include "delay_regulate_framerate.bi"
#ifdef __FB_WIN32__
_resetTimer()
#endif
Screen 12
Dim As Ulong FPS = 60
Do
Static As Ulongint l
Static As Single dt
Screenlock
Cls
Color 11
Print Using "Requested FPS : ###"; FPS
Print
Print Using "Applied delay : ###.### ms"; dt
Print Using "Measured FPS : ###"; framerate()
Print
Print
Print
Color 14
Print "<+> : Increase FPS"
Print "<-> : Decrease FPS"
Print "<Escape> : Quit"
Line (0, 80)-(639, 96), 7, B
Line (0, 80)-(l, 96), 7, BF
Screenunlock
l = (l + 1) Mod 640
Dim As String s = Inkey
Select Case s
Case "+"
If FPS < 100 Then FPS += 1
Case "-"
If FPS > 10 Then FPS -= 1
Case Chr(27)
Exit Do
End Select
#ifdef __FB_WIN32__
dt = regulate(FPS, 32)
#else
dt = regulate(FPS)
#endif
Loop
Last edited by fxm on May 29, 2023 11:52, edited 1 time in total.
-
- Posts: 4156
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
-
- Posts: 4156
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: FreeBasic's Timer
On second thoughts, you may be right.hhr wrote:As I said before, you are dealing with a difficult subject.

Re: FreeBasic's Timer
For those interested, I started writing the new documentation page:
- ProPgDelayRegulate → fxm [new page in progress 'Fine-grain procedure for waiting and in-loop procedure for regulating FPS']
- ProPgDelayRegulate → fxm [new page in progress 'Fine-grain procedure for waiting and in-loop procedure for regulating FPS']
-
- Posts: 605
- Joined: Nov 28, 2012 1:27
- Location: CA, USA moving to WA, USA
- Contact:
Re: FreeBasic's Timer
@deltarho[1859]:
hhr popped in with what he could (and I think there are others with enough experience that could, also) but I think think most of us feel very comfortable that a couple of you are doing such a very good job of tackling topics that will improve look/feel/performance of FB.
This is lazy and selfish, perhaps.
But our respect and appreciation is not small.
And it is not possible to praise highly enough fxm's tenacity and attention to detail.
I may disagree with his firm hand and opinion, at times, but there is no denying his persistence, focus, and discipline has helped every one involved on just about every topic he has been entangled with.
@coderjeff:
Why Not?
A good idea is a good idea - thrown out there for consideration by the group.
A contribution is a contribution: given in hopes that it will useful and used.
If that contribution is converted into a more system sustainable and efficient reference, even better!
david
Yeah, I hear crickets, also. And I am one of them. Please: always look at the view count. Many more people than just me are very interested in topics like this.Yours truly wrote:
Perhaps some comments from members would be helpful. Stand aside to avoid being crushed.
See what I mean? At PowerBASIC quite a few members would have responded by now.
hhr popped in with what he could (and I think there are others with enough experience that could, also) but I think think most of us feel very comfortable that a couple of you are doing such a very good job of tackling topics that will improve look/feel/performance of FB.
This is lazy and selfish, perhaps.
But our respect and appreciation is not small.
And it is not possible to praise highly enough fxm's tenacity and attention to detail.
I may disagree with his firm hand and opinion, at times, but there is no denying his persistence, focus, and discipline has helped every one involved on just about every topic he has been entangled with.
@coderjeff:
There is no good place to add in user contributed source, and I don't think we want to convert user's fb code to C to put in the rtlib.
Why Not?
A good idea is a good idea - thrown out there for consideration by the group.
A contribution is a contribution: given in hopes that it will useful and used.
If that contribution is converted into a more system sustainable and efficient reference, even better!
david
Re: FreeBasic's Timer
I have looked at 'mouse and maze' from BasicCoder2.
viewtopic.php?p=298935#p298935
In the first lines I set speed = 60.
I copied 'mouse and maze' into a second tab and replaced the function regulate of BasicCoder2 with the function regulate of fxm.
Then in the main loop at the end of the program 'sleep regulate(speed,fps),1' must be replaced by 'regulate(60,0)'.
Both programs jerk a bit, but otherwise work the same.
As intended, I then added the section with "timeBeginPeriod" to the program with regulate from fxm.
Thus the program with regulate of fxm runs more evenly.
If I insert the section also into the program of BasicCoder2, both programs run again equally.
So in the program of BasicCoder2 only the section with "timeBeginPeriod" is missing.
My point is that one must not be hasty. As much as I appreciate fxm's work, I have to say that the functions can perhaps be improved.
Copy and paste is completely sufficient. If it were built into FreeBasic, further development would be difficult.
Does anyone know how game programmers handle this problem?
Translated with the help from www.DeepL.com/Translator (free version)
viewtopic.php?p=298935#p298935
In the first lines I set speed = 60.
I copied 'mouse and maze' into a second tab and replaced the function regulate of BasicCoder2 with the function regulate of fxm.
Then in the main loop at the end of the program 'sleep regulate(speed,fps),1' must be replaced by 'regulate(60,0)'.
Both programs jerk a bit, but otherwise work the same.
As intended, I then added the section with "timeBeginPeriod" to the program with regulate from fxm.
Thus the program with regulate of fxm runs more evenly.
If I insert the section also into the program of BasicCoder2, both programs run again equally.
So in the program of BasicCoder2 only the section with "timeBeginPeriod" is missing.
My point is that one must not be hasty. As much as I appreciate fxm's work, I have to say that the functions can perhaps be improved.
Copy and paste is completely sufficient. If it were built into FreeBasic, further development would be difficult.
Does anyone know how game programmers handle this problem?
Translated with the help from www.DeepL.com/Translator (free version)
Last edited by hhr on May 29, 2023 21:54, edited 1 time in total.
Re: FreeBasic's Timer
Quite simply, nobody's put in the effort to make it happen. And when you consider nobody maintains the examples that are already shipped with freebasic, who do you think is going to maintain and document 2,000 other completely random pieces of code as they break and become obsolete? (2,000 being the number of codes linked in The Big Review topic in the source forum)speedfixer wrote: ↑May 29, 2023 18:26 @coderjeff:
There is no good place to add in user contributed source, and I don't think we want to convert user's fb code to C to put in the rtlib.
Why Not?
Lumping yet another thing at the feet of the people who seemingly already do everything is a bit of a rum do. But who else would do it? I certainly wouldn't
Windows NT 3.1 from 1993, here's what the docs said then. You can get the whole NT3.1 documentation set here if you'd like.As I mentioned, timeBeginPeriod was introduced in Windows 2000.
Re: FreeBasic's Timer
@hhr,
Using '0' as second parameter of 'regulate()' is the worst value for regulation accuracy.
For a Windows platform:
Without "timeBeginPeriod", use '32' instead.
With "timeBeginPeriod", use '3' instead.
Using '0' as second parameter of 'regulate()' is the worst value for regulation accuracy.
For a Windows platform:
Without "timeBeginPeriod", use '32' instead.
With "timeBeginPeriod", use '3' instead.