Hiding sprites and OAM decay

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Hiding sprites and OAM decay

Post by za909 »

I have this issue where I would like to hide sprites behind a HUD, which is at the top of the screen. The first idea I had was disabling sprites during VBlank and enabling them from an IRQ at the bottom of the status bar. Although this would be the least CPU-intensive method possible, it could be problematic because what if this causes OAM to decay? If that's the case, I figured I could do a mid-frame OAM DMA before the scanline I would turn sprites back on unless this causes glitches as well... and also it depends on whether it's worth giving up 513/514 clock cycles and not do it in software instead. I would definitely like to avoid having to use 8 blank sprites on top of that horizontal bar to hide sprites (and then putting them off-screen once they would go above the bar).
Image
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Hiding sprites and OAM decay

Post by rainwarrior »

OAM does not decay when the background is being rendered. It only decays when both background and sprites are disabled.

You should not attempt to OAM DMA while the background is being rendered, because it is still actively fetching sprites even though they aren't shown.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hiding sprites and OAM decay

Post by tokumaru »

Your first idea is the best way to do what you want, it's the least "invasive" approach, in the sense that it doesn't interfere at all with the work of the PPU.

As long as at least one layer (sprites OR background) is enabled, the PPU functions as normal, doing everything it normally would if both layers were enabled (doing all the memory fetches, sprite evaluation, and so on), it just inhibits the output of pixels of the one layer that's disabled.

EDIT: BTW, your graphics are really good... I'm getting an SNES vibe from them, which is kinda impressing for the NES. Now I want to see what the sprites look like! :wink:
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Hiding sprites and OAM decay

Post by Bregalad »

There is 2 "alternative" ways to do that and one of them is definitely better in my opinion.

Let's start with the one which is not better : If you're using CHR-ROM you could use a blank CHR-ROM page for sprites for the HUD, and replace it with a non-blank page after the HUD. This let you selectively disable only some sprites "behind" the HUD.

But the really supperior way in my opinion is to do it abusing the 8 sprites per scanline limitation. Have 8 dummy high priority sprites at the bottom of your HUD, and this will cleanly cut sprites which are partially on the HUD. You should then disable sprites which are entierely in the HUD by software. This require absolutely zero real-time CPU intervention, however if you use split-scrolling on your HUD it doesn't change anything since you need real-time code to write to $2005 (and possibly also $2006 ,$2000 and/or CHR-ROM bank registers). Your sprite #0 could be one of the dummy 8 high priority sprites. Also, this method let you selectively disable sprites in the HUD, obviously.

Both of those techniques are better, because simply disabling sprites by $2001 will not allow to selectively enable sprites in the HUD.

Finally, personally I like to have sprites above the HUD, since this is the standard for NES games, but I do not think it really matters.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Hiding sprites and OAM decay

Post by Dwedit »

tokumaru wrote:EDIT: BTW, your graphics are really good... I'm getting an SNES vibe from them, which is kinda impressing for the NES. Now I want to see what the sprites look like! :wink:
SNES games had a limited layer 3 that only supported 3 colors + transparent, so they often put the text or game UI on Layer 3. With 3 colors to work with, they usually used two colors for a vertical gradient, then added a shadow color. This font almost does the same thing, minus the shadow.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hiding sprites and OAM decay

Post by tokumaru »

IMO, using $2001 is simpler and cleaner than switching blank patterns, which offers very little benefit for the added cost.
Bregalad wrote:But the really supperior way in my opinion is to do it abusing the 8 sprites per scanline limitation.
The OP did specifically say he didn't want to do it like this. I think it's a valid option, but since you're already syncing with the PPU in order to change the scroll for the playfield, you might just as well simply enable sprites at the same time instead of wasting 8 OAM entries.
Finally, personally I like to have sprites above the HUD, since this is the standard for NES games, but I do not think it really matters.
I don't think there's a standard for this. There are plenty of examples of both cases. I don't particularly mind having the player go in front of the status bar if he jumps while near the top, but if more objects started doing things there and actual gameplay took place in the status bar area, then it'd bother me a lot.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Hiding sprites and OAM decay

