PPU sprite priority
In the NES PPU, each sprite has two values that affect priority, or what appears behind what: the index of the sprite within OAM (0 to 63), and the priority bit (attribute 2 bit 5, set to 0 for front or 1 for back). In some cases, putting a back-priority sprite in front of a front-priority sprite can let the background show through and cover up the front-priority sprite. Super Mario Bros. 3 uses this for power-ups sprouting from blocks, putting a blank block "behind" the block at a low index and then putting the power-up "behind" that at a high index. (You can see the corners of this blank block when Mario hits a note block in World 1-2, as the note block becomes more squared off.)
The Nintendo DS PPU handles priority the "obvious" way,[1] and some NES emulator developers initially think the NES PPU handles it the same way:
- Front priority sprites in front
- The background plane in the middle
- Back priority sprites in back
What really happens in the NES PPU is conceptually more like this:
- During sprite evaluation for each scanline (cycles 256 to 319), the eight frontmost sprites on this line get drawn front (lower index) to back (higher index) into a buffer, taking only the first opaque pixel that matches each X coordinate. Priority does not affect ordering in this buffer but is saved with each pixel.
- The background gets drawn to a separate buffer.
- For each pixel in the background buffer, the corresponding sprite pixel replaces it only if the sprite pixel is opaque and front priority.
(Low-level hardware detail: The buffers don't actually exist as full-scanline buffers inside the PPU but instead as a set of counters and shift registers. The above logic is implemented a pixel at a time.)