Decompilation of Sly Cooper and the Thievius Raccoonus for the PS2
Go to file
2023-12-01 05:08:45 -05:00
src Add file documentation 2023-11-30 04:12:16 -05:00
test Fix all enum definitions 2023-11-27 03:26:33 +00:00
tools Wording and layout tweaks 2023-02-21 18:01:45 -05:00
.gitattributes Add .gitignore and .gitattributes. 2021-11-08 19:59:05 -05:00
.gitignore Wording and layout tweaks 2023-02-21 18:01:45 -05:00
CMakeLists.txt Added splice lib target 2022-07-20 22:19:30 -04:00
CMakeSettings.json Fixed some stuff and made more progress 2023-05-24 20:49:35 -04:00
CONTRIBUTING.MD Copyedits 2023-11-27 03:06:59 +00:00
Doxyfile Add doxyfile 2023-12-01 05:01:25 -05:00
logo.png Update readme and add logo 2023-12-01 04:27:35 -05:00
README.md Move logo down 2023-12-01 05:08:45 -05:00

Sly Cooper and the Thievius Raccoonus

Build status Discord Channel Contributors Docs Wiki

This is a work-in-progress decompilation of Sly Cooper and the Thievius Raccoonus for the PlayStation 2. It is based on the NTSC-U version of the game (SCUS-971.98).

The goal of this project is to better understand how the game works. This repo does not contain any game assets or code from the game's executable.

Documenation of the code can be found at theonlyzac.github.io/sly1. Research on the game's internal structures and mechanics is available on the SlyMods Wiki.

New contributors are welcome and encouraged to make a pull request! If you would like to help but aren't sure where to begin, you can join our Discord server and read CONTRIBUTING.md for info on how to get started.

Building

Windows/Linux - CLI

Prerequisites: gcc, cmake, ninja

git clone https://github.com/TheOnlyZac/sly1
cd sly1
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .

To build unit tests, cd into the build directory and run cmake --build . --target check or make check. Run them with ctest -C Debug.

Windows - Visual Studio

Prerequisites: C++ CMake tools for Windows

Clone the repo and open Visual Studio. Click File > Open > CMake... and open the file CMakeLists.txt in the main project folder. Set the startup item to SCUS_971.98.

For unit testing, build the target "Check" and the tests should appear in the Test Explorer window. It will run the tests, and the results will show in the Test Explorer as well as the Output window.

Structure

The project is split into two main directories: src and test. The src folder contains the decompiled code, and the test folder contains unit tests.

The src folder contains the directory P2 which contains the code for the game engine. P2/splice contains the code for the game's scripting engine, Splice.

The test folder contains the directory comprises subdirectories for each game system. Each subdirectory contains unit tests for that system.

sly1
├───src
│   ├───P2
│   │   ├───splice
│   │   └───...
└───test
    ├───P2
    │   ├───clock
    |   |───difficulty
    │   └───...
    └───...

Unit Tests

Unit tests are implemented using CTest. Each test is a program with a main function; the test passes if the program exits with a return code of 0. Each subdirectory in the test folder contains a CMakeLists.txt file which adds the unit test using the add_unit_test command as follows:

add_unit_test(PARALLEL TRUE NAME system.test_name SOURCES test_name.cpp LIBS ${P2_LIB_TARGET})

system should be the same as the name of the directory where you are adding the test. test_name should be a unique name for the test which is the same as the source file containing the test.

The PARALLEL option specifies whether the test can be run in parallel with other tests. If PARALLEL is TRUE, the test will be run in parallel with other tests. If PARALLEL is FALSE, the test will be run in serial with other tests.

The test runner is a program called check which runs each test and reports the results. It is built automatically when you build the check target.

Writing Tests

If you are not function matching, it is recommended that you write tests for any new code you add to ensure it behaves the same way as the original code. You can use the JtAssert(condition) macro to assert that a condition is true. If the condition is false, the test will fail and the test runner will print the file and line number where the assertion failed.

JtAssert(1 == 1); // Passes
JtAssert(1 == 2); // Fails

FAQ

What is a decompilation?

When the developers created the game they wrote programming code that we call the source code. Then they compiled the source code into machine code that can run on the PS2. Our job is to reverse-engineer the compiled code and produce new, original code that behaves the same way. This process leaves us with code that is very similar (but not identical) to the source code and helps us understand what the programmers were thinking when they made the game.

How does it work?

We use a tool called Ghidra which was created by the NSA for reverse-engineering software. Ghidra analyzes the game binary to identity functions, variables, data types and structures. We then reimplement each individual function by writing C++ code that produces the same output. We do not copy/paste any code or include any original assembly code from the game binary in the decompilation.

Has this ever been done before?

This is one of the first large-scale PS2 decompilation projects. We take inspiration from other projects like the Super Mario 64 decomp for the N64 and the Breath of the Wild decomp for the Wii U (the latter being more similar in scope to this project). There is also a Jak & Daxter decomp/PC port called OpenGOAL, though that game is written in 98% GOAL language rather than C/C++.

Is this a matching decomp?

Most of the decompiled code is not yet matching. We are actively researching the PS2 compiler and working to come up with with a process for function matching.

How can I help?

If you would like to contribute but have no idea where to start, you can join our discord server and read CONTRIBUTING.md for some resources and advice to get started!

Star History

Star History Chart