Backgrounds — Mode 2 offset-per-tile: per-column scroll from BG3.
Modes 2, 4 and 6 have a trick no other mode does: offset-per-tile (OPT). BG3 stops being a drawable layer and becomes an offset table — for each 8-pixel column of BG1/BG2 the PPU reads a scroll offset out of BG3's tilemap. That lets each column scroll independently, which is how you get a flag rippling in the wind, heat-haze, or per-column parallax without a scanline of HDMA.
Here BG1 is a stack of horizontal colour bands; a sine table written into BG3 gives every column its own vertical offset, so the bands ripple. The phase advances each frame. Only BG1 is shown — BG3 is pure offset data.
ROM mode: LoROM (project default).
- SNES Concepts
- Mode 2 OPT: setMode(BG_MODE2, 0); BG3's tilemap is the offset source, not a picture
- Per column N≥1 the PPU reads BG3 tile-row 0 for the H offset word and tile-row 1 for the V offset word; column 0 cannot be offset
- Offset word: bit 0x2000 = apply to BG1 (0x4000 = BG2); V value in bits 0-9, H value in bits 3-9. This example writes only V words
- Modes 4 and 6 reuse this exact data path (mode 4 packs H/V into one word)
- What to Observe
- Horizontal colour bands ripple as a travelling sine wave — each column at a different vertical offset, all from one small BG3 table. wave_phase is the probe oracle.
- Modules Used
- console, dma, background, math
- See also
- lib/include/snes/video.h — setMode(BG_MODE2)