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

Mode 7 racing — an F-Zero-style mini game (#4, part 1). More...

#include <snes.h>
#include <snes/mode7.h>
#include <snes/math.h>
#include <snes/input.h>

Macros

#define ACCEL   6
 Physics tuning (positions in 12.4 fixed, speeds in 8.8).
#define BRAKE   12
#define CAR_SCREEN_X   120
 Screen position of the car sprite (rotation pivot).
#define CAR_SCREEN_Y   168
#define DRAG   2
#define MAX_GRASS   0x00C0 /* grass cap: 0.75 px/frame */
#define MAX_SPEED   0x0300 /* 3.0 px/frame */
#define STEER_STEP   2

Functions

static void build_car_sprite (void)
 Draw the car arrow into a 16x16 pixel grid, encode as 4bpp.
int main (void)
u8 track_class_at (u16 idx)
 Banked-data accessor (data.asm): C pointer derefs are bank-$00-hardcoded (B2), so the 16 KB class map in bank $01+ is read through one lda.l track_class,x in ASM.

Variables

u8 car_heading
u16 car_speed
u8 car_surface
static u8 car_tiles [128]
 4 8x8 4bpp tiles = one 16x16 car (built at init)
u16 car_x
 Probe oracles / game state (12.4 fixed-point pixels).
u16 car_y
u8 track_map []
u8 track_map_end []
u8 track_pal []
u8 track_pal_end []
u8 track_til []
u8 track_til_end []

Detailed Description

Mode 7 racing — an F-Zero-style mini game (#4, part 1).

A drivable race circuit on the Mode 7 plane. The car stays fixed near the bottom of the screen and the WORLD rotates and scrolls under it — the classic SNES racing camera: per frame, mode7SetAngle(heading) + mode7SetScroll/SetCenter follow the car's fixed-point position. This is also the per-frame dogfooding of the C-migrated mode7 module (C1 audit).

  • D-pad left/right: steer — A: accelerate — B: brake
  • Grass slows the car down; the red wall ring stops it.

The track is generated at build time (gen_track.py -> gfx4snes -M 7); collision reads a 128x128 class map (road/grass/wall, one byte per tile) through a far pointer — 16 KB of data deliberately outside bank $00 (see the bank $00 budget rules).

ROM mode: LoROM (project default).

SNES Concepts
  • The F-Zero camera: SetCenter(car) makes the car the rotation pivot, SetScroll places it low on screen, SetAngle spins the world opposite to the car's heading
  • Fixed-point driving physics from the math module: velocity = fixMul(speed, fixSin/fixCos(heading)) — same 0-255 angle unit as mode7SetAngle, so heading feeds both directly
  • Mode 7 VRAM interleave loaded with dmaCopyVramMode7(); OBJ tiles coexist at name base 3 (word $6000)
  • A procedural 16x16 car sprite (4bpp planes built in C)
What to Observe
Boot on the start line. Hold A: the checker line recedes and the track streams under the car; steer through the chicane. Cutting the grass visibly slows you; the border wall is solid.
Modules Used
console, dma, background, sprite, math, input
See also
gen_track.py — the reproducible track generator
lib/source/mode7.c — the C Mode 7 module this game exercises

Macro Definition Documentation

◆ ACCEL

#define ACCEL   6

Physics tuning (positions in 12.4 fixed, speeds in 8.8).

◆ BRAKE

#define BRAKE   12

◆ CAR_SCREEN_X

#define CAR_SCREEN_X   120

Screen position of the car sprite (rotation pivot).

◆ CAR_SCREEN_Y

#define CAR_SCREEN_Y   168

◆ DRAG

#define DRAG   2

◆ MAX_GRASS

#define MAX_GRASS   0x00C0 /* grass cap: 0.75 px/frame */

◆ MAX_SPEED

#define MAX_SPEED   0x0300 /* 3.0 px/frame */

◆ STEER_STEP

#define STEER_STEP   2

Function Documentation

◆ build_car_sprite()

void build_car_sprite ( void )
static

Draw the car arrow into a 16x16 pixel grid, encode as 4bpp.

Palette indices: 0 transparent, 1 body (red), 2 cockpit (white). The arrow points UP — the world rotates, the car never does.

◆ main()

int main ( void )

◆ track_class_at()

u8 track_class_at ( u16 idx)
extern

Banked-data accessor (data.asm): C pointer derefs are bank-$00-hardcoded (B2), so the 16 KB class map in bank $01+ is read through one lda.l track_class,x in ASM.

Variable Documentation

◆ car_heading

u8 car_heading

◆ car_speed

u16 car_speed

◆ car_surface

u8 car_surface

◆ car_tiles

u8 car_tiles[128]
static

4 8x8 4bpp tiles = one 16x16 car (built at init)

◆ car_x

u16 car_x

Probe oracles / game state (12.4 fixed-point pixels).

◆ car_y

u16 car_y

◆ track_map

u8 track_map[]
extern

◆ track_map_end

u8 track_map_end[]

◆ track_pal

u8 track_pal[]
extern

◆ track_pal_end

u8 track_pal_end[]

◆ track_til

u8 track_til[]
extern

◆ track_til_end

u8 track_til_end[]