SNES PPU for NES developers: Difference between revisions
NovaSquirrel (talk | contribs) (→Tilemaps/Nametables: Accuracy fix) |
Rainwarrior (talk | contribs) (→Background modes: explain overscan and scrolling differences) |
||
Line 23: | Line 23: | ||
== Background modes == | == Background modes == | ||
There are a variety of [[Background modes]] that change how the background layers work. The most common (mode 1) provides two layers with 16 colors per tile, and a third layer with 4 colors per tile. The third layer may be given priority over everything else, which makes it useful as a HUD or status bar. | There are a variety of [[Background modes]] that change how the background layers work. The most common (mode 1) provides two layers with 16 colors per tile, and a third layer with 4 colors per tile. The third layer may be given priority over everything else, which makes it useful as a HUD or status bar. | ||
While the SNES produces a similar 240 line picture to the NES, by default it blanks the top and bottom 8 rows to increase vblank time. PPU register $2133 [[PPU registers#SETINI|SETINI]] can be used to enable "overscan" to make it more like the NES' picture viewport. | |||
The SNES always blanks the first scanline of BG rendering, so the 240 line mode is actually only 239 active lines. The 224 line mode similarly starts its active picture 1 scanline lower than might be expected, though it still has 224 active lines. A Y scroll position of 0 will ''not'' show the top pixel row of the BG. | |||
Positions given to the scroll registers are relative to the top left of the active picture (minus the blanked 1st line), so switching between 224 and 240 lines doesn't just crop the picture with letterboxing, but the 224 line version is also shifted 8 lines lower on the screen. On SNES mid-screen scroll changes are also still relative to the top left, unlike the NES. | |||
== Tilemaps/Nametables == | == Tilemaps/Nametables == |
Revision as of 01:29, 16 May 2022
The SNES PPU and NES PPU use every similar concepts for displaying graphics. This article will summarize some important differences and similarities, and lay out some basics before you learn about things more in-depth.
VRAM
Video RAM is 64KB and contained within the console. Additional video memory cannot be added via cartridge. VRAM contains the tilemaps used for backgrounds as well as the graphics data for background tiles and sprite tiles. You can decide how much VRAM to dedicate to each use, and there are registers that set the base address for different things.
Like the NES, VRAM is accessed by setting an address via registers, and then writing the data you want to store to other registers, with the address automatically increasing after each write. Unlike the NES, the VRAM address is spread across two registers, and VRAM is 16-bit, so the VRAM data is also spread across two registers (for accessing the low and high byte at each VRAM address). This means that you're writing addresses between $0000-$7FFF instead of $0000-$FFFF like you might expect.
Palettes/CGRAM
The palette consists of 256 RGB colors, with 5 bits used for the red, green and blue values of each color. You can choose to think of it as 8 background palettes and 8 sprite palettes, each with 15 colors plus a "transparency" color, though different Background modes can change the specifics.
VRAM and CGRAM are accessed with different registers. Colors in the palette are RGB values (with 5 bits per color channel).
DMA
DMA is much more flexible than it is on the NES. You can configure the SNES's DMA unit to write to any PPU register, as well as to other registers in the same address range as them. As a result, DMA can transfer data directly from the cartridge (or CPU RAM) into VRAM, CGRAM, OAM, or into CPU RAM.
DMA can work in reverse (copy from VRAM into CPU RAM) as well as do fills. It cannot, however, copy from one section of CPU RAM to another. For that, you can use the new MVN or MVP instructions.
HDMA
HDMA is a special case of DMA, in which a small amount of data is transferred at the end of a scanline, during HBlank. This makes raster effects much easier, as they no longer require precise timing. Instead, you choose a register and provide a table that lists both a series of values to write into that register, as well a series of scanline counts to wait before the next value is written.
There is still an interrupt that allows you to do things the old way, and you can specify a horizontal coordinate to trigger the interrupt at too.
Background modes
There are a variety of Background modes that change how the background layers work. The most common (mode 1) provides two layers with 16 colors per tile, and a third layer with 4 colors per tile. The third layer may be given priority over everything else, which makes it useful as a HUD or status bar.
While the SNES produces a similar 240 line picture to the NES, by default it blanks the top and bottom 8 rows to increase vblank time. PPU register $2133 SETINI can be used to enable "overscan" to make it more like the NES' picture viewport.
The SNES always blanks the first scanline of BG rendering, so the 240 line mode is actually only 239 active lines. The 224 line mode similarly starts its active picture 1 scanline lower than might be expected, though it still has 224 active lines. A Y scroll position of 0 will not show the top pixel row of the BG.
Positions given to the scroll registers are relative to the top left of the active picture (minus the blanked 1st line), so switching between 224 and 240 lines doesn't just crop the picture with letterboxing, but the 224 line version is also shifted 8 lines lower on the screen. On SNES mid-screen scroll changes are also still relative to the top left, unlike the NES.
Tilemaps/Nametables
SNES tilemaps consist of a series of 16-bit values, containing the palette, priority bit, horizontal/vertical flips, and a tile number. There is no separate attribute table, and a tilemap can access 1024 different tiles instead of only 256.
Tilemaps are 32x32 (instead of the NES's 32x30) and a background layer can decide to have a single tilemap, arrange two horizontally, arrange two vertically, or have a square of four different tilemaps. A background layer can also choose to have 16x16 tiles instead of 8x8.
Sprites/OBJ/OAM
Sprite limits are much higher. There are 128 sprites, and 32 can be on the same scanline before sprites start to disappear. There is additionally a limit of 34 sprite tiles per scanline.
Sprites can be several different sizes, e.g. 8x8, 16x16, 32x32, 64x64. You can pick two sprite sizes for the PPU to use at one time, and each individual sprite can pick one of those two sizes for itself. There is no 8x16 sprite size.
Sprite data is similar in structure to the NES (X, Y, tile, attributes) but in a different order, and with some additional properties:
- X has a 9th bit allowing a sprite to be placed partially off the left side.
- You have 8 15-color palettes to choose from. Sprite tiles are always 4bpp.
- Priority now has 4 values, allowing each sprite to be placed above, below, or between the various BG layers.
The sprite rendering layer is referred to as OBJ, though the sprite priority attribute potentially makes it work like several layers. Color math and windowing can apply to the OBJ layer in the same way as the BG layers.