GameCube and Wii
GameCube and Wii decomps share one CPU family, one compiler family and one mature toolchain. Most active projects on these consoles are built from the same template, so once you know one, you can find your way around the others.
The hardware and the compiler
Section titled “The hardware and the compiler”- CPU: PowerPC (Gekko on GameCube, Broadway on Wii), big-endian.
- Compiler: almost always Metrowerks CodeWarrior (
mwcceppc), shipped with the official SDK. Many versions exist, and they generate different code, so finding the right version for your game (and sometimes for each library inside it) is one of the first jobs. Projects refer to them by labels such asGC/1.2.5n,GC/1.3.2or Wii versions. - Executables: a main
.dol, often plus.relmodules (relocatable code loaded at runtime, roughly like DLLs). - Languages: C and C++. C++ games bring mangled names, vtables and compiler-generated code you must reproduce.
CodeWarrior is a Windows program. On Linux and macOS the template runs it through wibo, a small wrapper for 32-bit Windows command-line tools, and downloads it for you.
The toolchain
Section titled “The toolchain”| Tool | What it does |
|---|---|
decomp-toolkit (dtk) |
Analyzes the DOL and RELs, splits them into objects from your config, and handles disc images, archives and maps. |
| dtk-template | The project scaffold: configure.py, a ninja build, CI and progress reporting. |
| objdiff | Diffs your compiled objects against the original, function by function, and writes the progress report. |
| m2c | Drafts C from assembly. It supports PowerPC and has CodeWarrior-specific handling. |
| decomp.me | Shares a single function as a “scratch” so others can help match it in the browser. |
| sjiswrap | Lets the compiler read UTF-8 source as Shift JIS, for Japanese strings. |
Starting a project
Section titled “Starting a project”The template’s own getting started guide is the reference; this is the outline so you know what to expect.
- Install the dependencies. Python and ninja. On Windows, use native tools; the template notes that objdiff can’t watch files for automatic rebuilds under WSL.
- Create your repository from dtk-template and clone it.
- Add your game. Rename
orig/GAMEIDto your game’s ID (for exampleGZ2E01) and put your disc image there. The template accepts several formats (ISO, RVZ, WBFS and others) or a disc you extracted with Dolphin. Everything underorig/is ignored by git, apart from a.gitkeep. - Configure. Rename
config/GAMEIDtoo, and fill inconfig.ymlusing the example file next to it. - Write the expected hashes.
config/GAMEID/build.sha1lists the SHA-1 of each file the build must produce. The template suggests generating it withdtk shasum, then pointing the paths atbuild/instead oforig/. - Generate and build. Add the ID to
VERSIONSinconfigure.py, runpython configure.py, thenninja.
The first ninja run analyzes the binary and writes symbols.txt and splits.txt for you. Expect it not to link
straight away: the generated splits are a starting point you refine.
If the disc has a map or debug ELF
Section titled “If the disc has a map or debug ELF”Some discs ship a linker .map file, or a debug build left in the files. These are gold: they give you real
function names, sizes and the original file each function came from. The template can read a .map during the
first analysis to fill symbols.txt and splits.txt, and dtk can generate a config from a matching .elf.
Check the template’s guide for the exact keys, and remove the map entries once the analysis has run.
The two files you’ll edit most
Section titled “The two files you’ll edit most”symbols.txtnames every function and object with its address, type and size. Renaming a symbol here renames it everywhere: in the split assembly, in objdiff and in the report.splits.txtsays which address ranges of each section belong to which source file. Getting units right matters: link order, padding and data placement all depend on it.
Both files are documented in the template’s docs/ folder.
From assembly to C
Section titled “From assembly to C”In configure.py, each source file is declared as an object with a status:
Matching: it matches, so it is compiled and linked into the final build;NonMatching: it is still being worked on, so the build uses the original code for it;Equivalent: it behaves the same but doesn’t match, and is linked only when you configure with--non-matching.
The usual loop:
- Pick a unit, mark it
NonMatchingand create its.cor.cppfile. - Open the project in objdiff. It reads
objdiff.json, which the build generates, and shows each function of the unit side by side with the original. - Write a function, save, and watch the diff update. When the whole unit matches, switch it to
Matching. - Run
ninjaand check that the final hashes still pass.
See the matching workflow for how to tackle one function.
CodeWarrior habits worth knowing early
Section titled “CodeWarrior habits worth knowing early”- Version and flags come first. If a whole family of simple functions refuses to match the same way, suspect the compiler version or a flag for that library, not your C.
- Inlining and ordering are part of the match. CodeWarrior’s inlining decisions, and the order of functions
and data in a file, follow the source. A missing
inline, or a helper defined in the wrong place, shows up in the diff. - C++ needs the class layout. Constructors, destructors, vtables and virtual calls only match once the class hierarchy and member order are right. Real names from maps help a lot here.
- The SDK is shared. Many games link the same SDK and runtime libraries. Other projects may already have matched the version your game uses, so look before you start.
Progress and CI
Section titled “Progress and CI”The template defines progress categories in configure.py, by default game (Game Code) and sdk (SDK Code), so
you can report game code apart from libraries. Building build/GAMEID/report.json runs
objdiff-cli report generate over every unit; ninja progress prints a summary in the terminal.
For CI, the template ships an example GitHub Actions workflow. It builds inside a container image that holds the
game files, and that image comes from a separate private repository, so the files never become public. Follow
the template’s docs/github_actions.md to set it up.
Once CI produces report.json, add one step to upload it to decmp.dev: see
Upload your progress.
Where to get help
Section titled “Where to get help”- The template’s README links the GC/Wii decompilation community Discord, whose
#dtkchannel covers the tooling. - Existing projects are the best reference. Most of them use this exact layout, so find one on a similar engine or SDK version and read how they solved the same problems.