OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
main.c File Reference

DSP-1 ground: the Super Mario Kart floor — per-scanline Mode 7 matrices streamed by the coprocessor's Raster command. More...

#include <snes.h>
#include <snes/dsp1.h>
#include "res/ground.inc"
#include "res/sky.inc"

Macros

#define CAM_AZS   (0x4000 - 655)
 Zenith angle of the view line: 0x4000 is horizontal (horizon at the screen centre); 0x4000 - 655 tilts down 3.6 degrees so the horizon lands 16 lines above centre (line 96) and the ground below fits one 126-line HDMA repeat block.
#define CAM_HEIGHT   80
 Camera height above the ground plane (DSP-1 integer units). Lower = more dramatic near-row magnification; SMK sits low like this.
#define CAM_LES   256
 Viewpoint → screen distance: 256 gives the 50-degree horizontal FOV of a 256-pixel screen, and it is the vertical focal length that turns the tilt into a horizon raster (Vva = -256*tan(tilt)).
#define CAM_LFE   96
 Base point → viewpoint distance; the viewer sits this far behind the camera point along the view line.
#define CH_AB   HDMA_CHANNEL_3
#define CH_CD   HDMA_CHANNEL_4
#define CH_MODE   HDMA_CHANNEL_1
 HDMA channels: BGMODE switch, TM switch, M7A/M7B, M7C/M7D. 1-4 like mode7/perspective (0 is the general-DMA channel, 7 the OAM one).
#define CH_TM   HDMA_CHANNEL_2
#define GROUND_MAX   127
 Largest HDMA repeat block (7-bit count). The ground uses one.
#define MOVE_STEP   4
 Forward speed in ground units per frame.
#define TABLE_HDR   6
 Payload offset in a matrix table: [sky count][4 sky bytes][repeat header].
#define TABLE_SIZE   (TABLE_HDR + GROUND_MAX * 4 + 1)
 One matrix table: sky entry, repeat block of GROUND_MAX rasters, terminator.
#define TURN_STEP   0x0100
 Heading change per frame while turning (16-bit angle, 2^16 = 360).

Functions

static void cameraUpdate (void)
 Re-run the projection for the current camera and cache what the rest of the frame needs (horizon raster, ground centre).
int main (void)
static void tableInit (u8 FAR *t, u8 sky, u8 lines, u16 diag)
 Build one matrix table skeleton: a sky entry holding the identity matrix, then the repeat-block header the DSP-1 payload sits under.

Variables

static u8 back
 Table set being filled this frame (the other one is on screen).
static Dsp1Camera cam
 The camera: position on the ground plane (x, y wrap with the 1024-unit texture), height, lens, heading (aas: 0 looks up the map, -Y; 0x4000 looks to +X) and tilt. The luna manifest reads x, y and aas.
static s16 cx
 Ground point under the imaginary centre (last dsp1SetCamera).
static s16 cy
volatile u16 dsp1_ok = 0
 1 when the DSP-1 answered the known-answer probe (luna manifest asserts it).
static u8 ground_lines
volatile u16 raster_lines = 0
 Rasters streamed in the last dsp1Raster call (luna manifest asserts it).
static u8 sky_lines
 Screen line of the first ground raster and the block length.
static FAR u8 tab_ab [2][(6+127 *4+1)]
 Double-buffered M7A/M7B tables: HDMA reads one while the DSP-1 fills the other.
static FAR u8 tab_cd [2][(6+127 *4+1)]
 Double-buffered M7C/M7D tables.
static u8 tab_mode [5]
 BGMODE table: Mode 3 for the sky lines, then Mode 7 for the rest.
static u8 tab_tm [5]
 TM table: BG2 (sky) for the sky lines, then BG1 (ground).
static s16 vof
 Geometry from the last dsp1SetCamera: imaginary-centre raster, horizon raster.
static s16 vva

Detailed Description

DSP-1 ground: the Super Mario Kart floor — per-scanline Mode 7 matrices streamed by the coprocessor's Raster command.

mode7/perspective fakes a receding floor with a precomputed M7A/M7D table; this example asks the DSP-1 for the real thing. Each frame the CPU sends the camera (position, height, heading, tilt) with dsp1SetCamera, then dsp1Raster streams one 2x2 matrix per screen line — A, B, C and D, so the floor rotates with the heading for free — straight into two HDMA payloads. The HDMA channels replay them next frame while the CPU already computes the frame after (double buffering). Above the horizon the same HDMA split as mode7/perspective shows a Mode 3 sky.

The three numbers dsp1SetCamera hands back beside the matrices are the whole geometry: Vva says on which raster the horizon sits, Cx/Cy say which ground point is under the screen centre (they go to M7X/M7Y), and the Mode 7 scroll registers just pin that centre to the middle of the screen.

SNES Concepts
  • DSP-1 Raster: open-ended command streaming Mode 7 matrices per raster
  • Parameter outputs (Vof, Vva, Cx, Cy) driving M7X/M7Y and the HDMA split
  • HDMA_MODE_2REG_2X repeat blocks feeding M7A/M7B and M7C/M7D
  • Double-buffered HDMA tables swapped with hdmaSetTable in VBlank
  • dsp1Triangle as the movement sin/cos
