FreeBasic's Timer

General FreeBASIC programming questions.
Post Reply
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBasic's Timer

Post by deltarho[1859] »

@speedfixer

Pushing 3000 views in 11 days is not a typical thread and, obviously, indicates a high level of interest.

Regarding the difference between the PowerBASIC forum and the FreeBASIC forum, it may well simply be that the PowerBASIC forum has a high percentage of commercial programmers. Now, although I am a hobbyist, being an active member of the PowerBASIC forum for 14 years may have seen some of their attitude rub off onto me. This may lead to some frustration when on the FreeBASIC forum, where the vast majority of members are hobbyists.

If the above is true, then any frustration is down to me and not the FreeBASIC forum. I may have upset some members here by my remarks in the past, and for that, I apologize.
This is lazy and selfish, perhaps.
There is no perhaps about it – there is more than an element of truth in that.

Members who could participate and did not are missing out on having a conversation with one of the very best FreeBASIC coders that we have. fxm and I have collaborated a few times, and each time I have regarded myself as fxm's junior assistant; a bit like a PhD student and their doctoral advisor. Having said that, a fair amount of my ideas are to be found in the final code. I struggled to get some included and had to find the right words to persuade fxm to include them. fxm listens and will accept suggestions if they have merit, and that is why he is one of the very best FreeBASIC coders that we have.

You mentioned hhr. Now there is somebody who is smarter than he makes out. He has a well-developed level of competence; unlike some people who fly past their competence level with the utmost disregard. Those people are, of course, incompetent. I look forward to collaborating with hhr one of these days.

@adeyblue

Windows NT 3.1 from 1993

Wow, that was thirty years ago.
paul doe
Moderator
Posts: 1732
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: FreeBasic's Timer

Post by paul doe »

hhr wrote: May 29, 2023 21:22 ...
Does anyone know how game programmers handle this problem?
...
Have a look at https://gafferongames.com/post/fix_your_timestep/ to have a glimpse of the challenges involved (and consider that the article is pretty old!). Perhaps this might explain the overall apathy: while useful, the code discussed here is far too simplistic (albeit still useful for simple games and graphic demos).

Anything more complex than that, you need a more involved game loop and timings.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBasic's Timer

Post by deltarho[1859] »

@fxm

In the new Wiki entry, you refer to the user with the 'he' pronoun. It would be better if you used 'they'.

So far so good – it is a good read. :)
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBasic's Timer

Post by dodicat »

Paul doe.
It is easy enough to get an accurate regulator using looping.
But the cpu usage is huge.
Using sleep works well in FreeBASIC and gives the cpu some space in not too cpu hungry graphics or whatever.
Of course sleep 1 is actually 15 in Windows and 10?? in Linux, so that is a problem for large framerates.(Then looping can be used)

Sleeping works well in fb and pascal for framerates less than about 60, I use my regulator for both, but C++ isn't so happy about it.
So I can only assume that it isn't an overall solution, but looping probably is.
The code below should bring up the task manager in windows, fps of less than about 60 - not much cpu, otherwise much cpu.
It is only common sense that a sleep works wonders, it does for about everything else on the biosphere anyways.
The graphics are not too heavy.
Previous example +

Code: Select all

Function readkey(x As Long,y As Long,st As String,message As String,clr As Ulong) As String
      Static As String j,blink
      Var c=Color
      Var i=Inkey()
      If Left(i,1)=Chr(08) Then j=Mid(j,1,Len(j)-1)
      Select Case Left(i,1)
      Case Chr(0) To Chr(254)
            If Left(i,1)<>Chr(08) Then
                  j=j+Left(i,1)
            End If
      End Select
      If Frac(Timer)>.5 Then blink=" " Else blink="_"
      If Left(i,1)=Chr(27) Then j=""
      If i<>Chr(13) Then
            Locate x,y,0
            Color clr
            Print  st & j & blink 
            Color c
      Else
            j=Rtrim(j,Chr(13))
            message=j
            j=""
      End If
      Return i
End Function

Function regulate Overload(MyFps As Long,Byref fps As Long) As Double
      Dim As Double k=1/MyFps
      Static As Double timervalue
      Var c=timervalue
      Do While (Timer - TimerValue) <= k
      Loop 
      Var ans=(Timer-timervalue)
      timervalue=Timer
      fps=1/(timervalue-c)
      If Abs(Myfps-fps)>MyFps\2 Then fps=60
      Return ans*60
End Function


Function Regulate(Byval MyFps As Long,Byref fps As Long,Byref gap As Double) As Double
      Static As Double timervalue,_lastsleeptime,t3,frames
      Var T=Timer
      frames+=1
      If (t-t3)>=1 Then t3=t:fps=frames:frames=0
      Var sleeptime=_lastsleeptime+((1/myfps)-T+timervalue)*1000
      If sleeptime<1 Then gap=sleeptime:sleeptime= 1
      _lastsleeptime=sleeptime
      timervalue=T
      Return sleeptime
