NES / Famicom
| Spec | Value |
|---|---|
| Resolution | 256×240 (NTSC) / 256×239 (PAL) |
| Total colors | 54 unique (64-entry LUT with duplicates) |
| Simultaneous | 25 (4 bg palettes × 4 + backdrop + 4 sprite palettes × 3) |
| Constraint | 16×16 attribute blocks |
| Display | CRT composite |
| Year | 1983 |
| Maker | Nintendo |
Color palette
The NES PPU generates color via NTSC composite video — there is no single “correct” RGB palette. bitmapped uses a 2C02 PPU reference palette. The 64-entry lookup table is organized as 4 rows of 16, encoding brightness × hue:
The key constraint: 16×16 attribute blocks
The NES nametable uses attribute bytes that assign one of four background palettes to each 16×16 pixel region (a 2×2 group of 8×8 tiles). Every pixel within that block must use colors from the same 4-color palette.
This forces color boundaries to align to a coarse grid — it’s why NES games have that distinctive blocky color look, where you can often see rectangular regions of different color sets.
bitmapped’s attribute-block constraint solver divides the image into 16×16 blocks and selects the optimal 4-color subpalette for each block, minimizing color error.
Interactive demo
Code example
import { process } from 'bitmapped';
import { getPreset } from 'bitmapped/presets';
const nes = getPreset('nes-ntsc')!;
const result = process(imageData, {
blockSize: 4,
palette: nes.palette!,
dithering: 'floyd-steinberg',
distanceAlgorithm: 'redmean',
constraintType: 'attribute-block',
attributeBlockConfig: {
width: 16,
height: 16,
maxColors: 4,
},
});Presets
bitmapped includes two NES presets:
nes-ntsc— NTSC timing (256×240), 2C02 PPU palettenes-pal— PAL timing (256×239), same palette
Hardware notes
The NES PPU (2C02) doesn’t store RGB values — it generates NTSC composite video directly from a 6-bit color index (2 bits value × 4 bits hue). The signal is decoded by the TV’s NTSC decoder, which is why every CRT displays NES games slightly differently.
Color $0D generates a “blacker than black” signal that can damage some CRT monitors. It should always be mapped to pure black.
The PPU supports emphasis bits ($2001 bits 5-7) that tint the entire screen by dimming selected color channels ~20%. This is used in some games for fade effects.
The background palette is organized as 4 subpalettes of 4 colors each, with color 0 of all palettes sharing a single backdrop color. The attribute table assigns one of these four palettes to each 16×16 region.