OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
mode7.h File Reference

SNES Mode 7 Support. More...

#include <snes/types.h>

Go to the source code of this file.

Macros

#define MODE7_FLIP_H   0x01
 Flip Mode 7 plane horizontally.
#define MODE7_FLIP_V   0x02
 Flip Mode 7 plane vertically.
#define MODE7_TILE0   0xC0
 Show tile 0 when out of bounds.
#define MODE7_TRANSPARENT   0x80
 Show transparent when out of bounds.
#define MODE7_WRAP   0x00
 Wrap around when out of bounds (default).

Functions

void mode7Init (void)
 Initialize Mode 7.
void mode7Rotate (u16 degrees)
 Set rotation in degrees (0-359).
void mode7SetAngle (u8 angle)
 Set Mode 7 rotation angle.
void mode7SetCenter (s16 x, s16 y)
 Set Mode 7 center point.
void mode7SetExtBg (u8 on)
 Enable/disable Mode 7 EXTBG (SETINI bit 6): a second, split layer.
void mode7SetMatrix (s16 a, s16 b, s16 c, s16 d)
 Set Mode 7 matrix directly.
void mode7SetScale (u16 scale_x, u16 scale_y)
 Set Mode 7 scale factors.
void mode7SetScroll (s16 x, s16 y)
 Set Mode 7 scroll position.
void mode7SetSettings (u8 settings)
 Set Mode 7 settings register.
void mode7Transform (u16 degrees, u16 scalePercent)
 Set rotation and scale together.

Detailed Description

SNES Mode 7 Support.

Functions for Mode 7 rotation and scaling effects. Mode 7 is the SNES's hardware rotation/scaling mode, famously used in F-Zero, Super Mario Kart, and Pilotwings.

Usage

#include <snes.h>
// Initialize Mode 7
// Set scale (0x0100 = 1:1, 0x0080 = magnified twice, 0x0200 = shrunk twice)
mode7SetScale(0x0100, 0x0100);
// Set rotation angle (0-255, where 256 = 360 degrees)
// In main loop
while (1) {
angle++;
}
void WaitForVBlank(void)
Wait for next VBlank period.
static u16 angle
Mode 7 ground: 9-tile prefab track (original art).
Definition main.c:46
void mode7SetScale(u16 scale_x, u16 scale_y)
Set Mode 7 scale factors.
void mode7SetAngle(u8 angle)
Set Mode 7 rotation angle.
void mode7Init(void)
Initialize Mode 7.
OpenSNES common-case master header.

Mode 7 VRAM Layout

Mode 7 uses a special interleaved VRAM format:

  • Tilemap in low bytes of VRAM words 0x0000-0x3FFF
  • Tile data in high bytes of VRAM words 0x0000-0x3FFF

Use dmaCopyVramMode7() (two DMAs: tilemap to the low bytes, tiles to the high bytes, from any bank) or set up DMA manually with interleaved data.

Author
OpenSNES Team

Macro Definition Documentation

◆ MODE7_FLIP_H

#define MODE7_FLIP_H   0x01

Flip Mode 7 plane horizontally.

◆ MODE7_FLIP_V

#define MODE7_FLIP_V   0x02

Flip Mode 7 plane vertically.

◆ MODE7_TILE0

#define MODE7_TILE0   0xC0

Show tile 0 when out of bounds.

◆ MODE7_TRANSPARENT

#define MODE7_TRANSPARENT   0x80

Show transparent when out of bounds.

◆ MODE7_WRAP

#define MODE7_WRAP   0x00

Wrap around when out of bounds (default).

Function Documentation

◆ mode7Init()

void mode7Init ( void )

Initialize Mode 7.

Writes the identity matrix (A = D = $0100, 1:1), the center point (128,128), M7HOFS = 0 and M7VOFS = $17F (texel row $180 on the first line: the view starts in the middle of the 1024-texel plane, not at its top — call mode7SetScroll(0, 0) to see row 0 first), and the scale mode7SetAngle() uses to 0x0100 (1:1). Call this before using other Mode 7 functions.

Note
This does NOT set BGMODE to Mode 7. You must do that separately:
REG_M7SEL = 0x00; // No flip, wrap around
REG_TM = TM_BG1; // Enable BG1
#define BG_MODE7
Definition video.h:41
#define REG_BGMODE
BG mode and tile size (W).
Definition registers.h:64
#define REG_M7SEL
Mode 7 settings (W).
Definition registers.h:133
#define REG_TM
Main screen designation (W).
Definition registers.h:187
#define TM_BG1
Definition registers.h:443

◆ mode7Rotate()

void mode7Rotate ( u16 degrees)

Set rotation in degrees (0-359).

Convenience function that converts degrees to the internal 0-255 format.

Parameters
degreesRotation angle in degrees (0-359)
mode7Rotate(45); // Rotate 45 degrees
mode7Rotate(180); // Rotate 180 degrees
void mode7Rotate(u16 degrees)
Set rotation in degrees (0-359).

◆ mode7SetAngle()

void mode7SetAngle ( u8 angle)

Set Mode 7 rotation angle.

Sets the rotation angle and recalculates the transformation matrix. The angle is 0-255 where 256 would equal 360 degrees (wraps at 256).

Parameters
angleRotation angle (0-255)

This function:

  1. Looks up sin/cos from table
  2. Multiplies by current scale using hardware multiplier
  3. Writes the 4 matrix values (M7A, M7B, M7C, M7D) to PPU
