{{fbdoc item="title" value="Fine-grain procedure for waiting and in-loop procedure for fine-regulating FPS"}}----
**""-""** Improving SLEEP feature by using a **fine-grain waiting procedure**.
**""-""** Controlling **FPS** (Frames Per Second) by using an **in-loop fine-regulating procedure**.

**Preamble:**

	The proper use of the SLEEP and TIMER keywords in user procedures requires a good knowledge of their limits and behaviors.
	
	__SLEEP keyword__
		Generally the SLEEP feature has not a good accuracy with respect to the delay requested and does not allow to produce very low waiting times.
		
		The accuracy of SLEEP is variable depending on the OS cycle time:
			Windows NT/2K/XP: 15 ms, 9x/Me: 50 ms, Linux: 10ms, DOS: 55 ms.
		And using for the delay values lower than these accuracy values does not allow SLEEP to produce the corresponding wait values (always higher wait, and of the order of these values) except for the delay value '0'.
		
	__TIMER keyword__
		The accuracy of the time returned by TIMER is much greater than that generally of the SLEEP keyword to generate a wait:
			for modern processors, sub-microsecond accuracy is expected.
			
		On some platforms (except Windows and Linux), the return value of TIMER is reset at midnight, so if the start and end time are on either side of the reset point, this could cause unexpected behavior in some programs if this event is ignored.
		
{{fbdoc item="section" value="1. Principles to overcome the penalizing behaviors of SLEEP and TIMER keywords"}}
	To implement effective time management procedures based on SLEEP and TIMER keywords, some bad behaviors as described above must be overcome.
	
	__Principle for producing a waiting feature with accurate delay__
		Using SLEEP does not hog the CPU, but provides poor accuracy and is not compatible with very small delays.
		Using a loop while testing the TIMER value produces a good accuracy but hogs the CPU.
		
		The principle is to chain:
				""-"" a large-grain delay using SLEEP for the first part of the requested delay,
				""-"" then a fine-grain delay for the rest of the time using a loop that tests the TIMER value.
		A time threshold makes it possible to switch between these two types of operation.
		
		A typical setting for this threshold corresponds to a value of 2 times the OS cycle period.
		This value corresponds to a tradeoff between CPU load and delay accuracy.
		
	__Principle for compensating a possible reset of the TIMER return value__
		The detection of a possible reset (at midnight) of the TIMER between two calls is carried out by testing the sign of the difference between the two returned values from the TIMER.
		If the second value is smaller than the first (due to a reset of the TIMER), a negative temporal compensation is applied on the first, corresponding to a day expressed in seconds.

{{fbdoc item="section" value="2. Procedures body (without declarations) description"}}
	3 procedures are described here:
			""-"" 'delay()' procedure => to generate the wait for an accurate time (floating value expressed in ms)
			""-"" 'regulate()'procedure => to finely control and regulate a loop frequency (number of loops per second in integer value)
			""-"" 'framerate()' procedure => tool to measure the instantaneous loop frequency (number of loops per second in integer value)
			
	The 2 first procedures are well suited to finely regulate and/or control the FPS (Frames Per Second) of an image refresh.
	'delay()' is more for one-shot use every now and then, while 'regulate()' is more suited for inserting a fine delay into a loop to generally adjust its FPS.
	
	'regulate()' and 'framerate()' are not thread safe because they each use a 'Static' variable.
	
	**Note:** Like any waiting feature, it is strongly discouraged to use 'delay()' or 'regulate()' when the screen is locked, so no call from inside a [""ScreenLock""...""ScreenUnlock""] block.
	
	__'delay()' procedure body (improving SLEEP feature by using a fine-grain waiting)__
		The 'delay()' sub is useful for generating accurate wait functionality, more precise than that provided by the SLEEP keyword, and also compatible with very short wait times.
		If the requested wait 'amount' is greater than the 'threshold' (+ 0.5), a first part of the requested waiting time ('amount' - 'threshold') is executed thanks to the SLEEP keyword (not hogging the CPU), and the remaining time is generated by testing in loop the accurate values of TIMER up to the target value.
		An eventual resetting of the TIMER is also tested to compensate for it if it occurs.
		%%(freebasic)
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
%%		When the 'delay()' sub above is called from the "delay_regulate_framerate.bi" file to be included (see its definition below in paragraph 3.), a declaration added ahead the body of the sub defines its second parameter ('threshold') as an optional parameter and sets its default value.
		
	__'regulate()' procedure body (fine-controlling FPS by using an in-loop regulating)__
		The 'regulate()' function is built around the 'delay()' sub, but where the waiting time to be applied (if any remains) is deducted from the requested frame period (the inverse of the FPS) and the time already elapsed since the last call.
		For debugging purposes, the 'regulate()' function returns the delay it applied (the one added to the initial loop). If the user does not wish to use this debug data, then they can call the function as a Sub quite simply.
		If this delay value returned is very small, this means that it becomes difficult to reach the FPS setpoint. Otherwise, the fluctuation of the delay returned (assuming that the regulation is very accurate) represents the fluctuation of the user code executed in the loop from frame to frame.
		%%(freebasic)
