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

Tilemap-based sprite engine with 32x32 and 64x64 map modes. More...

#include <snes.h>
#include "map32x32.h"
#include "map64x64.h"

Macros

#define FONT_TILE_OFFSET   0x100
 Font tile number offset.
#define SPRITE_GARGOYLE   1
 Tile index for the gargoyle character sprite.
#define SPRITE_ROCKFORD   2
 Tile index for the Rockford character sprite (pre-converted C64 data).
#define VRAM_BG2_GFX   0x2000
 VRAM word address for BG2 tile character base.
#define VRAM_BG2_MAP   0x6800
 VRAM word address for BG2 tilemap (text overlay, SC_32x32).
#define VRAM_FONT   0x3000
 VRAM word address for 4bpp font tiles (within BG2 gfx region).
#define VRAM_SPRITE_GFX   0x4000
 VRAM word address for BG1 8bpp sprite tile characters.
#define VRAM_SPRITEMAP   0x1000
 VRAM word address for BG1 tilemap (SC_64x64 = 4 nametable pages).

Functions

static void drawSpriteFrame32x32 (u16 sprite)
 Draw a border frame of sprites around the 32x32 map perimeter.
static void drawSpriteFrame64x64 (u16 sprite)
 Draw a border frame of sprites around the 64x64 map perimeter.
static void initDemoMap32x32 (void)
 Initialize the 32x32 tilemap demo mode.
static void initDemoMap64x64 (void)
 Initialize the 64x64 tilemap demo mode with 16x16 BG tiles.
int main (void)
 Main entry point – dynamic tilemap sprite engine demo.
void smapDma (u16 byte_offset, u16 vram_addr, u16 byte_count)
 DMA a portion of the WRAM tilemap buffer to VRAM.

Variables

u8 is_map32x32 = 1
 When true, 32x32 map mode is active; when false, 64x64 mode.
u16 max_scroll_height
 Maximum vertical scroll offset in pixels for the current map mode.
u16 max_scroll_width
 Maximum horizontal scroll offset in pixels for the current map mode.
u8 palsprite16
 Palette for gargoyle sprite in 32x32 mode.
u8 palsprite16_64x64
 Palette for gargoyle sprite in 64x64 mode.
u8 palsprite16_64x64_end
u8 palsprite16_end
static const u8 rockford_8bpp [256]
 Pre-computed Rockford sprite in SNES 8bpp planar format.
u8 scroll_lock = 1
 When true, scrolling is clamped to map boundaries; when false, wraps freely.
u8 sprite16
 8bpp gargoyle sprite tiles for 32x32 map mode (from data.asm)
u8 sprite16_64x64
 8bpp gargoyle sprite tiles for 64x64 map mode (from data.asm)
u8 sprite16_64x64_end
u8 sprite16_end
u16 spritemap_len = 0x2000
 Total size of the SC_64x64 tilemap in bytes (4 pages x 2KB).

Detailed Description

Tilemap-based sprite engine with 32x32 and 64x64 map modes.

Demonstrates a custom tilemap sprite engine where 16x16 "sprites" are drawn as background tile entries on BG1 in Mode 3 (8bpp, 256 colors). This technique allows hundreds of on-screen objects without hitting the 128-hardware-sprite limit, at the cost of tile-aligned positioning.

The tilemap buffer lives in bank $7E extended WRAM (above the 8KB low-WRAM limit) and is accessed via assembly helpers (smapWrite, smapClear, smapDma) because the compiler generates sta.l $0000,x which always reads bank $00. Tilemap DMA to VRAM uses the 1-page-per- VBlank pattern (2KB per frame) to avoid flicker.

Also displays a C64 Boulder Dash Rockford sprite from a pre-computed SNES 8bpp planar array, demonstrating direct VRAM tile upload while the screen is on.

Port of the PVSnesLib DynamicMap example.

SNES Concepts
  • Mode 3: 8bpp BG1 (256 colors) + 4bpp BG2 (text overlay)
  • Extended WRAM ($7E:2000+) for large tilemap buffers
  • SC_64x64 tilemap layout (4 nametable pages, 8KB total)
  • 1-page-per-VBlank DMA pattern for flicker-free tilemap updates
  • 8bpp planar tile format and direct VRAM tile upload
  • 16x16 tile mode (BG1_TSIZE16x16) for 64x64 map variant
What to Observe
  • A gargoyle sprite border frames the map area
  • A = toggle between 32x32 and 64x64 map modes
  • B = toggle scroll lock on/off
  • X = place gargoyle sprites at random positions
  • Y = display the C64 Boulder Dash Rockford sprite
  • D-pad = scroll the map (respects scroll lock bounds)
Modules Used
console, sprite, dma, background, text, text4bpp, input
See also
background.h, dma.h, input.h, text.h

Macro Definition Documentation

◆ FONT_TILE_OFFSET

#define FONT_TILE_OFFSET   0x100

Font tile number offset.

Tilemap entries reference tiles relative to the BG's character base. The font is loaded at VRAM_FONT but the base is VRAM_BG2_GFX, so the first font tile has index (VRAM_FONT - VRAM_BG2_GFX) / 16 = 0x100. Each 4bpp tile is 32 bytes = 16 VRAM words.

◆ SPRITE_GARGOYLE

#define SPRITE_GARGOYLE   1

Tile index for the gargoyle character sprite.

◆ SPRITE_ROCKFORD