End Function

Sub ball()
      Static  As Double x= 10
      Static  As Double y = 10
      Static  As Double dx=.5
      Static  As Double dy =.5
      x += dx : y += dy
      If x<10 Or x>=630 Then dx = -dx
      If y<10 Or y>=470 Then dy = -dy
      Circle(x,y),10,4,,,,f 
End Sub


Sub drawline(x As Long,y As Long,angle As Single,length As Long,col As Ulong)
      Var x2=x+length*Cos(angle)
      Var y2=y-length*Sin(angle)
      Line(x,y)-(x2,y2)
      Circle(x2,y2),20,6,,,,f
End Sub

Sub pendulum
      #define dmod(x,y) (y)*Frac((x)/(y)) 
      Const pi=4*Atn(1)
      Static As Single angle
      angle+=.005
      angle=dmod(angle,2*pi)
      drawline(400,100,.4*Sin(angle)-pi/2,300,4) 
End Sub

Dim As String message="50"
Dim As Long fps
Dim As Long MyChoice,flag
Dim As String LastChoice
Dim As Double gap
gap=2

shell("start taskmgr.exe")

Screen 12

Do
      Screenlock
      Cls
      
      readkey(4,2,Ucase("Input required framerate, ESC to finish "),message,3)
      Color 7
      Locate 7,2
      Print "required framerate ";message
      Locate 10,2
      Print "actual framerate   ";fps

      Locate 16,2
      Color 5
      Print Iif(flag=true,"Regulate with sleep","Regulate with while")
      ball
      pendulum
      
      Screenunlock
      
      MyChoice=Valint(message)
      If Mychoice<=0 Then message=LastChoice:Continue Do
      
      If gap>1 Then '< about 60 fps
            Sleep  regulate(MyChoice,fps,gap) ,1
            flag=true
      Else
            gap=regulate(MyChoice,fps)
            flag=false
      End If
      
      
      LastChoice=message 
      
Loop Until Multikey(1)'esc

 
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBasic's Timer

Post by deltarho[1859] »

If you intend to use fxm's delay() and/or regulate() in code to be published on the forum then I strongly recommand you use the code in the Wiki (still in work in progress) and the latest FreeBASIC manual (still in work in progress).

The following code has been designed specifically for users on Windows 10/11 only and personal use. Firstly, on Windows because the check on whether Timer requests straddle midnight or not is not employed. Secondly, on Windows 10 where we do not have to let a clock tick pass before we can use the increased resolution.

You will notice that _setTimer and _resetTimer are used inside the procedures, and wonder if their inclusion will 'upset the apple cart'. The '_setTimer/_resetTimer' as a pair only takes 4.3 microseconds on my machine to execute. This will add to the Sleep part of the delay, but will be compensated by the 'Timer polling' part of the delay. There is no effect on the accuracy. We need not be concerned where _setTimer or _resetTimer are used. The 1000Hz timer will be employed for only the Sleep duration.

So please do not use the following for anything apart from Windows 10/11.

Code: Select all

Declare Function _setTimer Lib "winmm" Alias "timeBeginPeriod"(As Ulong=1) As Long
Declare Function _resetTimer Lib "winmm" Alias "timeEndPeriod"(As Ulong=1) As Long
 
Sub delay(Byval t As Single)  '' delay 't' expressed in milliseconds
Dim As Double t1 = Timer
Dim As Double t2 = t1 + t / 1000
  _setTimer
  If t > 3 Then Sleep t - 3, 1
  _resetTimer
  Do : Loop Until Timer >= t2
End Sub
 
Function regulate(Byval MyFps As Long) As Double  '' return delay applied in milliseconds
Static As Double timervalue
Dim As Single tt = 1 / MyFps
Dim As Double tf = timervalue + tt
Dim As Double t = Timer
Dim As Single dt = (tt - (t - timervalue)) * 1000
  _setTimer
  If dt >= 3 Then Sleep dt - 3, 1
  _resetTimer
  Do : Loop Until Timer >= tf
  timerValue = Timer
  Return dt
End Function
 
Function framerate() As Ulong
Dim As Double t2 = Timer
Static As Double t1
Dim As Ulong dt = 1 / (t2 - t1)
  t1 = t2
  Return dt
End Function
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBasic's Timer

Post by dodicat »

Deltarho
I have been using my regulator for years, I see many others have used it.
With or without settimer.
Why should I take your advice and use something else.
Freebasic is a free spirited language where a person is perfectly entitled to create their own methods and use them.
Please refrain from telling me what to do or not to do, I would appreciate that.
If you have a hero then good and well. Myself, I have very few heroes, and I like it that way.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBasic's Timer

Post by deltarho[1859] »

@dodicat

