Xenosaga Episode I: Der Wille zur Macht
OrigenPlayStation 2
TecnologíaPort Nativo C/C++ (Reimplementación de Motor)
Disponible paraWindows, Linux, macOS
Ver proyecto oficialSobre el proyecto
Xenosaga es una serie de videojuegos del género JRPG, con temáticas de ciencia ficción, space opera y ciertos elementos provenientes de doctrinas como el gnosticismo. Fueron publicados por Namco, y desarrollados por Monolith Soft, quienes más tarde desarrollarían también la popular saga Xenoblade Chronicles, la cual reutiliza numerosos conceptos e ideas.
Información oficial del proyecto
Xenosaga Episode I
This project is developed with AI assistance.
A matching decompilation of Xenosaga Episode I: Der Wille zur Macht for the PlayStation 2.
The goal is readable C source that reproduces the original machine code. The Sony SDK and public libraries do not need to be recovered.
Progress
Published source coverage: 7,380 of 7,645 in-scope game functions (96.534%).
| Version | Target | Functions | Progress |
|---|---|---|---|
| NTSC-U | SLUS_204.69 | 3,671 / 3,671 | 100.000% |
| NTSC-U | OV01.OVL | 879 / 1,081 | 81.314% |
| NTSC-U | OV02.OVL | 110 / 110 | 100.000% |
| NTSC-U | OV10.OVL | 298 / 361 | 82.548% |
| NTSC-U | OV11.OVL | 139 / 139 | 100.000% |
| NTSC-U | OV12.OVL | 1,788 / 1,788 | 100.000% |
| NTSC-U | SSD.IRX | 442 / 442 | 100.000% |
| NTSC-U | RSSD.IRX | 53 / 53 | 100.000% |
Building
The historical compilers are 32-bit Linux executables. On 64-bit Ubuntu,
install libc6-i386 and python3-venv. On Windows, use WSL and keep the
checkout and build on a Linux filesystem: the old compilers cannot read some
Windows filesystem metadata and report Value too large for defined data type.
You need three things the repository does not contain: your own copy of the game, the original toolchain, and a Python environment for the disassembler.
1. The originals
Extract SLUS_204.69, OV01.OVL, OV02.OVL, OV10.OVL, OV11.OVL,
OV12.OVL and the IOP/ directory from your own disc image and put them in one
folder. config/originals.json names the six files with their sizes and
SHA-256; the build refuses anything else, so it tells you immediately if you
have a different release. This project reproduces the NTSC-U release.
2. The toolchain
config/toolchain-identity.json: for every compiler and
assembler it gives the version, the SHA-256 of each payload, and the provenance
needed to obtain or rebuild it. Two of the tools are patched, and both patches
are recorded there in full:
| Tool | What the build uses it for | Where it comes from |
|---|---|---|
ee-gcc2.96-realconv-lp7 | cc1 for the game code (Monolith) and the C runtime (newlib/libgcc) | the published ee-gcc2.96 archive, with twenty-nine documented patches to cc1 (six single bytes that restore the original decimal-literal rounding, two that restore the R5900 short-loop padding, five multi-byte alias-analysis patches, fsv1, fsv3 and fsv4 (%lo-addressed global scalars and struct-field accesses may be reordered in either direction, a non-small-data global's memory reference gets its type's alias set, and gcse load-PRE keeps a fixed scalar load across an in-struct store through a varying pointer), the two fsv5 (qisi) patches (a char sign-extended to 64 bits is lb plus a separate in-place extendsidi2, never one extendqidi2_insn), the three fsv6 patches (symbolic sym(reg) addresses are always legitimate and an address-taken variable gets alias set 0, instead of depending on host heap garbage), the four fsv7 patches (gcse load-PRE: a struct store through a pointer loaded from global S kills a later load of S), the two fsv8 patches (a small-data global with a non-zero initializer gets its type's alias set, as a non-small-data global does), the fsv9 patch (gcse load-PRE: a struct store through a pointer loaded from any global kills a later load of a global), the two fsv10 patches (gcse: a 32-bit union member store through a struct pointer is tested with rtx_varies_p), and the two fsv12 patches (after reload, an address load into a callee-saved register that follows a call in its block is split into lui/addiu)) |
ee-gcc2.9-991111 | cc1 for the SCE SDK scaffold objects only (out of recovery scope, INCLUDE_ASM of the original assembly. | the published ee-gcc2.9-991111 archive, unmodified |
ee-as-la29-vsqrt | assembler for every game and runtime object | GNU as 2.9-ee-991111 built from the pinned ps2-ee-toolchain commit with the recorded four-change diff (an overlap-safe memmove, the vsqrt opcode's bits 21-22, labels left before the hazard nops append_insn inserts, and la of a base register plus a 16-bit constant as one addiu) |
ee-as-2.9-plain | assembler for the SCE SDK objects | the same commit, unpatched |
ps2dev-binutils | linker and objcopy of every image, and modern GAS for data objects and retail blobs | ps2dev binutils 2.45.1, the linker, objcopy and modern GAS |
Lay them out under one directory as config/toolchain-identity.json's
tools.<id>.dir / .path say. Then:
python3 -B tools/tu/toolchain.py --check
It prints where it looked and what it found, and refuses with the tool's name, both hashes and the recipe when something is missing or different.
3. The disassembler
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
4. Tell the build where those three are
By environment variable:
export XENO_GAME_DIR=/path/to/extracted-iso
export XENO_TOOLCHAIN_DIR=/path/to/toolchains
export XENO_SPLAT_PYTHON=$PWD/.venv/bin/python
or once, in config/toolchain-local.json (untracked):
{
"game_dir": "/path/to/extracted-iso",
"toolchain_root": "/path/to/toolchains",
"splat_python": "/path/to/.venv/bin/python"
}
Three of the tools are built from source rather than downloaded, so their bytes
depend on the host compiler. A build of the same source that assembles the same
bytes still reproduces the images: accept it one tool at a time with
XENO_TOOLCHAIN_ALLOW=ee-as-la29-vsqrt,ee-as-2.9-plain,ps2dev-binutils. The
build then says which check it relaxed.
5. Build
./configure.py # generate every unit build directory and build.ninja
ninja # build and compare all six originals
ninja gate # + per-unit status and the whole-file SHA-256 gate
ninja gate writes build/gate.json. "result": "pass" means every one of the
six files came out byte for byte identical to your original.
Public builds use config/objects/data-carves.json to place constants and jump
tables emitted by the recovered C functions. Terminal object padding is verified
from the published object ranges and original ELF symbols when the private
config/tu-build.json is absent. Neither requires private acceptance records.
Contributing
Pick an object from config/objects/<unit>.objects.json that has no source yet,
write the C, and build: ninja tells you whether the file still comes out
identical. A function counts when its translation unit's source defines it in C
and the whole-file gate passes.
Acknowledgments
Thanks to the developers and contributors of the projects on which this work relies:
- splat, spimdisasm, and Rabbitizer for splitting and disassembly.
- m2c for first-pass decompilation of MIPS assembly into C.
- decomp-permuter for the bounded mutation search over a compiled non-exact base.
- ps2dev/binutils-gdb and SSXModding/ps2-ee-toolchain for EE toolchains.
- decomp.me's compiler collection for historical compiler distributions.
- PCSX2 for its documented EE implementation and behavioral reference.
Disclaimer
A legally obtained copy of the game is required. No original game binaries or copyrighted game assets are distributed in this repository. All game rights belong to their respective owners; this project is not affiliated with or endorsed by them.