Timed Delay
Moderators:Administrator, Global Moderator
For the past several months (about 13) I have been working on this game.... For the moment I am using a for loop to do the delay, but need a delay that is independent of the CPU speed (as most people have faster then my 300 Mhz K6) I have been looking threw my old ASM books and have been unable to find the delay that I am capable of using with my limited ASM knowledge.... So what I need is a routine that I can use in Qbasic 5.4 or 7.1 that does not require a liburary.
- frankiebaby
- Global Moderator
- Posts:95
- Joined:Tue Apr 30, 2002 1:38 am
- Location:Pennsylvania
- Contact:
Re: Timed Delay
how little or how large a delay are you looking for? For a delay of a tenth a sec, just use a TIMER based delay, im sure you probly know this, so I figure your going for a shorter delay. otherwise,
T! = TIMER
do: loop until TIMER != T
maybe
do: loop until TIMER 'could slow it down?
You can wait for the horizontal retrace, which can eliminate flicker on most of the screen, but it causes flicker at the top. Thats a very short delay. I have used a loop that calculates the frame rate, and increases the amount of times to wait for the vertical retrace to keep the framerate at about 60. some flicker though, but it works.
T! = TIMER
do: loop until TIMER != T
maybe
do: loop until TIMER 'could slow it down?
You can wait for the horizontal retrace, which can eliminate flicker on most of the screen, but it causes flicker at the top. Thats a very short delay. I have used a loop that calculates the frame rate, and increases the amount of times to wait for the vertical retrace to keep the framerate at about 60. some flicker though, but it works.
Re: Timed Delay
Acualy, no. I thought that TIMER would only calculate the number of seconds (full seconds) past midnight. I have seen in help that there is a such thing as TIMER ON and other such functions, but after experimenting with them, I have failed to find out how to use the functions... don't mean to sound like an idiot, but could you explain to me how to use them?
I don't think I need anything smaller then tenths of a second, so that should not be a problem.
Thanks
I don't think I need anything smaller then tenths of a second, so that should not be a problem.
Thanks
-
- Full Member
- Posts:36
- Joined:Tue Mar 18, 2003 3:04 am
- Location:Lancashire, UK
- Contact:
Re: Timed Delay
ON TIMER (n) GOSUB statement sets a delay of n seconds (whole seconds only) and after that delay branches to the subroutine. Once you've set the delay (has to be in the same module of the program as the subroutine not a separate module) TIMER ON starts the timer, TIMER OFF stops it.
The program branches to the subroutine every n seconds until you stop it (so you could use it for a clock display, with ON TIMER (1) GOSUB seconds to update a seconds display every one second. Unfortunately, you can't have smaller increments and it's not very accurate as it depends on your pc's internal clock which doesn't work in integers. I'm not sure it would necessarily do what you want for your program unless you wanted to run a short delay every second or so - that might make things a BIT jerky!
The TIMER device function does return the number of seconds since midnight/since boot, as you state. This example program times a delay of 5 seconds and then moves on:
WaitTime!=5 :'(length of pause time in seconds)
StartTime!=TIMER: 'store starting time
beep
WHILE (TIMER-StartTime!)<WaitTime!
WEND:'loop for WaitTime! seconds
beep
program continues......
This may work with shorter delays if you don't use integers and possibly with the code provided by Frankiebaby (which is effectivvely the same I think although a different approach).
Another way may be to program a sound so high it can't be heard and which lasts a certain length of time.
The program branches to the subroutine every n seconds until you stop it (so you could use it for a clock display, with ON TIMER (1) GOSUB seconds to update a seconds display every one second. Unfortunately, you can't have smaller increments and it's not very accurate as it depends on your pc's internal clock which doesn't work in integers. I'm not sure it would necessarily do what you want for your program unless you wanted to run a short delay every second or so - that might make things a BIT jerky!
The TIMER device function does return the number of seconds since midnight/since boot, as you state. This example program times a delay of 5 seconds and then moves on:
WaitTime!=5 :'(length of pause time in seconds)
StartTime!=TIMER: 'store starting time
beep
WHILE (TIMER-StartTime!)<WaitTime!
WEND:'loop for WaitTime! seconds
beep
program continues......
This may work with shorter delays if you don't use integers and possibly with the code provided by Frankiebaby (which is effectivvely the same I think although a different approach).
Another way may be to program a sound so high it can't be heard and which lasts a certain length of time.
- frankiebaby
- Global Moderator
- Posts:95
- Joined:Tue Apr 30, 2002 1:38 am
- Location:Pennsylvania
- Contact:
Re: Timed Delay
yes, thats a good idea. I dont beleive that TIMER ON is what you want to use. A TIMER based delay is probly all ya need. As far as using the SOUND statement, it used to work great, but now most newer computers do NOT stop when a system speaker sound is being made.
I'll try to rephrase the ANSWER
The TIMER function is what you need for what you want to do.
Walk with me please...for the sake of argument I'll use low numbers so that you can grasp what is happening.
-------------
Say TIMER = 100 to start and increments by 10 each time the computer checks the time.
EndTime = TIMER (which is 100) + 40
(now EndTime = 140 but TIMER still =100)
#1) DO WHILE TIMER (still 100) < EndTime (still 140)
#1) LOOP (goes back to DO above...but TIMER has increased! see next section)
#2) DO WHILE TIMER (now 110) < EndTime (still 140)
#2) LOOP (goes back to DO above, theres no code in between so there is nothing to do but go back to DO above...again TIMER has increased!)
#3) DO WHILE TIMER (now 120) < EndTime (still 140)
#3) LOOP (goes back to DO above cause 120 is less than 140...again TIMER has increased!)
#4) DO WHILE TIMER (now 130) < EndTime (still 140)
#4) LOOP (goes back to DO above...getting the picture? there's no code, nothing to process, only thing this DO/LOOP does is check the number of seconds in TIMER and compares it to EndTime to find out if it should terminate the loop. And 130 is less than 140, so it checks again...see next section)
#5) DO WHILE TIMER (look!! 140) < EndTime (is 140)
#5) LOOP (well TIMER is NOT LESS THAN EndTime. TIMER is equal to or greater than EndTime so therefore let's get out of the loop and continue with the program)
-------------
here try this visual experiment:
-------------
CLS
PRINT "This "; : SLEEP 1
PRINT "prints "; : SLEEP 1
PRINT "one "; : SLEEP 1
PRINT "word "; : SLEEP 1
PRINT "per "; : SLEEP 1
PRINT "second!"; : SLEEP 1
PRINT
PRINT
PRINT "This "; : GOSUB Delay
PRINT "prints "; : GOSUB Delay
PRINT "one "; : GOSUB Delay
PRINT "word "; : GOSUB Delay
PRINT "per "; : GOSUB Delay
PRINT "half "; : GOSUB Delay
PRINT "second!"; : GOSUB Delay
PRINT
PRINT
PRINT "This "; : GOSUB QDelay
PRINT "prints "; : GOSUB QDelay
PRINT "one "; : GOSUB QDelay
PRINT "word "; : GOSUB QDelay
PRINT "per "; : GOSUB QDelay
PRINT "quarter "; : GOSUB QDelay
PRINT "second!"; : GOSUB QDelay
END
Delay:
MyDelay = TIMER + .5
DO WHILE TIMER < MyDelay
LOOP
RETURN
QDelay:
MyDelay = TIMER + .25
DO WHILE TIMER < MyDelay
LOOP
RETURN
-------------
Hope this helps.
--MiggyD
Walk with me please...for the sake of argument I'll use low numbers so that you can grasp what is happening.
-------------
Say TIMER = 100 to start and increments by 10 each time the computer checks the time.
EndTime = TIMER (which is 100) + 40
(now EndTime = 140 but TIMER still =100)
#1) DO WHILE TIMER (still 100) < EndTime (still 140)
#1) LOOP (goes back to DO above...but TIMER has increased! see next section)
#2) DO WHILE TIMER (now 110) < EndTime (still 140)
#2) LOOP (goes back to DO above, theres no code in between so there is nothing to do but go back to DO above...again TIMER has increased!)
#3) DO WHILE TIMER (now 120) < EndTime (still 140)
#3) LOOP (goes back to DO above cause 120 is less than 140...again TIMER has increased!)
#4) DO WHILE TIMER (now 130) < EndTime (still 140)
#4) LOOP (goes back to DO above...getting the picture? there's no code, nothing to process, only thing this DO/LOOP does is check the number of seconds in TIMER and compares it to EndTime to find out if it should terminate the loop. And 130 is less than 140, so it checks again...see next section)
#5) DO WHILE TIMER (look!! 140) < EndTime (is 140)
#5) LOOP (well TIMER is NOT LESS THAN EndTime. TIMER is equal to or greater than EndTime so therefore let's get out of the loop and continue with the program)
-------------
here try this visual experiment:
-------------
CLS
PRINT "This "; : SLEEP 1
PRINT "prints "; : SLEEP 1
PRINT "one "; : SLEEP 1
PRINT "word "; : SLEEP 1
PRINT "per "; : SLEEP 1
PRINT "second!"; : SLEEP 1
PRINT "This "; : GOSUB Delay
PRINT "prints "; : GOSUB Delay
PRINT "one "; : GOSUB Delay
PRINT "word "; : GOSUB Delay
PRINT "per "; : GOSUB Delay
PRINT "half "; : GOSUB Delay
PRINT "second!"; : GOSUB Delay
PRINT "This "; : GOSUB QDelay
PRINT "prints "; : GOSUB QDelay
PRINT "one "; : GOSUB QDelay
PRINT "word "; : GOSUB QDelay
PRINT "per "; : GOSUB QDelay
PRINT "quarter "; : GOSUB QDelay
PRINT "second!"; : GOSUB QDelay
END
Delay:
MyDelay = TIMER + .5
DO WHILE TIMER < MyDelay
LOOP
RETURN
QDelay:
MyDelay = TIMER + .25
DO WHILE TIMER < MyDelay
LOOP
RETURN
-------------
Hope this helps.
--MiggyD
Re: Timed Delay
that won't work becuse TIMER is only updated every full second so your little TIMER +.5 wont work.... mabey you should not mock people. 'cuase you are pretty dumb. (making fun of the last kid who responded with the lengthy and pointless code).
No. I need to make the delay less then a full second. The delay is going to manage a lot of graphics and AI movement statements and they must be seperated by less then a second (preferable 1/100 or less, but 1/10 will sufice.)
No. I need to make the delay less then a full second. The delay is going to manage a lot of graphics and AI movement statements and they must be seperated by less then a second (preferable 1/100 or less, but 1/10 will sufice.)
What QB are you using?
So sorry. I thought you wanted help in understanding what is going on with TIMER and why you SHOULD USE IT for your graphics delay.
But, I would like to respond to some of your statements:
"that won't work becuse TIMER is only updated every full second so your little TIMER +.5 wont work"
Are you sure about that? The Sleep function is the one that is updated every full second; not TIMER. Try the following test code I just whipped up:
StartTimer = TIMER
DO
PRINT TIMER
LOOP UNTIL TIMER >= StartTimer + .12
PRINT TIMER;
EndTimer = TIMER
PRINT
PRINT "StartTimer:", "EndTimer:"
PRINT StartTimer, EndTimer
PRINT STR$(40,"-"): PRINT
StartTimer = TIMER
sleep .5 'note: Fractions are rounded off for SLEEP
PRINT TIMER;
EndTimer = TIMER
PRINT
PRINT "StartTimer:", "EndTimer:"
PRINT StartTimer, EndTimer
END
Let us know what you got (start/end times) after you test it.
"mabey you should not mock people. 'cuase you are pretty dumb. (making fun of the last kid who responded with the lengthy and pointless code). "
I didn't mock anyone. If you read it again, you'll notice that I was trying to help you understand (step by step). If you believe that is mocking then so-be-it.
I don't believe that you can judge me to be dumb, only my wife can. Have you known me for the 17 years that I have been programming? No, don't think so.
If you truely believe I was "making fun of the last kid", you are sadly mistaken in your judgement. If my pseudo-code is pointless to you, it may not be for another person who's just started QB for their first time and want to know the processes and sequence of events that are happening and why they happen.
"they must be seperated by less then a second (preferable 1/100 or less, but 1/10 will sufice.) "
Try the code above to see what if it'll work for you or not. If it doesn't then I don't know of any other way using QB, other than writing asembly code. But, if it does then I'm glad you solved your problem and hope you remember this function for the next time you need it. And by the way, I hope you have a nice day.
--MiggyD
But, I would like to respond to some of your statements:
"that won't work becuse TIMER is only updated every full second so your little TIMER +.5 wont work"
Are you sure about that? The Sleep function is the one that is updated every full second; not TIMER. Try the following test code I just whipped up:
StartTimer = TIMER
DO
PRINT TIMER
LOOP UNTIL TIMER >= StartTimer + .12
PRINT TIMER;
EndTimer = TIMER
PRINT "StartTimer:", "EndTimer:"
PRINT StartTimer, EndTimer
PRINT STR$(40,"-"): PRINT
StartTimer = TIMER
sleep .5 'note: Fractions are rounded off for SLEEP
PRINT TIMER;
EndTimer = TIMER
PRINT "StartTimer:", "EndTimer:"
PRINT StartTimer, EndTimer
END
Let us know what you got (start/end times) after you test it.
"mabey you should not mock people. 'cuase you are pretty dumb. (making fun of the last kid who responded with the lengthy and pointless code). "
I didn't mock anyone. If you read it again, you'll notice that I was trying to help you understand (step by step). If you believe that is mocking then so-be-it.
I don't believe that you can judge me to be dumb, only my wife can. Have you known me for the 17 years that I have been programming? No, don't think so.
If you truely believe I was "making fun of the last kid", you are sadly mistaken in your judgement. If my pseudo-code is pointless to you, it may not be for another person who's just started QB for their first time and want to know the processes and sequence of events that are happening and why they happen.
"they must be seperated by less then a second (preferable 1/100 or less, but 1/10 will sufice.) "
Try the code above to see what if it'll work for you or not. If it doesn't then I don't know of any other way using QB, other than writing asembly code. But, if it does then I'm glad you solved your problem and hope you remember this function for the next time you need it. And by the way, I hope you have a nice day.
--MiggyD
- crossroads
- Administrator
- Posts:34
- Joined:Wed Feb 13, 2002 10:15 pm
- Location:Germany
- Contact:
Re: Timed Delay
This is what Jehovah wrote as a new topic while QBCafe's Forum was in Maintenance Mode:
This program would not let me add replies to the topic "Timed Delay" so I have made this topic to place a formal apology to MiggyD (I think that was the name). I did, in fact, find what you said as mocking and insulting, but that matters no more. You are correct in that the TIMER statment is NOT updated every full second and that after commenting out one of your print statments on you code, it worked.
To answer your question, I am using qb 7.1.
Thanks for the help, and sorry that I did not listen to you and called you dumb. I only said this because of how you stated your reply. This is also why I did not even try your code before replying to it.
crossroads (QBCafe Forum Admin)
I apologize as well
Jehovah,
I've re-read my original posting and you are right. It may sound a little condescending but that was not my intension. So I apologize for any ill-will you may have felt from it.
I am glad, however, that you were able to resolve your situation and hope to offer future advice in your endevours.
--MiggyD
I've re-read my original posting and you are right. It may sound a little condescending but that was not my intension. So I apologize for any ill-will you may have felt from it.
I am glad, however, that you were able to resolve your situation and hope to offer future advice in your endevours.
--MiggyD