-
Notifications
You must be signed in to change notification settings - Fork 58
Decompilation
This page aims to help newcomers to help contributing into the project.
Be sure to follow the Build guide first.
Open your ~/.zshrc
or ~/.bashrc
and add the following aliases to make the process more streamlined:
alias sotn="make clean && make -j extract && make -j build && make expected"
alias dec=".venv/bin/python3 ./tools/decompile.py"
alias differ=".venv/bin/python3 ./tools/asm-differ/diff.py -mow3 --overlay"
- We have a list of all of the functions in the repository sorted by approximate difficulty here.
- The length of the function and number of branches gives an estimate of the difficulty. Generally, if the function is longer and has more complex control flow, it's going to be harder to get a match.
- Jtbl indicates that the function uses jump tables. These require a special process to decompile, explained here.
- A decomp.me scratch may already exist for the file you are interested in. These are listed in the last column and can be used as a starting point for your work.
- Check if the function is a duplicate before starting it. You may be able to either use the decompiled version as-is, or with minor adjustments. See here.
- Run
sotn
at least once and ensure to get allOK
- Choose a function to decompile
- Check if the function is a duplicate
- With a CTRL+Shift+F search the function name. You will find a line which targets its assembly counterpart (eg.
INCLUDE_ASM("st/wrp/nonmatchings/6FD0", func_801873A0);
) - Run
dec func_801873A0
to decompile the function in the C code - Do a
differ OVERLAY_NAME FUNCTION_NAME
and check if you have to fix any compilation error before proceeding (eg. differ st/wrp func_801873A0) - When differ succeeds, you will get a screen that shows on the left how the original assembly looks like and on the right how your decompiled version translates into.
- Keep refactoring the code until the two assemblies match.
- Try refactoring and perform clean-ups while ensuring your C function still matches the original assembly code.
- Create a commit on your fork and make a PR!
These steps involve the website https://decomp.me/ which gives an easy user interface for decompiling.
- Figure out the file that contains your function and run
SOURCE=path/to/my/function.c make context
- Click "Start Decompiling" on decomp.me
- Select "PlayStation"
- The compiler should be
gcc 2.6.3-psx + maspsx
and the preset should beCastlevania: Symphony of the Night
. - Paste ctx.c into the "Context" pane.
- Paste the assembly for your function into the "Target assembly" pane.
- Click "Create scratch".
Currently the decomp supports the following SOTN builds:
us
hd
pspeu
saturn
To switch to a different game build, simply invoke on a terminal export VERSION=GAME_BUILD_ID
(e.g. to decompile the PSP build, do export VERSION=pspeu
). By default the version is set to us
, which is the US build of SOTN for PSX.
To restore the default version in your environment, run unset VERSION
.
- Use decomp.me with the "Castlevania: Symphony of the Night" preset.
- The “context” section of decomp.me, is provided by the cmd
SOURCE=src/dra/42398.c make context
. - Use decomp-permuter to solve some mismatches.
- Use this and this guide to understand how some compiler patterns work.
- Use the
#ifndef NON_MATCHING
if your code is logically equivalent but you cannot yet fully match it. - Some SotN specific register tricks can be found here.
See Decompiling functions with jump tables
TODO
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 duplicate functions. If you aim to decompile a duplicated function you might get around by just copy&pasting it into the right overlay
The game has multiple overlays, one for each stage, boss, and familiar. Adding new overlays to the decompilation requires prior agreement, either through GitHub Issues or via our Discord Server. This is because adding a new overlay significantly increases the project scope. Gradually adding overlays allows us to better tackle duplicate code and identify common patterns to automate the process.
If you're interested in adding a new overlay, please contact us. You can also add the same overlay from another version of the game. The reference version is us
, but we're open to overlays from hd
, pspeu
, eu
, hk
and so on.
Below are the steps to add a new overlay, using cen
with version hd
as an example. You can also refer to this pull request for guidance.
- Generate the splat config (e.g.
VERSION=hd tools/make-config.py cen
). - Add the SHA1 checksum of the targeted overlay in
config/check.{VERSION}.sha
. - Add the binary build step in
Makefile
(search forcen:
as an example). - Update the build step
build_{VERSION} in the
Makefile`. - Update
.PHONY:
at the end ofMakefile
.
If you're adding a PSX overlay, you'll also need to:
- Add the overlay to
Makefile.psx.mk
(seePSX_KSTAGES
and similar for reference). - Add the overlay to the
extract_assets
list inMakefile.psx.mk
. - Add the overlay to the
build_assets
list inMakefile.psx.mk
.
After these steps, running VERSION=hd make -j
should complete the process and give you an 🆗. Be sure the build path matches the version and overlay name of what you're targeting. Though time-consuming, this is just the first part.
- In the
Makefile
add the new overlay to theformat-symbol
. - In the
Makefile
add the new overlay to theforce_symbols
. - In the
Makefile
add the new overlay to thedisk_prepare
. - Add the overlay as a new
SrcAsmPair
object intools/dups/main.rs
.
- Add the overlay as a new
DecompProgressStats
object intools/progress.py
. - Update the
README.md
to include the progress shield icon by copying an existing link and changing the overlay name.
After completing these steps, submit a pull request with your changes.Additionally, make a separate pull request targeting the docs
branch after adding the overlay to gamemeta.js.
- Project Documentation Style Guide
- List of resource for sotn https://github.com/TalicZealot/SotN-Utilities (speedrun oriented, but still very useful).
- PS1’s CPU R3000 instruction manual and cheat sheet
- SOTN map viewer written in C
- PCSX emulator with debugger
- NO$PSX emulator with debugger
- Beginner friendly MIPS video lectures 1, 2