Small SNES homebrew project built with PVSnesLib. The game ROM is generated as snesgame2.sfc and can be run in a SNES emulator after building.
- C for game logic in
src/main.c - PVSnesLib for the SNES SDK and build rules
- GNU Make under a Linux or WSL shell
- PVSnesLib graphics conversion tools during
make - Python helper scripts in
tools/for regenerating source BMP art
src/main.c: main game codeMakefile: build rules and graphics conversion stepstools/: helper scripts to regenerate some sprite BMP assets*.bmp/pvsneslibfont.png: authored source graphics used by the build*.pic,*.pal,*.inc,*_data.as: generated SNES graphics data consumed by the gamesnesgame2.sfc: built ROM output
The build targets a Linux or WSL shell with GNU Make.
Install PVSnesLib and set PVSNESLIB_HOME to point at it, using a Unix-style
path. Add it to your shell profile (e.g. ~/.bashrc) so every shell has it:
export PVSNESLIB_HOME=/opt/pvsneslibThe Makefile reads PVSNESLIB_HOME and stops with an error if it isn't set.
Needed to run the helper scripts in tools/ that regenerate some BMP assets.
They use only the standard library (no pip install required).
Any emulator that can load .sfc ROMs should work.
The build works in two stages:
- Convert image assets into SNES graphics data.
- Compile and link the game into
snesgame2.sfc.
The Makefile target flow is:
all: artifacts snesgame2.sfcartifacts groups the asset-conversion steps (bitmaps, musics, brrsound).
The bitmaps target regenerates SNES-ready graphics data from the source images:
pvsneslibfont.png->pvsneslibfont.pic,pvsneslibfont.palsprites.bmp->sprites.pic,sprites.palenemy.bmp->enemy.pic,enemy.paltac2.bmp->tac2.pic,tac2.palbullet.bmp->bullet.pic,bullet.pal
From those assets, the PVSnesLib build rules generate the final ROM.
With PVSNESLIB_HOME set (see Required Tools), build from the project directory:
makeTo rebuild just the converted assets without linking the ROM:
make artifactsTo remove all build output and generated asset data:
make cleanmake/make all: convert assets, compile code, and producesnesgame2.sfcmake artifacts: convert source art/sound into SNES data, without linking the ROMmake clean: remove the ROM, build intermediates, and generated asset data through the PVSnesLib clean rules
This project keeps source art in standard image formats and converts them during the build.
sprites.bmp: player sprite sheetenemy.bmp: enemy sprite sheet (Genesis console; one hit to destroy)tac2.bmp: tough enemy sprite (TAC-2 joystick; takes three hits to destroy)bullet.bmp: bullet spritepvsneslibfont.png: font image
The conversion step produces files such as:
.pic: tile graphics.pal: palettes.inc: include symbols for the game code*_data.as: assembler data blobs used by the linker
These generated files are already present in the repository, but they can be regenerated by rebuilding.
The Python scripts in tools/ are not part of the normal make target. They are helper utilities for regenerating the source BMP files before running the build. They share tools/snesbmp.py (a small standard-library helper that draws onto an indexed canvas and writes the 8bpp BMP), and they use only the Python standard library, so they run the same on Windows, Linux, and WSL.
- Rebuilds
sprites.bmp - Preserves an original backup at
tools/sprites_src.bmp - Downscales the player art to roughly
21x21inside a32x32sprite cell
Run it with:
python3 tools/make_player_bmp.py- Generates
enemy.bmp - Creates an 8bpp
32x32enemy sprite with a fixed palette - Downscales the art to roughly
21x21inside a32x32sprite cell
Run it with:
python3 tools/make_enemy_bmp.py- Generates
tac2.bmp - Creates an 8bpp
32x32sprite of a Suncom TAC-2 arcade joystick (red ball-top stick, chrome shaft, black base with a red fire button) - Draws the art in the top-left
21x21of the32x32cell so it lines up with the enemy hit-box - This is the tougher enemy: it takes three hits to destroy (a screen-clearing bomb still flattens it in one), descends more slowly, and is worth more points
Run it with:
python3 tools/make_tac2_bmp.py- Generates
bullet.bmp - Creates an 8bpp
8x8bullet sprite with a small fixed palette
Run it with:
python3 tools/make_bullet_bmp.pyAfter running any of these scripts, rebuild the project so the .bmp changes are converted into SNES asset data.
Successful builds produce:
snesgame2.sfc
Other intermediate files such as object files, symbol files, and converted graphics data may also be produced or refreshed.
If make stops immediately with a message about PVSNESLIB_HOME, export the
variable so it points at your PVSnesLib install (a Unix-style path), e.g.
export PVSNESLIB_HOME=/opt/pvsneslib, and add it to your shell profile so it
persists.
PVSNESLIB_HOME must be a Unix-style path (PVSnesLib's build rules reject paths
containing a backslash). Under WSL, point it at a Linux path or a /mnt/c/...
mount, not a C:\... path.
If you edited or regenerated a BMP or the font PNG, rebuild the ROM so the graphics conversion step runs again.
python3 tools/make_enemy_bmp.py
python3 tools/make_bullet_bmp.py
makeIf you did not change the source art, only make is needed.