This issue is one I've been pondering and wanted to get some feedback.
In BK1 I do animate things with palettes, but it's mostly triggered. I was thinking of doing something a lot simpler and just update memory each frame and have it be written in. I might restrict it to a series of jump tables where it can be BG only, sprite only, a combo of both, etc. Rather than having something like 40 different triggers.
Anyone know if any games just take this route for simplicity sake?
If you can spare the vblank time, go ahead and update the palette every frame. Or update it during every frame when you don't have too many pattern or nametable updates. Or make a VRAM update scheduler that can copy generic 16-byte segments using an unrolled loop, and schedule a background palette update or sprite palette update when needed. Just be careful about the scheduling if you're extending vblank because palette updates during forced blanking show glitched lines.
Another thing I learned about NES palettes last night while putting a fade routine into Concentration Room: If you have a fade routine, use $20 for ordinary white and $30 for superbright white.
You called it "BK1", and I don't think it's "1" as in Air Force One. Sequel?
Seems like a waste of time to do every frame, unless you're actually changing the palette that quickly. If you did it every other frame, and had other tasks that were performed every other frame as well, you'd be able to interleave the two. Or maybe you could do something round-robin, where you update 1/4 of the palette each frame, and cycle through quarters, so that the entire palette is updated over four frames.
blargg wrote:
If you did it every other frame, and had other tasks that were performed every other frame as well, you'd be able to interleave the two.
Are you saying run the game at 20-30 fps like a Micronics game? It's doable, but I seem to remember someone on this board complaining about 2D games running at anything below 50 fps. But limiting palette update rate isn't entirely unjustified: Nintendo's lot check guidelines since sometime in the 2000s ban rapid palette changes for fear of lawsuits from parents of gamers with a seizure disorder. This forced some slight ROM hacking in several Virtual Console games such as Shining Force II and Zelda II in order to conform.
Quote:
Or maybe you could do something round-robin, where you update 1/4 of the palette each frame, and cycle through quarters, so that the entire palette is updated over four frames.
If you're not updating the entire BG palette or the entire sprite palette, the overhead of seeking with PPUADDR ($2006) becomes significant.
Generally I also update the palette every frame, it was also very common in commercial games because I saw it a lot when ripping NSFs. I figure it as a standard part of the 'worst case' code timing, where it would only take longer to have a branch avoiding it.
But yeah that is a good point about doing it every other frame, especially if you have CHR-RAM and have animations to update as well as different types of scrolling. Even still, 32 bytes full palette is only 2 tiles of CHR-RAM, it's not gonna make much of a difference unless it's really being pushed (which would be cool to see, who needs weird sized ROM banking when you can have arbitary-length animation data?).
I treat the palette as one of the things that need VBlank slots to be updated, exactly like name and attribute table data. Then again, my palette updates are not just 32-byte transfers: at the time of the update I modify the hue and the brightness of the colors dynamically (for fading and other effects) before sending them to the PPU.
This means that my palette updates take longer than usual, but I find it nice that I don't have to worry about modifying the palette that stays in RAM, since all the brightness and hue tweaking is handled dynamically.
To keep my VBlank updates simple, I wrote all the bureaucratic stuff first (such as detecting lag frames, resetting the scroll, etc) and divided the remaining time into equally sized (cycle-wise) slots (3 of them). I just have to set the 3 addresses for the desired update routines every frame, and the 3 slots are called during VBlank. Since I'm limited to 3 updates per frame, I had to set up a priority system that wouldn't result in glitches or any sort of undesirable effects.
But if you are in fact just copying 32 bytes and you do have the free VBlank time to do it, I don't see why not do it every frame.
tepples wrote:
blargg wrote:
If you did it every other frame, and had other tasks that were performed every other frame as well, you'd be able to interleave the two.
Are you saying run the game at 20-30 fps like a Micronics game?
No, just that
some game tasks might be performed less-often than every frame. For example, you might have enemies do some behavior checking every other frame, or like Solomon's Key, run the enemies on a separate thread that gets whatever time is available. Definitely run movement at full speed, as 30 FPS games look sucky (Rambo for example, a sidescroller at 30 FPS, WTF?).