From f31bbc26fb3488e750b104930019aa26bdfa3d1f Mon Sep 17 00:00:00 2001 From: Aetias Date: Wed, 27 Dec 2023 13:26:42 +0100 Subject: [PATCH] Add documentation --- CONTRIBUTING.md | 140 ++++++++++++++++++++++++++++++++++++++ README.md | 6 ++ docs/actors.md | 17 +++++ docs/inline_assembler.md | 36 ++++++++++ docs/items.md | 141 +++++++++++++++++++++++++++++++++++++++ docs/memory.md | 15 +++++ docs/overlays.md | 67 +++++++++++++++++++ 7 files changed, 422 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 docs/actors.md create mode 100644 docs/inline_assembler.md create mode 100644 docs/items.md create mode 100644 docs/memory.md create mode 100644 docs/overlays.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..4cc55a0d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,140 @@ +# Contribution guide +- [Project structure](#project-structure) +- [Decompiling a function](#decompiling-a-function) +- [Code style](#code-style) +- [Creating new `.c`/`.cpp` files](#creating-new-ccpp-files) +- [Non-matching functions](#non-matching-functions) + +## Project structure +- `asm/`: Non-decompiled assembly code + - `ovXX/`: Code for overlay `XX` + - `*.s`: Source file in assembly + - `include/*.inc`: External symbols imported by respective source file +- `build/`: Build output + - `arm9_linker_script.lcf`: Linker command file for ARM9 program, specifies the order to put code and data into the ROM + - `arm9_objects.txt`: List of object files to pass to the linker + - `eur/`: Compiled/linked files + - `asm/`: Built assembly code + - `src/`: Built C/C++ code + - `overlays/`: Contains `.bin` and `.lz` files for each overlay + - `*.bin`: Linked code/data to compress or put in the ROM + - `*.lz`: Compressed code to put in the ROM + - `main.bin.xMAP`: Map file listing RAM addresses for all symbols +- `docs/`: Documentation about the game +- `include/`: Include files +- `ph_eur/`: Game assets, extracted from your own supplied ROM + - `assets/`: Unmodified assets + - `banner/`: Banner logo and text that shows on the DS home menu + - `arm7.bin`: Extracted ARM7 program + - `arm9_ovdata.bin`: Data about ARM9 overlays +- `src/`: Source C/C++ files +- `tools/`: Tools for this project + - `compress/`: Compresses code before it is put in the ROM + - `mwccarm/`: Compiler toolchain + - `rom/`: Extracts and builds ROMs + - `lcf.py`: Generates `arm9_linker_script.lcf` + - `patch_mwcc.py`: Patches bugs in the toolchain + - `requirements.txt`: Python libraries + - `setup.py`: Sets up the project +- `assets.txt`: The order of asset directories to put in the ROM +- `*.sha1`: SHA-1 digests of different versions of the game + +## Decompiling a function +WIP + +## Creating new `.c`/`.cpp` files +New source files must be added to the LCF (Linker Command File). This is done via `lcf.py`, which generates the LCF when +building. + +In `lcf.py`, you will see a list of overlays near the top. Each overlay then has a list of source files ending in `.s`, `.c` or +`.cpp`. Those source files, when compiled, are appended to the ROM in the order that they appear in the list. + +So, to create a new source file, you put the path to the source file in the correct overlay so that it appears in the correct +order in relation to other source files. + +## Code style +The code style is not strict, but please try to mimic the existing style as much as possible. + +If it's impossible to match a function while following the code style, then it's OK to not follow it. But do let us know when +this happens so we may amend the code style. + +Below is an example of the code style in this project. If something is unclear, look at existing code. If the existing code is +insufficient, then you may decide the code style in that situation. +```cpp +// Space before pointer asterisk * and reference ampersand & +s32 MyClass::MyMethod(MyStruct *myStruct, s32 &anInteger) { + // Opening brace { on the same line + // Space after `if`, `while`, `for` and `switch` + if (myStruct->isCool) { + // Access member fields using `this` + // Class member fields are prefixed with "m" + this->mInteger = anInteger; + } + // No space before asterisk * in pointer casts + // Space after cast operator + this->mPointer = (u32*) &anInteger; + + // Prefer pre-increment ++i + // Use s32, s16, s8, etc. instead of int, short, char + for (s32 i = 0; i < 10; ++i) { + // Use `char` instead of s8 to indicate actual characters + char ch = 'A' + i * 2; + this->mString[i] = ch; + } + + // Put long conditions on new line + if ( + // Add clarifying parentheses for bool operators + (this->mInteger > 10 && this->mPointer != NULL) || + (this->mInteger < 5) + ) { + // Add clarifying parentheses for bitwise operators + this->mBool = ((this->mInteger >> 5) & 1) != 0; + } + + do { + // Call member functions using `this` + this->DoStuff(); + // In do-while loops, `while` on same line as closing brace } + } while (this->CanDoStuff()); + + switch (this->mInteger) { + // Indent `case` + // If possible, put braces after `case` + case 8: { + return *this->mPointer; + // If possible, put `break` after closing brace } + } break; + } + + // No parentheses around return value + return this->mInteger; +} +``` + +## Non-matching functions +This project supports non-matching functions, and you can build them by using `make NONMATCHING=1`. + +Non-matching functions must be written as follows: +```cpp +#include "global.hpp" + +NONMATCH void MyFunction() { + #ifndef NONMATCHING + #include "../asm/path/to/asm.inc" + #else + // non-matching code here + #endif +} +``` + +When building normally, the `NONMATCH` macro will mark `MyFunction` as an assembly function, and the `NONMATCHING` macro will +not be defined so that the `asm.inc` file will be included. + +Conversely, when building in non-matching mode, `MyFunction` will be a regular C/C++ function, and the non-matching code will +be inserted instead of `asm.inc`. + +When contributing non-matching functions to this project, please build in both modes and fix any build errors you may get. +Delete the `.o` file between building in each mode so that the `Makefile` runs the compiler both times. + +> [!NOTE] The inline assembler does not function the same as the standalone assembler. [See differences here.](inline_assembler.md#differences-from-standalone-assembler) diff --git a/README.md b/README.md index 60c1c21d..136bbe47 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,9 @@ extract assets from. ## How to install See [INSTALL.md](INSTALL.md) for instructions on how to install the project. + +## Contribution +A work in progress, but [CONTRIBUTING.md](CONTRIBUTING.md) has guidelines for how to contribute to the project. + +## Documentation +See [/docs](/docs) for documentation about the game. diff --git a/docs/actors.md b/docs/actors.md new file mode 100644 index 00000000..72382438 --- /dev/null +++ b/docs/actors.md @@ -0,0 +1,17 @@ +# Actors +This file documents what is known about actors in the game. +- [Actor IDs](#actor-ids) + +## Actor IDs +Many actors have a 4-character ID associated with it. This table shows all known IDs and their respective meanings or +translations. Feel free to contribute to this list! + +> [!NOTE] +> These IDs will appear in memory in reverse order. This is because allocation IDs are often interpreted as 32-bit integers, +> and integers are stored in little-endian which effectively "reverses" the character order. + + ID | Translation | Meaning +-------|-------------|--------- +`NAVI` | Navi | Spirit of Courage (Ciela) +`FCNV` | Force Navi | Spirit of Power (Leaf) +`WSNV` | Wisdom Navi | Spirit of Wisdom (Neri) diff --git a/docs/inline_assembler.md b/docs/inline_assembler.md new file mode 100644 index 00000000..62e792c2 --- /dev/null +++ b/docs/inline_assembler.md @@ -0,0 +1,36 @@ +# Inline assembler +- [Differences from standalone assembler](#differences-from-standalone-assembler) + +## Differences from standalone assembler +Below is a list of differences between the inline assembler and the standalone disassembler. If something is missing, feel free +to contribute to the list! +- [Pool constants](#pool-constants) +- [Data sections](#data-sections) +- [Comments](#comments) + +### Pool constants +There is no `.word` or other data directives in the inline assembler. Instead, use the built-in `dcd` instruction: +```asm +mov r0, [pc, #0] +bx lr +dcd 0x1234 +``` + +This can also be written as: +```asm +lda 0x1234 +bx lr +``` + +The built-in `lda` instruction will be replaced by an ARM load instruction and also append a pool constant to the function. + +### Data sections +Directives such as `.section`, `.data` and `.bss` are not supported in the inline assembler. There might be a way to change +section with a `#pragma`, but there's no need to. Data should only be defined in standalone assembly or C/C++. + +### Comments +Inline assembly is handled by the compiler, so comments must be in C/C++ format. This means using `//` and `/* */` instead of +`#` or `;`. + +Semicolons `;` instead mark the end of an instruction and are optional. You can use them to put multiple instructions on one +line, but we avoid doing it so that we can preserve as much similarity to standalone assembly as possible. diff --git a/docs/items.md b/docs/items.md new file mode 100644 index 00000000..2883464a --- /dev/null +++ b/docs/items.md @@ -0,0 +1,141 @@ +# Items +This file documents what is known about items in the game. +- [Item IDs](#item-ids) + +## Item IDs +Might be inaccurate due to there being seemingly multiple IDs/enumerations for items. Feel free to contribute to this list! + + ID | Item +-------|---------------- +`0x00` | Key +`0x01` | Key +`0x02` | Big Green Rupee +`0x03` | Oshus's Sword +`0x04` | Shield +`0x05` | --- +`0x06` | Yellow Force Gem +`0x07` | Bomb +`0x08` | Bow +`0x09` | Green Rupee +`0x0a` | Heart +`0x0b` | --- +`0x0c` | Boomerang +`0x0d` | Shovel +`0x0e` | Bombchu +`0x0f` | Boss Key +`0x10` | `rev` +`0x11` | --- +`0x12` | --- +`0x13` | Sea Chart +`0x14` | Sea Chart +`0x15` | Sea Chart +`0x16` | Sea Chart +`0x17` | --- +`0x18` | Blue Rupee +`0x19` | Red Rupee +`0x1a` | Big Red Rupee +`0x1b` | Gold Rupee +`0x1c` | Yellow Force Gem +`0x1d` | Red Force Gem +`0x1e` | Blue Force Gem +`0x1f` | Hammer +`0x20` | Grapple Hook +`0x21` | Square Crystal +`0x22` | Circle Crystal +`0x23` | Triangle Crystal +`0x24` | `fp` +`0x25` | --- +`0x26` | Sun Key +`0x27` | --- +`0x28` | Quiver +`0x29` | Bomb Bag +`0x2a` | Bombchu Bag +`0x2b` | --- +`0x2c` | King's Key +`0x2d` | Power Gem +`0x2e` | Wisdom Gem +`0x2f` | Courage Gem +`0x30` | --- +`0x31` | --- +`0x32` | --- +`0x33` | --- +`0x34` | --- +`0x35` | --- +`0x36` | --- +`0x37` | --- +`0x38` | Ghost Key +`0x39` | `tic_tada` +`0x3a` | `tic_ohome` +`0x3b` | `tic_rare` +`0x3c` | `neckl` +`0x3d` | Salvage Arm +`0x3e` | --- +`0x3f` | Telescope +`0x40` | Notebook +`0x41` | Letter +`0x42` | Card +`0x43` | `marron` +`0x44` | Phantom Blade +`0x45` | --- +`0x46` | --- +`0x47` | --- +`0x48` | --- +`0x49` | --- +`0x4a` | --- +`0x4b` | --- +`0x4c` | --- +`0x4d` | --- +`0x4e` | --- +`0x4f` | --- +`0x50` | --- +`0x51` | --- +`0x52` | --- +`0x53` | --- +`0x54` | --- +`0x55` | --- +`0x56` | --- +`0x57` | --- +`0x58` | --- +`0x59` | --- +`0x5a` | --- +`0x5b` | --- +`0x5c` | --- +`0x5d` | --- +`0x5e` | --- +`0x5f` | --- +`0x60` | --- +`0x61` | --- +`0x62` | --- +`0x63` | --- +`0x64` | --- +`0x65` | --- +`0x66` | --- +`0x67` | --- +`0x68` | --- +`0x69` | --- +`0x6a` | --- +`0x6b` | --- +`0x6c` | --- +`0x6d` | --- +`0x6e` | --- +`0x6f` | --- +`0x70` | --- +`0x71` | --- +`0x72` | --- +`0x73` | --- +`0x74` | --- +`0x75` | --- +`0x76` | --- +`0x77` | --- +`0x78` | --- +`0x79` | --- +`0x7a` | --- +`0x7b` | --- +`0x7c` | --- +`0x7d` | --- +`0x7e` | --- +`0x7f` | --- +`0x80` | --- +`0x81` | --- +`0x82` | --- +`0x83` | --- diff --git a/docs/memory.md b/docs/memory.md new file mode 100644 index 00000000..048c1868 --- /dev/null +++ b/docs/memory.md @@ -0,0 +1,15 @@ +# Memory +This file documents what is known about memory management in the game. +- [Allocation IDs](#allocation-ids) + +## Allocation IDs +Many heap-allocated objects have a 4-character ID associated with it. This table shows all known IDs and their respective +meanings or translations. + +> [!NOTE] +> These IDs will appear in memory in reverse order. This is because allocation IDs are often interpreted as 32-bit integers, +> and integers are stored in little-endian which effectively "reverses" the character order. + + ID | Translation | Meaning +-------|-------------|--------- +`EXPH` | ? | SysObject diff --git a/docs/overlays.md b/docs/overlays.md new file mode 100644 index 00000000..7ca1263c --- /dev/null +++ b/docs/overlays.md @@ -0,0 +1,67 @@ +# Overlays +Below is a list of all the overlays and what we call them. Feel free to contribute to this list! + + ID | Name +-----|---------------- +`00` | --- +`01` | --- +`02` | --- +`03` | --- +`04` | --- +`05` | --- +`06` | --- +`07` | --- +`08` | --- +`09` | --- +`10` | --- +`11` | --- +`12` | --- +`13` | --- +`14` | --- +`15` | --- +`16` | --- +`17` | --- +`18` | --- +`19` | --- +`20` | --- +`21` | --- +`22` | --- +`23` | --- +`24` | --- +`25` | --- +`26` | --- +`27` | --- +`28` | --- +`29` | --- +`30` | --- +`31` | --- +`32` | --- +`33` | --- +`34` | --- +`35` | --- +`36` | --- +`37` | --- +`38` | --- +`39` | --- +`40` | --- +`41` | --- +`42` | --- +`43` | --- +`44` | --- +`45` | --- +`46` | --- +`47` | --- +`48` | --- +`49` | --- +`50` | --- +`51` | --- +`52` | --- +`53` | PlayerBoomerang +`54` | PlayerShovel +`55` | PlayerBomb +`56` | PlayerBow +`57` | PlayerRope +`58` | PlayerBombchu +`59` | PlayerHammer +`60` | --- +`61` | ---