Best practice when updating entire nametable

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

casprog
Posts: 70
Joined: Fri Oct 28, 2016 12:37 pm

Re: Best practice when updating entire nametable

Post by casprog »

Yes, if you know your code is executing withing vblank, it is an OK time to turn on/off rendering without any visual problem. The exact mechanism of your "Wait_vblank" routine might be important. If it's waiting on your NMI routine to increment a counter, you might need to ensure that the NMI actually returns quickly enough to still be in vblank. (e.g. if your NMI routine also plays music, this may not be guaranteed.)
gotcha, thanks, and yes I am relying on a counter changing.

I've been thinking about the pros and cons of swapping the entire nametable or only updating what needs to change via some buffer during NMI. I have found that for what I'm building maybe half the tiles will need to change level to level, and so I can go either way but I was concerned about space if I store full tables, but this would keep it simple.. Currently the nametable updates once per level, it will not change again until the next level. My space concern is I have 8KB of PRG ROM to work with using MMC1 correct? So in theory that would be 8 full nametables with no room left for palettes and sprites?
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Best practice when updating entire nametable

Post by rainwarrior »

casprog wrote:I've been thinking about the pros and cons of swapping the entire nametable or only updating what needs to change via some buffer during NMI. I have found that for what I'm building maybe half the tiles will need to change level to level, and so I can go either way but I was concerned about space if I store full tables, but this would keep it simple.. Currently the nametable updates once per level, it will not change again until the next level. My space concern is I have 8KB of PRG ROM to work with using MMC1 correct? So in theory that would be 8 full nametables with no room left for palettes and sprites?
MMC1 can address 512k of PRG-ROM. (16k at a time in the lower half.) Did you read PRG-RAM by mistake? It can optionally have PRG-RAM as well.
casprog
Posts: 70
Joined: Fri Oct 28, 2016 12:37 pm

Re: Best practice when updating entire nametable

Post by casprog »

Looks like I did indeed cross the ROM with RAM :| thank you

In that case, since I don't need many levels, I will keep it simple and just generate the various tables and do a clean swap.
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Re: Best practice when updating entire nametable

Post by slembcke »

So I sort of successfully applied the suggestions in this thread to avoid flashes when changing screens in my game. I write the desired change to my mask copy variable, and then wait for the NMI. The very first thing my NMI routine does is to apply mask/ctrl. This only made the flashes at least stay at the top of the screen, but didn't quite go away.

The two workarounds I've found is to stop calling famitone update (the last thing the NMI handler does), or to wait for two full vsyncs after the mask is set before writing to the PPU. Am I missing something?
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Best practice when updating entire nametable

Post by rainwarrior »

If you've disabled rendering (e.g. write 0 to $2001) then you can write anywhere in CHR without visual glitches EXCEPT palettes. Whenever $3F00-3FFF is written to it outputs that colour directly to the screen while the write address remains in that location.

You should not have to disable music while updating (I recommend leaving it on to avoid the unpleasant skip), and you definitely don't need to wait for extra vsyncs. If the problem was the palettes, I would only guess that doing either of these things coincidentally moved the timing of the palette writes off the visible portion of the screen.
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Re: Best practice when updating entire nametable

Post by slembcke »

I do change the BG color of the palette when switching screens, but gets run as part of my normal NMI handler. I already knew to avoid setting that outside of vblank.

My full NMI handler is: Check the NMI ready flag (set by my wait_nmi routine), write mask/ctrl, write buffered data (including palette changes), write scroll, and finally update famitone. If NMI ready is not set, it skips to only update famitone. Seems pretty standard right?

I agree that avoiding skips in the music is desirable. Waiting for two vblanks is working ok, even during animated transitions without causing a very noticeable delay really. It just seemed really weird that I need to do it. I must be doing something else wrong, I just don't see what it could be...
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Best practice when updating entire nametable

Post by rainwarrior »

Maybe if you could screenshot or describe the flashes better? Or post a ROM, that would make it very easy to diagnose.
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Re: Best practice when updating entire nametable

Post by slembcke »

