In article <9817@uqcspe.cs.uq.oz.au>, warwick@cs.uq.oz.au (Warwick Allison) writes:
|> 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();
|> }
This is fine. but is a previous post you mentioned that sprites could be updated
at different speeds which made me think you were using some arbitrary interleaving
of draws & wipes.
|> >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.
Maybe, maybe not - it depends on your sprite drawing method. The code I originally
posted only read the screen implicity with
or.w d0,(a0)+
type instructions. Now if you do it explicity you need an extra 4cy (canceling out any saving combining your save under code) and you need and an extra reg
which could slow down the rest of your code.
BTW the code I posted is (slightly) faster than the 32x32 sprite code in
your GNUchess port even under the most pessimistic assumptions (you did a great
job on the port though...).
|> 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...
No, it was just a sugestion for a better competition goal than the rather
pointless TOS hacking in Nat!'s competion.
60 sprites at 50Hz is quite amazing on a non-blitter ST. At 25Hz rather less so.
Still I can't resist the challenge...
Steven
* One plane 16x16 sprites (draw code only)
*
* Entry:
* a0 pointer to sprite
* a1 pointer to where to draw it
* d7 shift (0 - 15)
*
moveq #4,d6 ; (4+1)*3+1 = 16 lines
loop:
moveq #0,d0
moveq #0,d1
moveq #0,d2
moveq #0,d3
moveq #0,d4
moveq #0,d5
movem.w (a0)+,d0-d5 ; get three lines of mask & sprite
ror.l d7,d0 ; rotate mask
and.w (a1),d0 ; combine with bgnd
ror.l d7,d1 ; rotate sprite
or.w d1,d0 ; combine
move.w d0,(a1) ; replace
addq.w #8,a1 ; next word
swap d0 ; low part of mask
and.w (a1),d0 ; combine with bgnd
swap d1 ; low part of sprite
or.w d1,d0 ; combine
move.w d0,(a1) ; replace
lea 152(a1),a1 ; next line
ror.l d7,d2 ; rotate mask
and.w (a1),d2 ; combine with bgnd
ror.l d7,d3 ; rotate sprite
or.w d3,d2 ; combine
move.w d2,(a1) ; replace
addq.w #8,a1 ; next word
swap d2 ; low part of mask
and.w (a1),d2 ; combine with bgnd
swap d3 ; low part of sprite
or.w d3,d2 ; combine
move.w d2,(a1) ; replace
lea 152(a1),a1 ; next line
ror.l d7,d4 ; rotate mask
and.w (a1),d4 ; combine with bgnd
ror.l d7,d5 ; rotate sprite
or.w d5,d4 ; combine
move.w d4,(a1) ; replace
addq.w #8,a1 ; next word
swap d4 ; low part of mask
and.w (a1),d4 ; combine with bgnd
swap d5 ; low part of sprite
or.w d5,d4 ; combine
move.w d4,(a1) ; replace
lea 152(a1),a1 ; next line
dbra d6,loop
moveq #0,d0
moveq #0,d1
ror.l d7,d0 ; rotate mask
and.w (a1),d0 ; combine with bgnd
ror.l d7,d1 ; rotate sprite
or.w d1,d0 ; combine
move.w d0,(a1) ; replace
addq.w #8,a1 ; next word
swap d0 ; low part of mask
and.w (a1),d0 ; combine with bgnd
swap d1 ; low part of sprite
or.w d1,d0 ; combine
move.w d0,(a1) ; replace
Come to think of it, if the sprites are only one pixel deep why not preshift