# Contributing Thank you for your interest in contributing to this project! ## Dependencies There are a few additional dependencies needed when contributing to this project. You can install them with `./install.sh --extra`. ## Build System You will need to re-run `./configure.py` whenever `splat.yaml` or the number of source files changes (e.g. a function is matched and its `.s` file is removed). If you `git pull` and `ninja` breaks, you probably need to re-run `./configure.py`. 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. ## Tutorial: Matching a function ### Setup Once you've created a successful (`OK`) build, copy `ver/us/build/` to `ver/us/expected/build/`: ```sh $ mkdir -p ver/us/expected $ cp -r ver/us/build ver/us/expected ``` (If you're working with other versions of the game, replace `us` in the file paths.) ### Roughly converting assembly to C Decide on a function to match. These can be found in the subdirectories of `ver/us/asm/nonmatchings/`. 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)). 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/code_FOO/func_DEADBEEF`: ```diff // src/code_FOO.c - INCLUDE_ASM("code_FOO", func_DEADBEEF); + s32 func_DEADBEEF() { + // ... + } ``` Compile the ROM: ```sh ninja ``` 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 you may find in [Star Rod's library database](https://github.com/nanaian/star-rod/blob/master/database/common_func_library.lib). 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: ```sh ./diff.py -mwo function_name ``` (Sometimes, `-mwo` doesn't work. We don't know why yet; use `-mw` if you encounter issues.) `diff.py` displays the difference between the original game's assembly (on the left) and what your C code generated (on the right). ### Matching the function You're on your own now. Get your C code compiling to match the original assembly! `diff.py`, when running with `-m`, 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.) 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 ### After matching Once you've matched a function, run the following: ```sh ./coverage.py --delete-matched ``` Then, go ahead and [create a pull request](https://github.com/pmret/papermario/pulls)!