Post by Bregalad »

tokumaru wrote: The OP did specifically say he didn't want to do it like this. I think it's a valid option, but since you're already syncing with the PPU in order to change the scroll for the playfield, you might just as well simply enable sprites at the same time instead of wasting 8 OAM entries.
I somehow didn't notice this mentionned at all. Sorry.
And you are right, if you are synching with PPU in all cases, then it is not very meaningful to combine it with a technique which was designed to avoid this.
I don't think there's a standard for this. There are plenty of examples of both cases.
Then please give me an example where the objects are "below" the HUD. I mean a solid status bar, not just some sprites showing game status (in which case I agree there's no standard).

The only game I can think off that does this is Castelvania - Bloodlines, but this is for the Megradrive, not the NES. Perhaps sprites below HUD is standard on Mega Drive, but I do not know enough MD games to really know.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hiding sprites and OAM decay

Post by tokumaru »

Maybe it's common for status bars at the bottom of the screen to hide sprites? I'm pretty sure that Kirby's Adventure hides sprites, but I can't check right now. I can't think of any examples of sprites going on front of a status bar at the bottom of the screen, but I don't know if this is because games are actively masking the sprites or simply because game objects have little reason to go down there.
User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Re: Hiding sprites and OAM decay

Post by za909 »

For the record, I'm using CHR-ROM and it's not going to be backswitched... this is supposed to be a tiny game aiming high... (1-bit BNROM-register to enable 64k of PRG)
I added the gradient because CHR-ROM can't be compressed anyway... for monochrome fonts it's pretty easy by leaving out the second 8 bytes for every tile if you're using CHR-RAM.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Hiding sprites and OAM decay

Post by rainwarrior »

Bregalad wrote:Then please give me an example where the objects are "below" the HUD. I mean a solid status bar, not just some sprites showing game status (in which case I agree there's no standard).
Super Mario 3, Wizards and Warriors, Guardian Legend, and Crystalis all hide sprites for the HUD. I think it's very common for bottom HUDs, anyway.

Or are you looking for only examples of a HUD at the top? The lack of sprite 0 probably makes that an unattractive proposition without a mapper IRQ. (Not even Battletoads hides sprites there.)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hiding sprites and OAM decay

Post by tokumaru »

rainwarrior wrote:The lack of sprite 0 probably makes that an unattractive proposition without a mapper IRQ.
IRQ or no IRQ, most games are already syncing with the PPU so they can change the scroll for the gameplay window, so enabling sprites is something they can do essentially for free.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Hiding sprites and OAM decay

Post by rainwarrior »

tokumaru wrote:
rainwarrior wrote:(In examples of a HUD at the top...) The lack of sprite 0 probably makes that an unattractive proposition without a mapper IRQ.
IRQ or no IRQ, most games are already syncing with the PPU so they can change the scroll for the gameplay window, so enabling sprites is something they can do essentially for free.
Yeah but you can't time the split "for free". If you don't have an IRQ, you need sprite 0 hit or a cycle-counted NMI routine. If you want to use sprite 0, you can't disable sprite rendering on the HUD. (Hence the 8-sprite method, or I think more often just ignoring the problem.)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hiding sprites and OAM decay

Post by tokumaru »

Doh! That's true, you can't use a sprite 0 hit if sprites are disabled. :oops:
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Hiding sprites and OAM decay

Post by tokumaru »

In the past, I have used a variation of the 8 sprites approach. I actually used 9 sprites, so that in addition to masking any sprites that attempted to go up there, they also triggered the sprite overflow flag, and I used this flag instead of the sprite 0 hit in order to sync with the PPU, to handle the transition into the gameplay window.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Hiding sprites and OAM decay

Post by tepples »

Or use sprite 0, turn off sprites, and do constant-timed tasks for 8 scanlines before turning them back on.
Post Reply