Function regulate(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Single
	'' '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
%%		When the 'regulate()' function above is called from the "delay_regulate_framerate.bi" file to be included (see its definition below in paragraph 3.), a declaration added ahead the body of the function defines its second parameter ('threshold') as an optional parameter and sets its default value.
		
	__'framerate()' procedure body (tool for FPS measuring)__
		For debugging purposes, an instantaneous measurement of FPS (by measuring the frame time and calculating the inverse) can be provided by calling from anywhere in the loop the following very simple tooling function 'framerate()'.
		If 'framerate()' is placed right next to 'regulate()', this measures the intrinsic precision of the regulation.
		If 'framerate()' is placed elsewhere in the program loop, it may be additionally impacted by program execution fluctuations from frame to frame.
		%%(freebasic)
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
%%		Unlike 'delay()' and 'regulate()', the 'framerate()' function above can be used even when the screen is locked, so called even from inside a [""ScreenLock""...""ScreenUnlock""] block.

{{fbdoc item="section" value="3. Complete source code to be included containing all the declarations and the procedure bodies"}}
	A header contains the declarations for the bodies of the 3 procedures described above.
	For 'delay()' and 'regulate()', these allow to declare their second parameter as optional and to set the default values according to the platform used (Windows, Linux, DOS, or other).
	
	File to be included: "delay_regulate_framerate.bi"
	{{fbdoc item="filename" value="examples/manual/proguide/graphics/delay_regulate_framerate.bi"}}%%(freebasic)
'  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 Single
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 Single
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 Single
	'' '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 Single
#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 Single
#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 Single
#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 Single
	'' '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
%%	This code ('delay_regulate_framerate.bi' file) should be included at the top of the user source program so that they can call the 3 procedures:
		###include "delay_regulate_framerate.bi"##

{{fbdoc item="section" value="4. Examples of use"}}
	Two examples are available here:
			""-"" first example using the 'delay()' sub,
			""-"" second example using the 'regulate()' function (and also the 'framerate()' function as debug tool).
			
	__Example using 'delay()' sub__
		An example generating, thanks to 'delay()', 4 small waits of decreasing values:
			100 ms, 10 ms, 1 ms, 0.1 ms
		{{fbdoc item="filename" value="examples/manual/proguide/graphics/use_delay.bas"}}%%(freebasic)
#include "delay_regulate_framerate.bi"

Dim As Double t
Dim As Single t0 = 100

For N As Integer = 1 To 4
	Print "Requested 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
%%		The measured results seem fairly accurate throughout the full range of use.
		
	__Example using 'regulate()' function and 'framerate()' tooling function__
		An example controlling, thanks to 'regulate()', the FPS (Frames Per Second) refreshing of a graphic image:
			FPS range available from 10 to 100 in steps of 1
		{{fbdoc item="filename" value="examples/manual/proguide/graphics/use_regulate_framerate.bas"}}%%(freebasic)
#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
%%		The measured FPS is almost stable and tracks the requested FPS well.
		To monitor the regulation, the delay added in the loop by 'regulate()' is also visualized.

{{fbdoc item="section" value="5. Adjusting the commutation threshold (large-grain/fine-grain) for 'delay()' and 'regulate()' procedures depending on the real OS cycle period"}}
	If the user wants to refine or modify the default value of the large-grain/fine-grain commutation threshold for the 'delay()' or 'regulate()' procedures, just call it by explicitly specifying the second parameter (integer value given in ms).
	But a typical setting for this threshold corresponds to a value of 2 times the OS cycle period (default values set in the file to be included: "delay_regulate_framerate.bi"):
			""-"" 2 times the OS cycle period is the recommended value => tradeoff between CPU load and delay accuracy.
			""-"" A higher threshold would promote the delay accuracy (increasing), but to the detriment of CPU load (increasing).
			""-"" A lower threshold would promote the CPU load (decreasing), but to the detriment of delay accuracy (decreasing).
			""-"" A downright null threshold would induce no CPU load as long as the required delay is greater than 0.5 ms. Only for a necessary required delay < 0.5 ms, the CPU load would not be minimized, but this small value already means that it will become difficult to reach the FPS setpoint.
			
	Default values set in the header of the 'delay_regulate_framerate.bi' file to be included, according to the platform used:
			""-"" Windows ##(basic resolution OS cycle period = 16 ms)## => ##**threshold = 2 * 16 ms**##
			""-"" Windows ##(high resolution OS cycle period = 1 ms)## => ##**threshold = 2 * 1 ms**## (only used by 'delayHR() and 'regulateHR(), see paragraph 6 below).
			""-"" Linux ##(OS cycle period = 10 ms)## => ##**threshold = 2 * 10 ms**##.
			""-"" DOS ##(OS cycle period = 55 ms)## => ##**threshold = 2 * 55 ms**##.
			""-"" Other ##(OS cycle period per default = 16 ms)## => ##**threshold = 2 * 16 ms **by default##.
	If the actual resolution of the OS cycle period is better than the default one above (depending on platform), the user can call 'delay()' and 'regulate()' by explicitly specifying the second parameter (two times this actual resolution value given in ms).

{{fbdoc item="section" value="6. Windows platform"}}
	For the Windows platform only, the user can force temporarily the high resolution of the OS cycle period to 1 ms (instead of 16 ms) by calling 'delayHR()' or 'regulateHR()' instead.
	The correct threshold (2 * 1 ms) is also temporarily applied.
	This mainly reduces the CPU load because the threshold can be low.
	
	'delayHR()' procedure included in the "delay_regulate_framerate.bi" file:
	%%(freebasic)
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
%%
	'regulateHR()' procedure included in the "delay_regulate_framerate.bi" file:
	%%(freebasic)
Function regulateHR(ByVal MyFps As Ulong, ByVal threshold As Ulong) As Single
	'' '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
%%	'regulateHR()' is not thread safe because it uses a 'Static' variable.
	
	In any cases, a call to 'delay()' and 'regulate()' always runs in the default resolution, but with a threshold adapted to the basic resolution (2 * 16 ms).
	So if the OS cycle period is already in high resolution (1 ms), it is necessary to use 'delayHR()' and 'regulateHR()' to also apply the correct corresponding threshold, otherwise this high resolution combined with a much too high threshold will not reduce CPU load compared to basic resolution (on the other hand the delay accuracy will be good).
	Preferably use 'delay()' and 'regulate()' only when the OS cycle period is in basic resolution (16 ms).
	
	**Note:**
		For the Windows platform, the "delay_regulate_framerate.bi" file is only supported from Windows 2000 (because it refers to high resolution for OS cycle period).
		For earlier Windows systems, remove all references to high resolution from the "delay_regulate_framerate.bi" file (last part of the ##'""#if defined(__FB_WIN32__)""'##):
				""-"" remove declarations of '-setTimer', '_resetTimer', 'delayHR' and 'regulateHR',
				""-"" delete the body of the 'delayHR' and 'regulateHR' procedures.

{{fbdoc item="section" value="7. Enhanced example of use"}}
	This example is improved compared to the second example of the paragraph 4.
	
	It allows in addition to:
		**""-""** Switch between the normal resolution and the high resolution of the OS cycle period for the Windows platform only.
		**""-""** Modify the value of the optional parameter 'threshold'.
		{{fbdoc item="filename" value="examples/manual/proguide/graphics/use_regulate_framerate_2.bas"}}%%(freebasic)
#include "delay_regulate_framerate.bi"

Screen 12, , 2
Screenset 1, 0

Dim As Ulongint MyFps = 100
	
Dim As String res = "N"
Dim As Ulong thresholdNR = 32
Dim As Ulong thresholdHR = 2

Do
	Static As Ulongint l
	Static As Double dt
	Static As Ulong fps
	Static As Double t
	Static As Ulong averageFps
	Static As Double sumFps
	Static As Double averageDelay
	Static As Double sumDelay
	Static As Long N
	Static As Ulong fpsE
	Dim As Double t1
	Dim As Double t2
	t = Timer
	Cls
	Print
	Color 15
	Select Case res
	Case "N"
		Print "                      NORMAL RESOLUTION"
	Case "H"
		Print "                      HIGH RESOLUTION (for Windows only)"
	End Select
	Print
	Select Case res
	Case "N"
		Print " Procedure : regulate( " & MyFPS & " [, " & thresholdNR & " ])"
	Case "H"
		Print " Procedure : regulateHR( " & MyFPS & " [, " & thresholdHR & " ])"
	End Select
	Print
	Color 11
	Print Using " Measured FPS  : ###          (average : ###)"; fpsE; averageFps
	Print Using " Applied delay : ###.### ms   (average : ###.### ms)"; dt; averageDelay
	Print
	Print
	Print
	Color 14
	#if defined(__FB_WIN32__)
	Print " <n> or <N> : Normal resolution"
	Print " <h> or <H> : High resolutiion"
	Print
	#endif
	Print " <+>        : Increase FPS"
	Print " <->        : Decrease FPS"
	Print
	Print " Optional parameter :"
	Select Case res
	Case "N"
		Print "    <i> or <I> : Increase NR threshold"
		Print "    <d> or <D> : Decrease NR threasold"
		Draw String (320, 280), "(optimal value : 32)"
	Case "H"
		Print "    <i> or <I> : Increase HR threshold"
		Print "    <d> or <D> : Decrease HR threasold"
		Draw String (320, 280), "(optimal value : 2)"
	End Select
	Print
	Print " <escape>   : Quit"
	Line (8, 128)-(631, 144), 7, B
	Line (8, 128)-(8 + l, 144), 7, BF
	Do
	#if Not defined(__FB_WIN32__) And Not defined(__FB_LINUX__)
		t2 = Timer
		If t2 < t Then t -= 24 * 60 * 60
	Loop Until t2 >= t + 0.002
	#else
	Loop Until Timer >= t + 0.002
	#endif
	Screencopy
	l = (l + 1) Mod 624
	Dim As String s = Ucase(Inkey)
	Select Case s
	Case "+"
		If MyFPS < 500 Then MyFPS += 1
	Case "-"
		If MyFPS > 10 Then MyFPS -= 1
	#if defined(__FB_WIN32__)
	Case "N"
		If res = "H" Then
			res = "N"
		End If
	Case "H"
		If res = "N" Then
			res = "H"
		End If
	#endif
	Case "I"
		Select Case res
		Case "N"
			If thresholdNR < 64 Then thresholdNR += 16
		Case "H"
			If thresholdHR < 4 Then thresholdHR += 1
		End Select
	Case "D"
		Select Case res
		Case "N"
			If thresholdNR > 0 Then thresholdNR -= 16
		Case "H"
			If thresholdHR > 0 Then thresholdHR -= 1
		End Select
	Case Chr(27)
		Exit Do
	End Select
	sumFps += fpsE
	sumDelay += dt
	N += 1
	If N >= MyFps / 2 Then
		averageFps = sumFps / N
		averageDelay = sumDelay / N
		N = 0
		sumFps = 0
		sumDelay = 0
	End If
	Select Case res
	Case "N"
		dt = regulate(MyFps, thresholdNR) 
	#if defined(__FB_WIN32__)
	Case "H"
		dt = regulateHR(MyFps, thresholdHR)
	#endif
	End Select
	fpsE = framerate()
Loop
%%
{{fbdoc item="section" value="See also"}}
	- ##[[KeyPgSleep|Sleep]]##
	- ##[[KeyPgTimer|Timer]]##
	- [[ProPgAntiFlickering|Graphics Mode Refresh and Anti-Flickering]]
	- [[ProPgLiteRegulate|Lite regulation function to be integrated into user loop for FPS control]]

{{fbdoc item="back" value="CatPgProgrammer|Programmer's Guide"}}