1. Controlling Speed

I'd like to throw my two cents in on the question of controlling a
program's speed. I'm using this method for a game, so that no matter how
fast the computer is the game executes at the same speed. The code is
shown below...

global atom delay_time
global atom last_time

last_time = 0
delay_time = .05

global procedure delay ( )
    while last_time + delay_time > time ( ) do
        -- nothing
    end while

    last_time = time ( )
end procedure

before running this you have to put a value into delay_time. This is the
maximum number of seconds that the delay() procedure will wait. If the
amount of time has already passed it doesn't wait at all, it just keeps
going.

In the example above I set last_time to zero (I think that is the only
logical choice) and delay_time to .05, or 1/20th of a second. If you put
a call to delay() in your main program loop you can insure that the
program only goes through the loop at most 20 times per second.

This code has some shortcomings, I know...
1) What happens when the internal Euphoria time() function has to reset
to 0. This would seem to kill my delay() procedure immediately. RDS: How
big a number can time() return?
2) This only works if the delay() procedure is imbedded into a main loop
that is executing constantly. It does not slow down a program unless it
is called relatively constantly.
3) Calling delay() just 1 time won't necessarily cause a delay. If
delay() is called milliseconds before last_time + delay_time will be >
time() then the procedure will not cause a noticeable pause.

For good measure, here is my generic pause routine...

global procedure wait ( atom seconds )
    atom t
    t = time()
    while ( t + seconds ) > time() do
        -- do nothing
    end while
end procedure

John.

new topic     » topic index » view message » categorize

2. Re: Controlling Speed

>This code has some shortcomings, I know...
>1) What happens when the internal Euphoria time() function has to reset
>to 0. This would seem to kill my delay() procedure immediately. RDS: How
>big a number can time() return?

I think it start at zero, when your start-up your computer.
It wouldnt be likely to reach zero. If would be simerlar to the Y2K problem,
however only fixable with new hardware.. (64 bit chips instead of 32 bit
would double its time scope)

But even then, I dont think you would be capable of running your computer
for that long.
At least not when you have windows running blink and if did occur, you would
be braking a record I think. (the longest up-time of win95 blink

Ralf

new topic     » goto parent     » topic index » view message » categorize

3. Re: Controlling Speed

>global atom delay_time
>global atom last_time
>
>last_time = 0
>delay_time = .05
>
>global procedure delay ( )
>    while last_time + delay_time > time ( ) do
>        -- nothing
>    end while
>
>    last_time = time ( )
>end procedure

I once had a delay procedure that used similar logic to this
it was more like:

global procedure delay ()
    atom t
    t = time ()
    while time () - t < .05 do end while
end procedure

or

global procedure delay (atom d) -- you can specify the
    atom t                      -- time to wait
    t = time ()
    while time () - t < d do end while
end procedure

Actually I think yours is more readable.
However one time, Robert Pilkington told me that the time would reset to
zero again at midnight so he suggested something like this: (but used
more variables with more discriptive names)

include machine.e
tick_rate (30)

procedure delay ()
    atom t
    t = time ()
    while time () = t do end while -- just checks to see if
end procedure             -- the time has changed any yet

this routine only delays for one clock tick but you can change the delay
with "tick_rate(x)" (bigger x is the shorter the delay) or you can call
delay n number of times in a forloop to achieve a desired pausse.

Assuming that I didn't make any errors in my coding all of these
routines should work. Can anyone tell me if Robert's way is the best?

I think someone made a delay routine that used a dos interupt timer.
Would this be even better?

Sincerely,

Lewis Townsend
|\   F""\       | | /""\
| \  |_  \  |\  | | \__
|  \ |    \ | \ | |    \
|   \L___  \|  \| | \__/
| |\ \
| | \ \    |""\ T==TT==7
| |  \ \   |   |   ||
| |___\ \  |__/    ||
|        \ |  \    ||
|_________\|   \   ||

______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com

new topic     » goto parent     » topic index » view message » categorize

4. Re: Controlling Speed

On Tue, 3 Nov 1998, John DeHope wrote:
> This code has some shortcomings, I know...

> 1) What happens when the internal Euphoria time() function has to reset
> to 0. This would seem to kill my delay() procedure immediately. RDS: How
> big a number can time() return?
How's this?

