mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 12:02:30 +01:00
38249a8967
* propose new stuff for ifdefs * oopth * Update CONTRIBUTING.md
135 lines
6.1 KiB
Markdown
135 lines
6.1 KiB
Markdown
# 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 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`.
|
|
|
|
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, run
|
|
|
|
```sh
|
|
./make_expected.sh
|
|
```
|
|
|
|
to copy `ver/us/build/` to `ver/us/expected/build/`.
|
|
|
|
### Roughly converting assembly to C
|
|
|
|
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`).
|
|
|
|
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.)
|
|
|
|
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
|
|
// src/FOO.c
|
|
- INCLUDE_ASM("FOO", func_DEADBEEF);
|
|
+ s32 func_DEADBEEF() {
|
|
+ // ...
|
|
+ }
|
|
```
|
|
|
|
Recompile 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). 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.
|
|
|
|
### 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)!
|
|
|
|
## 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.
|