OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
The OpenSNES toolbox

Your game is written in C, but the SNES does not eat PNGs, Tiled maps, or WAV files — it eats tiles, tilemaps, BGR555 palettes, BRR samples, and SPC700 soundbanks. The OpenSNES tools are the converters that bridge the two: each takes an artist- or musician-friendly source format and emits the exact binary the hardware (and this SDK's runtime) expects.

You rarely run most of them by hand — the build system wires the common ones in, so dropping a .png or .wav in an example's res/ is usually enough. But knowing what each tool does, and which knobs it exposes, is what takes you from "the example builds" to "I shaped my own assets on purpose." That confidence is what this section is here to give.

The pipeline

Most assets flow through a short, one-way pipeline from source art to ROM data:

RGB art ──► img2snes ──► gfx4snes ──► tmx2snes ──► map engine
(.png) (quantize) (tiles + (Tiled map (mapLoad)
palette + + that .map
tilemap) → map binaries)
font.png ──► font2snes ──► text tiles (dmaCopyVram)
sound.wav ─► wav2brr ──► .brr sample (audioLoadSample)
music.it ──► smconv ──► SNESMOD bank (snesmodLoadModule / snesmodPlay)
hero.ase ─┬► gfx4snes -P ──► tiles + metasprite table (oamDrawMetasprite)
└► aseprite2snes ──► AnimClip tables (animPlay / animTick)

Each tool does exactly one conversion; the Makefile chains them. It is the Unix-pipe idea applied to asset building — small, composable, individually testable steps rather than one opaque converter.

The tools at a glance

Tool Turns… …into In your build
gfx4snes — images to tiles, palettes & maps an indexed PNG/BMP tiles + palette + tilemap auto (drop a PNG in GFXSRC)
tmx2snes — Tiled levels to SNES map data a Tiled JSON map tilemap + collision + objects one line per example
img2snes — RGB artwork to indexed palettes RGB/RGBA artwork a palette-indexed PNG (feeds gfx4snes) manual pre-step
font2snes — font images to text tiles a 96-glyph font PNG 2bpp/4bpp text tiles manual, optional
wav2brr — WAV to BRR sound samples a PCM .wav a .brr sound sample auto (drop a WAV in res/)
smconv — tracker modules to SNESMOD soundbanks an Impulse Tracker .it a SNESMOD soundbank auto (USE_SNESMOD)
palplan — project shared-palette planner a manifest of .pal files a CGRAM layout + C header manual, project-level
aseprite2snes — Aseprite animations → AnimClip tables an Aseprite animation export AnimClip tables (one per tag) one line per sprite

Three levels of wiring

The tools sit at three levels of automation — worth knowing so you reach for the right one:

  1. Zero-config, automatic. gfx4snes (via the GFXSRC Makefile variable) and wav2brr (any res/*.wav) and smconv (USE_SNESMOD := 1) run for you during make. Drop the source in, reference the output, done.
  2. One explicit line. tmx2snes is called from an example's own Makefile, because a Tiled project has choices (which layers, which extra outputs) the build cannot guess.
  3. By hand, when you need them. img2snes (RGB → indexed) and font2snes (custom font) are standalone pre-steps you run once and commit the result. Looping wav2brr samples are also hand-built (the loop points are yours). palplan sits a level up from the per-asset tools: it plans your whole project's palettes into the SNES's 8 BG + 8 sprite slots at once, so you run it when your palette count grows, not per asset. (In the opensnes-* family these three are opensnes-palette quantize, opensnes-text font and opensnes-palette plan, and the font and the plan run from the build.)

All binaries live in bin/ and are built by make tools. Every tool prints --help; the pages here are the guided version.

Where the tools are going

The opensnes-* family replaces these converters — one tool per function, the same conventions everywhere, settings beside each asset. The opensnes-* tools: conventions is the contract; the earlier tools stay one more release. The first two are opensnes-sample — WAV to BRR samples (WAV → BRR) and opensnes-music — Impulse Tracker to soundbank (Impulse Tracker → soundbank); opensnes-rom — is the ROM good? runs the post-link checks of every build; opensnes-sprite — sheets, metasprites and Aseprite clips is the sprite artist's tool (sheets, metasprites, Aseprite clips); opensnes-level — Tiled levels to SNES map data turns a Tiled level into map, tile tables and entities; opensnes-tileset — pictures to tilesets and tilemaps the background artist's (tilesets, tilemaps, palette banks); opensnes-text — bitmap fonts for the text module converts a typeface; opensnes-palette — a project's palettes plans a project's palettes into CGRAM and quantizes RGB art; opensnes-image — full-screen pictures and their tables makes HiColor screens and the Mode 7 perspective tables; opensnes-save — battery save files creates, reads and patches battery save files; and opensnes — the project tool is the project's own command (init, build, run, test, doctor).

Your Makefile

The build itself has knobs — cartridge mapping, save RAM, coprocessor, ROM size, the link-time checks. Your project's Makefile lists every one with its default.

The emulator: luna

Testing is not a converter, but it is the other tool you will run every day. luna is the cycle-accurate emulator behind make tests, luna mcp is the debugger, and luna — command reference (pinned v1.38.0) is the pinned release's own --help, one section per subcommand — generated from the binary, so it cannot drift from testing/luna.version.

Where they fit with the rest of the docs

The one rule. Keep the source (the PNG, the Tiled project, the WAV, the .it) as your single source of truth and let the tools regenerate the binary on every build. The moment you hand-edit a .pic or a .brr, it drifts from its source and you have lost the pipeline's whole benefit.