PPU attribute tables: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
m (→‎Glitches: There was a typo on the attempt to add an Multiplication sign.)
m ("it's" and "its" mean completely different things)
Line 81: Line 81:
There are some well known glitches when rendering attributes in NES and Famicom games.
There are some well known glitches when rendering attributes in NES and Famicom games.


The Attribute Table in each of the four Name Table (and it's mirrors), contains four colors, and four 16x16 segments out of a 32x32 segment, (as in: 2 bits x 4 = 1 Byte,)
The Attribute Table in each of the four Name Table (and its mirrors), contains four colors, and four 16x16 segments out of a 32x32 segment, (as in: 2 bits x 4 = 1 Byte,)


This is the reason why games that use the Horizontal or Vertical [[Mirroring]] mode for Diagonal [[PPU scrolling|Scrolling]] often have color artifacts on one side of the screen (on the right side in ''Super Mario Bros. 3''; on the trailing side of the scroll in ''Kirby's Adventure''; and at the top and bottom in ''Super C'').
This is the reason why games that use the Horizontal or Vertical [[Mirroring]] mode for Diagonal [[PPU scrolling|Scrolling]] often have color artifacts on one side of the screen (on the right side in ''Super Mario Bros. 3''; on the trailing side of the scroll in ''Kirby's Adventure''; and at the top and bottom in ''Super C'').


The game ''Alfred Chicken'' hides them completely by using left clipping and hiding the right side of the screen with solid-colored sprites. Such approach would occupy 15 entries of 64 in the sprite table in 8x16 sprite mode, or 30 entries in the 8x8 mode.
The game ''Alfred Chicken'' hides them completely by using left clipping and hiding the right side of the screen with solid-colored sprites. Such approach would occupy 15 entries of 64 in the sprite table in 8x16 sprite mode, or 30 entries in the 8x8 mode.

Revision as of 17:21, 11 June 2017

The attribute table is a 64-byte array at the end of each nametable that controls which palette is assigned to each part of the background.

Each attribute table, starting at $23C0, $27C0, $2BC0, or $2FC0, is arranged as an 8x8 byte array:

       2xx0    2xx1    2xx2    2xx3    2xx4    2xx5    2xx6    2xx7
     ,-------+-------+-------+-------+-------+-------+-------+-------.
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xC0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xC8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xD0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xD8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xE0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xE8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xF0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
2xF8:|   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     `-------+-------+-------+-------+-------+-------+-------+-------'
,---+---+---+---.
|   |   |   |   |
+ D1-D0 + D3-D2 +
|   |   |   |   |
+---+---+---+---+
|   |   |   |   |
+ D5-D4 + D7-D6 +
|   |   |   |   |
`---+---+---+---'

Each byte controls the palette of a 32×32 pixel or 4×4 tile part of the nametable and is divided into four 2-bit areas. Each area covers 16×16 pixels or 2×2 tiles, the size of a [?] block in Super Mario Bros. Given palette numbers topleft, topright, bottomleft, bottomright, each in the range 0 to 3, the value of the byte is

value = (topleft << 0) | (topright << 2) | (bottomleft << 4) | (bottomright << 6)

Or equivalently:

7654 3210
|||| ||++- Color bits 3-2 for top left quadrant of this byte
|||| ++--- Color bits 3-2 for top right quadrant of this byte
||++------ Color bits 3-2 for bottom left quadrant of this byte
++-------- Color bits 3-2 for bottom right quadrant of this byte

Most games for the NES use 16×16 pixel metatiles (size of Super Mario Bros. ? block) or 32x32 pixel metatiles (width of SMB pipe) in order to align the map with the attribute areas.

Worked example

The background in the game Thwaite, with an overlaid attribute grid.
Each 16x16 pixel color area has one of four color sets assigned to it, and one byte controls four color areas.
The background palette is divided into four color sets.

The byte at $23F2 has color set 3 at top left, 1 at top right, 2 at bottom left, and 2 at bottom right. Thus its attribute is calculated as follows:

value = (topleft << 0) | (topright << 2) | (bottomleft << 4) | (bottomright << 6)
      = (3       << 0) | (1        << 2) | (2          << 4) | (2           << 6)
      = $03            | $04             | $20               | $80
      = $A7

Glitches

There are some well known glitches when rendering attributes in NES and Famicom games.

The Attribute Table in each of the four Name Table (and its mirrors), contains four colors, and four 16x16 segments out of a 32x32 segment, (as in: 2 bits x 4 = 1 Byte,)

This is the reason why games that use the Horizontal or Vertical Mirroring mode for Diagonal Scrolling often have color artifacts on one side of the screen (on the right side in Super Mario Bros. 3; on the trailing side of the scroll in Kirby's Adventure; and at the top and bottom in Super C).

The game Alfred Chicken hides them completely by using left clipping and hiding the right side of the screen with solid-colored sprites. Such approach would occupy 15 entries of 64 in the sprite table in 8x16 sprite mode, or 30 entries in the 8x8 mode.