Fading the palette to black

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

Moderator: Moderators

User avatar
SecretServiceDude
Posts: 99
Joined: Wed Oct 22, 2008 3:49 pm
Location: Los Angeles, CA

Fading the palette to black

Post by SecretServiceDude »

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?
CKY-2K/Clay Man
Posts: 214
Joined: Sun Apr 01, 2007 2:10 pm

Post by CKY-2K/Clay Man »

Sounds all good to me.
Image
Here to at least get an idea of how the NES works. I mean I know alot of the basic things, but this place'll help me grasp more how NES functions.
Major respect to NES developers.
albailey
Posts: 177
Joined: Thu Jul 13, 2006 3:15 pm

Post by albailey »

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
User avatar
SecretServiceDude
Posts: 99
Joined: Wed Oct 22, 2008 3:49 pm
Location: Los Angeles, CA

Post by SecretServiceDude »

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?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

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.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

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.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

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.
ccovell
Posts: 1041
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Post by ccovell »

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.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Maybe color emphasis could also be used for some extra steps...
User avatar
SecretServiceDude
Posts: 99
Joined: Wed Oct 22, 2008 3:49 pm
Location: Los Angeles, CA

Post by SecretServiceDude »

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.
User avatar
SecretServiceDude
Posts: 99
Joined: Wed Oct 22, 2008 3:49 pm
Location: Los Angeles, CA

Post by SecretServiceDude »

tokumaru wrote:Maybe color emphasis could also be used for some extra steps...
Hot damn, that's way out of control, dude. :shock:
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

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.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

Here is my way of doing fade outs exprimed in pseudo-code for clarity :

Code: Select all

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]
Useless, lumbering half-wits don't scare us.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

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.
Celius
Posts: 2159
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

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.
Post Reply