palette, emphasis, monochrome, and graphics qustions

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
palette, emphasis, monochrome, and graphics qustions
by on (#12236)
if the play field palette is 16 bytes 0x0 - 0xf and the sprite palette is 0x10 - 0x1f, and ignoring the mirroring, that is 16 + 16 = 32 bytes. i read that there are 6 bits in the palette which is 64 bytes. i have a 64 palette table, but only the first 32 are used. where and how are the last 32 bytes used ?

i also read that if the monochrome bit is set the lower 4 bits are not used leaving bits 4 and 5, (starting at 0).

and how do the color emphasis bits effect the monochrome bit ?

right now i am drawing each pixel from ppu output and and using a 64 bit palette array. i wanted to use a hardware palette. i was looking at sdl and that has an 8 bit palette. and wanted to use that.

i havent dont graphics programming so this is a first.

thanks

matt

by on (#12237)
You're confusing things.

The sprite and background palettes take up 32 words of memory (actually just 28, with the mirroring and stuff). Each of those words is 6 bits wide - that is, each can have one of 64 values.

There are 64 colors total - you can choose up to 28 of them at once.


When you turn on grayscale, the 64 color values get reduced down to 4 color values - 00-0F become 00, 10-1F become 10, 20-2F become 20, and 30-3F become 30.
Color emphasis is a whole 'nother can of worms.

by on (#12238)
ok, i think i got that. how the color emphasis bits effect the grey scale bits ?

thanks

matt

by on (#12239)
Monochrome bit is applied at the palette lookup stage, and color emphasis is applied to the whole video signal after that.

by on (#12241)
There are 32 total logical palette entries divided into background and foreground palettes, 16 entries each. These are mapped to 28 physical palette entries (described elsewhere), each holding 6 bits of information. During rendering, the physical entries are used to determine colors for background and sprite pixels. If the monochrome bit is set, the low four bits of a palette entry are treated as zero. Finally, the three color emphasis/tint bits in $2001 alter the appearance of all colors in a somewhat complex way.

As for the on-topic question, how to implement this in an emulator using an 8-bit (palette) SDL surface, you can write the palette indicies (i.e. 0-15 for bg pixels, 16-31 for sprite pixels) into the surface pixels and then set the surface's palette to the NES palette at the end of the frame:

Code:
static SDL_Color nes_colors [64] = { {102,102,102}, ... };

SDL_Color palette [32];
for ( i = 0; i < 32; i++ )
   palette [i] = nes_colors [ppu_palette [i]];
SDL_SetColors( surface, palette, 0, 32 );

by on (#12242)
That's how nesticle did it, and nesticle doesn't handle mid-screen palette changes.

by on (#12245)
i was going to use the 6 bit as the sdl ( or any other graphics lib ) palette, so it didnt matter if teh nes did a mid screen palette change.

so i could have a 6 bit sdl pallet, but then if i wanted to include emphasis bits, i would add 3 to get 9 ? and i though i saw that there was a 512 color palette that someone used. 512 = 2^9

but sdl can only do an 8 bit palette. are there any graphics libs that can do a 9 bit palette ? or should i leave off the color empasis and add code when that is needed. not sure how often games will use that.

anyone use this method for effifient rendering ? i know blargg has his ntsc lib, i am not that far yet.....

thanks, matt

by on (#12247)
You can support only two different color emphases per frame like FCEU does. This will take 128 colors, leaving you with 128 for the GUI.

by on (#12248)
The scheme I described can easily be extended to support 8 mid-frame palette changes by sliding the active range forward each time there is a change to the palette. You start out using entries 0-31, then 32-63 after the first palette change, etc.

As for handling color emphasis bits, treat the combination of the 6-bit palette entries and the 3 emphasis bits as an effective palette of 9-bit colors. Thus a change to a palette entry or the emphasis bits is treated as a change to the palette. Then when you're setting the SDL surface's palette, incorporate the emphasis bits into the color index and use a larger color table incorporating the emphasis bits:

Code:
static SDL_Color nes_colors [512] = { {102,102,102}, ... };
SDL_Color palette [32];
int emphasis = (ppu_2001 & 0xE0) << 1;
for ( i = 0; i < 32; i++ )
    palette [i] = nes_colors [emphasis | ppu_palette [i]];
SDL_SetColors( surface, palette, 0, 32 );


You can use my nes_ntsc library to generate the color table (output: nes_palette.txt):

Code:
unsigned char palette [512 * 3];
nes_ntsc_setup_t setup = nes_ntsc_composite;
int i;
setup.palette_out = palette;
nes_ntsc_init_emph( 0, &setup );
for ( i = 0; i < 512; i++ ) {
    printf( "{%3d,%3d,%3d},",
            palette [i*3+0], palette [i*3+1], palette [i*3+2] );
    if ( i % 4 == 3 ) printf( "\n" );
}


I use the above scheme in my emulator and it works quite well. If the video card is in 15-bit RGB or higher, you can even eliminate the limit of 8 palette changes per frame by blitting a partial frame when the limit is reached, then starting from color index 0 again.

by on (#12249)
i think i get that, i will have to play around with it a bit. thanks blargg.

how often do games change the emphasis bits during the frame? if games do, is it either some emphasis on or off, or mixed emphasis. where on or off could be 010 to 000 or 101 to 000; and where mixed would be starting at 000 -> 010 -> 110 -> 001.. all of this in one frame.

sorry if thats worded bad, i am about to rewrite my ppu and was thinking ahead...

and, if the monochrome bit is set, i would mask the 9 bit color index ?

(3 bit emphasis with 6 bit palette) & 0x1f0; ?

again, sorry if thats hard to understand.

thanks

matt

by on (#12251)
I think most games don't use color emphasis and don't do any mid-frame palette changes. I have heard that Final Fantasy changes emphasis mid-scanline for one particular effect. Here's monochrome handling added to the example code:

Code:
int emphasis = (ppu_2001 & 0xE0) << 1;
int monochrome = (ppu_2001 & 1) ? 0x30 : 0x3F;
for ( i = 0; i < 32; i++ )
{
   int color = (ppu_palette [i] & monochrome) | emphasis;
    palette [i] = nes_colors [color];
}

by on (#12256)
Don't mix up everything :
- Final Fantasy I and II changes the emphasis bits between frames when a battle is encountered to make a screen flashing effect.
- Final Fantasy I use the monochrome bit *mid-scanline* to do a light beam effect when you light up an orb. Very few emulators emulate this correctly (almost only Nintendulator, I think).
- Final Fantasy III uses the monocrome bit on battle encounter that alternate from normal to monochrome every frame in order to have the screen flashing more than in the first two games.

On a side note, almost all games use the emphasis "000" as a standard, and sometimes change it to flash the screen. Just Breed, is the only exeption as far I know. It uses the emphasis "111" as a standard, and may clear some of the bits to flash the screen (I'm not sure it really does). This output in theory a screen that is constantly darker, but it isn't noticeable on my NES. I won't tell myself "my, those graphics are damn dark" everytime I play the game.

by on (#12288)
I'm sure most emulators currently actively in development emulate the FF1 orb effect correctly.

Airwolf (the American version), also uses a darker "111" screen as a standard.

by on (#12313)
...and Felix the Cat during the entire game. I wonder why...