Open-source project
SAT-R/sa2 avatar
SAT-R/sa2

sa2: a matching C decompilation of Sonic Advance 2 with desktop ports

A decompilation and port of Sonic Advance 1 & 2 - GameBoy Advance game's written in C

685 stars72 forksCLicense varies

At a glance

What is it?
SAT-R/sa2 rebuilds Sonic Advance 1 and 2 from C source so the binaries match the retail ROMs byte for byte, and layers SDL, Win32, PS2 and PSP ports on top. It is written for people who want to read, document and port the game rather than just play it.
Who is it for?
sa2 fits reverse engineers, students and hobbyists who want a readable C reconstruction of a Game Boy Advance game and a base for their own ports. It does not fit players looking for a convenient way to run the game, since the Win32 port is marked not functional and the build still depends on unmatched assembly.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 83 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What a matching decompilation of Sonic Advance actually is

The goal here is unusually strict. Most reverse engineering efforts produce a program that behaves like the original. This project aims higher: the C source has to compile into a binary identical to the retail cartridge, byte for byte, which is verified against published SHA1 hashes. The project page lists the ROMs it targets, including sa1.gba for Europe, sa2.gba for the USA, European and Japanese releases, the Japanese Virtual Console release and an October 2002 beta, each with its hash and a link to the corresponding datomatic.no-intro.org record.

That target changes how the code is written. When the output has to match a fixed binary, a function cannot merely behave correctly, it must produce the same bytes, in the same order, with the same register use. That is why the repository still contains assembly files that are pulled into the C compilation process, and why functions are tracked individually in a non_matching directory rather than rewritten wholesale.

The audience is people who want to read the source of a game they love. The maintainer states that the project was created as a learning exercise, and that its real world outcomes are the ability to play, mod and port the game. The idea is that reading a disassembly is slow and reading C is not, so a faithful C reconstruction is a teaching tool. For an engineer evaluating this repository, that framing matters more than the ports.

The project also links a sibling effort for Sonic Advance 3 and points out that the Kirby & The Amazing Mirror decompilation uses the same engine, since the original game was written by the same team, Dimps. That shared engine is the reason this reconstruction is interesting to study.

Non-matching assembly is compiled inside the C build, not kept aside

The architecture of the repository makes one design choice visible from the first look. Under asm there are two directories: macros, holding common macros used in assembly files, and non_matching, holding the non-matching assembly that is pulled into the C compilation process. Assembly is therefore part of the build, not a leftover artefact sitting next to it.

The project tracks its own progress with per-game badges generated from JSON report files, split into decompilation progress and decompilation matching progress for SA1, SA2 and the sub games. Two numbers in the README describe where the work stands for SA2: the build is described as being 100 percent from C files, with roughly 60 functions that currently do not match, and more than 600 functions are still unnamed even though most aspects of core gameplay have been documented.

Those two figures point in different directions, and the difference is instructive. The code is written in C and the assets are extracted, but a function only counts as matching when its compiled output equals the original. Roughly 60 functions still do not. Those functions live in asm/non_matching and are assembled during the build, which keeps the binary correct while the human work continues.

Everything else has been pulled out of the ROM and documented. All assembly code has been extracted, disassembled and decompiled by hand into its C equivalent. Songs are extracted and documented as matching MIDI files. Sprite animation frames are extracted to PNGs and used to build the matching ROM, and tilemaps have been documented with their tiles extracted.

Four ports beyond the Game Boy Advance original

Beyond the matching GBA builds, the project ships port targets. The README describes an SDL 64-bit port for Linux and macOS, an SDL 64-bit port for Windows, a Win32 OpenGL port, a PlayStation 2 port that requires PS2DEV, and a PlayStation Portable SDL port that requires PSPDEV. The PSP target produces an EBOOT.PBP, which is the format the handheld expects.

The port targets are selected with make arguments named in the README: `make sdl` for the Linux and macOS SDL build, `make sdl_win32` for the Windows SDL build, `make win32` for the Win32 OpenGL port, `make ps2` for the PlayStation 2 ISO and `make sdl_psp` for the PSP EBOOT.PBP. The Win32 OpenGL target is marked with a construction sign and described as not functional, so treat it as an unfinished path rather than a working one.

One deliberate change carries across the ports. The game compiles to a widescreen port at 426x240 for multiple platforms. That is a modification of the original output, which sits in tension with the matching goal, and it is a good example of how the project separates the two ambitions: the GBA targets aim at byte-identical output, while the desktop and console ports are freer.

None of the port binaries are released as GitHub releases, and the project has no GitHub releases at all. You produce these artifacts yourself from source.

The Makefile picks a cross compiler from PLATFORM and CPU_ARCH

Build configuration lives in the Makefile and a config.mk file that the Makefile includes, with the file noting that overrideable default flags are set there. The Makefile sets a few useful properties for a decompilation build: it clears default suffixes, keeps intermediate files with .SECONDARY, deletes files that were not built properly with .DELETE_ON_ERROR, and enables secondary expansion because dependency variables in object rules need it.

The toolchain selection is driven by two variables. When PLATFORM is gba, the toolchain comes from DEVKITARM and the compiler prefix is arm-none-eabi-, with the compiler binary path exported so the build finds it. When CPU_ARCH is i386, the platform value decides between a MinGW toolchain at /usr/x86_64-w64-mingw32/ for the two Windows targets and the native compiler for the SDL build. The PSP and PS2 branches are separate again:

bash
  PSPDEV    ?= $(HOME)/pspdev
  PSPSDK    := $(PSPDEV)/psp/sdk