Here is a ROM that replicates the issue. Press up/down to select characters.
http://files.slembcke.net/temp/FlickerBug.nes

The character animations are almost 2k per, so I have to decompress them directly into CHR RAM, and thus need to disable to the PPU to do it. The garbage happens at the very top of the screen, but only when music is playing. I don't understand why, since the ctrl / mask registers are set before famitone even runs.

Related code snippets:
https://gist.github.com/slembcke/6a53fd ... 5729a98bf7
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Best practice when updating entire nametable

Post by tokumaru »

slembcke wrote:The character animations are almost 2k per, so I have to decompress them directly into CHR RAM, and thus need to disable to the PPU to do it.
I haven't checked the ROM yet because I'm on my phone, but blanking the screen during character selection is not very good for the presentation of your game. In this case, it would be much better to update the tiles progressively each vblank and keep rendering on. If you copy a modest 128 bytes per frame, it'll take 16 frames to transfer the whole 2KB, which is still less than 0.3 seconds, fast enough to feel nearly "instantaneous" in a menu (definitely not during gameplay though).
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Best practice when updating entire nametable

Post by rainwarrior »

I personally think the design of the character selection is fine.

However, the problem you are seeing is indeed palette writes happening outside of vblank. The actual colours of that artifact are a telltale sign that it's palettes, since they match the palettes you're using.

These palettes don't seem to be written by any code in that snippet, though. You have something that does LDA #$3F directly in the ROM, which is not in your snippet.

Mesen is really good for debugging when exactly writes happen. You can use its Event Viewer to visually see PPU writes overlaid on the screen, and also the "step back" feature of its debugger can help figure out what happened that made your palette writes so late.
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Re: Best practice when updating entire nametable

Post by slembcke »

tokumaru wrote:but blanking the screen during character selection is not very good for the presentation of your game
Well, the character animations are all lz4 compressed. They don't need to be if I just put less of them in the game, but what fun would that be? Really it was a joke that I implemented the character select at all, but that's not really the point.

The point is that I turn the screen off to write some new sprites to the CHR RAM and rewrite the character's bio text. I could have picked any of the other screen transitions in the game that have the exact same problem without being "pointless", but this one was easy to trigger repeatedly.
rainwarrior wrote:However, the problem you are seeing is indeed palette writes happening outside of vblank. The actual colours of that artifact are a telltale sign that it's palettes, since they match the palettes you're using.
Oooh! Are you saying that any palette writes, and not just the BG color is what can be causing the issue? I do blit the final palettes to VRAM outside of NMI. I was setting the BG color outside of that block because the majority screen color is often not the BG color for reasons of how the palettes work.

I'll try pushing the final palette load into another display list buffer.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Best practice when updating entire nametable

Post by rainwarrior »

Yes, basically whenever the PPU address points to $3F00-3FFF it will be constantly outputting the palette colour at that address (not just colour 0). The whole palette should be written within vblank.
User avatar
slembcke
Posts: 172
Joined: Fri Nov 24, 2017 2:40 pm
Location: Minnesota

Re: Best practice when updating entire nametable

Post by slembcke »

slembcke wrote:Oooh! Are you saying that any palette writes, and not just the BG color is what can be causing the issue?
Aurgh! Yeah, that seems to fix it. Pushing all of the palette writes into the NMI routine instead of just the BG color seems to work.

I guess you said exactly what I needed to hear before, "writing palettes will cause colour to appear in the middle of the screen". Since I was already writing the BG color separately in NMI to avoid half colored frames, I guess I just read that to mean what I wanted it to mean. -_-

Thanks again!

(I fixed the download link on the game's page to be transition glitch free: viewtopic.php?f=2&t=17611 :D )
Last edited by slembcke on Fri Aug 24, 2018 10:24 pm, edited 1 time in total.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Best practice when updating entire nametable

Post by tokumaru »

rainwarrior wrote:I personally think the design of the character selection is fine.
I checked the ROM now and I see that there's an animated transition, so yeah, that looks fine. It could be even smoother with progressive updates, but it doesn't look bad as is.
Post Reply