Giter VIP home page Giter VIP logo

sotn-decomp's Introduction

Castlevania: Symphony of the Night Decompilation

A work-in-progress decompilation of Castlevania Symphony of the Night for PlayStation 1. It aims to recreate the source code from the existing binaries using static and/or dynamic analysis. The code compiles byte-for-byte to the same binaries of the game, effectively being a matching decompilation. Currently it only supports the US version of the game SLUS-00067.

This repo does not include any assets or assembly code necessary for compiling the binaries. A prior copy of the game is required to extract the required assets.

Bins decomp progress

File name Code coverage Decomp functions Description
SLUS_000.67 N/A N/A Shared libraries
DRA.BIN code coverage DRA.BIN decompiled functions Game engine
BIN/RIC.BIN code coverage RIC.BIN decompiled functions Playable Richter
ST/CEN/CEN.BIN code coverage CEN.BIN decompiled functions Center
ST/DRE/DRE.BIN code coverage DRE.BIN decompiled functions Nightmare
ST/MAD/MAD.BIN code coverage MAD.BIN decompiled functions Debug Room
ST/NO3/NO3.BIN code coverage NO3.BIN decompiled functions Entrance (first visit)
ST/NP3/NP3.BIN code coverage NP3.BIN decompiled functions Entrance
ST/NZ0/NZ0.BIN code coverage NZ0.BIN decompiled functions Alchemy Laboratory
ST/SEL/SEL.BIN code coverage SEL.BIN decompiled functions Title screen
ST/ST0/ST0.BIN code coverage ST0.BIN decompiled functions Final Stage: Bloodlines
ST/WRP/WRP.BIN code coverage WRP.BIN decompiled functions Warp Room
ST/RWRP/RWRP.BIN code coverage RWRP.BIN decompiled functions Warp Room (reverse)
SERVANT/TT_000.BIN code coverage TT_000.BIN decompiled functions Bat Familiar

Code coverage means how many bytes of code have been successfully converted from assembly into C code, while decomp function is how many functions have been succesfully decompiled.

Game versions

ID Console Build date Notes
jp10 PS1 1997-02-20
jp11 PS1 1997-03-06 same psx.exe as jp10
usproto PS1 1997-06-17 same psx.exe as jp10
us PS1 1997-09-01
eu PS1 1997-09-30
hk PS1 1997-11-30 same psx.exe as jp10
jp12 PS1 1998-01-23 same psx.exe as jp10
saturn Saturn 1998-04-27
hd PS1 2006-10-22 build found in the PSP game
pspko PSP 2007-09-07
pspus PSP 2007-09-10
pspjp PSP 2007-09-14
pspeu PSP 2007-11-21

Game internals

