This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Fading the palette to black

Fading the palette to black
by on (#39589)
Do you guys ever fade the palette to black in your games? I've got a simple method that works well, but was curious if there are alternate methods out there.

Image

Looking at the palette above, it seems like a straightforward way is to subtract 16 from each palette entry every n frames; or if the palette entry is less than 16 to begin with, set it to black ($0E).

By adding 16 every n frames (and capping appropriately) instead of subtracting 16, I suppose this method would also work for fading to white, but I haven't tried it yet.

Thoughts?

by on (#39590)
Sounds all good to me.

by on (#39592)
There's one little gotcha.
You need to do a special check to prevent setting 0x0D (blacker than black). It really only matters if you plan to run on a real NES on a real TV since I dont think emulators emulate the 0x0D insanity.
Otherwise, yes drop16, then on the last step set to 0x0F

Al

by on (#39594)
albailey wrote:
There's one little gotcha.
You need to do a special check to prevent setting 0x0D (blacker than black). It really only matters if you plan to run on a real NES on a real TV since I dont think emulators emulate the 0x0D insanity.

Ah yes, the infamous "blacker than black".

I can't believe I forgot to check for that; thanks for reminding me!

Also: I've been using $0E for black, but it looks like other folks use $0F. Is there any difference? I mean, is there any reason to use one over the other, or is it just a matter of personal preference?

by on (#39595)
The only time you'll ever get $0D in practice is if you're using $2D or $3D. Those colors are nearly identical to $00 and $10 respectively on an NTSC or PAL NES, but they show up black (identical to $xE or $xF) on an RGB PPU, such as the one in Famicom Titler or PlayChoice 10. Do any licensed games actually use those grays, or would they have failed lot check? I haven't tried injecting code into Nintendo's official emulator to see if they show up.

by on (#39597)
The usual "subtract 16" method works well, but there are very few steps before everything turns black. For my game I wanted a more smoth transition, and from looking at the MD/GEN Sonic games I noticed that the palette shifts towards blue as it fades out.

So I did something similar: since there are 12 hues and 2 blue columns ($x1 and $x2), I make everything to the left of $x1 ($x8 to $xC) bluer every frame, as I do with everything at the right of $x2 ($x3 to $x7). It's like the 2 blue columns expand to the sides, slowly killing all the yellow, until everything is blue. At the same time I reduce brightness. This way I can achieve a smother transition that loks more like that of the original Sonic games.

I use tables for this though, because fade-ins are not as easy calculated in real time and because greys need special treatment.

by on (#39599)
SecretServiceDude wrote:
Also: I've been using $0E for black, but it looks like other folks use $0F. Is there any difference? I mean, is there any reason to use one over the other, or is it just a matter of personal preference?

$xE and $xF all produce proper black.

by on (#39600)
tepples wrote:
The only time you'll ever get $0D in practice is if you're using $2D or $3D. Those colors are nearly identical to $00 and $10 respectively on an NTSC or PAL NES, but they show up black (identical to $xE or $xF) on an RGB PPU, such as the one in Famicom Titler or PlayChoice 10. Do any licensed games actually use those grays, or would they have failed lot check? I haven't tried injecting code into Nintendo's official emulator to see if they show up.

Yeah, I used a table in my game to step down one level of brightness... this can allow for more transitions from full brightness -> black than just the standard 4 maximum.

And as for a licensed game that did use a grey in the $xD region, Totally Rad! / Magic John used it for the wall background in the 1st level. So in some magazines, this BG showed up as black due to their using an RGB PPU for the screenshot.

by on (#39601)
Maybe color emphasis could also be used for some extra steps...

by on (#39604)
blargg wrote:

Slightly off topic, but I've been meaning to ask: How on earth do you guys get all that detailed technical information? It's one thing for a guy like me to read documents that others have already put together, but to generate the info in the first place? It's most impressive.

by on (#39605)
tokumaru wrote:
Maybe color emphasis could also be used for some extra steps...

Hot damn, that's way out of control, dude. :shock:

by on (#39608)
SecretServiceDude wrote:
How on earth do you guys get all that detailed technical information?

Obsession with having full understanding, and plenty of time. Kevtris also did some video signal measurements and documented his process more.

by on (#39610)
Here is my way of doing fade outs exprimed in pseudo-code for clarity :
Code:
for(int j=0; j<4; j++)
{
  for(int i =0; i<0x20; i++)
  {
    paletteHue = palette[i] && 0x0F;
    paletteBright = palette && 0x30 >> 4;
    palette[i] = paletteHue || paletteFadeTbl[paletteBright];
  }
  wait a couple of VBlanks here;
}

paletteFadeTbl:
   .db $0f, $00, $10, $20

It doesn't check for $0d black, so be sure to never use $xd (anyways $1d is almost as $0f, $2d as $00 and $3d as $10).
For fading in, it would be more complicated. You'd just have to set the initial palette to $0x, where x is the desired hue, and then increase the brightness until it reaches the desired value.
Another alternative would be to use the fade out 4 consecutive times, then 3 times, then 2, 1 and finally print the normal palette. This would have the advantage of making the lighter color fade in while other are still on black.

By playing with the hues instead of the brightnesses, you can get interesting effects (as in Final Fantasy when doing into the menu). This is something that RGB palettes can't do easily, and proves the supperiority to HSB palettes.[/code]

by on (#39616)
The problem with simply messing with the luminance is that the resulting animation is not linear. IMO, and ideal fade-out animation should have each color turn into black over the same period of time, so that they all reach black at the same time. Of course this is not actually possible, but if you used a program to calculate the ideal levels of brightness and rounded off the results to values the NES actually has to create a table, you could possibly achieve a smoother animation. Smoother than a 4-level fade where dark colors immediately turn into black.

Another advantage of using tables is that the same ones can be used for fading in and out. Even more interestingly, they can be used not only for fading, but also for defining the current level of brightness, so that you can use lighting affects during the game, such as lights turning on and off.

In my game, I have a set of tables for various brightness levels. A pointer indicates the current brightness level, and the routine that updates the palette uses the color values as indexes into the current brightness table, and the resulting color gets written to the PPU. This means that the game engine always sees the unmodified palette, and it's only modified when written to the PPU. The fading routines simply change the brightness levels by modifying the pointer accordingly.

by on (#39623)
Yeah, the 16 subtraction fade out sounds like it'd be good. But yeah, what Tokumaru said is actually a great idea too. You could use that subtract 16 method somehow in combination with the blue emphasis. In my game, there'll be a part where the room you're in is supposed to be all dark without really any light. I wouldn't want to do the subtract 16 thing for this, because it wouldn't look right at all. I'll be turning on the blue emphasis and possibly some other stuff to make it look actually dark in the room. Blue is a very dark color, and is great for this sort of thing.

And about finding that technical stuff out, I wouldn't even know where to begin. I look at all of those REALLY technical things and barely understand what they're talking about. Yeah, and I also can't really fathom how one would go about finding all of that out. To all who did: thanks a whole bunch. The really precise timing things are what really get me...

EDIT: Also, you might want to create a table like Tokumaru said. Because if you didn't you'd have to do various checks to make the color black after it reaches $0x. With a table you could do:

FadeOutTable:
.db $30,$20,$10,$00,$3F
.db $31,$21,$11,$01,$3F
....

And if you wanted for any reason, you could choose a different color for it to fade out to. So you could have:

.db $31,$22,$12,$11,$3F

If you wanted to for some reason. I'm not sure how that'd look, but it's up to you.

This is what's great about the SNES. There's an actual brightness setting as well as a whole crap load of different colors to choose from.

by on (#39659)
Quote:
The problem with simply messing with the luminance is that the resulting animation is not linear. IMO, and ideal fade-out animation should have each color turn into black over the same period of time, so that they all reach black at the same time.

Well, personally I prefer when dark color becomes black before light colors for some reason. I think it looks better, but you can disagree (that's why I proposed to do it that way as well for fade-in).

I'll definitely use my technique for my games, and your table method sound like a terrible waste of ROM to me. It could be of some use if there were more brightness levels available, but for only 4 (5 including black) it's really not worth having all those table arround. But if it works that way for you go ahead for it.

by on (#39660)
I say try to imitate what other games did. They just subtracted to get the darker color, then replaced it with black.

by on (#39667)
Bregalad wrote:
Well, personally I prefer when dark color becomes black before light colors for some reason. I think it looks better, but you can disagree (that's why I proposed to do it that way as well for fade-in).

I actually haven't tried the linear approach yet, I just assumed it would look better and feel smoother, but maybe you are right.

Quote:
I'll definitely use my technique for my games, and your table method sound like a terrible waste of ROM to me.

Again the ROM space issue... Advanced techniques require more ROM and RAM, but if you are using a board that supports the extra memory there is no reason why you shouldn't do it.

I'm using a bit less than 1KB for my brightness tables, and although it might sound like much for a NROM or CNROM project, it's nothing for a TKROM game with 256KB of ROM. I even have all my PPU updating routines in a separate bank, since they are not needed during game logic, and if I didn't have tables like these I wouldn't even be able to use the space for something else anyway.

The method I presented is a perfectly valid option, and much more versatile than "subtract 16" as I've already explained, so please don't ditch it just because it isn't suited to your current project. If your next project uses a less limited board, you might realize that you don't have to be so greedy with memory. Some effects and performance gains are well worth the necessary memory, hopefully you'll see that.

Quote:
But if it works that way for you go ahead for it.

OK, thanks. And if you can get away without this kind of stuff, good for you too. There is nothing wrong with either approach, they're both valid options.

Dwedit wrote:
I say try to imitate what other games did. They just subtracted to get the darker color, then replaced it with black.

Yeah, keep doing only what has already been done and nothing really creative will ever show up. We can sure learn from the old games, but even the programmers back then weren't perfect, you know?

by on (#39687)
Depending on the project, it may be more important to optimize space, and it's good to mention that one method is more space-consuming while the other may be more time-consuming or not as flexible. If you're working with limited space, it's probably best to do as many calculations as you can without using up space with big tables. However, for very fast games (e.g. Sonic), you'd probably want to in the beginning give yourself more space so you can save time with tables. Everyone programs with different goals in mind. Some people choose space over time, and some people choose time over space. I actually don't pay as much attention to time as I do to space, though my goal in programming for the NES is to have as much complexity as possible. I gave myself 512k of PRG data (CHR is embedded in it), so I actually try and save as much space as I can so I can have lots of options. So since I have lots of space, and lots of compression, I can have really unique things everywhere you go. Not like Metroid with 256 different screens on a large map (I have 1024, and I don't even know if there'll be that many screens displayed). Though for my polygonal movie engine, time is way more important than space, as it needs to run at a decent frame rate.

Anyways, I'm sure SSD will look at these options and probably get ideas from all of them to produce his own fading method. I actually got some good ideas from this thread, too!

by on (#39692)
Celius wrote:
Anyways, I'm sure SSD will look at these options and probably get ideas from all of them to produce his own fading method. I actually got some good ideas from this thread, too!

Definitely. Thanks for all the responses, gents. Even when I've more or less decided on a particular algorithm for doing something, I like to toss it up on the forums for discussion, because sometimes a great suggestion comes along that causes me to reconsider.

Right now I'm using NROM for my project (32K PRG-ROM, 8K CHR-ROM). I'll eventually have to switch to something like MMC1, but I actually like working with extremely limited memory because it forces me to conserve space wherever possible. Once my data formats for maps, music, etc. are sufficiently compressed, I can give myself more memory to work with. At that point, I'll be able to have more varied levels, more songs, more enemies, etc.

by on (#39699)
Yeah, I'm actually going to make an NROM platformer so I can really teach myself how to conserve space wherever possible. Though it'll be pretty simple, and only have a few levels in comparison to SMB1. It'll probably have about 8 levels total, but with very different moods in each one. This might be difficult with only 8k of CHR. I also find it really hard to work with CHR ROM because it's so limiting. I hate feeling really limited! Though it's good to know how to work with what you have.

And when you move on, you'll probably be able to put all music in one bank, all maps in another, all enemy data in another, etc. Though there are some things you'll want to combine if you're not filling the whole bank up. And map data might span across multiple banks. In my game there's a system where I define all the metatiles in one bank, and in another I define all the screens which are composed of those metatiles, and then in another I define the rooms which are composed of those screens. So it's kind of a step system. It takes a lot of space to do it like that, but I do have 512k, so I can get away with it.