diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..7c5f3917 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,63 @@ +name: Build + +on: + push: + pull_request: + +jobs: + build: + # This is a *private* build container. + # See docs/github_actions.md for more information. + container: ghcr.io/rainchus/marioparty4-build:main + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Add game versions here + version: [GMPE01_00] + + steps: + # Checkout the repository (shallow clone) + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: recursive + + # Set Git config + - name: Git config + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + # Copy the original files to the workspace + - name: Prepare + run: cp -R /orig . + + # Build the project + - name: Build + run: | + python configure.py --map --version ${{ matrix.version }} \ + --binutils /binutils --compilers /compilers + ninja all_source build/${{ matrix.version }}/progress.json + + # Upload progress if we're on the main branch + - name: Upload progress + # If you're using a different branch, change this to match + if: github.ref == 'refs/heads/main' + continue-on-error: true + env: + # Replace with your project slug + PROGRESS_SLUG: marioparty4 + # Set the API key in your repository secrets + PROGRESS_API_KEY: ${{ secrets.PROGRESS_API_KEY }} + run: | + python tools/upload_progress.py -b https://progress.decomp.club/ \ + -p $PROGRESS_SLUG -v ${{ matrix.version }} \ + build/${{ matrix.version }}/progress.json + + # Upload map files + - name: Upload map + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.version }}_maps + path: build/${{ matrix.version }}/**/*.MAP \ No newline at end of file diff --git a/README.md b/README.md index 60577b3f..53e82df1 100644 --- a/README.md +++ b/README.md @@ -5,30 +5,30 @@ Mario Party 4 -[Build Status]: https://github.com/zeldaret/tww/actions/workflows/build.yml/badge.svg -[actions]: https://github.com/zeldaret/tww/actions/workflows/build.yml +[Build Status]: https://github.com/Rainchus/marioparty4/actions/workflows/build.yml/badge.svg +[actions]: https://github.com/Rainchus/marioparty4/actions/workflows/build.yml -[Progress]: https://img.shields.io/endpoint?label=Code&url=https%3A%2F%2Fprogress.decomp.club%2Fdata%2Ftww%2FGZLE01%2Fall%2F%3Fmode%3Dshield%26measure%3Dcode +[Progress]: https://img.shields.io/endpoint?label=Code&url=https%3A%2F%2Fprogress.decomp.club%2Fdata%2Fmarioparty4%2FGMPE01_00%2Fall%2F%3Fmode%3Dshield%26measure%3Dcode -[DOL Progress]: https://img.shields.io/endpoint?label=DOL&url=https%3A%2F%2Fprogress.decomp.club%2Fdata%2Ftww%2FGZLE01%2Fdol%2F%3Fmode%3Dshield%26measure%3Dcode +[DOL Progress]: https://img.shields.io/endpoint?label=DOL&url=https%3A%2F%2Fprogress.decomp.club%2Fdata%2Fmarioparty4%2FGMPE01_00%2Fdol%2F%3Fmode%3Dshield%26measure%3Dcode -[RELs Progress]: https://img.shields.io/endpoint?label=RELs&url=https%3A%2F%2Fprogress.decomp.club%2Fdata%2Ftww%2FGZLE01%2Fmodules%2F%3Fmode%3Dshield%26measure%3Dcode +[RELs Progress]: https://img.shields.io/endpoint?label=RELs&url=https%3A%2F%2Fprogress.decomp.club%2Fdata%2Fmarioparty4%2FGMPE01_00%2Fmodules%2F%3Fmode%3Dshield%26measure%3Dcode -[Discord Badge]: https://img.shields.io/discord/727908905392275526?color=%237289DA&logo=discord&logoColor=%23FFFFFF +[Discord Badge]: https://img.shields.io/discord/994839212618690590?color=%237289DA&logo=discord&logoColor=%23FFFFFF [discord]: https://discord.gg/T4faGveujK A work-in-progress decompilation of Mario Party 4. diff --git a/configure.py b/configure.py index 251f8db7..22e3af3a 100644 --- a/configure.py +++ b/configure.py @@ -55,6 +55,12 @@ parser.add_argument( default=Path("build"), help="base build directory (default: build)", ) +parser.add_argument( + "--binutils", + metavar="BINARY", + type=Path, + help="path to binutils (optional)", +) parser.add_argument( "--compilers", dest="compilers", @@ -67,6 +73,11 @@ parser.add_argument( action="store_true", help="generate map file(s)", ) +parser.add_argument( + "--no-asm", + action="store_true", + help="don't incorporate .s files from asm directory", +) parser.add_argument( "--debug", dest="debug", @@ -81,10 +92,10 @@ if not is_windows(): help="path to wibo or wine (optional)", ) parser.add_argument( - "--build-dtk", - dest="build_dtk", + "--dtk", + metavar="BINARY | DIR", type=Path, - help="path to decomp-toolkit source (optional)", + help="path to decomp-toolkit binary or source (optional)", ) parser.add_argument( "--sjiswrap", @@ -98,6 +109,12 @@ parser.add_argument( action="store_true", help="print verbose output", ) +parser.add_argument( + "--non-matching", + dest="non_matching", + action="store_true", + help="builds equivalent (but non-matching) or modded objects", +) args = parser.parse_args() config = ProjectConfig() @@ -108,13 +125,17 @@ version_num = VERSIONS.index(config.version) # Apply arguments config.build_dir = args.build_dir -config.build_dtk_path = args.build_dtk +config.dtk_path = args.dtk +config.binutils_path = args.binutils config.compilers_path = args.compilers config.debug = args.debug config.generate_map = args.map +config.non_matching = args.non_matching config.sjiswrap_path = args.sjiswrap if not is_windows(): config.wrapper = args.wrapper +if args.no_asm: + config.asm_dir = None # Tool versions config.binutils_tag = "2.42-1" @@ -882,7 +903,7 @@ config.libs = [ Object(Matching, "REL/executor.c"), Object(Matching, "REL/m410Dll/main.c"), Object(Matching, "REL/m410Dll/stage.c"), - Object(NonMatching, "REL/m410Dll/game.c"), + Object(Matching, "REL/m410Dll/game.c"), Object(Matching, "REL/m410Dll/player.c"), }, ), diff --git a/include/REL/m410Dll.h b/include/REL/m410Dll.h index 81e3c34e..ff6a02e1 100644 --- a/include/REL/m410Dll.h +++ b/include/REL/m410Dll.h @@ -205,7 +205,7 @@ void fn_1_28AC(s32 arg0); s32 fn_1_28DC(void); float fn_1_2FD4(float arg8, float arg9, float argA); float fn_1_30F0(float arg8, float arg9); -s32 fn_1_76B8(void *arg0, Vec *arg1, u16 arg2); +s32 fn_1_76B8(Vec arg0, Vec arg1, u16 arg2); void fn_1_77E8(void *arg0); void fn_1_77F8(u16 arg0, Vec *arg1); void fn_1_7840(u16 arg0, Vec *arg1); diff --git a/include/game/hsfman.h b/include/game/hsfman.h index d4b6eae8..704648c6 100644 --- a/include/game/hsfman.h +++ b/include/game/hsfman.h @@ -64,7 +64,7 @@ typedef struct model_data { Vec rot; Vec scale; Mtx unk_F0; - void *unk_120; + ParticleData *unk_120; } ModelData; // sizeof 0x124 typedef struct camera_data { f32 fov; diff --git a/src/REL/m410Dll/game.c b/src/REL/m410Dll/game.c index 899dcca5..bc6eb040 100644 --- a/src/REL/m410Dll/game.c +++ b/src/REL/m410Dll/game.c @@ -1091,15 +1091,14 @@ void fn_1_7494(void) void fn_1_7520(Vec *arg0) { ParticleData *var_r30; // no, custom struct - void *var_r31; + HsfanimStruct01 *var_r31; var_r30 = Hu3DData[lbl_1_bss_38].unk_120; // unk_120 is not ParticleData - // var_r31 = var_r30->unk_48 + (var_r30->unk_02++ * 0x44); - 100.0f; // to fit rodata temporarily - // var_r31->unk_2C = 100.0f; - // var_r31->unk_34 = arg0->x; - // var_r31->unk_38 = arg0->y; - // var_r31->unk_3C = arg0->z; + var_r31 = &var_r30->unk_48[var_r30->unk_02++]; + var_r31->unk2C = 100.0f; + var_r31->unk34.x = arg0->x; + var_r31->unk34.y = arg0->y; + var_r31->unk34.z = arg0->z; } s32 lbl_1_data_110 = 60; @@ -1107,58 +1106,48 @@ s32 lbl_1_data_110 = 60; void fn_1_75A0(ModelData *model, ParticleData *particle, Mtx matrix) { HsfanimStruct01 *var_r30; - s16 var_r29; - u8 var_r28; + s32 var_r29; + s32 var_r28; if (!particle->unk_00) { particle->unk_00 = 1; - var_r30 = &particle->unk_48[particle->unk_02]; // TODO - var_r29 = particle->unk_02; - for (; var_r29 < particle->unk_30; var_r29++, var_r30 += 0x44) { + var_r30 = &particle->unk_48[particle->unk_02]; + for (var_r29 = particle->unk_02; var_r29 < particle->unk_30; var_r29++, var_r30++) { var_r30->unk2C = 0.0f; } } var_r28 = (lbl_1_data_110 * 0xFF) / 60; var_r30 = particle->unk_48; - // for (var_r29 = 0; var_r29 < particle->unk_02; var_r29++, var_r30 += 0x44) { - // var_r30->unk_43 = var_r28; // 43? - // } - // if (--lbl_1_data_110 == 0) { - // model->unk_50 = model->unk_50 | 1; - // } - // DCStoreRange(particle->unk_048, particle->unk_30 * 0x44); + for (var_r29 = 0; var_r29 < particle->unk_02; var_r29++, var_r30++) { + var_r30->unk40.a = var_r28; // 43? + } + if (--lbl_1_data_110 == 0) { + model->attr |= 1; + } + DCStoreRange(particle->unk_48, particle->unk_30 * 0x44); } -s32 fn_1_76B8(void *arg0, Vec *arg1, u16 arg2) +s32 fn_1_76B8(Vec arg0, Vec arg1, u16 arg2) { - UnkM410Struct2 *var_r31; + UnkM410Struct2 *var_r31 = lbl_1_bss_58->data; s32 var_r30; - var_r31 = &((UnkM410Struct2 *)lbl_1_bss_58->data)[arg2 * 15]; - var_r30 = 0; - while (TRUE) { - if (var_r30 >= 15) { - return 0; - } - if (!var_r31->unk_00_field0) { - var_r31->unk_00_field4 = 0; // TODO this sets two bytes... so maybe wrong struct, the size is right though - // var_r31->unk_0 = var_r31->unk_0 | 0x80; - // var_r31->unk_0 = var_r31->unk_0 | 0x20; - // var_r31->unk_04 = arg0->unk_0; - // var_r31->unk_08 = arg0->unk_04; - // var_r31->unk_0C = arg0->unk_08; - // var_r31->unk_1C = arg1->unk_0; - // var_r31->unk_20 = arg1->unk_04; - // var_r31->unk_24 = arg1->unk_08; - var_r31->unk_28 = 30.000002f; - var_r31->unk_38 = 0; - var_r31->unk_36 = 0; - return 1; - } - var_r30++; - var_r31++; - } + var_r31 = &var_r31[arg2 * 15]; + for(var_r30=0; var_r30<15; var_r30++, var_r31++) { + if (!var_r31->unk_00_field0) { + *(s16 *)var_r31 = 0; + var_r31->unk_00_field0 = 1; + var_r31->unk_00_field2 = 1; + var_r31->unk_04 = arg0; + var_r31->unk_1C = arg1; + var_r31->unk_28 = 30.000002f; + var_r31->unk_38 = NULL; + var_r31->unk_36 = 0; + return 1; + } + } + return 0; } void fn_1_77A4(u16 arg0, u16 arg1, u16 arg2) diff --git a/src/REL/m410Dll/player.c b/src/REL/m410Dll/player.c index b5d02b1e..98d1e2c4 100644 --- a/src/REL/m410Dll/player.c +++ b/src/REL/m410Dll/player.c @@ -528,11 +528,7 @@ void fn_1_9040(omObjData *object) sp2C.y = 0.016666668f * var_f27; sp2C.z = (sp20.z - var_r31->unk_70.z) * 0.016666668f / var_f31; } - sp8 = sp2C; - var_r26 = &sp8; - sp14 = var_r31->unk_70; - var_r25 = &sp14; - fn_1_76B8(var_r25, var_r26, object->work[0]); + fn_1_76B8(var_r31->unk_70, sp2C, object->work[0]); var_r31->unk_18 = 0; var_r31->unk_24 = 0; if (var_r31->unk_1C) {