From: warwick@cs.uq.oz.au (Warwick Allison)
Newsgroups: comp.sys.atari.st.tech
Subject: Re: Sprite code (Re: Second&last time: Hacking Contest)
Date: 14 Aug 92 04:14:22 GMT
Reply-To: warwick@cs.uq.oz.au

eker@loria.crin.fr (Steven Eker) writes:
>warwick@cs.uq.oz.au (Warwick Allison) writes:

>>>Yuk! There are several good ways to handle the background. Saving on a sprite
>>>by sprite basis, interleaved with drawing the sprites is not one of them.
>> 
>> Well, IMO, it IS the best method, for these reasons:
>> 
>> 	1. Encapsulated (don't need some GLOBAL background map)
>> 	2. Allows for different update frequencies of different sprites
>> 	3. Memory efficient
>> 	4. Fast

>The real problem with this method is when sprites overlap - then doing
>the right thing gets complicated & slow.

Complicated?  All you do is push them onto a stack when you draw then,
and pull them off to get the wiping order.  Usually, it is sufficient
to just do it with code, rather than doing it dynamically:

    while (1) {
	Sprite1.Wipe();
	Sprite2.Wipe();
	Sprite3.Wipe();

	Sprite3.Draw();
	Sprite2.Draw();
	Sprite1.Draw();

	Pages->Flip();
    }

>If you aren't replacing the
>background thru the (possibly) shifted mask (which is slower) the
>sprites don't even have to overlap - just the 32x32 (or whatever)
>rectangles.  

I can't believe anyone would ever consider replacing the background
through a shifted mask!

>|> 	2. Keeping global background
>|> 		- This one is too dependent on the application to
>|> 		  be viable as a general scheme.  For example, it
>|> 		  works okay for a static background, but once you
>|> 		  start animating the background, your CPU-load
>|> 		  massively increases as you keep having to update
>|> 		  both the display images and the backgrouind store.

>I believe STOS does this. If you have lots of sprites and comparatively little
>background movement then this can win.

I believe STOS is a slow, hacky pile of sh!t...  Have you seen some of the
programs written with it - ewww, chunky-slow to the max!

>How about:
>	4. Wipe all sprites, Save under new positions, draw all sprites etc.

This is exactly my #1 method, except mine is encapsulated.

You are saying:
	for each sprite 1..n { sprite.Wipe }
	for each sprite 1..n { sprite.SaveUnder }
	for each sprite 1..n { sprite.Draw }

I am saying:
	for each sprite 1..n { sprite.Wipe }
	for each sprite n..1 { sprite.DrawAndSaveUnder }

My method is superior, simply because I get the sprite.SaveUnder almost
for free:  YOU ALREADY HAVE TO READ THE SCREEN IN ORDER TO DRAW THE SPRITE,
so you may as well store that read data as you draw, saves reading twice.

>		Okay you need to double (better still triple) buffer to avoid
>		flicker but its fast & you can decide on sprite priorities
>		& handle overlapping sprites correctly.

Obviously you have to double buffer.  Any program that doesn't double-buffer
is a hack.  (BIG smily!! -- Even Shift doesn't double-buffer - but I love it)

>IMHO the best way the handle background is dependant on the number of
>sprites & the nature of the background. For this reason I prefer the
>keep the "save under" code separate from the "draw sprite" code so one
>can choose whether & when to use it.

While I prefer to write code that works well in the general case :-)

>Do you have seperate code for each "partly off the edge of screen"
>case (actually you only have to worry about the left & right edges)?
>That must multiply up to quite a bit of asm.  

Haven't had any need for a ClippedColourSprite yet.  When I do, it will
only be a small matter of coding up the one sized clipped version.

Which reminds me - was this a competition?  I wrote some VERY fast 
sprite routines in a furious discussion with Dave B. - 60 or so
single-bitplane 16x16 sprites at arbitrary positions on an arbitrary
background was I believe my limit...



--
Warwick
--
  _-_|\      warwick@cs.uq.oz.au            /Disclaimer:
 /     * <-- Computer Science Department,  /  
 \_.-._/     University of Queensland,    /      void (if removed)
      v      Brisbane, Australia.        /