For the PlayStation 2 the prefix changes to a different cross compiler:

bash
  PREFIX := mips64r5900el-ps2-elf-

The Makefile starts with a small amount of shared setup, including the root directory detection and the host operating system lookup:

bash
include config.mk
MAKEFLAGS += --no-print-directory

Because the PSP and PS2 toolchains are external projects, the build for those ports cannot work on a machine that has not installed PS2DEV or PSPDEV first. That is the main practical constraint on the port targets.

Sub games are bundled into the main build on purpose

Sonic Advance 2 contains sub games, and the project decompiles some of them as part of the same effort. The reason given is practical rather than sentimental: these sub games are automatically compiled and bundled during the main build process, because they are necessary to create a matching binary. The repository holds chao_garden for the tiny Chao Garden project based on the SA2 version, and multi_boot for multiboot ROMs used in singlepak multiplayer, including collect_rings.

This is the sort of detail that separates a real decompilation from a reimplementation. A reimplementation would drop the sub games and ship a cleaner program. A matching build cannot, because the bytes have to line up, so the Chao Garden code and the multiplayer boot ROMs become part of the compilation graph whether or not anyone plays them.

The repository layout follows the same logic. src contains the C sources, with subdirectories for game, where sa1, sa2 and shared folders hold code used across all three games, lib for libraries that were originally statically linked such as agb_flash and m4a, platform for port related code, and data for C files that pull assets in as part of the compilation. Graphics, sound and raw data live outside src, and tools holds the tooling used for compilation or extraction. Scripts under scripts are the ones used in the decompilation process itself. There is also a libagbsyscall directory holding the agbsyscall library from the Nintendo SDK.

The data and asset directories are how the ROM is reconstructed without shipping the original file: sprites become PNGs, songs become MIDI, backgrounds become tilemaps with extracted tiles, and the build assembles them back into place.

Contributions are refused when they come from a language model

This repository has a policy you will not find in most open source projects, and it shapes who can contribute. The rules state no LLMs for issues and no LLMs for pull requests. The stated reason is that the project exists to let humans practise reverse engineering, documenting and understanding, and that maintainers want accountability for what was submitted and the knowledge behind it. The policy is described as based on Zig's code of conduct.

For an engineer reading this repository, that has a direct effect. A generated pull request will be rejected, so an automated agent cannot be used to close the gap of unmatched functions, however many functions remain. The remaining work, more than 600 unnamed functions and around 60 that do not match, is human work by definition.

The project asks for documentation help explicitly. The README says the maintainers are always looking for people to document the code base, and points to the many non-matching functions that need human input. decomp.me is recommended as a resource for creating matching functions, and the FAQ section of the Zelda 64 Majora's Mask project is cited for further information.

Setup is delegated to a separate file. The README says to follow the instructions in INSTALL.md, which is the right place to look for the actual build steps, since the main page concentrates on project state, ports and layout rather than on a full setup walkthrough.

Release tags, licence status and how to judge the maintenance signal

The repository has no GitHub releases, so there is no version history to consult and no changelog to read. The signals available are the commit history and the progress badges. The last push to the repository was on 2026-08-01, and it is not archived, so work on the codebase continues.

The README states plainly that the project is not completed and still under active development, and that it is a work in progress matching decompilation of Sonic Advance 1, 2 and eventually 3, with the third game living in its own repository. There is a CI badge for the build workflow, and the repository carries a .clang-format configuration, a .devcontainer directory, .vscode settings and a .git-blame-ignore-revs file, which together suggest a project set up for regular contributors rather than a single-person snapshot.

The licence situation is worth checking before you build anything on top of this. No licence identifier is given for the repository, and the file list at the root shows no LICENSE file, unlike the layout of many comparable projects. That is not a licence grant, and it means redistribution of derived work has no stated permission. If your plan involves shipping a port or a modified build, resolve that question with the maintainers before publishing.

Hashes are published for each target ROM, and those hashes are the reference point for the entire project. Whether a function matches is decided by comparing compiled bytes against that reference, which is why the matching progress badge is the number to watch rather than the raw decompilation percentage.

Editorial conclusion

sa2 fits reverse engineers, students and hobbyists who want a readable C reconstruction of a Game Boy Advance game and a base for their own ports. It does not fit players looking for a convenient way to run the game, since the Win32 port is marked not functional and the build still depends on unmatched assembly. Before starting, read INSTALL.md, check the per-game progress badges, and confirm that your toolchain matches the PLATFORM value in the Makefile, because the x86, PSP and PS2 branches each expect a different cross compiler.

Frequently asked questions

What is sa2 and what does it try to achieve?

It is a work in progress matching decompilation of Sonic Advance 1 and 2 written in C, where the compiled output is compared against published SHA1 hashes of the retail ROMs.

How do I build sa2 for the Game Boy Advance or for the desktop ports?

The project keeps its setup steps in INSTALL.md, and the README lists make targets for the SDL, SDL Windows, Win32 OpenGL, PS2 and PSP builds, with PS2DEV or PSPDEV required for the console targets.

Why does the sa2 build still contain assembly code?

Around 60 functions currently do not match the original, and the non-matching assembly in asm/non_matching is pulled into the C compilation process so the binary stays correct while that work continues.

Can I contribute changes to sa2 generated by an AI?

No. The project states no LLMs for issues and no LLMs for pull requests, because the aim is that humans practise the reverse engineering work themselves.

Official sources

  1. Issues
  2. Project website
  3. README
  4. SAT-R/sa2 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sat-r-sa2.svg)](https://hysenlabs.com/projects/sat-r-sa2)

Was this useful?