* fix: Cleanup structure in INSTALL.md * fix: Clean undefined link * feat: Copypaste decompiling.md and start porting over * feat: Keep porting decompiling.md and adding some details * feat: Add images and fix links * Apply suggestions from code review Co-authored-by: Yanis <35189056+Yanis002@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Yanis <35189056+Yanis002@users.noreply.github.com> Done manually because I screwed-up on github * feat: Update decomp.me export instructions, adapt review about thumb region * feat: Add instructions to reserve non-actor files * feat: Add small details for LSP and reminder for installation * feat: Add instructions for coding style (format and naming) * fix: Expand on UnkSystem naming * feat: Add details for objdiff errors * feat: Add information about symbols and tips.md * feat: Add information about UnkAngleStruct * fix: Update the CI build command in tips.md with the actual one * feat: Add some information about naming guidelines * feat: Add information about vtable symbols * feat: Small improvements * feat: Update doc's links layout a bit * feat: Some updates to install.md * feat: Apply reviews * `func_ovxxx_xxxxxxx` -> `func_ovxxx_02xxxxxx` --------- Co-authored-by: Yanis <35189056+Yanis002@users.noreply.github.com>
4.7 KiB
Contribution guide
Decompiling
/docs/decompiling.md has most information as to how to approach decompilation and how to get started.
Reading the rest of this file gives information on the structure of the project and coding style, it is highly recommended to read it.
Project structure
build/: Build outputeur|jp/: Target versionbuild/: Linked ROM objectsdelinks/: Objects delinked from the base ROMlibs|src/: Built C/C++ codearm9.o: Linked ELF objectarm9.o.xMAP: Map file listing memory addresses for all symbols
config/:dsdconfiguration filesdocs/: Documentation about the gameextract/: Game assets, extracted from your own supplied ROMeur|jp/:ds-romextract directories
include/: Include filessrc/: Source C/C++ filestools/: Tools for this projectmwccarm/: Compiler toolchainconfigure.py: Generatesbuild.ninjam2ctx.py: Generates context for decomp.memangle.py: Shows mangled symbol names in a given C/C++ filerequirements.txt: Python librariessetup.py: Sets up the projectvtable_sym.py: Renames and relocates vtable symbols
*.sha1: SHA-1 digests of different versions of the game
Code style
This project has a .clang-format file and all C/C++ files in this project should follow it. We recommend using an editor
compatible with clang-format to format the code as you save.
As a rule of thumb, try to mimick the style that can be observed in already decompiled files.
Please write hexadecimal numbers in upper case (0x9ABCDEF instead of 0x9abcdef). Lowercase numbers are used for global names (old functions names like func_ovxxx_02xxxxxx, data, etc).
Class members use uppercase numbers too (e.g., mUnk_0C for a member placed at position 0xC).
New function names should follow PascalCase, even if they include numbers.
Naming new things
You may have to create new classes, structs, member attributes or functions, etc. Here is described how to name them according to what they are.
Once you find out what something does, it helps to give it a meaningfull name (eg. ModelRender class, Actor::IsAlive() function or Actor.mPrevPos member attribute).
If you don't know yet what a piece of code does, try to follow this rough format: {type}_ov{num}_{address}.
typeis the kind of code you're naming,UnkStructfor a struct,mUnkfor a member attribute,Unk{D}System{X}for a class or group of functions. In the last case,Xwould then be an arbitrary, unique identifier. Likely a number that would increase for every newSystemto name.Dis optional and aimed to give more information about the context in which the system is used (eg.FileorActor).numis the id of the overlay the code is part of.addressis the address of the data you're naming. This may not always be applicable, in which case you can ignore it (and remove the trailing_of the format given above).
You can also name thing based on where they are used. Say that some class ActorP has a member mUnk_{X} that needs it class, you can call the class UnkStruct_ActorP_{X}. Same goes for functions (but try to rather name things with their vtable address when applicable, so that they are easier to find and merge later on).
Creating a class
If you are to create a new class, try to follow this structure:
class Foo {
public:
/* 00 */ int mBar;
/* 04 */
Foo();
/* 00 */ virtual void vfunc_00();
/* 04 */ virtual void vfunc_04();
/* 08 */ virtual ~Foo();
/* 0C */
// itcm
bool func_01fff1e0();
// overlay 0
void func_ov000_0208a318(unk32 param1, unk32 param2, unk32 param3);
void func_ov000_0208bbd4(unk32 param1, VecFx32 *param2, u16 param3);
static UnkStruct_027e0ce0_34 *func_ov000_0205c904();
// overlay 1
void func_ov001_020bc5f8();
void func_ov001_020bc524(bool param1);
static Foo *Create();
static void Destroy();
// overlay 17
void func_ov017_020bd69c();
};
In order, the parts are:
- Member attributes.
- Constructor (ctor).
- Virtual functions (the placement of the destructor (dtor), if there is any, can vary).
- Other methods, grouped by overlay with a comment indicating which one.
Using private may sometime be required to enable some inlining, so feel free to when use it you feel like you should.