Warning
Call it during VBlank (right after WaitForVBlank()), as the examples do: the PPU multiplier it uses is M7A/M7B, which the Mode 7 renderer reads during active display, and the M7A write latch is shared with BG1HOFS/M7HOFS — an HDMA or interrupt write to those between the two M7A bytes corrupts the product (snesdev-wiki, "Multiplication"). The same holds for mode7Rotate() and mode7Transform(), which call it.

◆ mode7SetCenter()

void mode7SetCenter ( s16 x,
s16 y )

Set Mode 7 center point.

Sets the center of rotation/scaling, a point of the plane. Default is (128, 128). It shows on screen at (center - scroll): for a rotation around the middle of the screen, the center is (scrollX + 128, scrollY + 112).

Parameters
xCenter X coordinate (13-bit signed, -4096 to 4095)
yCenter Y coordinate (13-bit signed, -4096 to 4095)

◆ mode7SetExtBg()

void mode7SetExtBg ( u8 on)

Enable/disable Mode 7 EXTBG (SETINI bit 6): a second, split layer.

Parameters
on1 to enable, 0 to disable

With EXTBG on, BG2 shows the same Mode 7 plane as BG1 (same tilemap, same pixels, same transform), but reads each pixel's bit 7 as a priority bit and bits 0-6 as its colour (128 colours). Front to back, Mode 7 EXTBG draws: sprites of priority 3, sprites 2, BG2 pixels with bit 7 set, sprites 1, BG1, sprites 0, BG2 pixels with bit 7 clear (anomie's register doc, Mode 7; snesdev-wiki, Backgrounds). So a sprite of priority 1 passes in front of the bit-7-clear pixels and behind the bit-7-set ones: put BG2, not BG1, on the screen (BG1 would cover the low pixels), e.g. setMainScreen(LAYER_BG2 | LAYER_OBJ). BG1 still reads all 8 bits, so a pixel 0x83 is colour 3 on BG2 and colour 131 on BG1. Direct colour does not apply to BG2.

SETINI is write-only: this goes through the same software copy as videoSetInterlace(), videoSetOverscan() and videoSetPseudoHires(), so it does not clear their bits.

#define LAYER_BG2
Definition video.h:109
#define LAYER_OBJ
Definition video.h:112
void mode7SetExtBg(u8 on)
Enable/disable Mode 7 EXTBG (SETINI bit 6): a second, split layer.
#define setMainScreen(layers)
Enable layers on the main screen.
Definition video.h:133
void setMode(u8 mode, u8 flags)
Set background mode.

◆ mode7SetMatrix()

void mode7SetMatrix ( s16 a,
s16 b,
s16 c,
s16 d )

Set Mode 7 matrix directly.

For advanced users who need direct control over the transformation matrix. Bypasses the angle/scale system.

The matrix maps screen (x,y) to Mode 7 plane (X,Y): X = A*(x-cx) + B*(y-cy) + sx + cx Y = C*(x-cx) + D*(y-cy) + sy + cy

Parameters
aMatrix A (1.7.8 fixed point)
bMatrix B (1.7.8 fixed point)
cMatrix C (1.7.8 fixed point)
dMatrix D (1.7.8 fixed point)

◆ mode7SetScale()

void mode7SetScale ( u16 scale_x,
u16 scale_y )

Set Mode 7 scale factors.

Sets the X and Y scale for Mode 7 transformation, 8.8 fixed point (texels per screen pixel):

  • 0x0100 = 1:1 (matrix A = D = $00FE: the sine table peaks at 127/128)
  • 0x0080 = magnified twice (the plane looks larger)
  • 0x0200 = shrunk twice (the plane looks smaller) Valid up to 0x3FFF.
Warning
Changed in 0.48.0: before, mode7SetAngle() wrote a matrix of half the scale, so 0x0200 was 1:1 and 0x0100 magnified twice. Code written for that halves its scales: 0x0200 becomes 0x0100.
Parameters
scale_xHorizontal scale (8.8 fixed point)
scale_yVertical scale (8.8 fixed point)
Note
Call mode7SetAngle() after changing scale to update the matrix.

◆ mode7SetScroll()

void mode7SetScroll ( s16 x,
s16 y )

Set Mode 7 scroll position.

Sets the scroll offset for the Mode 7 plane.

Parameters
xHorizontal scroll (13-bit signed)
yVertical scroll (13-bit signed); written as y - 1 to M7VOFS, the same scanline-0 convention as bgSetScroll()

◆ mode7SetSettings()

void mode7SetSettings ( u8 settings)

Set Mode 7 settings register.

Controls flipping and out-of-bounds behavior.

Parameters
settingsM7SEL value: Bit 1: Flip vertically Bit 0: Flip horizontally Bits 7-6: Out of bounds behavior (0=wrap, 0x80=transparent, 0xC0=tile 0)

◆ mode7Transform()

void mode7Transform ( u16 degrees,
u16 scalePercent )

Set rotation and scale together.

Combined transformation with rotation in degrees and percentage-based scaling.

Parameters
degreesRotation angle in degrees (0-359)
scalePercentScale as a percentage (100 = 1:1, 50 = magnified twice, 200 = shrunk twice; computed as percent x 2.5, so 100 is 0x00FA, within 3 % of 0x0100)
mode7Transform(45, 100); // 45 degree rotation, 1:1
mode7Transform(0, 50); // no rotation, magnified twice
mode7Transform(90, 200); // 90 degrees, shrunk twice
void mode7Transform(u16 degrees, u16 scalePercent)
Set rotation and scale together.