Metasprite composition with switchable OBJ size modes. More...
#include <snes.h>#include "res/hero8_meta.inc"#include "res/hero16_meta.inc"#include "res/hero32_meta.inc"Macros | |
| #define | BASE_TILE_16 (HERO32_TILES) |
| #define | BASE_TILE_32 0 |
| Base tile numbers for oamDrawMeta(). | |
| #define | BASE_TILE_8 (HERO32_TILES + HERO16_TILES) |
| #define | HERO16_TILES 96 |
| Number of tiles in the 16x16 hero sprite sheet. | |
| #define | HERO32_TILES 192 |
| Number of tiles in the 32x32 hero sprite sheet. | |
| #define | HERO8_TILES 16 |
| Number of tiles in the 8x8 hero sprite sheet. | |
| #define | TILE_BYTES 32 |
| Bytes per 4bpp 8x8 tile (8 rows x 4 bits/pixel x 8 pixels / 8 bits = 32) | |
| #define | VRAM_FONT 0x4000 |
| VRAM word address for the 4bpp BG1 font tiles. | |
| #define | VRAM_HERO16 0x0C00 |
| VRAM word address for 16x16 hero tiles (after 32x32 tiles) | |
| #define | VRAM_HERO32 0x0000 |
| Metasprite frame definitions generated by gfx4snes -P. | |
| #define | VRAM_HERO8 0x1200 |
| VRAM word address for 8x8 hero tiles (after 16x16 tiles) | |
| #define | VRAM_TEXT_MAP 0x6800 |
| VRAM word address for the BG1 text tilemap. | |
Functions | |
| static void | changeObjSize (void) |
| Atomically switch OBJSEL size mode and update OAM in one VBlank. | |
| static void | drawMenu (void) |
| Redraw the on-screen menu showing all three OBJ size modes. | |
| static void | drawSprites (void) |
| Render metasprites using oamDrawMeta() for the current size mode. | |
| int | main (void) |
| Entry point: metasprite demo with switchable OBJ size modes. | |
Variables | |
| u16 | selectedItem |
| Currently selected OBJ size mode index (0-2), controlled by UP/DOWN. | |
| u8 | spritehero16_til [] |
| 4bpp tile data for the 16x16 hero sprite | |
| u8 | spritehero32_pal [] |
| Shared palette for all three hero sprite sizes. | |
| u8 | spritehero32_til [] |
| 4bpp tile data for the 32x32 hero sprite (defined in data.asm) | |
| u8 | spritehero8_til [] |
| 4bpp tile data for the 8x8 hero sprite | |
Metasprite composition with switchable OBJ size modes.
Demonstrates metasprites: large characters built from multiple hardware OAM entries using oamDrawMeta(). The SNES OBJSEL register ($2101) provides two sprite sizes (small and large) that all 128 OAM entries share. This example lets the user switch between three size combinations to see how the same character is composed from differently-sized pieces.
Three sprite sheets (8x8, 16x16, 32x32) are pre-loaded to contiguous VRAM. The gfx4snes -T flag transposes the sprite sheet tiles into SNES OBJ VRAM layout, and the -P flag generates metasprite frame definitions (tile offsets + positions) included as C arrays.
When the OBJ size mode changes, OBJSEL and OAM must be updated atomically within the same VBlank to avoid one frame of garbled sprites.
| #define BASE_TILE_16 (HERO32_TILES) |
First tile of 16x16 sheet (192)
| #define BASE_TILE_32 0 |
Base tile numbers for oamDrawMeta().
oamDrawMeta() adds the baseTile offset to each metasprite entry's relative tile number to compute the final OAM tile index. Since all three sprite sheets are loaded contiguously in VRAM, each sheet's base tile is the cumulative tile count of all preceding sheets. First tile of 32x32 sheet
| #define BASE_TILE_8 (HERO32_TILES + HERO16_TILES) |
First tile of 8x8 sheet (288)
| #define HERO16_TILES 96 |
Number of tiles in the 16x16 hero sprite sheet.
| #define HERO32_TILES 192 |
Number of tiles in the 32x32 hero sprite sheet.
| #define HERO8_TILES 16 |
Number of tiles in the 8x8 hero sprite sheet.
| #define TILE_BYTES 32 |
Bytes per 4bpp 8x8 tile (8 rows x 4 bits/pixel x 8 pixels / 8 bits = 32)
| #define VRAM_FONT 0x4000 |
VRAM word address for the 4bpp BG1 font tiles.
| #define VRAM_HERO16 0x0C00 |
VRAM word address for 16x16 hero tiles (after 32x32 tiles)
| #define VRAM_HERO32 0x0000 |
Metasprite frame definitions generated by gfx4snes -P.
Each .inc file defines arrays (e.g., hero8_frame0[]) that describe how to compose a character from multiple OAM entries. Each entry in the array contains the relative X/Y offset and tile number for one hardware sprite. oamDrawMeta() reads these arrays to populate OAM.
VRAM word address for 32x32 hero tiles
| #define VRAM_HERO8 0x1200 |
VRAM word address for 8x8 hero tiles (after 16x16 tiles)
| #define VRAM_TEXT_MAP 0x6800 |
VRAM word address for the BG1 text tilemap.
|
static |
Atomically switch OBJSEL size mode and update OAM in one VBlank.
Changing OBJSEL and OAM must happen in the same VBlank frame. If OBJSEL changes in one VBlank but OAM still contains tile numbers calculated for the old size mode, the PPU interprets the tiles with the wrong dimensions for one frame, causing visible sprite garbling.
The "fresh sync" pattern clears vblank_flag after preparing the OAM buffer, ensuring WaitForVBlank() waits for a NEW NMI (not a stale flag from an NMI that may have fired mid-preparation and DMA'd a partial buffer).
|
static |
Redraw the on-screen menu showing all three OBJ size modes.
Prints the three available size combinations with a ">" cursor next to the currently selected mode. The text is rendered to a BG1 tilemap buffer and DMAed to VRAM by the NMI handler during the next VBlank.
|
static |
Render metasprites using oamDrawMeta() for the current size mode.
oamDrawMeta() reads metasprite frame data (tile offsets + positions) and populates multiple OAM entries to compose a large character from smaller hardware sprite pieces. It returns the next available OAM ID, allowing multiple metasprites to be drawn without ID conflicts.
Each size mode uses a different combination of LARGE and SMALL sprites to render two characters: one larger (left) and one smaller (right).
< First tile of 16x16 sheet (192)
< First tile of 8x8 sheet (288)
< First tile of 32x32 sheet
< First tile of 8x8 sheet (288)
< First tile of 32x32 sheet
< First tile of 16x16 sheet (192)
| int main | ( | void | ) |
Entry point: metasprite demo with switchable OBJ size modes.
Sets up a text menu on BG1, loads three sizes of hero sprite tiles to contiguous OBJ VRAM, and lets the user switch between three OBJSEL size combinations to see how metasprites are composed from differently-sized hardware sprite pieces.
| u16 selectedItem |
Currently selected OBJ size mode index (0-2), controlled by UP/DOWN.
|
extern |
4bpp tile data for the 16x16 hero sprite
|
extern |
Shared palette for all three hero sprite sizes.
|
extern |
4bpp tile data for the 32x32 hero sprite (defined in data.asm)
|
extern |
4bpp tile data for the 8x8 hero sprite