Decompilation of Castlevania: Symphony of the Night (PSX+Saturn)
Go to file
2022-02-20 12:57:46 +00:00
.github/workflows Disassemble DRE, ST0, WRP and RWRP 2022-02-09 12:49:33 +00:00
asm/main/psxsdk Upload disassembly 2022-01-02 13:35:44 +00:00
bin Use GCC 2.6.3 to obtain better matching 2022-02-07 00:07:42 +00:00
config Decompile two functions related to the librarian card 2022-02-19 10:35:51 +00:00
include Attempt to match a few functions 2022-02-20 12:57:46 +00:00
src Attempt to match a few functions 2022-02-20 12:57:46 +00:00
tools More menu drawing decompilation 2022-02-16 10:56:48 +00:00
.gitignore Add two map files 2022-01-20 22:21:40 +00:00
.gitmodules Upload disassembly 2022-01-02 13:35:44 +00:00
diff_settings.py Tweak asm-diff settings 2022-01-24 20:41:45 +00:00
Makefile More menu drawing decompilation 2022-02-16 10:56:48 +00:00
README.md Disassemble DRE, ST0, WRP and RWRP 2022-02-09 12:49:33 +00:00
slus00067.sha Disassemble DRE, ST0, WRP and RWRP 2022-02-09 12:49:33 +00:00

Castlevania: Symphony of the Night disassembly

Recompilable code that creates 1:1 binaries for the commercial videogame Castlevania: Symphony of the Night for the PlayStation 1. This repository aims to create a full decompilation in C.

Game revision

All the files refers to the SLUS-00067 version of the game.

SHA-1 checksum File name Progress
54828d4e44ea9575f2a0917ff63def42a304abff main.exe N/A
2eac5f7162e77416166c2511c787995488f01c37 DRA.BIN progress DRA.BIN
e42976f45b47d1c4912a198ae486b77ee6d77c9c ST/DRE.BIN progress DRE.BIN
adb3303e1ea707c63dfa978511a88cab4f61970a ST/MAD.BIN progress MAD.BIN
5d06216b895ab5ff892c88b0d9eff67ff16e2bd1 ST/NO3.BIN progress NO3.BIN
7c78a2bec6a26acfb62456e7f517915fe0c0e3f5 ST/NP3.BIN progress NP3.BIN
bc2fabbe5ef0d1288490b6f1ddbf11092a2c0c57 ST/ST0.BIN progress ST0.BIN
2ae313f4e394422e4c5f37a2d8e976e92f9e3cda ST/WRP.BIN progress WRP.BIN
3bbdd3b73f8f86cf5f6c88652e9e6452a7fb5992 ST/RWRP.BIN progress RWRP.BIN

Build

  1. You need gcc-mipsel-linux-gnu that you can easily install on any Debian-based Linux distribution. On Windows it is highly recommended to just use Ubuntu with WSL
  2. Place your main.exe from the file SLUS_000.67, DRA.BIN and the ST folder in the root directory of the repository
  3. Run make extract to generate the assembly files
  4. Run make all to compile the binaries into the build/ directory

Check for function matching

Thanks to asm-differ you can check if a funtion written in C matches its assembly counterpart.

  1. Be sure to resolve the submodule with git submodule update --init
  2. Ensure to create a matching binary with make clean && make extract && make all && mkdir expected && cp -r build expected/
  3. Choose a function to match (eg. func_8018E964), an overlay (eg. st/mad) and then invoke python3 ./tools/asm-differ/diff.py -mwo --overlay st/mad func_8018E964

Non-matching build

Some non-matching functions are present in the source code by disabled 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.

Restore MAD (debug room)

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 CPP_FLAGS=-DFIX_MAD make mad you can restore it by redirecting the old pointers to the retail version of the game. Use CPP_FLAGS="-DNON_MATCHING -DFIX_MAD" make mad to compile it with the functions that have not been yet matched. For now it does not really work due to the undefined reference. But it will. Someday.

Two important points to know are that not all the offsets have been yet redirected, second is that the checksum will obviously not match.

Technical details

The game is divided in three modules:

  • main is the game engine of the game. It contains all the necessary logic to interact with the gamepad, CD, memory card, the SPU and to render the sprites on-screen. It appears to not contain any game logic by itself.
  • DRA is the game itself. It contains the gameloop and the necessary API to draw maps, entities, load levels, handle entities, animations and collisions. It also contains some common data such as Alucard's sprites, candle's sprites and the common rooms' (save, loading, teleport) layout.
  • ST/ are the overlays for each area. An area (eg. Castle's entrance, Alchemy Laboratory, etc.) contains all the unique logic to handle map's specific events, cutscenes, enemies' AI, collisions and more. It also contains the rooms and entities layout.

Notes

  • I suspect that GCC 2.7.2 / PSY-Q 3.6 have been used to originally compile DRA.BIN
  • main.exe uses PS-X libraries that might've been created with a different compiler and with -O1 rather than -O2

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
  • There is no CI/CD pipeline to test the correctness of the compiled code