papermario/CONTRIBUTING.md

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

133 lines
6.0 KiB
Markdown
Raw Normal View History

2021-01-15 17:28:05 +01:00
# Contributing
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
Thank you for your interest in contributing to this project!
## Dependencies
2020-12-24 09:38:37 +01:00
There are a few additional dependencies needed when contributing to this project. You can install them with `./install_deps.sh --extra`.
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
## Build System
2021-09-29 09:30:58 +02:00
You will need to edit `splat.yaml` and re-run `./configure` in certain circumstances, among which are the changing of source file names, the creation or deletion of source files, and migrating data from a .data.s file into c. If you `git pull` and `ninja` breaks, you probably need to re-run `./configure`.
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
If you use Visual Studio Code, you can use _Run Build Task_ (Ctrl+Shift+B) to run `ninja`. Any errors or warnings generated by the compiler will show up in the _Problems_ tab.
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
## Tutorial: Matching a function
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
### Setup
2020-12-24 09:38:37 +01:00
Once you've created a successful (`OK`) build, run
2020-12-24 09:38:37 +01:00
```sh
./make_expected.sh
2020-12-24 09:38:37 +01:00
```
to copy `ver/us/build/` to `ver/us/expected/build/`.
2021-01-15 17:28:05 +01:00
### Roughly converting assembly to C
2020-12-24 09:38:37 +01:00
Decide on a function to match. These can be found in the subdirectories of `ver/us/asm/nonmatchings/`. Also find the `.c` file that uses the function (it will have the function name in an `INCLUDE_ASM`).
2020-12-24 09:38:37 +01:00
Most of the time you will want to generate a context file that defines all the project-specific structs and function prototypes, as well as information specific to the file. You can make this file by running
```sh
./tools/m2ctx.py <path/to/c_file.c>
```
(replace the contents of the `<>` by the actual path to the file from the repository root!); this will make a file called `ctx.c` in the repository's root directory.
Take the relevant `.s` file and pass it to [mips_to_c](https://github.com/matt-kempster/mips_to_c) ([online version](https://simonsoftware.se/other/mips_to_c.py)). Both versions work essentially the same way.
- if you want to use a local version, clone the repository into a separate directory in `papermario`s parent directory, read the documentation, and run it with `../mips_to_c/mips_to_c.py <path/to/func_asm.s>` from the root of the `papermario` repository. You pass the context file with `--context ctx.c`. Run with `-h` to see more options.
- the web version has two boxes: you paste the contents of the assembly file into the top box and the contents of the context file into the lower box.
(The web version is easier to use to start with, but you'll probably find that the local version is more efficient once you get used to it.)
2020-12-24 09:38:37 +01:00
Splat refactor (#257) * all non-world rodata migrated * data disasm * kinda working * updated yaml * bloop * linker header * configure 2.0 * bin * mass rename to remove code_ * pause rename * battle partner stuff * whew * more renames * more renames * more renaming * it builds! * updates * remove main prefix * one more thing * crc, yay0 * .data, .rodata, .bss * img * dead_atan2 * it buildsgit add -A * split battle/partner/6FAD10 * rm &s on sleepy_sheep syms * sha1sum ninja rule description * OK but commented out PaperMarioMapFS and PaperMarioNpcSprites * uncomment * fix mapfs * match func_8003CFB4 * . * clean up and name npc_iter_no_op * npc.c * enable cc warnings * name npc_find_near * use singular options.asset_path * smores * cc_dsl only when needed * kinda fix configure for splat refactor2 * ok! * new msg format * remove old msg format docs * slight bug fixes, splat adjustment * git subrepo pull (merge) --force tools/splat subrepo: subdir: "tools/splat" merged: "cfc140bb76" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "cfc140bb76" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * git subrepo pull (merge) --force tools/splat subrepo: subdir: "tools/splat" merged: "85349befcd" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "85349befcd" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * Update symbol addrs * git subrepo pull tools/splat subrepo: subdir: "tools/splat" merged: "a44631e194" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "a44631e194" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" Co-authored-by: Alex Bates <hi@imalex.xyz>
2021-04-13 09:47:52 +02:00
Open up the `.c` file that uses your function and replace the function's `INCLUDE_ASM` macro with the output from mips_to_c. For example, for a function `asm/nonmatchings/FOO/func_DEADBEEF`:
```diff
Splat refactor (#257) * all non-world rodata migrated * data disasm * kinda working * updated yaml * bloop * linker header * configure 2.0 * bin * mass rename to remove code_ * pause rename * battle partner stuff * whew * more renames * more renames * more renaming * it builds! * updates * remove main prefix * one more thing * crc, yay0 * .data, .rodata, .bss * img * dead_atan2 * it buildsgit add -A * split battle/partner/6FAD10 * rm &s on sleepy_sheep syms * sha1sum ninja rule description * OK but commented out PaperMarioMapFS and PaperMarioNpcSprites * uncomment * fix mapfs * match func_8003CFB4 * . * clean up and name npc_iter_no_op * npc.c * enable cc warnings * name npc_find_near * use singular options.asset_path * smores * cc_dsl only when needed * kinda fix configure for splat refactor2 * ok! * new msg format * remove old msg format docs * slight bug fixes, splat adjustment * git subrepo pull (merge) --force tools/splat subrepo: subdir: "tools/splat" merged: "cfc140bb76" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "cfc140bb76" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * git subrepo pull (merge) --force tools/splat subrepo: subdir: "tools/splat" merged: "85349befcd" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "85349befcd" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * Update symbol addrs * git subrepo pull tools/splat subrepo: subdir: "tools/splat" merged: "a44631e194" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "a44631e194" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" Co-authored-by: Alex Bates <hi@imalex.xyz>
2021-04-13 09:47:52 +02:00
// src/FOO.c
- INCLUDE_ASM("FOO", func_DEADBEEF);
+ s32 func_DEADBEEF() {
+ // ...
+ }
2020-12-24 09:38:37 +01:00
```
Recompile the ROM:
2020-12-24 09:38:37 +01:00
```sh
ninja
2020-12-24 09:38:37 +01:00
```
This will probably end up either `FAIL`ing (the resulting ROM does not match the baserom), or the compilation of the C file you just modified did not succeed. mips_to_c loves to use void pointers and weird syntax that won't compile properly. Fixing this will involve typing the function signature correctly, which can involve trial and error. For structs, see [common_structs.h](include/common_structs.h).
Once the C file compiles, you can compare the assembly generated by your code versus the original assembly with the following command, replacing `function_name` with the name of the function you're working on:
2020-12-24 09:38:37 +01:00
```sh
./diff.py -mwo function_name
```
`diff.py` displays the difference between the original game's assembly (on the left) and what your C code generated (on the right). If you want to compare with the last saved version as well, you can use `-3` to get a three-column diff of the original (left), current (middle), and previous (right). Passing `-b` instead of `-3` gives a three-way diff of original, current, and the version from when `diff.py` was started. Run `./diff.py -h` to see other flags and options.
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
### Matching the function
2020-12-24 09:38:37 +01:00
You're on your own now. Get your C code compiling to match the original assembly! `diff.py`, when running with `-mw`, will automatically recompile your code whenever you save the `.c` file.
If you use Visual Studio Code, you can use _Run Test Task_ to run `diff.py` and show you errors and warnings from the compiler inline. (You might want to attach _Run Test Task_ to a keybinding, as you'll be using it often.)
2020-12-24 09:38:37 +01:00
If you have any questions or encounter any issues, we suggest:
- Reaching out [on Discord](https://discord.gg/urUm3VG)
- Using [decomp permuter](https://github.com/simonlindholm/decomp-permuter) if your code is logically equivalent
- Wrapping what you have in `#ifdef NON_MATCHING` (see other examples of this in the codebase) and trying a smaller function
2020-12-24 09:38:37 +01:00
2021-01-15 17:28:05 +01:00
### After matching
2020-12-24 09:38:37 +01:00
Once you've matched a function, run the following:
2020-12-24 09:38:37 +01:00
```sh
./coverage.py --delete-matched
2020-12-24 09:38:37 +01:00
```
Then, go ahead and [create a pull request](https://github.com/pmret/papermario/pulls)!
## Trouble matching a function
Sometimes when working on a function, for various reasons, you'll be unable to match it. The following two sections describe what labels we give these functions and when. Any time you wrap a function in a label like this, please leave a comment above the function with a brief description of the issue(s).
### NON_EQUIVALENT
If you are working on a function but can't figure out how to tackle certain parts, or you're sure that it's not equivalent, you can wrap it in NON_EQUIVALENT.
Please make a best-effort attempt on any function you put in a PR, though. Half-finished functions aren't necessarily much use to the next decomper.
```c
// can't figure out the MULT_HI() stuff
#ifdef NON_EQUIVALENT
void func(void) {
// ...
}
#else
INCLUDE_ASM(void, "file", func, void);
#endif
```
### NON_MATCHING
If you are unable to 100% match a function but are fairly certain it's equivalent in behavior, you can wrap the C code in NON_MATCHING.
```c
// s3/s4 swap
#ifdef NON_MATCHING
void func(void) {
// ...
}
#else
INCLUDE_ASM(void, "file", func, void);
#endif
```
Once the project is shiftable, NON_MATCHING functions will be used in place of the included ASM.