Firstly, in hhr's post here we have “If I insert the section also into the program of BasicCoder2, both programs run again equally.”. hhr is comparing fxm's regulate and your regulate. I have no reason to question his conclusion.

Secondly, in my last post, I opened with: “If you intend to use fxm's delay() and/or regulate() in code to be published on the forum …”. If that intent is not true, then there is no point in reading any further. If that intent is not true, then they can use their own or yours.

fxm introduced his regulate procedure here and I have been playing with it ever since. At no point in this thread have I referred to your regulate, and therefore made no comparison.
Why should I take your advice and use something else.
Please refrain from telling me what to do or not to do, I would appreciate that.
WHAT?

I wish this was not the case, but the older I get, the easier I find it to read people. Your objections are secondary to the real reason which is upsetting you. Hell will freeze over before you give the real reason. I don't need you to tell me what that is – it is rather obvious, and I am sure may others will be reckoning the same.
If you have a hero then good and well.
WHAT? Strewth!

You were one of mine, but you sure as hell are not now.

In conclusion, I have to say: “F*****g grow up”.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBasic's Timer

Post by dodicat »

deltarho
I know you like Psychology, you have said it in the past.
But what do you mean by the real reason I am upset?
I just don't like being preached to.
I think that is the real reason, and I am not particularly upset anyway, only maybe because my monitor packed up and I am using an old thing now.
I'll stop all this stuff now, WE should not interrupt the flow of this thread anymore, there may be more ideas floating.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBasic's Timer

Post by deltarho[1859] »

dodicat wrote:I think that is the real reason
So, you are not certain? It was then a knee-jerk reaction. You need to consider why that happened. Being preached to is not the reason.

You should do what I do – compose offline. That gives you time to consider carefully what you are writing. It won't be the first time that I have felt myself boiling over – stopped composing and went back when I had cooled down.
I am not particularly upset anyway
The hell you weren't.
only maybe because my monitor packed up and I am using an old thing now.
Erm, right – I think.
I'll stop all this stuff now, WE should not interrupt the flow of this thread anymore, there may be more ideas floating.
Excellent idea.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBasic's Timer

Post by fxm »

fxm wrote: May 29, 2023 8:52 For those interested, I started writing the new documentation page:

The documentation page is now complete in its first version:
  • - ProPgDelayRegulate → fxm [new page 'Fine-grain procedure for waiting and in-loop procedure for regulating FPS']
    - ProPgAntiFlickering → fxm [added link to 'Fine-grain procedure for waiting and in-loop procedure for regulating FPS']
    - CatPgProgrammer → fxm [added link to 'Fine-grain procedure for waiting and in-loop procedure for regulating FPS']
    - PrintToc → fxm [added link to 'Fine-grain procedure for waiting and in-loop procedure for regulating FPS']
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBasic's Timer

Post by dodicat »

Thanks fxm.
Looks good.
I only have win 10 just now, so I am automatically on the windows resolution of 1 millisecond during the program.
That is OK I suppose, to keep the cpu load low.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBasic's Timer

Post by fxm »

@Jeff,

Can you tell me if the code below is safe (to change the default value of a procedure parameter during the program execution) ?
For my part, I would think it is !

Code: Select all

Sub test(Byval I As Integer) : Print I : End Sub
    
#undef test
Declare Sub test(Byval I As Integer = 1)
test()

#undef test
Declare Sub test(Byval I As Integer = 2)
test()

#undef test
Declare Sub test(Byval I As Integer = 3)
test()

Sleep
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: FreeBasic's Timer

Post by deltarho[1859] »

dodicat wrote:Thanks fxm.
Looks good.

Image

"You can fool some of the people all of the time, and all of the people some of the time, but you can not fool all of the people all of the time." Possibly Abraham Lincoln.

dodicat I have just put you on my ignore list.
hhr
Posts: 208
Joined: Nov 29, 2019 10:41

Re: FreeBasic's Timer

Post by hhr »

You shouldn't argue.
I suspect deltarho means something I've been annoyed about all along.
There is something here that you might call unfairness.
You could do better with questions and collaboration.
I made the following measurements:

Code: Select all

CPU Usage 'mouse and maze' original with speed = 60: 13% with "timeBeginPeriod" and stable, 1% without "timeBeginPeriod" and flickering.

CPU Usage 'mouse and maze' with fxm's regulator:

Without "timeBeginPeriod":
regulate(60,32): 50% and flickering
regulate(60, 3): 4% and flickering
regulate(60, 0): 4% and flickering

With "timeBeginPeriod":
regulate(60,32): 56% and stable
regulate(60, 3): 25% and stable
regulate(60, 0): 16% and stable
Both functions work about the same.
For CPU Usage, Dodicat's feature is the winner. So there is still work to be done.
By flickering I mean the mouse stumbles a bit, and that's the same in all cases.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBasic's Timer

Post by fxm »

On my PC, I never see any noticeable "flickering" whatever the configuration.
Post Reply