Offset-per-tile

From SNESdev Wiki
Revision as of 05:20, 16 May 2022 by Fiskbit (talk | contribs) (Minor clarity improvements (hopefully).)
Jump to navigationJump to search

Offset-per-tile is a feature of background modes 2, 4, and 6. It allows overriding a layer's horizontal and vertical scroll position on a tile-by-tile basis. This is used by Yoshi's Island for the dizzy effect and Tetris Attack to have two different playfields with different vertical positions.

This feature can be used to simulate a rotating background for small rotation angles, as seen in Star Fox.

Details on how the feature works

In offset-per-tile mode, background layer 3's tilemap data is used differently. Layer 3's scroll position (divided by 8) is used to select a row of "tiles" that can override horizontal scroll values, and the row underneath can override vertical scroll values. In mode 4, there is only enough bandwidth to read one row, so there is a bit that allows selecting between horizontal and vertical.

Layer 3's tilemap entries are interpreted like this:

15  bit  8   7  bit  0
 ---- ----   ---- ----
 V21. ..SS   SSSS Ssss
 |||    ||   |||| ||||
 |||    ++---++++-++++- New scroll value for this tile. For horizontal values, the bottom three bits are ignored
 ||+------------------- Override scroll value for layer 1
 |+-------------------- Override scroll value for layer 2
 +--------------------- Mode 4 only: Scroll direction (0 = horizontal, 1 = vertical)

Layer 3's scroll values can be changed multiple times throughout a frame via HDMA or otherwise, to allow the game to use multiple different "sets" of scroll overrides in different parts of the screen.

An important detail to note about offset-per-tile is that the leftmost column of tiles in the displayed layers are never affected by offset-per-tile, even if they have the bits set to select those layers. A way to work around this quirk is to simply set the layer's scroll position to what the leftmost column's scroll position is supposed to be, and override the scroll value on every tile after that.