piuGBA

November 8, 2025 · View on GitHub

This is a PIU simulator for the GBA that uses StepMania SSC charts.

demo1demo2demo3demo4demo5demo6demo7demo8demo9demo10demo11demo12

rlabs Created by [r]labs.

discord Join our community!

Key features

  • Full .ssc files support, including:
    • Normal, hold and fake notes
    • BPM changes
    • Scroll speed changes
    • Stops/Delays and async-stops
    • Warps and fast-BPM warps
  • Multiple game modes:
    • Campaign: Play, unlock songs and defeat bosses
    • Arcade: Play songs in any numerical difficulty level
      • Single: 1 player, either Single (5-panel) or Double (10-panel) charts
      • Multi VS: VS battles via Link Cable or Wireless Adapter
      • Multi COOP: Double (10-panel) charts via Link Cable or Wireless Adapter
    • Impossible: Faster songs with insane mods
  • Speed multipliers can be changed in-game
  • Mods support:
    • Stage break: On, Off or SuddenDeath
    • Pixelate: Mosaic effect
    • Jump/Reduce: Moves game area
    • Bounce: Makes the arrows bounce
    • Color filter: Alters colors
    • Speed hack: AutoVelocity, FixedVelocity or RandomSpeed
    • Mirror and random steps
    • Training mode: Rate, Fast-forward, Rewind
    • AutoMod: Swaps mods randomly
  • Background videos (uncompressed 240x160) can be displayed using a flash cart
  • HQ audio (uncompressed s8 PCM) can be played using a flash cart
  • Two themes: Classic and Modern
  • BGA DARK background with blink effect
  • Song selector with names, backgrounds and sound previews
  • Hardware integrations:
    • Rumble
    • I/O LED Sync
    • SRAM LED Sync
    • PS/2 input
  • Optimized to support ~70 songs per ROM file.

Downloads

The downloads provided in our Releases section include:

  • A portable song importer for Windows.
  • 4 clean builds (without songs) ready to be used with the importer.
    • If you use the portable importer, these files are not needed!
  • A small demo with 9 songs from Project Outfox Serenity's Volume I & II sets.

To play, you need to build a ROM with your songs.

How does it work?

A node.js script (the importer) converts a list of SSC/MP3/PNG files into binary files which the GBA can then understand. For audio, it uses GSM audio files which are very small in size.

Charts are converted into a format created for this project called PIUS. Then everything is bundled in a GBFS file (a filesystem created by the GBA scene) and appended to the final ROM.

Read the wiki for more details!

How to a build a ROM

Wiki: Building a ROM

Developing

Install - Any OS (Docker)

  • If you are on Windows, install WSL2
  • Install Docker
  • Run:
# download docker image
docker pull afska/piugba-dev

# compile game assets
./dockermake.sh assets

# install importer dependencies
./dockermake.sh install

# run ./dockermake.sh {action} {arguments...}
# for example, to build a clean Arcade ROM, use:
./dockermake.sh build ENV=production ARCADE=true

Actions

Commands

  • make install: Installs the importer dependencies
  • make check: Verifies that all the tools are installed correctly
  • make clean: Cleans build artifacts (except assets)
  • make assets: Compiles the needed assets in src/data/content/_compiled_sprites (required for compiling)
  • make build: Compiles and generates a .gba file without data
  • make import: Imports the songs from src/data/content/songs to a GBFS file
  • make pkg: Appends the GBFS file to the ROM (piugba.gba -> piugba.out.gba)
  • make package: Compiles and appends the GBFS file to the ROM (build+pkg)
  • make start: Packages and starts the compiled ROM (package + launch rom)
  • make rebuild: Recompiles a full ROM (clean+package)
  • make restart: Recompiles and starts the ROM (rebuild+start)
  • make reimport: Reimports the songs and starts the ROM without recompiling (import+package+start)

Parameters

NameValuesDescription
ENVdevelopment, or debug or productiondebug: everything is unlocked, backgrounds are disabled, and stage-break is OFF.
development: the same thing, but including backgrounds.
production: backgrounds, stage-break ON, and working locks.

Non-production versions also have:

1) PIU-style controls by default, and a debug menu to correct songs' offsets. See Wiki: Correcting offsets.

2) If SELECT is pressed when a campaign song starts, stage-break will be ON regardless of the environment.

3) Profiling code and some logs.
BOSSfalse or trueAutomatically adds boss levels to the campaign modes.
ARCADEfalse or trueCreates an arcade-only version of the game that only uses numeric levels, without the campaign modes.

