Skip to content
PORTSNATIVE.
HomeCatalog
Web GamesEmulatorsToolsNews
PORTSNATIVE.

A catalog for discovering ports and related projects. We link to official sources and do not host original game files.

ExploreCatalogMy list
InformationAbout usSuggest a portSupportDonationsLegal notice
© 2026 PortsNative
Back to catalog
Wild 9
PORTSNATIVE

Wild 9

NATIVE PORTACTION / ADVENTUREWINDOWSLINUXMACOSALPHA

Wild 9

OriginPlayStation

TechnologyNative C/C++ port (engine reimplementation)

Available forWindows, Linux, macOS

View official project

About the project

Wild 9 es un videojuego de acción y aventura publicado por Interplay Entertainment en 1998.

2 versions of Wild 9

You're viewing: Wild 9

Wild 9github.com/plinkr/Wild9-Decompilation
Windows
Linux
macOS
Current
Wild 9 (PC)github.com/plinkr/Wild9Recomp
Windows
›

Official project information

Author's original READMEOpen on GitHub ↗

Wild 9 Decompilation

Matching decompilation of Wild 9 for the Sony PlayStation 1, NTSC-U executable SLUS_004.25

<img width="1800" height="841" alt="8c46df32775afcc338f82c9abe645cc2" src="https://github.com/user-attachments/assets/8414f47b-1f38-42c5-b154-d4ccd9990c5a" />

Overview

This project reconstructs the NTSC-U Wild 9 PlayStation 1 executable as matching C source and MIPS R3000A assembly. The primary goal is a byte-for-byte matching rebuild of the original executable (SLUS_004.25).

The codebase is structured around progressive decompilation. Matched functions are written as standalone C files under src/functions/ and promoted into src/main.c, replacing the corresponding INCLUDE_ASM disassembly entries. Unmatched code remains as generated assembly slices. Each promoted function is independently compiled, linked, and matched against the original binary before being patched into the final rebuilt executable.

Useful links

  • decomp.dev progress report
  • Wild 9 Recomp

Project status

Work in progress. See the decomp.dev progress report for current coverage.

This repository is not a playable version of Wild 9. It contains the decompilation sources, build scripts, tools, and generated code required to reproduce the original executable from a legally obtained copy of the game. The original game executable and other copyrighted game assets are not included in this repository.

For a playable native PC recompilation of Wild 9, see Wild 9 Recomp.

Features

  • Byte-for-byte matching rebuild against NTSC-U executable SLUS_004.25.
  • Splat-based executable splitting and disassembly generation.
  • Automated per-function assembly splitting (split_800_functions.py) into asm/nonmatchings/main/.
  • GCC 2.8.1 PSX compiler toolchain with maspsx (ASPSX 2.77) assembly translation.
  • Isolated GNU binutils 2.42 environment targeting mipsel-linux-gnu.
  • In-tree toolchain download and verification (make toolchain).
  • Per-function standalone compilation, linking, and byte-exact verification.
  • Automated function promotion workflow integrating matching C code into the main translation unit.
  • Submodule integration for decompilation tools including asm-differ, decomp-permuter, m2c, m2ctx, maspsx, and mipsmatch.

Requirements

The build and matching toolchain targets x86_64 Linux.

Host packages:

# Debian or Ubuntu
sudo apt install git make python3 python3-pip python3-venv curl binutils zstd file clang-format

# Arch Linux, Manjaro, or CachyOS
sudo pacman -S git make python python-pip curl binutils zstd file clang

Target game data:

A legally obtained original NTSC-U Wild 9 PlayStation executable must be placed at:

iso/us/SLUS_004.25

Expected file identity:

Size:    425984 bytes
SHA-1:   1dac75ee3a0ef5a62e025a85183076fa1a6cf824
SHA-256: ab280169ed52906589b8353a00c5cb4e9851da21d1023c98569de51958a44012

The original executable is not included in this repository.

Setup

1. Clone the repository

Clone the repository with all Git submodules:

git clone --recursive https://github.com/plinkr/Wild9-Decompilation.git
cd Wild9-Decompilation

If the repository was cloned without --recursive, initialize the submodules:

make tools

2. Python environment

Create the Python virtual environment and install pinned dependencies:

make install

This installs splat64 and spimdisasm into .venv.

Whenever you execute Python scripts or tools directly without Make, you must run them within this virtual environment. You can either activate the virtual environment in your current shell:

source .venv/bin/activate
python scripts/extract_psx_exe.py ...

Or invoke the virtual environment Python interpreter directly without activating:

.venv/bin/python scripts/extract_psx_exe.py ...

3. Toolchain installation

The matching build requires GCC 2.8.1 PSX and GNU binutils 2.42 (mipsel-linux-gnu). Both are installed into tools/toolchain/ without modifying system packages or requiring root access.

Install both automatically using the Makefile:

make toolchain

This downloads the precompiled GCC 2.8.1 PSX archive (decompals/old-gcc release 0.17) and the Ubuntu Noble binutils 2.42 packages, validates their SHA-256 checksums, and extracts them into tools/toolchain/.

To verify that the in-tree toolchain is present:

make check-toolchain

If you prefer to download and unpack the packages manually, see docs/TOOLCHAIN.md.

4. Load the environment (required for commands without Make)

The Makefile automatically exports the private binutils PATH and LD_LIBRARY_PATH to all recipes, so executing make works without any manual environment setup.

However, to execute any commands without Make in your shell (such as mipsel-linux-gnu-as, mipsel-linux-gnu-ld, mipsel-linux-gnu-objcopy, or standalone compilation scripts), you must first load the binutils environment:

source scripts/binutils-env.sh

5. Install the original executable

Wild 9 (NTSC-U) ships as SLUS_004.25. You need this executable in iso/us/ before building.

Extract it from your own Wild 9 disc image

If you have a Redump-style dump of Wild 9 (.cue + .bin, or a bare .bin), use the helper script in this repo:

.venv/bin/python scripts/extract_psx_exe.py "/path/to/Wild 9 (USA).cue"

The script reads the filesystem inside the dump, follows SYSTEM.CNF to the boot executable, and writes SLUS_004.25 to the current directory. Then move it into place:

mkdir -p iso/us
mv SLUS_004.25 iso/us/SLUS_004.25

You can also pass the output path directly:

.venv/bin/python scripts/extract_psx_exe.py "/path/to/Wild 9 (USA).bin" iso/us/SLUS_004.25

Or copy it manually

