# khdays-decomp [![Discord](https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/rVeTPhPbsx) A work-in-progress **matching decompilation** of *Kingdom Hearts 358/2 Days* (Nintendo DS). The goal is C source that recompiles to a binary **byte-for-byte identical** to the original game code. > ### Disclaimer > This repository does **NOT** contain the game ROM, any game assets, or any of > the original binary/assembly. **An existing, legally-obtained copy of the game > is required** to extract and build it. > > This repository is a **matching decompilation only**. It does not contain or > produce a playable build or any redistributable game binary, and building it > requires an original, legally-obtained copy of the game. All trademarks and the > original game are property of their respective owners. ## Status Every function of the EU (`YKGP`) ARM9 program and its overlays is matched, and all of the initialized data is reconstructed: the rebuilt modules are byte-identical to the game's (306 of 306). All of the game's own code is C except two functions that need the `clz` instruction, which the compiler cannot produce from C. The rest of the assembly is library code (NitroSDK, the CodeWarrior runtime, MobiClip) whose original source was assembly too. The work now is making that C readable: declaring the game's shared structures once in `include/` instead of in every file that uses them, naming what is still named by address or offset, and grouping functions back into the files they came from. Progress is split into categories so that assembly is never counted as C decompilation. | Category | Count | Meaning | |---|---:|---| | Real C-decompiled matched functions | **23,125** / ~23,233 (~99.5% by function count) | Functions implemented in C and verified byte-exact | | Complete functions (C + verified original library assembly) | **23,231** / ~23,233 (~100.0%) | Real C, plus library functions whose original source is assembly (NitroSDK/MSL `asm`, BIOS veneers): C cannot express them, so they count once integrated as that assembly and byte-verified with source evidence in `config/arm9/report_asm_matches.json`. | | Real C-decompiled matched **bytes** | **4,716,202** / 4,728,788 (~99.73% by code bytes) | Real-C-only byte progress; `asm_stubs/`, inline ASM and `nonmatching/` are excluded. decomp.dev additionally counts source-hashed, verified SDK assembly and authorized CLZ exceptions as matching, not as C. See [progress policy](docs/PROGRESS_POLICY.md). | | Inline ASM / ASM stub matched functions | **108** / ~23,233 (~0.5%) | ASM implementations: the libraries' own assembly and the authorized inline exceptions (two game functions that need `clz`); never counted as real C. Only explicitly verified manifest entries contribute to decomp.dev matching coverage. | | SDK/library byte-match identifications | **0** / ~23,233 (~0.0%) | NitroSDK or library functions identified separately by byte matching | | Named but not decompiled | **0** / ~23,233 (~0.0%) | Functions known to the project but not implemented as C | | Initialized DATA | **188,336** / 188,340 (**100.00%**) | Byte/relocation-verified `.rodata`/`.data`; includes the separately reported MobiClip executable payload at 26,012/26,012 bytes. | | Total known functions | **23,240** | Function index for the EU `YKGP` target | | Region | EU (`YKGP`) | | | Compiler | CodeWarrior `mwccarm` 3.0 build 139 | Per-module progress is in `PROGRESS.md`. A few precompiled-middleware translation units (e.g. the `ov028` anti-tamper crypto core) build with an older `mwccarm` via a per-file compiler override (`config/arm9/file_compilers.json`). | The current counts are generated by `python tools/audit_progress.py`. See [docs/PROGRESS_POLICY.md](docs/PROGRESS_POLICY.md) for what counts as real decompiled progress. ### Progress reporting policy Only real C implementations are counted as C-decompiled progress. Assembly, whether a library's own or an authorized inline exception, is counted separately, and so is anything under `nonmatching/`. SDK/library byte-match identifications are tracked separately from game-code decompilation. See [sdk/README.md](sdk/README.md) for the SDK identification workflow. ## Repository layout ```text src/engine/ the main module's game code (ITCM included); data/ holds its DATA src/overlays/scenes/ overlays loaded through the scene table (title, field, camp menu, ...) src/overlays/screens/ screens and menus a scene loads (shop, game over, ...) src/overlays/field/ modules loaded inside the field scene: battle, event script, pickups, ... src/overlays/players/ playable characters, one overlay per character and load slot src/overlays/enemies/ one overlay per enemy class (ovNNN_enemy_) src/overlays/system/ boot, wireless, MobiClip video, DS Protect, shared enemy framework include/ shared headers: basic types, NitroSDK/NitroSystem declarations, and the game's shared structures (game/: enemy actor, AI task, ...) libs/nitro/ libs/nns/ NitroSDK and NitroSystem libs/msl/ libs/mobiclip/ Metrowerks runtime and C library, MobiClip middleware config/ dsd project config (symbols / delinks / relocs per module) docs/ layout.md maps the binary to this tree; renames/ lists symbol renames tools/ Python tooling (build, verification, reports) sdk/ NitroSDK byte-match identification harness (see sdk/README.md) build/ generated manifests and reports; build output is git-ignored ``` Every function is one `.c` file named after it, in its module's directory: `src/engine/` for the main module, the overlay's own directory otherwise. An overlay directory keeps the FS overlay id the game loads it by (`ov114_enemy_00`); overlays whose purpose is not established yet keep the bare `ovNNN`. [docs/layout.md](docs/layout.md) explains what each overlay is and on what evidence. Library code under `libs/` keeps `auto/` and `calls/` for C and `asm_stubs/` for the libraries' own assembly (the NitroSDK's hand-written routines, the CodeWarrior runtime). That assembly may match the original bytes, but it is counted separately from real C decompilation progress, see [docs/PROGRESS_POLICY.md](docs/PROGRESS_POLICY.md). Structures the game shares between files are being moved into `include/game/` (the enemy actor, the AI task, the Mission Mode session, ...). A source that still declares a partial view of a structure locally only declares the fields it touches; `tools/structconv.py` moves such sources onto the shared declaration and keeps the change only when the source still compiles to the same bytes. The ROM, the extracted data (`dsd_extract/`, `asm/`), build artifacts, and the proprietary toolchain are intentionally **not** tracked; see `.gitignore`. ## Building / verifying You need your own copy of the game plus the toolchain (see [CONTRIBUTING.md](CONTRIBUTING.md) for setup). Then, to verify a single function: ```sh python tools/getcand.py func_XXXXXXXX # prints disasm + the verify command python tools/match.py <...> # compiles and byte-compares ``` A green `>>> MATCH <<<` means your C reproduces the original exactly. `python tools/verify_idx.py ` checks a source already in the tree, and `bash tools/gate.sh` rebuilds every module and compares the whole program. ## Toolchain - [`dsd`](https://github.com/AetiasHax/ds-decomp) - DS ROM extraction / delinking - `mwccarm` 3.0 (CodeWarrior for Nintendo DS) - the matching compiler - `arm-none-eabi-as` (GNU binutils) - assembling the libraries' own assembly routines - Python 3 with `capstone`, `pyelftools`, `ndspy` See the [Nintendo DS decompilation guide](https://decomp.wiki/platforms/nintendo-ds). ## Credits - The DS Protect 1.10 sources in ov028 (`src/overlays/system/ov028_dsprotect/dsprot/`) and `tools/dsprot_decrypt.py` are reconstructed after taxicat1's decompilation of DS Protect, [taxicat1/dsprot](https://github.com/taxicat1/dsprot) (branch `1.10`). - The NitroSDK identification harness in `sdk/` compiles the NitroSDK sources of pret's decompilation of Pokémon Diamond, [pret/pokediamond](https://github.com/pret/pokediamond), and several `libs/nitro` routines were cross-checked against its matched C. ## Contributing Contributions are very welcome; see **[CONTRIBUTING.md](CONTRIBUTING.md)**. Every matching function must pass **byte-exact verification**, and public C decompilation progress only counts real C implementations. Progress per module and how to claim one is in **[PROGRESS.md](PROGRESS.md)**. ## License The decompilation and tooling in this repository are dedicated to the public domain under [CC0 1.0](LICENSE). This applies only to the contributors' own work; the original game and its assets remain the property of their owners.