procedure delay()
  if time() < last_time then
    while MAXATOMSIZE - last_time + time() < delay_time do end while
  else
    while time() < last_time + delay_time do end while
  end if
  last_time = time()
end procedure

MAXATOMSIZE should be the largest value that time() returns.. which is
orobably, the largest positive atom.

> 2) This only works if the delay() procedure is imbedded into a main loop
> that is executing constantly. It does not slow down a program unless it
> is called relatively constantly.
But you only want slow down at certain times.. what you really want is a
contstant speed no matter how fast the processor is.. So I wouldn't
concider this a shortcoming.

> 3) Calling delay() just 1 time won't necessarily cause a delay. If
> delay() is called milliseconds before last_time + delay_time will be >
> time() then the procedure will not cause a noticeable pause.
>
Don't you want this?  Suppose you're writting a game and you want a
constant frame rate.  After computing the next frame you call delay, since
the time it took to compute the next frame varies, you want delay to fill
in the rest of the time.. creating a contant frame rate.

-Humberto Yeverino Jr.

"I kick ass for the Lord."
-Dead Alive (1992)

***********************************************************
Home Page:
  http://www.engr.csufresno.edu/~humberto/Home.html

Ti Page:
  http://www.engr.csufresno.edu/~humberto/tex.html

z80 Source Page:
  http://www.engr.csufresno.edu/~humberto/z80source.html

Official Tyrant Home Page:
  http://www.engr.csufresno.edu/~humberto/tyrant.html

E-mail:
  humberto at engr.csufresno.edu
***********************************************************

new topic     » goto parent     » topic index » view message » categorize

5. Re: Controlling Speed

>This code has some shortcomings, I know...
>1) What happens when the internal Euphoria time() function has to
>reset to 0. This would seem to kill my delay() procedure immediately.
RDS:
>How big a number can time() return?

I think it's 24 hours. I was running a screen saver I made using a delay
routine like yours, and it hung after about 24 hours. (It was hung when I
got back.)

>2) This only works if the delay() procedure is imbedded into a main
>loop that is executing constantly. It does not slow down a program
unless
>it is called relatively constantly.

Most delay routines are like that, so I don't consider it a shortcoming.
:)

>3) Calling delay() just 1 time won't necessarily cause a delay. If
>delay() is called milliseconds before last_time + delay_time will be >
>time() then the procedure will not cause a noticeable pause.

That's good for games: If the drawing/processing takes less than one
clock tick (about .05 seconds at the default 18.2 ticks/second), then the
framerate is set to 18 frames a second, just as long as the
drawing/processing takes place anywhere less. If it takes longer, the
game slows to half speed (or less, if the drawing/processing takes too
long.).

Here's my generic delay() routine: (Untested, written on the fly, but I
use it! blink

procedure tick_delay(integer ticks)
    atom oldtime

    for i = 1 to ticks do
        oldtime = time()
        while oldtime=time() do -- nothing
        end while
    end for
end procedure

tick_rate(30) -- include machine.e to get it. Sets framerate to 30, so
              -- tick_delay(1) will delay 1/30th a second, tick_delay(2)
              -- for 2/30th (1/15th), and so on. This line is optional,
of
              -- course, if you want 18 frames a second.


This way, even if the clock resets, oldtime will not equal time(), so the
loop will continue.


I think this is like the 3rd time I've mentioned this little routine...
:)
(One of them was to just one person, though.)

new topic     » goto parent     » topic index » view message » categorize

6. Re: Controlling Speed

John DeHope writes:
> 1) What happens when the internal Euphoria time() function
> has to reset to 0. This would seem to kill my delay()
> procedure immediately. RDS: How big a number can time() return?

