How do I make sprites invisible on certain horizontal lines?
Moderator: Moderators
How do I make sprites invisible on certain horizontal lines?
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?
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 (3.9 KiB) Viewed 3776 times
Last edited by pops on Sat Oct 05, 2013 11:28 am, edited 1 time in total.
Re: How do I make sprites invisible on certain horizontal li
You could put eight blank sprites on the scanlines that you don't want other sprites to appear on.
[url=gopher://zzo38computer.org/].[/url]
Re: How do I make sprites invisible on certain horizontal li
True. But with a window 64 pixels in height, I'd have to use 8x4 8x16 sprites - half of my OAM.zzo38 wrote:You could put eight blank sprites on the scanlines that you don't want other sprites to appear on.
Could I bank in an empty CHR-RAM bank - does MMC3 allow for CHR-RAM banking?
Re: How do I make sprites invisible on certain horizontal li
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.
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.
Re: How do I make sprites invisible on certain horizontal li
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.
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.
Re: How do I make sprites invisible on certain horizontal li
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.
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.
Re: How do I make sprites invisible on certain horizontal li
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.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.
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: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?).
- $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
Re: How do I make sprites invisible on certain horizontal li
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: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?)
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 $8001Then, 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?)
Re: How do I make sprites invisible on certain horizontal li
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:

Here's what VWF looks like in a commercially released NES multicart:

mmm mmm mmm
Code: Select all
iii iii iii
mmm mmm mmmHere's the difference:

Here's what VWF looks like in a commercially released NES multicart:
Re: How do I make sprites invisible on certain horizontal li
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.
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.
Re: How do I make sprites invisible on certain horizontal li
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?
Re: How do I make sprites invisible on certain horizontal li
I believe that disabling sprites in 2001 also disables MMC3 IRQ line counting. Am I wrong?
Re: How do I make sprites invisible on certain horizontal li
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.
Re: How do I make sprites invisible on certain horizontal li
I can check it tomorrow, although I won't be able to post a test rom.
Re: How do I make sprites invisible on certain horizontal li
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.