Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
23 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

snes-homebrew

Platform: SNES Language: C PVSnesLib 4.5.0

Original Super Nintendo games, written from scratch in C with PVSnesLib. These are real ROMs: each one is a single LoROM cartridge image under 512 KB, uses no enhancement chips, and boots on actual SNES hardware as well as emulators. A runtime region check keeps them running correctly on both NTSC (60 Hz) and PAL (50 Hz) consoles.

Inside you'll find a complete action-platformer demo and a smaller project that exercises the full build pipeline end to end.


Gothicvania (gothicvania/)

A SNES action-platformer demo set in a haunted graveyard.

Gothicvania — the hero faces a risen skeleton under a blood moon

  • Flow: title screen → play → "Game Over" (on death) or "Thanks for Playing" (on finish), driven by a TITLE → PLAY → END / GAMEOVER state machine.
  • World: a 4800 px horizontally-scrolling level with 3-depth HDMA parallax, a per-scanline colour-math sky gradient, and a moon — rendered by a custom 64×32 page-streaming engine that keeps the whole level resident in under 16 KB of VRAM.
  • Hero: run / jump / attack / hurt, gravity + per-tile collision (solid ground + one-way platforms), with movement speeds that stay equal on NTSC and PAL.
  • Enemies: three types sharing two streamed sprite slots — skeleton (rises from the ground, chases), hell-gato (paces back and forth), ghost (floats, bobs, turns to face you) — each with sword-kill + contact-knockback combat and a shared fiery death poof.
  • Hazards & life: spike pits (−1 HP), a 3-HP limit → game over, fall-out respawn.
  • Audio: original looping music (separate in-game and title tracks) + sound effects, via snesmod.

Art: the graphics are adapted from the GothicVania Cemetery pack by ansimuz, released under CC0, reworked to fit SNES VRAM and palette limits. (Full credits below.)

hello-world-region (hello-world-region/)

A region-aware "hello world" that walks the whole pipeline end to end (C → 816-tcc → WLA-DX → ROM → Mesen2 → hardware) and shows identical behaviour at 50 Hz and 60 Hz.

hello-world-region — region detection (NTSC / 60 Hz) and a per-second counter


Building it yourself

Toolchain

Tool Version Installed at Source
PVSnesLib 4.5.0 (released 2025-12-28) ~/pvsneslib$PVSNESLIB_HOME release 4.5.0 (pvsneslib_450_64b_darwin.zip)
Mesen2 2.1.1 (released 2025-07-06) /Applications/Mesen.app release 2.1.1 (macOS_ARM64_AppleSilicon)

Built and tested on macOS 26.4.1, Apple Silicon (arm64). Both the PVSnesLib tool binaries and Mesen are native arm64 — no Rosetta required.

Setup

PVSnesLib finds all its tools through a single environment variable, exported from ~/.zshrc:

export PVSNESLIB_HOME="$HOME/pvsneslib"

That's all the build needs — devkitsnes/snes_rules references every tool (816-tcc, wla-65816, wlalink, gfx4snes, smconv, snesbrr) by absolute path under $PVSNESLIB_HOME. make comes from the Xcode Command Line Tools. Open a new terminal (or source ~/.zshrc) so the variable is set.

Build

From a project directory (gothicvania/ or hello-world-region/):

make            # produces <ROMNAME>.sfc (+ .sym for the debugger)
make clean      # remove build artifacts

The committed gothicvania/res/*.png and *.bin are the source of truth for the art, and make builds the ROM straight from them. The original source-art pack isn't in the repo, so the tools/adapt_*.py / build_*.py converters are kept as readable references only — they no longer run (see the Makefile's "FROZEN ART" note).

Run it in Mesen

mesen gothicvania/gothicvania.sfc      # helper defined in ~/.zshrc

The mesen helper passes the ROM as a CLI argument (open -na Mesen --args <abs-path>). Plain open -a Mesen file.sfc won't work — Mesen.app declares no .sfc document type, so it launches without loading the ROM. You can also drag the .sfc onto the window, or use File → Open (⌘O). To see the NTSC/PAL behaviour, force each region in Mesen's emulation settings.

Building on macOS

PVSnesLib's shared build rules post-process the linker's .sym file with GNU-style sed -i '<script>'. macOS ships BSD sed, which misparses that form and fails the final build step (sed: ... extra characters at the end of h command) even though the ROM itself links fine.

The fix is to rewrite the two in-place edits in $PVSNESLIB_HOME/devkitsnes/snes_rules (around lines 178 and 184) to a portable temp-file form:

# before (GNU-only, breaks on macOS BSD sed):
	@sed -i '<script>' $(ROMNAME).sym
# after (portable, works with BSD and GNU sed):
	@sed '<script>' $(ROMNAME).sym > $(ROMNAME).sym.tmp && mv -f $(ROMNAME).sym.tmp $(ROMNAME).sym

The two scripts are s/:// and / SECTIONSTART_/d;/ SECTIONEND_/d;/ RAM_USAGE_SLOT_/d;. This file lives in the PVSnesLib install (outside this repo) and is shared by every PVSnesLib project on the machine, so re-apply the change after reinstalling or upgrading PVSnesLib. The original is preserved as snes_rules.orig.


Credits & acknowledgements

  • ArtGothicVania Cemetery by ansimuz, released under CC0. Adapted to fit SNES VRAM and palette limits.
  • PVSnesLib by Alekmaul and contributors — the C toolchain and SNES library these games are built on.
  • Mesen2 by SourMesen — emulator and debugger.

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.