Under DOS32, time() will reset after your program has been running
continuously for 24 hours (midnight is not a problem).
Under WIN32, it might be the same or better, I'm not sure.

Regards,
     Rob Craig
     Rapid Deployment Software
     http://members.aol.com/FilesEu/

new topic     » goto parent     » topic index » view message » categorize

7. Re: Controlling Speed

On Tue, 3 Nov 1998 12:54:08 -0500, John DeHope <jwap at TAMPABAY.RR.COM> wrote:

>I'd like to throw my two cents in on the question of controlling a
>program's speed. I'm using this method for a game, so that no matter how
>fast the computer is the game executes at the same speed. The code is
>shown below...
>
        <SNIP>
>
>This code has some shortcomings, I know...
>1) What happens when the internal Euphoria time() function has to reset
>to 0. This would seem to kill my delay() procedure immediately. RDS: How
>big a number can time() return?

My understanding for quite sometime was that the time() reset after 24
hours.  I originally believed it to be at midnight.  Midnight or not
it appears 24 hours is your limit.  My most secure method and most
accurate method of time delay follows only as description of how to
build it.  I have done this a few times and prefer it when worried
about reliablilty and accuracy.  Sometimes you want a delay much less
than .05 or sometimes less than .01.  This can be accomplished assuming
the speed of your computer.

First you must sample the computers speed.  This is done only once.
It is done when the program first starts.  To do this you time a loop.
Two methods of timing a loop exist.
Method 1:
    t = time()
    for A = 1 to large_number do
    end for
    t = time() - t
result is "t" seconds per "large_number" counts

    Pro: This method is personally believed to be very accurate.
    Con: This method can tie up a slow computer for what appears
         as an eternity.
Method 2:
    counts = 0
    t = time() + 30-- 30 second delay  Could be less.
    while t > time() do
      counts = counts + 1
    end while
result is "counts" per "t" 30 seconds or whatever your delay was.
    Pro: Guaranteed not to tie up the computer more than 30 seconds.
    Con: Assumed to be SLIGHTLY less accurate.

What you do with this timing is quite simple.
If you used method 1 then you now know that.
  for a = 1 to large_number
  end for
will pause for "t" seconds.
If you used method 2 you now know that.
  for a = 1 to counts do
  end for
will pause for 30 seconds.
In method to if you want to pause for one second you simply use
  for a = 1 to counts/30 do
  end for

I hope this is now Clear as mud.  You can use seperate time sampling
to determine how long you want to delay so as to achieve a consistent
frame rate.

>2) This only works if the delay() procedure is imbedded into a main loop
>that is executing constantly. It does not slow down a program unless it
>is called relatively constantly.

This is common and understood.

        <SNIP>
>
>John.

_________________________

Lucius L. Hilley III    lhilley at cdc.net
http://www.cdc.net/~lhilley
http://www.americanantiques.com
http://www.dragonvet.com
_________________________

new topic     » goto parent     » topic index » view message » categorize

8. Re: Controlling Speed

Lucius wrote:
>What you do with this timing is quite simple.
>If you used method 1 then you now know that.
>  for a = 1 to large_number
>  end for
>will pause for "t" seconds.

True

>If you used method 2 you now know that.
>  for a = 1 to counts do
>  end for
>will pause for 30 seconds.

Completely False. (sorry, Lucius blink

a = 0
while a < counts do
    a = a + 1
end while

will pause for the predefined time (30 seconds in your example)

For loops are much faster, and when they only contain one or no statements
at all they are extremely optimized, your 'pause' will be way off using for.

Other than that, your methods here are as I see it to be of the best result,
especially because you can restore a normal healthy type rate, after timing
the speed of the system. However, with all these multi-tasking and
semi-multitasking operation systems like Windhoos, etc. I fear, you should
at least keep re-checking the speed until you have almost exactly the same
result repeated a number of times. Re-checking your speed, once every so
often (when the user pauses the game/program/whatever) wouldnt hurt either..

Ralf

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu