Tilemap-based sprite engine with 32x32 and 64x64 map modes. More...
Macros | |
| #define | FONT_TILE_OFFSET 0x100 |
| Font tile number offset. | |
| #define | SPRITE_EMPTY 0 |
| Tile index for an empty (cleared) cell in the sprite map. | |
| #define | SPRITE_GARGOYLE 1 |
| Tile index for the gargoyle character sprite. | |
| #define | SPRITE_ROCKFORD 2 |
| Tile index for the C64-converted Rockford character sprite. | |
| #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 | convertC64Sprite (u8 chr_no) |
| Convert a C64 multicolor sprite to SNES 8bpp planar format. | |
| 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 u8 | getPixel (u8 chr_no, u8 tile, u8 x, u8 y) |
| Read a 2-bit pixel from a C64 sprite (multicolor mode). | |
| static void | initDemoMap32x32 (void) |
| Initialize the 32x32 tilemap demo mode. | |
| static void | initDemoMap64x64 (void) |
| Initialize the 64x64 tilemap demo mode with 16x16 BG tiles. | |
| static u8 | isBitSet (u8 b, u8 idx) |
| Test whether bit 'idx' is set in byte 'b'. | |
| int | main (void) |
| Main entry point – dynamic tilemap sprite engine demo. | |
| void | smapClear (u16 byte_count) |
| Clear the extended WRAM tilemap buffer ($7E:2000+). | |
| void | smapDma (u16 byte_offset, u16 vram_addr, u16 byte_count) |
| DMA a portion of the WRAM tilemap buffer to VRAM. | |
Variables | |
| u8 | c64_sprite |
| Raw C64 sprite data (Boulder Dash Rockford character) for conversion demo. | |
| 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. | |
| u16 | number_of_sprites = 0x40 |
| Maximum number of unique sprite-tile entries in the map. | |
| 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 C64 Rockford sprite already in SNES 8bpp 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 |
| static u8 | sprite_temp [256] |
| Temporary buffer for C64-to-SNES sprite format conversion. | |
| u16 | spritemap_len = 0x2000 |
| Total size of the SC_64x64 tilemap in bytes (4 pages x 2KB) | |
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, smapRead, 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 includes a C64-to-SNES 8bpp sprite format converter that demonstrates bitplane interleaving for the SNES graphics format.
Port of the PVSnesLib DynamicMap example.
| #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.
| #define SPRITE_EMPTY 0 |
Tile index for an empty (cleared) cell in the sprite map.
| #define SPRITE_GARGOYLE 1 |
Tile index for the gargoyle character sprite.
| #define SPRITE_ROCKFORD 2 |
Tile index for the C64-converted Rockford character sprite.
| #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)
|
static |
Convert a C64 multicolor sprite to SNES 8bpp planar format.
The SNES 8bpp tile format stores 8 bitplanes per pixel row, grouped in pairs: planes 0-1 for the first 16 bytes, planes 2-3 for the next 16, and so on up to planes 6-7. This function reads pixels from the C64 source (2-bit color) and distributes them across the 8 bitplanes, producing a 256-byte result in sprite_temp[] (4 tiles x 64 bytes each).
| chr_no | Base character number in the C64 sprite data to convert |
|
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.
| sprite | Sprite element index to place at each border cell |
|
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.
| sprite | Sprite element index to place at each border cell |
Read a 2-bit pixel from a C64 sprite (multicolor mode).
C64 multicolor sprites store 2 bits per pixel in a packed row format. The sprite is 8 double-wide pixels per row (16 effective pixels when stretched). This function decodes the pixel at (x, y) within a given tile quadrant of the 16x16 sprite.
| chr_no | Base character number in the C64 sprite data |
| tile | Tile quadrant (0=top-left, 1=top-right, 2=bottom-left, 3=bottom-right) |
| x | X pixel within the 8-pixel tile (0-7) |
| y | Y pixel row within the tile (0-7) |
|
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.
|
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.
Test whether bit 'idx' is set in byte 'b'.
| b | The byte to test |
| idx | Bit position (0 = LSB, 7 = MSB) |
| 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 C64 sprite conversion display. Tilemap updates to VRAM use the 1-page-per-VBlank pattern (2KB per frame) for flicker-free DMA.
|
extern |
Clear the extended WRAM tilemap buffer ($7E:2000+).
| byte_count | Number of bytes to zero in the tilemap buffer |
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.
| byte_offset | Byte offset into the WRAM tilemap buffer |
| vram_addr | VRAM word address destination |
| byte_count | Number of bytes to transfer |
|
extern |
Raw C64 sprite data (Boulder Dash Rockford character) for conversion demo.
| 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.
| u16 number_of_sprites = 0x40 |
Maximum number of unique sprite-tile entries in the map.
|
extern |
Palette for gargoyle sprite in 32x32 mode.
|
extern |
Palette for gargoyle sprite in 64x64 mode.
| u8 palsprite16_64x64_end |
| u8 palsprite16_end |
|
static |
Pre-computed C64 Rockford sprite already in SNES 8bpp format.
This 256-byte array encodes a 16x16 sprite as 4 tiles in 8bpp planar format (8 interleaved bitplanes per tile row). Used for direct VRAM upload without runtime conversion. The data matches what convertC64Sprite() would produce, serving as both a display asset and a verification reference.
| u8 scroll_lock = 1 |
When true, scrolling is clamped to map boundaries; when false, wraps freely.
|
extern |
8bpp gargoyle sprite tiles for 32x32 map mode (from data.asm)
|
extern |
8bpp gargoyle sprite tiles for 64x64 map mode (from data.asm)
| u8 sprite16_64x64_end |
| u8 sprite16_end |
|
static |
Temporary buffer for C64-to-SNES sprite format conversion.
Must reside in bank $00 WRAM (not const / not ROM) because the conversion function writes to it and dmaCopyVram reads from bank $00. 256 bytes = one 16x16 sprite in 8bpp format (4 tiles x 64 bytes).
| u16 spritemap_len = 0x2000 |
Total size of the SC_64x64 tilemap in bytes (4 pages x 2KB)