It is currently Thu Dec 14, 2017 10:20 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: 8+ sprites on a scanline
PostPosted: Fri Aug 05, 2005 11:26 am 
I just started suffering from the more than 8 sprites per scanline. I've heard about various techniques but haven't seen any code examples. If anybody has any ideas that have worked to reduce the effect let me know. So far I thought of periodically exchanging some of the Sprite Y positions with the bottom (NTSC invisible) line. I'd have to think of an optimum way of picking a subset of the Sprites to exchange and then cycle through all the Sprites in some way so that at any time a different subset was on the bottom line. This would still flicker but not as noticeably. Is this what is called OAM cycling? I guess the remedy would only have to be on if the "8 Sprite per scanline bit" was set. By the way, when is this bit cleared? Thanks for any help to a newbie.


Top
  
 
 Post subject:
PostPosted: Fri Aug 05, 2005 12:13 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
This bit is cleared every VBlank, but it's not a very reliable method, because I've heard it's not always set when more than 8 sprites are detected on a scanline.
A good method I've found to ensure OAM cycling : While write to the OAM buffer, instead of advancing the index by 4, you have to advance of any number divisible per 4, but not per 8 (so 4, 12, 20, 28, etc...). So you'll also have the whole 64 sprites array to your disposition, but it'll never be set in the same order. Another advantage of this is that, scince you're starting to draw the first sprite with an index of zero, you'll always have the first sprite assigned to sprite zero, and this is usefull to do sprite zero hit, or to have a sprite that has always higher priority than others (for example when your player has multiple sprite-layers to have more colors on him).
The simple way to do that is simply to initialise your variable by a value of 4, then adding or substracting 8 to/from it every VBlank.
Insead of :
Code:
DrawSprite:
lda SpriteVPos
sta $200,X
lda SpriteTileIndex
sta $201,X
lda SpritePalette
sta $202,X
lda SpriteHPos
sta $203,X
inx
inx
inx
inx
rts

You have
Code:
DrawSprite:
lda SpriteVPos
sta $200,X
lda SpriteTileIndex
sta $201,X
lda SpritePalette
sta $202,X
lda SpriteHPos
sta $203,X
txa
clc
adc SpriteCyclingValue
tax
rts

SomewhereInNMI :
lda SpriteCyclingValue
ora #$04 ;Needed if the variable isn't setup at #$04 before the first NMI
clc
adc #$08 ;sec sbc #$08 should work as well
sta SpriteCyclingValue
rts

The disadventage of this is that you can't have sprites with higher priority than other exept the sprite zero, so you wont be able to do effects like in the Double Dragon series (the first one doen't have OAM cycling at all, and the last two have, but it looks pretty bad).
If you want to do so, I would recommand to compare the vertical position to all object, then write to OAM the ones with a higest position first, in a order that sould periodically change, then do this for all possible various vertical position ranges.
Of course, it's a method I've found, there is many others, and probabily betters.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject: 8 sprites
PostPosted: Sun Aug 07, 2005 11:20 am 
Hi, thanks for your help. I hadn't even thought of varying the sprite priority. Thanks for your ideas. It's amazing the number of "tricks" there are in programming for the NES.


Top
  
 
 Post subject: Re: 8 sprites
PostPosted: Wed Aug 10, 2005 9:18 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
Lloyd_Gordon wrote:
I hadn't even thought of varying the sprite priority.

If so I don't know what you would mean by "sprite cycling". Maybe that swap DMA adress via $2003 before writing to $4014 would work, i.e. You write #$04 to $2003 so the sprite adress is set to 4, and while doing the DMA, the adress from (let's say you wrote #$02 to $4014) $200 will be copied to sprite RAM #4, $201 to sprite RAM #5, etc... then, when the time to read from $2fc had come, the sprite RAM index will override in #0, so this will be written to sprite RAM #0. I don't know it this would work at all, it's just a supposition.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject: 8+ sprites on a scanline
PostPosted: Wed Aug 17, 2005 5:41 pm 
I had the idea of cyclically putting a subset of the sprites on the bottom invisible (NTSC) row where they wouldn't cause problems, so that the sprites that didn't get rendered would be varied and the flicker would be there but less than without doing anything about the 8+ sprite problem. It didn't work at all and was not anywhere as good an idea as priority cycling. Right now I'm using this technique:

alternating priorities on every second frame:

Sprite 0-1-2-....-62-63
Sprite 0-63-62-61-60-...3-2-1.

This way the sprites that are not rendered flash at 1/30 second which is better than before. I'm going to try your offset method in combination with my reversal method and by itself later to see what happens. I tried the 2003&4014 offset method also but for some reason two sprites always got lost and it didn't seem to help much.

Thanks again for your interest.


Top
  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 8:17 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
Just reversing the sprite order works well, BUT :
- If, for example, 9 sprites are on a scanline, 2 will flicker and become "transparent" while 7 are unafected.
- If there is more than 16 sprites on a single scanline, some will become invisible at all

The offset thing seems definitely better, scince all sprites will flicker a bit, but not too much. So, if just 9 sprites are on a scanline, one of them will alternately be hidden.
It's better, but not perfect. The very best way to have it would allow sprite to still have priorities between them, witch is impossible there.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group