#define SPRITE_ROCKFORD   2

Tile index for the Rockford character sprite (pre-converted C64 data).

◆ VRAM_BG2_GFX

#define VRAM_BG2_GFX   0x2000

VRAM word address for BG2 tile character base.

◆ VRAM_BG2_MAP

#define VRAM_BG2_MAP   0x6800

VRAM word address for BG2 tilemap (text overlay, SC_32x32).

◆ VRAM_FONT

#define VRAM_FONT   0x3000

VRAM word address for 4bpp font tiles (within BG2 gfx region).

◆ VRAM_SPRITE_GFX

#define VRAM_SPRITE_GFX   0x4000

VRAM word address for BG1 8bpp sprite tile characters.

◆ VRAM_SPRITEMAP

#define VRAM_SPRITEMAP   0x1000

VRAM word address for BG1 tilemap (SC_64x64 = 4 nametable pages).

Function Documentation

◆ drawSpriteFrame32x32()

void drawSpriteFrame32x32 ( u16 sprite)
static

Draw a border frame of sprites around the 32x32 map perimeter.

Fills the top, bottom, left, and right edges of the 32x32 tilemap with the given sprite tile index, creating a rectangular frame. Writes go to the WRAM tilemap buffer (not VRAM) – the caller must DMA the buffer to VRAM afterward.

Parameters
spriteSprite element index to place at each border cell

◆ drawSpriteFrame64x64()

void drawSpriteFrame64x64 ( u16 sprite)
static

Draw a border frame of sprites around the 64x64 map perimeter.

Same as drawSpriteFrame32x32() but for the larger 64x64 map mode. Uses the 64x64 coordinate system and tile mapping functions.

Parameters
spriteSprite element index to place at each border cell

◆ initDemoMap32x32()

void initDemoMap32x32 ( void )
static

Initialize the 32x32 tilemap demo mode.

Configures Mode 3 with 8x8 BG1 tiles, loads gargoyle sprite tiles and palette to VRAM/CGRAM, clears the extended WRAM tilemap buffer, and DMAs the empty tilemap to VRAM. Must be called during force blank because it writes to VRAM directly.

◆ initDemoMap64x64()

void initDemoMap64x64 ( void )
static

Initialize the 64x64 tilemap demo mode with 16x16 BG tiles.

Similar to initDemoMap32x32() but uses BG1_TSIZE16x16 (bit 4 of mode register). In 16x16 tile mode, the SNES fetches the top and bottom halves of each tile from VRAM addresses 512 words apart, so tile data must be split between two VRAM regions per slot.

◆ main()

int main ( void )

Main entry point – dynamic tilemap sprite engine demo.

Initializes Mode 3 (8bpp BG1) with a text overlay on BG2, sets up the extended WRAM tilemap buffer via assembly helpers, and enters a loop handling scrolling, map mode toggling (32x32 / 64x64), random sprite placement, and Rockford sprite display. Tilemap updates to VRAM use the 1-page-per-VBlank pattern (2KB per frame) for flicker-free DMA.

Returns
0 (never reached – infinite game loop)

◆ smapDma()

void smapDma ( u16 byte_offset,
u16 vram_addr,
u16 byte_count )
extern

DMA a portion of the WRAM tilemap buffer to VRAM.

Because the tilemap lives in extended WRAM (bank $7E, above $2000), C code cannot access it directly – the compiler generates sta.l $0000,x which always reads bank $00. This assembly helper sets the DMA source bank to $7E and performs the transfer.

Parameters
byte_offsetByte offset into the WRAM tilemap buffer
vram_addrVRAM word address destination
byte_countNumber of bytes to transfer

Variable Documentation

◆ is_map32x32

u8 is_map32x32 = 1

When true, 32x32 map mode is active; when false, 64x64 mode.

◆ max_scroll_height

u16 max_scroll_height

Maximum vertical scroll offset in pixels for the current map mode.

◆ max_scroll_width

u16 max_scroll_width

Maximum horizontal scroll offset in pixels for the current map mode.

◆ palsprite16

u8 palsprite16
extern

Palette for gargoyle sprite in 32x32 mode.

◆ palsprite16_64x64

u8 palsprite16_64x64
extern

Palette for gargoyle sprite in 64x64 mode.

◆ palsprite16_64x64_end

u8 palsprite16_64x64_end

◆ palsprite16_end

u8 palsprite16_end

◆ rockford_8bpp

const u8 rockford_8bpp[256]
static

Pre-computed Rockford sprite in SNES 8bpp planar format.

This 256-byte array encodes a 16x16 sprite as 4 tiles in 8bpp planar format (8 interleaved bitplanes per tile row), ready for direct VRAM upload — no runtime conversion needed.

◆ scroll_lock

u8 scroll_lock = 1

When true, scrolling is clamped to map boundaries; when false, wraps freely.

◆ sprite16

u8 sprite16
extern

8bpp gargoyle sprite tiles for 32x32 map mode (from data.asm)

◆ sprite16_64x64

u8 sprite16_64x64
extern

8bpp gargoyle sprite tiles for 64x64 map mode (from data.asm)

◆ sprite16_64x64_end

u8 sprite16_64x64_end

◆ sprite16_end

u8 sprite16_end

◆ spritemap_len

u16 spritemap_len = 0x2000

Total size of the SC_64x64 tilemap in bytes (4 pages x 2KB).