An interactive menu to switch between all 6 SNES sprite size combinations. The SNES OBJSEL register defines two sizes (small and large) that apply to all 128 sprites. Each sprite chooses small or large via its OAM high-table bit.
| Button | Action |
|---|---|
| D-PAD UP/DOWN | Select sprite size mode |
Then open object_size.sfc in your emulator (Mesen2 recommended).
The built-in font is loaded as 4bpp tiles at VRAM $0000. The text system writes to a RAM buffer, then DMAs to the tilemap at $3800 during VBlank.
Force blank is required because larger sprites (32x32, 64x64) exceed the ~4 KB VBlank DMA budget. Without it, VRAM writes are silently dropped by the PPU.
Tile numbers are offsets from the OBJSEL name base ($4000):
$4100: tile = ($4100 - $4000) / 16 = $10$4500: tile = ($4500 - $4000) / 16 = $50| Mode | Small | Large | OBJSEL Constant |
|---|---|---|---|
| 0 | 8x8 | 16x16 | OBJ_SIZE8_L16 |
| 1 | 8x8 | 32x32 | OBJ_SIZE8_L32 |
| 2 | 8x8 | 64x64 | OBJ_SIZE8_L64 |
| 3 | 16x16 | 32x32 | OBJ_SIZE16_L32 |
| 4 | 16x16 | 64x64 | OBJ_SIZE16_L64 |
| 5 | 32x32 | 64x64 | OBJ_SIZE32_L64 |
Most SNES games use mode 3 (OBJ_SIZE16_L32) – 16x16 for characters and 32x32 for bosses/effects. Mode 0 (OBJ_SIZE8_L16) is common for simple games with small sprites.
This register sets the global size pair and name base address. Changing it affects ALL 128 sprites simultaneously, so games typically pick one mode at startup and stick with it for the entire game. The size pair defines what "small" and "large" mean – individual sprites select between the two via oamSetSize().
Each of the 128 sprites has 2 extra bits stored in 32 bytes of high table:
These bits are packed 4 sprites per byte. The oamSetSize() function writes the size bit; the X high bit is set automatically by oamSet() / oamSetX() when needed.
The SNES PPU silently ignores VRAM writes during active display (scanlines 0-223). A 64x64 sprite is 8 KB of tile data – far too much for VBlank DMA. Use REG_INIDISP = 0x80 to disable rendering, transfer the data, then restore with REG_INIDISP = 0x0F.
| Address | Content | Size |
|---|---|---|
$0000 | Font tiles (4bpp) | ~3 KB |
$3800 | BG1 tilemap (text) | 2048 bytes |
$4000 | Sprite name base | – |
$4100 | Small sprite tiles | varies |
$4500 | Large sprite tiles | varies |
| File | Purpose |
|---|---|
main.c | Menu UI, size mode switching, sprite loading |
data.asm | Four sprite sizes (8/16/32/64) with palettes via .INCBIN |
res/ | Source PNGs for each sprite size |
Makefile | LIB_MODULES := console sprite dma text text4bpp input background |
sprites/simple_sprite – Basic static sprite setupsprites/animated_sprite – Frame-based sprite animationsprites/dynamic_sprite – VRAM streaming for many animation frames