What to Observe
  • A textured ground plane receding to a horizon under a sky
  • D-pad Left/Right turn the camera: the floor rotates in true perspective and the sky pans with the heading (one turn = the 512-px sky map)
  • D-pad Up/Down drive forward/backward along the heading
Modules Used
console, dma, background, input, mode7, hdma, dsp1
Warning
Needs the DSP-1 firmware in luna (dsp1b.rom) — see the README.
See also
snes/dsp1.h, docs/tutorials/dsp1.md, examples/mode7/perspective

Macro Definition Documentation

◆ CAM_AZS

#define CAM_AZS   (0x4000 - 655)

Zenith angle of the view line: 0x4000 is horizontal (horizon at the screen centre); 0x4000 - 655 tilts down 3.6 degrees so the horizon lands 16 lines above centre (line 96) and the ground below fits one 126-line HDMA repeat block.

◆ CAM_HEIGHT

#define CAM_HEIGHT   80

Camera height above the ground plane (DSP-1 integer units). Lower = more dramatic near-row magnification; SMK sits low like this.

◆ CAM_LES

#define CAM_LES   256

Viewpoint → screen distance: 256 gives the 50-degree horizontal FOV of a 256-pixel screen, and it is the vertical focal length that turns the tilt into a horizon raster (Vva = -256*tan(tilt)).

◆ CAM_LFE

#define CAM_LFE   96

Base point → viewpoint distance; the viewer sits this far behind the camera point along the view line.

◆ CH_AB

#define CH_AB   HDMA_CHANNEL_3

◆ CH_CD

#define CH_CD   HDMA_CHANNEL_4

◆ CH_MODE

#define CH_MODE   HDMA_CHANNEL_1

HDMA channels: BGMODE switch, TM switch, M7A/M7B, M7C/M7D. 1-4 like mode7/perspective (0 is the general-DMA channel, 7 the OAM one).

◆ CH_TM

#define CH_TM   HDMA_CHANNEL_2

◆ GROUND_MAX

#define GROUND_MAX   127

Largest HDMA repeat block (7-bit count). The ground uses one.

◆ MOVE_STEP

#define MOVE_STEP   4

Forward speed in ground units per frame.

◆ TABLE_HDR

#define TABLE_HDR   6

Payload offset in a matrix table: [sky count][4 sky bytes][repeat header].

◆ TABLE_SIZE

#define TABLE_SIZE   (TABLE_HDR + GROUND_MAX * 4 + 1)

One matrix table: sky entry, repeat block of GROUND_MAX rasters, terminator.

◆ TURN_STEP

#define TURN_STEP   0x0100

Heading change per frame while turning (16-bit angle, 2^16 = 360).

Function Documentation

◆ cameraUpdate()

void cameraUpdate ( void )
static

Re-run the projection for the current camera and cache what the rest of the frame needs (horizon raster, ground centre).

◆ main()

int main ( void )

◆ tableInit()

void tableInit ( u8 FAR * t,
u8 sky,
u8 lines,
u16 diag )
static

Build one matrix table skeleton: a sky entry holding the identity matrix, then the repeat-block header the DSP-1 payload sits under.

Parameters
ttable to initialise
skyscanlines above the ground (non-repeat entry, written once)
linesground rasters (repeat entry: 4 bytes written every line)
diagvalue of the diagonal term in the sky entry (A or D)

Variable Documentation

◆ back

u8 back
static

Table set being filled this frame (the other one is on screen).

◆ cam

Dsp1Camera cam
static

The camera: position on the ground plane (x, y wrap with the 1024-unit texture), height, lens, heading (aas: 0 looks up the map, -Y; 0x4000 looks to +X) and tilt. The luna manifest reads x, y and aas.

◆ cx

s16 cx
static

Ground point under the imaginary centre (last dsp1SetCamera).

◆ cy

s16 cy
static

◆ dsp1_ok

volatile u16 dsp1_ok = 0

1 when the DSP-1 answered the known-answer probe (luna manifest asserts it).

◆ ground_lines

u8 ground_lines
static

◆ raster_lines

volatile u16 raster_lines = 0

Rasters streamed in the last dsp1Raster call (luna manifest asserts it).

◆ sky_lines

u8 sky_lines
static

Screen line of the first ground raster and the block length.

◆ tab_ab

FAR u8 tab_ab[2][(6+127 *4+1)]
static

Double-buffered M7A/M7B tables: HDMA reads one while the DSP-1 fills the other.

◆ tab_cd

FAR u8 tab_cd[2][(6+127 *4+1)]
static

Double-buffered M7C/M7D tables.

◆ tab_mode

u8 tab_mode[5]
static

BGMODE table: Mode 3 for the sky lines, then Mode 7 for the rest.

◆ tab_tm

u8 tab_tm[5]
static

TM table: BG2 (sky) for the sky lines, then BG1 (ground).

◆ vof

s16 vof
static

Geometry from the last dsp1SetCamera: imaginary-centre raster, horizon raster.

◆ vva

s16 vva
static