Abusing the 8 sprite per line limitation?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Abusing the 8 sprite per line limitation?
by on (#81050)
Hi, I'm near to finish MOE fixes and release "full" version of game.
The only "Big" fix to do is to abuse "8 sprite per line limit".
So when I place 5 items on the same height 5th item won't dissapear.(Every item is 16x16 pixels big)
I was reading this Doc by Bregaladl and I don't get it.
I can use 5th bit of $2002, but how I'm supposed to write code.
I mean...Ok, 5th bit of $2002 is set then I should..do what? These sprites are already drawn, so I can't disable them.I can disable (for example) sprites of item 2 for next frame.But again, how can I know which sprites are they in OAM?

by on (#81051)
Why not just do the flicker? I.e. alternate sprite indexes every frame.

by on (#81053)
Shiru wrote:
Why not just do the flicker? I.e. alternate sprite indexes every frame.


This.
Re: Abusing the 8 sprite per line limitation?
by on (#81054)
Denine wrote:
Hi, I'm near to finish MOE fixes and release "full" version of game.
The only "Big" fix to do is to abuse "8 sprite per line limit".
So when I place 5 items on the same height 5th item won't dissapear.(Every item is 16x16 pixels big)
I was reading this Doc by Bregaladl and I don't get it.
I can use 5th bit of $2002, but how I'm supposed to write code.
I mean...Ok, 5th bit of $2002 is set then I should..do what? These sprites are already drawn, so I can't disable them.I can disable (for example) sprites of item 2 for next frame.But again, how can I know which sprites are they in OAM?


I think the overflow flag was really only meant as an additional "hit test" condition not really as a "something's wrong, your code should do something to fix it NOW" condition. For example you can set up a line of 8 sprites on a scanline so that when your player sprite goes through that region he'll disappear (similar to Legend of Zelda dungeon when link walks north or south). If Legend of Zelda wanted to it could check for overflow being set and know it meant Link had tried to go through a dungeon door.
Re: Abusing the 8 sprite per line limitation?
by on (#81057)
cpow wrote:
If Legend of Zelda wanted to it could check for overflow being set and know it meant Link had tried to go through a dungeon door.

Terrible idea to trigger a game logic event with a video hardware peculiarity though. A game engine should know where all doors are regardless of what the video hardware is saying.
Re: Abusing the 8 sprite per line limitation?
by on (#81058)
tokumaru wrote:
cpow wrote:
If Legend of Zelda wanted to it could check for overflow being set and know it meant Link had tried to go through a dungeon door.

Terrible idea to trigger a game logic event with a video hardware peculiarity though. A game engine should know where all doors are regardless of what the video hardware is saying.


Ok ok stupid example, sorry. Could be useful for screen-split or something though, right?
Re: Abusing the 8 sprite per line limitation?
by on (#81062)
cpow wrote:
Could be useful for screen-split or something though, right?

I once considered using the sprite overflow for hiding scrolling glitches at the top of the screen. By placing 8 (or should it be 9?) high priority sprites at the very top of the screen, the overflow bit could be used to detect the start of the frame, and a fixed number of scanlines later I would enable background rendering. As a bonus, the high priority sprites would mask any other sprites near the top of the screen, so they could smoothly enter/leave the screen.

I was afraid to do that because it was discovered that the meaning of the overflow flag isn't as simple as "more than 8 sprites were found", and I was afraid of getting a false negative which would cause the game to hang/glitch waiting for the overflow.

by on (#81076)
When I was talking about "abusing the 8-sprite per line limitation" I really mant use it to hide sprites on purpose, like in Legend of Zelda's vertical doors, Castlevania II's marshes, and some of Nija Gaiden's "CGI" cutscenes.

by on (#81092)
Shiru wrote:
Why not just do the flicker? I.e. alternate sprite indexes every frame.

So, in theory, In frame 1 I use "sprite index1", in frame 2 I use "sprite index2", In frame 3 I use "sprite index1" etc.
I can use Vblank to change index number.But there's one problem.I have no ide how to setup these indexes.What sprite index 1 should contain? Which sprites? I should calculate it somehow? And should it be enabled only when there's 8 sprites on line?

by on (#81093)
You are probably having these problems because you hardcoded your objects to specific OAM locations. If this is not the case, then just ignore this post! :wink:

Most people when they start coding for the NES just use specific OAM locations for their objects (e.g. sprites 0 to 3 form the left paddle, sprites 4 to 7 form the right paddle and sprite 8 is the ball), which is actually fine for simpler games. For larger games however, with a bigger number of on-screen objects that require sprite flicker, this is hell. In such projects, you are supposed to manage your objects completely separated from the OAM, and once you know their final position you start filling the OAM. If you completely rewrite the OAM every frame you can start at different locations each time, and advance a different number of slots too, which will cause the sprite priorities to vary a lot from frame to frame.

Sprites are supposed to be just that, small graphical entities on the screen. Sprites are not supposed to be your objects, they are just supposed to represent your objects. You can think of the sprites as actors, that have a different role every frame. In one frame a sprite may be the corner of a coin, in the next frame, the right foot of your hero. They should not be hardcoded to specific objects.

by on (#81195)
tokumaru wrote:
You are probably having these problems because you hardcoded your objects to specific OAM locations. If this is not the case, then just ignore this post! :wink:

The only "hardcoded" sprite in OAM is Sprite0.

Quote:
Sprites are supposed to be just that, small graphical entities on the screen. Sprites are not supposed to be your objects, they are just supposed to represent your objects.

Yes, I understand this very well.

Just in case, I'll show how I write sprites:
Code:
this will provide data and call subroutine to draw sprites
$600 in RAM is OAM page.

 lda #$0   ;Write Strribute of sprite
 sta $7F0

 ldy #$BE ;Vertical position of sprite

 ldx #$8A  ;Horizontal position of sprite

 lda #$80   ;Tile number

 jsr Rys1 ;Start writing sprite data to $600

And this is "Rys1" function:
Code:
Rys1:
;------------------------------------------------------------------------------------
 stx $7F1   ;Save X position into temporary RAM location
 ldx $7F2   ;load X for SPR page

 sta $601,X  ;Write Tile number

 lda $7F1     ;Write X position
 sta $603,X

 TYA           ;Write Y position
 sta $600,X

 lda $7F0     ;Write attribute
 sta $602,X

 TXA
 clc
 adc #$04
 sta $7F2  ;Add 4 to SPR page X, so next sprite will be written propely.

Rys1Exit
 rts

It's just very simple example.In fact, data about sprite X,Y,tile number and attribute are read from ROM, then sent to first function.
So..to make flicker I need to, for example.In Frame 0 draw items in this order: Item1,Item3,Item5,Item2,Item4.
In frame 1 in this order:Item2,Item4,Item1,Item3,Item5.
And loop this pattern?(Frame0->Frame1->Frame0->Frame1 etc.)