Add this parameter to both import and build commands!
SONGSpath to a directorySongs directory. Defaults to: src/data/content/songs
VIDEOLIBpath to a directoryVideo library output directory. Defaults to: src/data/content/piuGBA_videos
VIDEOENABLEfalse or trueEnables the conversion of video files (from ${SONGS}/_videos) to the VIDEOLIB folder.
HQAUDIOLIBpath to a directoryHQ Audio library output directory. Defaults to: src/data/content/piuGBA_audios
HQAUDIOENABLEfalse or trueEnables the conversion of HQ audio files to the HQAUDIOLIB folder.
FASTfalse or trueUses async I/O to import songs faster. It may disrupt stdout order.

In Docker builds, for SONGS, VIDEOLIB and HQAUDIOLIB, only use relative paths to folders inside your project's directory!

Install - Windows (Native)

Advanced usage only! The code requires specific versions of tools that are difficult to obtain, and I cannot provide them. I created the Docker image so everyone can have the same environment.

  • Choose a folder (from now, GBA_DIR) and use this file structure:
    • gba
      • tools
        • devkitPro
      • projects
        • piugba
  • Install the toolchain:
    • Dev
      • devkitPro r53 (with gcc 9.1.0): The devkit for compiling GBA ROMs. It comes with:
        • grit: Used to convert paletted bitmaps to C arrays or raw binary files
        • gbfs: Used to create a package with all the game assets
        • ⚠️ While newer versions of gcc may work, they might require some tweaks. I've noticed that with gcc 14 the code runs 5% slower and have worse compatibility with some emulators, so I prefer to stick with gcc 9.
      • node 14.*: The JS runtime
      • make 3.81 (compiled for i386-pc-mingw32): The build automation tool
    • Media Processing
      • ImageMagick 7.0.10.3: The tool used to convert images to paletted bitmaps
      • ffmpeg 3.3.3 (bundled with libgsm): The tool used to convert audio files to GSM
        • ⚠️ Avoid using the ffmpeg.exe binary included with ImageMagick or any other version. After 3.3.3, they stopped including libgsm on Windows builds.
      • png-fix-IDAT-windowsize 0.5: A small command line util to fix corrupted PNG files
    • Other
      • Git Bash: Linux shell and tools. It contains required commands like dd or md5sum
      • VSCode: The IDE
  • Install node dependencies:
cd scripts/importer
npm install
  • Add to ~/.bash_profile:
# set your ImageMagick install path here:
export PATH=$PATH:/c/Program\ Files/ImageMagick-7.0.10-Q16

export GBA_DIR="/c/Work/gba" # <<< CHANGE THIS PATH

export DEVKITPRO="$GBA_DIR/tools/devkitPro"
export PATH="$PATH:$GBA_DIR/tools/devkitPro/bin"
export PATH="$PATH:$GBA_DIR/tools/devkitPro/devkitARM/bin"
export PATH="$PATH:$GBA_DIR/tools/devkitPro/tools/bin"
  • You can check if the tools are installed correctly by running make check

VSCode

  • Recommended plugins: C/C++ Extensions, EditorConfig, Prettier - Code formatter
  • Recommended settings: here

Scripts

Build sprites

# use #FF00FD as transparency color
grit *.bmp -ftc -pS -gB8 -gT ff00fd -O shared_palette.c

Build backgrounds

magick file.png -resize 240x160\! -colors 255 file.bmp
grit file.bmp -gt -gB8 -mRtf -mLs -ftb

Build music

ffmpeg -y -i file.mp3 -ac 1 -af 'aresample=18157' -strict unofficial -c:a gsm file.gsm
ffplay -ar 18157 file.gsm

Build filesystem

gbfs files.gbfs *.pius *.gsm *.bin
# pad rom.gba to a 256-byte boundary
cat rom.gba files.gbfs > rom.out.gba

Build gba-sprite-engine

rm -rf cmake-build-debug ; mkdir cmake-build-debug ; cd cmake-build-debug ; cmake ../ -G "Unix Makefiles" ; make ; cp engine/libgba-sprite-engine.a ../../piugba/libs/libgba-sprite-engine/lib/libgba-sprite-engine.a ; cd ../ ; rm -rf ../piugba/libs/libgba-sprite-engine/include/ ; cp -r ./engine/include ../piugba/libs/libgba-sprite-engine/

Build importer.exe

cd scripts/importer
npm install -g pkg
pkg --targets node14-win --config package.json -o importer.exe --public --public-packages "*" --no-bytecode --compress GZip src/importer.js

Troubleshooting

How to debug

  • In Makefile, replace -Ofast by -Og -g to include debug symbols in the .elf file
  • In mGBA, go to Tools -> Start GDB server...
  • Start debugging in VS Code

Undefined reference to function name

If you've added new folders, ensure they're in Makefile's SRCDIRS list!

Open-source projects involved