Offset-per-tile: Difference between revisions

From SNESdev Wiki
Jump to navigationJump to search
(link to more examples)
 
(5 intermediate revisions by the same user not shown)
Line 9: Line 9:
== Details on how the feature works ==
== 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.
In offset-per-tile modes, BG3's tilemap data is used instead as an offset map.


Layer 3's tilemap entries are interpreted like this:
This usually contains 2 rows of 32 entries (128 bytes total), the first for horizontal offset, and the second for vertical. Mode 4 only contains 1 row of 32 entries which instead choose either only horizontal or vertical per-entry.
* Horizontal entries will replace the BG HOFS value, except for the low 3 bits. The fine scroll of 0-7 pixels is retained, but the upper bits are replaced with the BG3 entry.
* Vertical entries will replace the BG VOFS value entirely.
 
Each entry is a 16-bit value:
<pre>
<pre>
15  bit  8  7  bit  0
15  bit  8  7  bit  0
Line 23: Line 27:
</pre>
</pre>


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.
The leftmost column of tiles is not affected by the offsets. The 0th entry for the offset map applies instead to the second visible column. This allows the first column's offset to be controlled by that layer's normal HOFS/VOFS setting, and the 32 entries affect the remaining 32 tiles that may be visible on that scanline. (Because the left column may be partially scrolled offscreen, up to 33 tiles can be at least partly seen on a scanline.)
 
Each entry affects an entire column of the image, because the screen Y position does not affect which row of BG3 is used. However, BG3VOFS does set the starting row's data position within the "tilemap", so [[HDMA]] or other timing techniques may be used to switch to multiple "sets" of scroll overrides in different parts of the screen.
 
The low 3 bits of HOFS are ignored for BG3's offset map, so it can be scrolled to match the other layers it applies to.
 
If needed, the "tilemap" can be two maps wide or tall (per [[PPU_registers#BGnSC|BG3SC]]), though this would not normally have much use. Having it two-wide might allow you to scroll a 64-entry pre-computed offset row in tandem with a two-wide background layer it affects.


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.
[[Category:Graphics]]

Latest revision as of 08:56, 5 October 2022

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.

See:

Details on how the feature works

In offset-per-tile modes, BG3's tilemap data is used instead as an offset map.

This usually contains 2 rows of 32 entries (128 bytes total), the first for horizontal offset, and the second for vertical. Mode 4 only contains 1 row of 32 entries which instead choose either only horizontal or vertical per-entry.

  • Horizontal entries will replace the BG HOFS value, except for the low 3 bits. The fine scroll of 0-7 pixels is retained, but the upper bits are replaced with the BG3 entry.
  • Vertical entries will replace the BG VOFS value entirely.

Each entry is a 16-bit value:

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)

The leftmost column of tiles is not affected by the offsets. The 0th entry for the offset map applies instead to the second visible column. This allows the first column's offset to be controlled by that layer's normal HOFS/VOFS setting, and the 32 entries affect the remaining 32 tiles that may be visible on that scanline. (Because the left column may be partially scrolled offscreen, up to 33 tiles can be at least partly seen on a scanline.)

Each entry affects an entire column of the image, because the screen Y position does not affect which row of BG3 is used. However, BG3VOFS does set the starting row's data position within the "tilemap", so HDMA or other timing techniques may be used to switch to multiple "sets" of scroll overrides in different parts of the screen.

The low 3 bits of HOFS are ignored for BG3's offset map, so it can be scrolled to match the other layers it applies to.

If needed, the "tilemap" can be two maps wide or tall (per BG3SC), though this would not normally have much use. Having it two-wide might allow you to scroll a 64-entry pre-computed offset row in tandem with a two-wide background layer it affects.