How do I make sprites invisible on certain horizontal lines?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

How do I make sprites invisible on certain horizontal lines?

Post by pops »

I'm creating a BG dialogue window for my game. I want Sprites to not appear on the lines where the dialogue window is being displayed. I'm using MMC3 for the scanline IRQs, and thus can't turn off sprites with $2001. I'm also using CHR-RAM, so I can't bank in blank data on those lines (or can I --- does MMC3 have chr-ram banking functionality?).

My best idea currently is to use the SMB3 trick that hides power up sprites using low-index back-priority sprites. However, implementing this would require tracking the positions of all my sprite objects so I could place the hiding sprites. I'm hoping there's a better way which wouldn't require so much time spent tracking objects.

Any ideas?
Attachments
Untitled-1.gif
Untitled-1.gif (3.9 KiB) Viewed 3776 times
Last edited by pops on Sat Oct 05, 2013 11:28 am, edited 1 time in total.
zzo38
Posts: 1080
Joined: Mon Feb 07, 2011 12:46 pm

Re: How do I make sprites invisible on certain horizontal li

Post by zzo38 »

You could put eight blank sprites on the scanlines that you don't want other sprites to appear on.
[url=gopher://zzo38computer.org/].[/url]
pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

Re: How do I make sprites invisible on certain horizontal li

Post by pops »

zzo38 wrote:You could put eight blank sprites on the scanlines that you don't want other sprites to appear on.
True. But with a window 64 pixels in height, I'd have to use 8x4 8x16 sprites - half of my OAM.

Could I bank in an empty CHR-RAM bank - does MMC3 allow for CHR-RAM banking?
3gengames
Formerly 65024U
Posts: 2281
Joined: Sat Mar 27, 2010 12:57 pm

Re: How do I make sprites invisible on certain horizontal li

Post by 3gengames »

There are a few ways:

Mask the sprite by putting the BG tiles as sprites and covering the sprite when the priorities get set on it.

Disable sprites between that area.

Put the sprite behind the BG, and use BG color 1 and 0 on each palette the same.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How do I make sprites invisible on certain horizontal li

Post by tokumaru »

The fact that you're using MMC3 IRQs for other things doesn't prevent you from using them for this as well. You just have to check what comes first, the other split or the text box, so that you can setup the IRQs in the correct order.

But if you really don't want to use IRQs, you can use the good old sprite 0 hit. As long as the top scanline of the text box has solid pixels, a sprite 0 hit can tell you when it starts, at which point you can disable sprite rendering and count cycles until it's time to enable them again. I'm assuming that wasting time on wait loops isn't an issue, since I doubt there will be much action going on while text is being displayed (most games I can think of are practically paused during that time).

The only disadvantage I see is that sprites could still be visible at the top left of the text box before you disable them, but you can solve that by using 7 high priority sprites in addition to sprite 0 to mask out whatever would be visible otherwise.
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Re: How do I make sprites invisible on certain horizontal li

Post by MottZilla »

Ninja Gaiden III at certain points just disables sprites at a particular line to make them appear as though they go behind the background. Ninja Gaiden III also uses the IRQs for the status bar at the top of the screen as well. So you can certainly use IRQs to do what you need.

Given that you have just a box area you want no sprites in I think disabling sprites is the way to go. No need to use other sprites to mask things.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How do I make sprites invisible on certain horizontal li

Post by tepples »

pops wrote:I'm creating a BG dialogue window for my game. I want Sprites to not appear on the lines where the dialogue window is being displayed. I'm using MMC3 for the scanline IRQs, and thus can't turn off sprites with $2001.
You could use an MMC3 IRQ for the top of the window and timed code for the bottom (may need to detect PAL or NTSC at startup). Or you could use an MMC3 IRQ for the top, timed code to wait about 16 lines before reenabling sprites, and sprite 0 for the bottom.
I'm also using CHR-RAM, so I can't bank in blank data on those lines (or can I --- does MMC3 have chr-ram banking functionality?).
Yes. Existing MMC3 boards with CHR RAM (TGROM, TQROM, TNROM) connect A10-A12 of the CHR RAM to the CHR A10-A12 outputs of the MMC3. Given that 128 tiles for all 64 sprites can fit in $1000-$17FF, it's feasible in some cases to leave $1C00-$1FFF of CHR RAM completely unused. Here's one possible way to arrange VRAM:
  • $0000-$0FFF: Background tiles
  • $1000-$17FF: Tiles for sprites 0-63
  • $1800-$1BFF: Alphabet tiles, or VWF plane if you're rendering text that way
  • $1C00-$1FFF: Blank
Homebrew boards or rewired donor boards that use a 62256 (32 KiB) instead of a 6264 (8 KiB) would additionally connect A13-A14 to the MMC3's CHR bank outputs. You can emulate such boards in any emulator that supports NES 2.0 headers by setting the "CHR RAM size" field to 32 KiB.
pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

Re: How do I make sprites invisible on certain horizontal li

Post by pops »

This is great information. Thanks everyone.

Here's how I'll run my dialogue box:
I'll set IRQ to call at the top of the dialogue window, and then again at the bottom.

Since MMC3 can bank CHR-RAM, I will keep the last 1kb of CHR-RAM empty at all times, and then when the top dialogue IRQ is called, switch all the CHR-RAM sprite banks to the final bank index:

Code: Select all

	lda #%00000111
	ldx #%00000010
	stx $8000
	sta $8001
	inx
	stx $8000
	sta $8001
	inx
	stx $8000
	sta $8001
Tepples, as you pointed out, I may not need to clear the third bank, since I can fit all my sprites into the first two.

Then, when the second dialogue IRQ is called, I'll reset the banks to their original indexes.

Since this code takes more than a hblank to run, I'll probably have some sprites bleeding one line into the dialogue box on the top left (and some sprites missing a line on the bottom left), but I think this is an acceptable compromise, and of course I can always use 8 low priority sprites to hide the glitch at the top of the dialogue box.

Again, thanks everyone!

(Tepples, what's a vwf plane?)
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How do I make sprites invisible on certain horizontal li

Post by tepples »

iii iii iii
mmm mmm mmm

Code: Select all

iii iii iii
mmm mmm mmm
A monospace or fixed-width font has glyphs of only one width. A proportional or variable-width font has glyphs of different widths. For example, in a Latin proportional font, m is wider than i. On NES, these would be rendered into a buffer in RAM and then copied as tiles to the PPU.

Here's the difference:
Image

Here's what VWF looks like in a commercially released NES multicart:
Image
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: How do I make sprites invisible on certain horizontal li

Post by Bregalad »

I think if you disable only sprites by $2001 it won't affect the scanline counter, because the PPU still fetches them. I might be wrong though.

Other ways to do it :
- Use blank CHR-ROM page
- Abuse 8-sprites per line limitation
- Just do it by software if it's acceptable to get only 8 pixel of accuracty (that's what I do in my game).

Also you don't need as much sprites as you're telling if you want to abuse 8-sprites per line limitation. Just use 8 sprites for the top line and 8 for the bottom line, and mask the sprites in between by software (i.e. just don't put them in OAM). This eats up 1/4 of OAM, sure, so in the worst case where all 64 are used and only one will have to be clipped, this won't be the best solution.
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Re: How do I make sprites invisible on certain horizontal li

Post by MottZilla »

It would be MUCH more simple to just disable sprites before the line of your dialog box and reenable them after it. Banking CHR to empty patterns takes more time too. I don't think there is any reason not to just disable sprites and reenable them after the break. Why are you opposed to doing that?
pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

Re: How do I make sprites invisible on certain horizontal li

Post by pops »

I believe that disabling sprites in 2001 also disables MMC3 IRQ line counting. Am I wrong?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How do I make sprites invisible on certain horizontal li

Post by tepples »

Who wants to be the first to post a test ROM for this? It'd have to disable sprites, enable the background, set up IRQs, and display an IRQ counter on the screen.
pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

Re: How do I make sprites invisible on certain horizontal li

Post by pops »

I can check it tomorrow, although I won't be able to post a test rom.
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Re: How do I make sprites invisible on certain horizontal li

Post by MottZilla »

There is no need for a test ROM. We can just look at Ninja Gaiden III again. Stage 2, IRQs are continued to be used after disabling sprites. Sprites are disabled on line 175. This hides sprites like they sink into the ground. However after this is done, another IRQ fires at line 206, to parallax scroll the very bottom portion of the screen. So the IRQ counter most definitely works with the sprites disabled.
Post Reply