From: dmb@wam.umd.edu (David M. Baggett)
Subject: Re: Is page flipping safe, and I need to know about syncing
Organization: University of Maryland, College Park
Date: Thu, 23 Jul 1992 18:46:57 GMT

chu@acsu.buffalo.edu (John C. Chu) writes:
>Is it ok to use Setscreen to do double buffered animation (i.e., draw
>on one buffer while the other is being displayed and switch.

The Setscreen and Vsync (X)Bios calls work fine for double buffering
(aka "page flipping").  There are some subtleties but for most
practical purposes you'll get good results using these calls and your
code will work with all versions of TOS (including, in theory, those
that are forthcoming).  You want to call Setscreen first and then
Vsync.  It doesn't work to call Vsync and then Setscreen.  Read the
Setscreen docs for an explanation of why.

Video cards that have drivers that steal the (X)bios calls should
also work.  I don't know how this translates in the real world though,
since I don't have a special video card.

>Also, a little while back, someone (Dave Baggett??) was talking about
>how one should sync one's game to update the screen every n vblanks
>(where n depends on how much is happening in the program), which will
>among other things, insure that the game plays at the same speed
>across variants of ST-type computers. Unfortunately, I wasn't paying
>attention at the time. How do I do this?

The scenario: You write a game with sprites, sampled sounds, and maybe
a scrolling window.  Chances are your game isn't going to complete
all of its processing for each "game turn" within 1/60th of second on
a stock 8Mhz ST.  This means that it will take 2 or more vertical
retrace periods to update the screen.  This isn't a problem in terms
of smoothness; most commercial games run at 2, 3, or 4 vertical
retraces per game turn and they look fine.

The problem: when you run your game on a faster machine (e.g., a Dave
Small 50Mhz accelerated '030 ST) your game might actually do all its
work within a single vertical retrace period (or at least in fewer
retrace periods than it would on a stock ST).  The result is that
your game runs way too fast.

The solution:

Instead of syncing to every single vertical blank, write a short
routine that checks the frclock system global and doesn't return
until at least n vertical blanks have passed.  That way if you're
running on a 100 MIPS supercharged ST your game will finish all its
processing for a particular game turn in the blink of an eye and then
just sit there waiting until the given number of vblanks have passed.
If it seems criminal to waste so many cycles I suppose you could
use the extra time to make the enemies more intelligent if you
were careful about it.  Or compute primes, for that matter.  :)

You need to tune your game to the minimum number of vertical retrace
periods that the slowest supported machine requires to complete all the
processing for a game turn.  You can do this scientifically by keeping
track of how many vertical blanks are happening per game turn on
average at the most "busy" point in the game, or you can just play it
by ear and pick a high value (6, for example) and then bump it down
stepwise until you see no difference in gameplay from one step to the
next.

A concrete example:  HacMan II uses the value 4 here, largely because
the ghosts' "thinking" algorithms are quite slow (relative to the
drawing speeds, at least).  I think Blox runs with 3 vsyncs per game
turn.  In the case of Blox the 11kHz samples slow down a stock ST quite
a bit.  But even if you use DMA stereo sound (which requires no CPU
cycles) the game will still run 3 vsyncs per game turn; hence game play
is totally unaffected by either your choice of CPU or sound D/A device.

The frclock system global is documented by Atari and guaranteed not to
change, so you should be safe using it.

Dave Baggett
dmb@wam.umd.edu
Newsgroups: comp.sys.atari.st.tech