If you already have SLUS_004.25 extracted (for example from DuckStation's disc browser), just place it at:

mkdir -p iso/us
cp /path/to/SLUS_004.25 iso/us/SLUS_004.25

Either way, the final layout must be:

iso/us/SLUS_004.25

6. Verify the toolchain

Verify the installed tools:

make versions
make check-toolchain

Build

Splat disassembly and per-function splitting

Disassemble the original binary and generate per-function assembly:

make split

Splat disassembles the main code segment into a single file, asm/800.s, but does not split it into functions. make split runs both stages:

  1. Splat disassembles iso/us/SLUS_004.25 into asm/800.s and data files.
  2. scripts/split_800_functions.py writes each function from asm/800.s to asm/nonmatchings/main/func_XXXXXXXX.s.

On a clean checkout, make (or make all) runs both stages automatically before building.

Re-splitting functions without re-running Splat

If asm/800.s already exists and you only want to regenerate the per-function files under asm/nonmatchings/main/:

make split-functions

You can also run the script directly using the virtual environment:

.venv/bin/python scripts/split_800_functions.py asm/800.s asm/nonmatchings/main

Recreating src/main.c (opt-in)

The repository provides a script to regenerate src/main.c with an INCLUDE_ASM stub for every function found in asm/800.s:

make generate-includes

Or run the script directly using the virtual environment:

.venv/bin/python scripts/generate_include_asm.py asm/800.s src/main.c

This is opt-in because src/main.c is the primary translation unit tracked in git. As functions are decompiled and matched, their INCLUDE_ASM calls are replaced with #include "functions/func_XXXXXXXX.c". If make split or make build regenerated src/main.c automatically, it would wipe out all promoted C functions. Only run make generate-includes if you are bootstrapping from scratch or intentionally resetting the translation unit.

Building and verifying

Build and verify the baseline all-assembly reference:

make original-verify

Build the target executable:

make build

Verify that the built executable matches the original:

make verify

The build process starts from the byte-exact reference and replaces promoted functions defined in src/main.c. Each promoted function is matched independently before its bytes are patched into the final executable.

Matching

Each decompiled function lives in its own file under:

src/functions/func_XXXXXXXX.c

To build and compare a standalone function against the original binary:

make match FUNCTION=func_XXXXXXXX

For example:

make match FUNCTION=func_800101A4

A successful match prints:

func_800101A4: MATCH

The standalone matching pipeline is:

src/functions/func_XXXXXXXX.c
    -> C preprocessor (CPP)
    -> GCC 2.8.1 PSX compiler
    -> scripts/prepare_function_asm.py (small-data handling and ASPSX
       delay-slot store preparation via scripts/aspsx_delay_slot.py)
    -> maspsx (ASPSX 2.77 translation)
    -> GNU assembler 2.42 (mipsel-linux-gnu-as)
    -> scripts/link_function.py (standalone link at original address)
    -> scripts/match_function.py (byte comparison against original binary)

The project does not modify the tools/maspsx submodule. scripts/prepare_function_asm.py handles small-data preparation before invoking maspsx, and scripts/aspsx_delay_slot.py restores the ASPSX expansion of bare macro stores that belong in a jump delay slot (lui $at,%hi(sym) hoisted before the jump, sw $reg,%lo(sym)($at) in the slot). The delay-slot rewrite only applies where the reference assembly proves the store is a delay-slot instruction.

Per-function compiler flags

Some parts of the original executable were compiled with different flags. A function that needs one declares it in its own C file, on a line of its own:

// CFLAGS: -fno-delayed-branch

The %.gcc.s rule reads that line and appends the flags to the compiler command. Only flags listed in FUNCTION_CFLAGS_ALLOWED in the Makefile are accepted; anything else stops the build. The directive applies to the standalone pipeline (make match, make build, make verify), which produces the patched executable. src/main.c (make c) is one translation unit and ignores it.

Known case: -fno-delayed-branch leaves the jr $ra delay slot as an explicit nop, which GCC 2.8.1 at -O2 would otherwise fill. Most functions in 0x80057xxx-0x80067xxx need it.

Known case: -mno-split-addresses makes GCC emit address macros such as lbu $2,sym($3) instead of an explicit lui %hi / addiu %lo pair. The assembler then expands them through $at (lui $at,%hi(sym) / addu $at,$at,$3 / lbu $2,%lo(sym)($at)). Some Sony library code in the same region was built this way, for example func_80058CC4 (toupper) and func_80058CF8 (tolower). Neighboring functions use the split form, so declare this flag per function and never apply it globally.

Use the directive only when the C is already correct and the flag is the sole remaining difference, verified by matching with and without it.

Development Workflow

1. Decompiling a function

Find an unpromoted function in src/main.c. Unpromoted functions appear as:

INCLUDE_ASM("asm/nonmatchings/main", func_XXXXXXXX);

The disassembled assembly generated by make split is located at:

asm/nonmatchings/main/func_XXXXXXXX.s

If asm/nonmatchings/main/ is missing, run make split-functions to regenerate it from asm/800.s.

Create a standalone C source file:

$EDITOR src/functions/func_XXXXXXXX.c

Write the C implementation using fixed-width types from include/types.h and shared declarations from include/functions.h, include/globals.h, and include/decomp.h.

2. Testing and matching

Compile and compare the function:

make match FUNCTION=func_XXXXXXXX

Iterate on the C code until make match reports MATCH. Decompilation helper submodules under tools/ (such as asm-differ or decomp-permuter) can be used to analyze differences.

3. Promoting a matched function

Once make match succeeds, promote the function:

make promote FUNCTION=func_XXXXXXXX

make promote performs the following steps:

  1. Verifies the standalone match with make match.
  2. Replaces the INCLUDE_ASM("asm/nonmatchings/main", func_XXXXXXXX); line in src/main.c with #include "functions/func_XXXXXXXX.c".
  3. Rebuilds the executable with make build.
  4. Runs make verify to ensure the entire binary matches byte-for-byte.
  5. If verification fails, it automatically restores src/main.c from backup.

4. Formatting

Format C source and header files:

make format

This applies the .clang-format rules and prepends the project SPDX license identifier to any C or header file that lacks it:

// SPDX-License-Identifier: AGPL-3.0-or-later

Do not alter code purely for formatting if the change modifies the generated assembly. Refer to docs/STYLE.md for coding and formatting conventions.

Project Structure

src/
  main.c
      Main translation unit containing promoted C includes and remaining INCLUDE_ASM macros.
  functions/
      Standalone C source files, one per decompiled function.

include/
  types.h
      Fixed-width integer types (u8, s8, u16, s16, u32, s32, bool).
  functions.h
      Shared function declarations.
  globals.h
      Shared game global variable declarations.
  decomp.h
      Decompilation helpers, hardware structures, and macros.
  include_asm.h
      INCLUDE_ASM and INCLUDE_RODATA macro definitions.
  macro.inc
      Assembler macros.
  labels.inc
      Assembler label declarations.
  gte_macros.inc
      PlayStation Geometry Transformation Engine (GTE) assembly macros.

config/slus_004.25/
  splat.yaml
      Splat disassembly and section split configuration.
  toolchain.json
      Compiler and assembler flags and tool versions.
  SLUS_004.25.sha1
      SHA-1 checksum of the original executable.
  SLUS_004.25.sha256
      SHA-256 checksum of the original executable.

symbols/
  slus_004.25.txt
      Hardware register mappings, BIOS symbols, and known addresses.

scripts/
  binutils-env.sh
      Sets PATH and LD_LIBRARY_PATH for the private binutils 2.42 environment.
  extract_psx_exe.py
      Extracts the boot executable from a .cue/.bin disc image.
  split_800_functions.py
      Splits asm/800.s into per-function assembly files in asm/nonmatchings/main/.
  generate_include_asm.py
      Generates src/main.c with INCLUDE_ASM stubs from asm/800.s (opt-in).
  match_function.py
      Compares standalone function binary against the original executable.
  link_function.py
      Links a standalone function object at its original address.
  prepare_function_asm.py
      Prepares standalone GCC assembly output before passing to maspsx.
  prepare_main_asm.py
      Prepares main translation unit assembly output.
  aspsx_delay_slot.py
      ASPSX-compatible expansion of bare macro stores that belong in a jump
      delay slot (used by the two prepare scripts above).
  promote_function.py
      Replaces INCLUDE_ASM entries with C includes in src/main.c.
  normalize_splat_config.py
      Normalizes generated Splat split configuration.
  inspect_psx_exe.py
      Parses and displays PlayStation executable header information.
  check_prototypes.py
      Verifies header prototypes match C function signatures.
  sort_declarations.py
      Sorts declarations in header files.
  generate_objdiff_config.py
      Generates the objdiff project configuration used for progress reports.

docs/
  STYLE.md
      C style guide, naming conventions, and matching guidelines.
  TOOLCHAIN.md
      Detailed toolchain setup instructions and package references.
  REPOSITORY.md
      Repository clean-room reverse engineering policy.

tools/
  Git submodules for decompilation tooling and local toolchain files.

Generated assembly (asm/), per-function assembly (asm/nonmatchings/main/), linker scripts, object files, and build outputs (build/) are ignored by Git.

Useful Commands

make help                           # Show available Makefile targets
make tools                          # Initialize the Git submodules
make install                        # Create .venv and install pinned Python dependencies
make toolchain                      # Install GCC 2.8.1 PSX and binutils 2.42 in-tree
make check-toolchain                # Report whether the in-tree toolchain is present
make versions                       # Print Python, splat, and spimdisasm versions
make info                           # Display PS-X EXE header fields
make fingerprint                    # Record SHA-1 and SHA-256 of the target binary
make split                          # Run Splat and regenerate per-function ASM
make split-functions                # Regenerate asm/nonmatchings/main/ from asm/800.s
make generate-includes              # Regenerate src/main.c INCLUDE_ASM stubs
make original-verify                # Build and verify the baseline assembly reference
make build                          # Build the final executable with promoted functions
make verify                         # Compare build/SLUS_004.25 with the original
make match FUNCTION=func_XXXXXXXX   # Build and match a single function
make promote FUNCTION=func_XXXXXXXX # Promote a matched function in src/main.c
make check-prototypes               # Verify header prototypes against C definitions
make sort-declarations              # Sort declarations in functions.h and globals.h
make objdiff-report                 # Write .decomp/report.json (needs objdiff-cli)
make format                         # Format C/header files with clang-format
make clean                          # Remove build artifacts and nonmatchings
make distclean                      # Remove build artifacts and Python virtualenv

Contributing

  • Keep one decompiled function per file under src/functions/func_XXXXXXXX.c.
  • Keep promoted functions in original address order in src/main.c.
  • Follow the conventions in docs/STYLE.md.
  • Before submitting a pull request, run:
    make format
    make verify
    
  • Do not commit original game executables, disc images, extracted assets, generated assembly, object files, or other build artifacts.

License

Project source code, scripts, configuration, and documentation are licensed under the GNU Affero General Public License version 3. See LICENSE.md.

The Wild 9 executable, disc data, artwork, audio, and other original game assets are copyrighted by their respective rights holders and are not licensed by this project.

Read official guide
CALIFICACIÓN
—
Loading votes…
Advertisement

PROJECT FILE

Project type
NATIVE PORT
Genre
Action / Adventure
Status
alpha
Original platform
PlayStation
Technology
Native C/C++ port (engine reimplementation)
Version
—
Updated
—

Target platforms 3

Windows
Linux
macOS
View on GitHub
Advertisement