The game is divided into three modules:

  • SLUS_000.67 the main executable. It contains all the hardware API (eg. gamepad, CD, memory card, GPU renderer) of the PlayStation 1 console. It does not contain any game logic.
  • DRA the game engine. It contains the business logic (eg. gameloop, API to draw maps, entities, load levels, handle entities, animations and collisions) and some data such as Alucard's sprites or the loading/save rooms.
  • ST/ the overlays for each area. An area (eg. Castle's entrance, Alchemy Laboratory, etc.) contains all the unique logic to handle map specific events, cutscenes, enemy AI, collisions and more. It also contains the rooms and entities layout. Each overlay can be considered as its own mini-game. The title screen SEL.BIN is an example of how a stage overlay can act very differently.

Even if different overlays are loaded at the same time in memory, like DRA and stages, they never communicate each other directly. Instead they share the same memory area where SLUS_000.67 is located. Each overlay exposes their API as function pointers in the shared memory area, effectively allowing overlays to communicate without directly coupling them. One prime example is struct GameApi, which exposes DRA APIs to the stages and stage APIs to DRA. All the shared area is defined in game.h.

Setup the project

This assumes you have Ubuntu, Debian or WSL in Windows:

git clone https://github.com/Xeeynamo/sotn-decomp.git
cd sotn-decomp
sudo apt-get update
sudo apt-get install -y $(cat tools/requirements-debian.txt)
make update-dependencies
  1. Run mv disks/*.cue disks/sotn.us.cue
  2. Run make extract_disk

Build

  1. Run make extract to generate the assembly files for the functions not yet decompiled.
  2. Run make all to compile the binaries in the build/ directory.
  3. Run make disk to create a new CUE/BIN pair based on the new compiled binaries.

In case there are any changes in the config/ folder, you might need to run make clean to reset the extraction.

Some non-matching functions are present in the source preprocessed by the macro NON_MATCHING. You can still compile the game binaries by running CPP_FLAGS=-DNON_MATCHING make. In theory they might be logically equivalent in-game, but I cannot promise that. Few of them could match by tuning or changing the compiler.

Start decompilation

  1. Run make clean extract all expected at least once
  2. After setup and build, choose an overlay (eg. ST/WRP)
  3. Look for one of those functions which hasn't successfully decompiled yet (eg. INCLUDE_ASM("asm/us/st/wrp/nonmatchings/6FD0", func_801873A0);)
  4. Run ./tools/decompile.py func_801873A0 to decompile the function in the C source code where the function is supposed to be located
  5. If the function does not compile, try addressing the compilation errors until make compiles
  6. If the function does not match, invoke python3 ./tools/asm-differ/diff.py -mwo --overlay st/wrp func_801873A0 and refactor the code until it matches
  7. If the function matches, try refactoring to keep the code clean while checking if the function still matches once in a while

There are a few tricks to make the process more streamlined:

  1. Use decomp.me with PSY-Q 3.5. Be aware that the repo is using GCC 2.6.x, therefore the local output might be slightly wrong.
  2. The “context” section of decomp.me, is provided by the cmd SOURCE=src/dra/42398.c make context.
  3. Use decomp-permuter to solve some mismatches.
  4. Use this and this guide to understand how some compiler patterns work.
  5. Use the #ifndef NON_MATCHING if your code is logically equivalent but you cannot yet fully match it.

Duplicate functions

Due to how the game is structured, a lot of duplicate code can be found across the different overlays. We track a live list of possible duplicate functions that is useful to avoid trying to decompile functions that have been already decompiled elsewhere.

Resources

To do

The project is very barebone at the moment and there is a massive room of improvement, mostly in the infrastructure:

  • Not all the zone overlays (ST/{ZONE}/{ZONE}.BIN) are disassembled
  • Integrate ASPSX instead of GNU AS
  • Split binary data (eg. map layout, graphics, other assets) into individual files

Notes

  • The debug room overlay ST/MAD.BIN was compiled earlier than the first retail release of the game. All the offsets that refers to DRA.BIN points to invalid portions of data or to the wrong API calls, effectively breaking the majority of its original functionalities. That is why the debug room does not contain any object. By compiling the debug room with make mad_fix you can restore it by redirecting the old pointers to the retail version of the game. Be aware that not all the offsets have been yet redirected, so it will still be not entirely functional until further update.
  • I suspect that PSY-Q 3.5 have been used to originally compile the game
  • main.exe uses PS-X libraries that might have been created with a different compiler and with -O1 rather than -O2

Special thanks

This project is possible thanks to the hard work of tools provided by the Decompilation community:

  • mips2c from @matt-kempster to decompile MIPS assembly into C. This proven to be more accurate than Hexrays IDA and Ghidra.
  • splat from @ethteck to disassemble code and extract data with a symbol map. This tool provides the fundamental of the SOTN decomp.
  • asm-differ from @simonlindholm to know how the decompiled code compares to the original binary.
  • decomp-permuter from @simonlindholm to pick different versions of the same code that better matches the original binary.
  • decomp.me by @ethteck, @nanaian and @mkst to provide a collaborative decompilation site to share and contribute to work-in-progress decompiled functions.
  • frogress by @ethteck to store and retrieve progression data.
  • esa-new by @mkst as an inspiration on how to set-up a PS1 decompilation project.
  • oot as an inspiration of what it is possible to achieve with a complete decompiled video game.

sotn-decomp's People

Contributors

frog404 avatar rainchus avatar sestrenexsis avatar smb123w64gb avatar sonicdcer avatar sozud avatar taliczealot avatar xeeynamo avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.