[comp.sys.atari.st] Animation Topics

dmb@TIS.COM (David M. Baggett) (09/10/88)

   There has been a bit of talk about animation here lately; here's my
two cent's worth:

Sprite Speed Limit
------------------
   Robert White asked about the time it takes to smoothly move a sprite
across the screen.
   Since the vertical refresh only occurs every 1/60th of a second, it will
indeeed take about 6 seconds for a sprite to move across the screen if you
move it one pixel per page flip.
   However, moving the sprite more pixels per refresh does not change the
smoothness of the animation as much as you might think.  The sprites in 
HacMan (a public domain game available at an archive near you :-) ) move
between 2 and 8 pixels per page flip.  The animation doesn't appear
jerky until about 5 pixels per page flip (Board 19, "Chris Vs. HacMan", has
the sprites moving at 4 pixels per page flip).
   Also, the page flips in HacMan do not even occur every 60th of a second;
they occur every 30th of a second (the program misses every other vblank),
and the animation is still satisfactory.
   The blurring effect you get when you move a sprite, say, 2 pixels every
60th of second is not flicker, it's strobing.  It's just that the new image
appears before the old image has completely faded from the screen.  This is
really obvious on IBM monochrome monitors, but only slightly evident on
the ST RGB monitor.

Implementing the Page Flipping
------------------------------
   It is true that you can change the screen pointer "by hand" by changing
a location in page 4.  Unfortunately this doesn't produce very nice
results (Setscreen works better than any hack I've seen).
   Setscreen doesn't cause any delay at all.  The call returns immediately.
However, if you change the physical screen base with Setscreen, the change
won't _take effect_ until the next vertical blank.  In other words, the
code to actually set the physcial screen base is in the vertical blank
interrupt code (along with code to set the palette and the "media changed"
flag code, etc.)  Thus, two succesive calls to Setscreen will frequently
only have the effect of the last call (unless a vertical blank happens to
occur between them).
   So, you have to explcitly wait for the vertical blank after you call
Setscreen to be sure that the new physical base got set.  E.g., 

	Setscreen((char *) -1L, (char *) new_phys_base, -1);
	Vsync();

   Anyone interested in animation should check out the Animatic demo in
the archives!  (Sorry, I just couldn't resist the temptation to 
advertise) :-)

			Hope this is useful...
			Dave

leo@philmds.UUCP (Leo de Wit) (09/14/88)

In article <8809100453.AA01878@TIS.COM> dmb@TIS.COM (David M. Baggett) writes:
    [much good stuff deleted...]
>   It is true that you can change the screen pointer "by hand" by changing
>a location in page 4.  Unfortunately this doesn't produce very nice
>results (Setscreen works better than any hack I've seen).
>   Setscreen doesn't cause any delay at all.  The call returns immediately.

Yes, unless it also sets the resolution; then it will wait for a VBL.

>However, if you change the physical screen base with Setscreen, the change
>won't _take effect_ until the next vertical blank.  In other words, the

No. The physical screen base *IS* set immediately by Setscreen (by storing
values at 0xff????), as is the logical screen. If you want to have the
phys. screen address changed whilst in the VBL you have to set a long in
the system variables (not the logical base, of course), because the code to
set the physical screen is there (like you said). Or add a VBL routine
that does something similar (not very productive).

I don't know what the official documentation says about the subject, but
both the RAM TOS and the old ROMs behave in the manner I just described.
I quote myself (part of an article, I believe even the same subject).

------------------------------ S t a r t s   h e r e -------------------------
I've got a copy of the book '3D Grafik Programmierung' from Data Becker.
It suggests that SETSCREEN swaps at vbl time. ***THIS IS NOT TRUE!!!***
(maybe you got the same impression). SETSCREEN does not wait for vbl
to set the screen(s); only if you also change the resolution it will wait
for vbl.
There's another 'know-it' about vbl:
You *CAN* set the screen at vbl time; this however sets logical and
physical screen to the same value (not suitable for your application).
The way to do this is: enter the new screen base into the system
variable screenpt ($45e).  At vbl time the screens will be set then (I
think you have to refill it with 0 to avoid having it set all the
time).
------------------------------ E n d s       h e r e -------------------------

If you want to use the vbl screen change, the way to go seems:
    1) set screenpt to your new screen value.
    2) wait for a vertical blank (either by the XBIOS call or by checking
       for instance the logical base pointer against the new screen value).
    3) enter 0 into screenpt to avoid having screens set at the next vbl.
    4) set the logical base pointer to the correct value (it has been
       changed by the vbl).

         Leo.

peter@sugar.uu.net (Peter da Silva) (09/18/88)

In article <8809100453.AA01878@TIS.COM>, dmb@TIS.COM (David M. Baggett) writes:
> 	Setscreen((char *) -1L, (char *) new_phys_base, -1);
> 	Vsync();

I'm not particularly familiar with the ST, but since SetScreen is asynchronous,
the following code (based on Amiga code) should work better:

	Generate animation in newscreen;
	Vsync();	/* wait for previous SetScreen (of oldscreen) to work */
	SetScreen(newscreen);
	Go back to generate next screen.

This way you get to do computations while waiting for SetScreen, and there's
always a screen out there waiting to show up.
-- 
		Peter da Silva  `-_-'  peter@sugar.uu.net
		 Have you hugged  U  your wolf today?