From 8c46368d5d93ad278c124ffc6446ab691dff8082 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Sat, 18 Jan 2025 08:58:12 -0700 Subject: [PATCH] Fix data, option menus, impl boos, fix demo camera (#156) * Fix data and option menus * safer code * wip boos impl * finish impl boos * Fix demo camera * slightly better match --- include/objects.h | 2 +- src/code_80005FD0.c | 164 +++++++------- src/code_8006E9C0.c | 7 +- src/data/some_data.c | 97 ++++++++- src/engine/courses/BansheeBoardwalk.cpp | 7 +- src/engine/courses/TestCourse.cpp | 6 +- src/engine/objects/Boos.cpp | 272 ++++++++++++++++++++++++ src/engine/objects/Boos.h | 75 +++++++ src/main.c | 4 - src/menu_items.c | 10 +- src/render_objects.c | 33 --- src/render_objects.h | 4 - src/update_objects.c | 247 +-------------------- src/update_objects.h | 3 - 14 files changed, 549 insertions(+), 382 deletions(-) create mode 100644 src/engine/objects/Boos.cpp create mode 100644 src/engine/objects/Boos.h diff --git a/include/objects.h b/include/objects.h index fecc902a3..4c3c6d77b 100644 --- a/include/objects.h +++ b/include/objects.h @@ -301,7 +301,7 @@ extern Vec3s gHedgehogPatrolPoints[]; */ extern s32 indexObjectList2[]; -#define NUM_BOOS 0xA +#define NUM_BOOS 10 #define NUM_FIRE_BREATHS 4 extern Vec3s gFireBreathsSpawns[]; diff --git a/src/code_80005FD0.c b/src/code_80005FD0.c index cb4157b63..d28138366 100644 --- a/src/code_80005FD0.c +++ b/src/code_80005FD0.c @@ -5904,31 +5904,28 @@ void func_80017054(Camera* camera, UNUSED Player* player, UNUSED s32 index, s32 // Really crazy diff, permuter only able to find fakematches for improvements (and they're big improvements) // There's something really, really wrong with the empty `if` statement void func_80017054(Camera* camera, UNUSED Player* player, UNUSED s32 index, s32 cameraId) { - UNUSED s32 stackPadding0; - UNUSED s32 stackPadding1; - f32 spAC; - f32 spA8; - f32 spA4; - UNUSED s32 stackPadding2; - UNUSED s32 stackPadding3; - f32 sp98; - f32 sp94; - f32 sp90; - f32 sp8C; - f32 sp88; - f32 sp84; - UNUSED f32 stackPadding4; - UNUSED f32 stackPadding5; - UNUSED f32 stackPadding6; - UNUSED s32 stackPadding7; - UNUSED s32 stackPadding8; - s16 sp6E; - s16 sp6C; - UNUSED s32 stackPadding9; - UNUSED s32 stackPaddingA; - UNUSED s32 stackPaddingB; + s32 pad5[2]; + f32 diffX2; + f32 diffY2; + f32 diffZ2; + s32 stackPadding2; + s32 stackPadding3; + f32 camX; + f32 camY; + f32 camZ; + f32 lookAtX; + f32 lookAtY; + f32 lookAtZ; + f32 diffX; + f32 diffZ; + f32 diffY; + f32 distance; + s32 pad; + s16 waypoint1; + s16 waypoint2; + s32 pad2[3]; s32 pathIndex; - UNUSED s32 stackPaddingC; + s32 pad3; s32 sp58; s16 sp56; s32 playerId; @@ -5939,71 +5936,76 @@ void func_80017054(Camera* camera, UNUSED Player* player, UNUSED s32 index, s32 sp58 = gWaypointCountByPathIndex[pathIndex]; D_80163238 = playerId; sp56 = gNearestWaypointByCameraId[cameraId]; - gNearestWaypointByCameraId[cameraId] = - func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex); - if (GetCourse() == GetYoshiValley()) { + gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex); + // if (GetCourse() == GetYoshiValley()) { + if (gCurrentCourseId == 4) { if ((sp56 != gNearestWaypointByCameraId[cameraId]) && (gNearestWaypointByCameraId[cameraId] == 1)) { pathIndex = (D_80163DD8[cameraId] = random_int(4U)); - gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], - gNearestWaypointByCameraId[cameraId], pathIndex); + gNearestWaypointByCameraId[cameraId] = func_8000D33C(camera->pos[0], camera->pos[1], camera->pos[2], gNearestWaypointByCameraId[cameraId], pathIndex); } } - sp6E = (gNearestWaypointByCameraId[cameraId] + 0xA) % sp58; - sp6C = (gNearestWaypointByCameraId[cameraId] + 0xB) % sp58; - func_8000BBD8(sp6E, D_80164688[cameraId], pathIndex); - sp8C = D_80162FA0[0] * 0.5; - sp84 = D_80162FA0[2] * 0.5; - func_8000BBD8(sp6C, D_80164688[cameraId], pathIndex); - sp8C += D_80162FA0[0] * 0.5; - sp84 += D_80162FA0[2] * 0.5; - sp6E = (gNearestWaypointByCameraId[cameraId] + 5) % sp58; - sp6C = (gNearestWaypointByCameraId[cameraId] + 6) % sp58; - sp88 = (D_80164550[pathIndex][sp6E].posY + D_80164550[pathIndex][sp6C].posY) * 0.5f; - sp6E = (gNearestWaypointByCameraId[cameraId] + 1) % sp58; - sp6C = (gNearestWaypointByCameraId[cameraId] + 2) % sp58; - func_8000BBD8(sp6E, D_80164688[cameraId], pathIndex); - sp98 = D_80162FA0[0] * 0.5; - sp90 = D_80162FA0[2] * 0.5; - func_8000BBD8(sp6C, D_80164688[cameraId], pathIndex); - sp98 += D_80162FA0[0] * 0.5; - sp90 += D_80162FA0[2] * 0.5; - sp94 = (D_80164550[pathIndex][sp6E].posY + D_80164550[pathIndex][sp6C].posY) * 0.5f; - stackPadding4 = sp98 - D_801645F8[cameraId]; - stackPadding5 = sp90 - D_80164618[cameraId]; - stackPadding6 = sp94 - D_80164638[cameraId]; - spAC = sqrtf(((sp98 * sp98) + (sp94 * sp94)) + (sp90 * sp90)); - if (spAC != 0.0) { - sp98 = D_801645F8[cameraId] + ((D_80164648[cameraId] * stackPadding4) / spAC); - sp94 = D_80164618[cameraId] + ((D_80164648[cameraId] * stackPadding5) / spAC); - sp90 = D_80164638[cameraId] + ((D_80164648[cameraId] * stackPadding6) / spAC); + + // LookAt XZ 0xA points ahead + waypoint1 = (gNearestWaypointByCameraId[cameraId] + 0xA) % sp58; + waypoint2 = (gNearestWaypointByCameraId[cameraId] + 0xB) % sp58; + func_8000BBD8(waypoint1, D_80164688[cameraId], pathIndex); + lookAtX = D_80162FA0[0] * 0.5; + lookAtZ = D_80162FA0[2] * 0.5; + func_8000BBD8(waypoint2, D_80164688[cameraId], pathIndex); + lookAtX += D_80162FA0[0] * 0.5; + lookAtZ += D_80162FA0[2] * 0.5; + + // LookAt Y 5 points ahead + waypoint1 = (gNearestWaypointByCameraId[cameraId] + 5) % sp58; + waypoint2 = (gNearestWaypointByCameraId[cameraId] + 6) % sp58; + lookAtY = (D_80164550[pathIndex][waypoint1].posY + D_80164550[pathIndex][waypoint2].posY) * 0.5f; + waypoint1 = (gNearestWaypointByCameraId[cameraId] + 1) % sp58; + waypoint2 = (gNearestWaypointByCameraId[cameraId] + 2) % sp58; + func_8000BBD8(waypoint1, D_80164688[cameraId], pathIndex); + camX = D_80162FA0[0] * 0.5; + camZ = D_80162FA0[2] * 0.5; + func_8000BBD8(waypoint2, D_80164688[cameraId], pathIndex); + camX += D_80162FA0[0] * 0.5; + camZ += D_80162FA0[2] * 0.5; + camY = (D_80164550[pathIndex][waypoint1].posY + D_80164550[pathIndex][waypoint2].posY) * 0.5f; + + diffX = camX - D_801645F8[cameraId]; + diffY = camY - D_80164618[cameraId]; + diffZ = camZ - D_80164638[cameraId]; + // magnitude + #define SQ(x) (x * x) + distance = sqrtf(SQ(diffX) + SQ(diffY) + SQ(diffZ) ); + if (distance != 0.0) { + diffX = D_801645F8[cameraId] + ((D_80164648[cameraId] * diffX) / distance); + diffY = D_80164618[cameraId] + ((D_80164648[cameraId] * diffY) / distance); + diffZ = D_80164638[cameraId] + ((D_80164648[cameraId] * diffZ) / distance); } else { - sp98 = D_801645F8[cameraId]; - sp94 = D_80164618[cameraId]; - sp90 = D_80164638[cameraId]; + diffX = D_801645F8[cameraId]; + diffY = D_80164618[cameraId]; + diffZ = D_80164638[cameraId]; } - if ((!(sp98 < (-10000.0))) && (sp98 > 10000.0)) { - if (sp98 && sp98) {} + + if (((diffX > (-10000.0))) && ((diffX < 10000.0))) { + camera->pos[0] = diffX; + camera->pos[2] = diffZ; } - camera->pos[0] = sp98; - camera->pos[1] = sp94 + 10.0; - camera->pos[2] = sp90; - if (1) {} - if (1) {} - if (1) {} - if (1) {} - if (1) {} - D_801645F8[cameraId] = sp98; - D_80164638[cameraId] = sp90; - D_80164618[cameraId] = sp94; - camera->lookAt[0] = sp8C; - camera->lookAt[1] = sp88 + 8.0; - camera->lookAt[2] = sp84; + + //camera->pos[0] = camX; + camera->pos[1] = diffY + 10.0; // Set camera 10 points above the ground + + if (1) { } if (1) { } if (1) { } if (1) { } if (1) { } + D_801645F8[cameraId] = diffX; + D_80164638[cameraId] = diffZ; + D_80164618[cameraId] = camY; + camera->lookAt[0] = lookAtX; + camera->lookAt[1] = lookAtY + 8.0; + camera->lookAt[2] = lookAtZ; func_80014D30(cameraId, pathIndex); - spAC = camera->lookAt[0] - camera->pos[0]; - spA8 = camera->lookAt[1] - camera->pos[1]; - spA4 = camera->lookAt[2] - camera->pos[2]; - camera->rot[1] = atan2s(spAC, spA4); - camera->rot[0] = atan2s(sqrtf((spAC * spAC) + (spA4 * spA4)), spA8); + diffX2 = camera->lookAt[0] - camera->pos[0]; + diffY2 = camera->lookAt[1] - camera->pos[1]; + diffZ2 = camera->lookAt[2] - camera->pos[2]; + camera->rot[1] = atan2s(diffX2, diffZ2); + camera->rot[0] = atan2s(sqrtf((diffX2 * diffX2) + (diffZ2 * diffZ2)), diffY2); camera->rot[2] = 0; } #else diff --git a/src/code_8006E9C0.c b/src/code_8006E9C0.c index d7bfd374b..dba0d21a7 100644 --- a/src/code_8006E9C0.c +++ b/src/code_8006E9C0.c @@ -175,11 +175,14 @@ void func_8006EF60(void) { s32 i; // `huh`'s and `i`'s types have to differ, for some reason s16 huh; - u8* wut; + u8* wut = 0; + + // Commented the below code out because it is sketchy. + // Just-in-case it results in ub or similar. // clang-format off // God forgive me for my sins... - huh = 0x14; if (0) {} for (i = 0; i < huh; i++) { D_8018D248[i] = CourseManager_GetProps()->MinimapTexture; wut += ResourceGetTexSizeByName(CourseManager_GetProps()->MinimapTexture); } + // huh = 0x14; if (0) {} for (i = 0; i < huh; i++) {D_8018D248[i] = CourseManager_GetProps()->MinimapTexture; wut += ResourceGetTexSizeByName(CourseManager_GetProps()->MinimapTexture); } // clang-format on } diff --git a/src/data/some_data.c b/src/data/some_data.c index cb8d1f3d3..6e7e4a100 100644 --- a/src/data/some_data.c +++ b/src/data/some_data.c @@ -403,6 +403,101 @@ SplineData D_800E5C90 = { }, }; +/** The below boo6-10 are generated to allow up to 10 boos **/ + +SplineData boo6 = { + 0x0016, + { + { { 0x0007, 0x0013, 0x0035 }, 0x0029 }, { { 0x0008, 0x000f, 0x0017 }, 0x0029 }, + { { 0x0001, 0x0013, 0x0002 }, 0x0029 }, { { 0x0016, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0xffe0 }, 0x0029 }, { { 0xfff1, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0xffe0 }, 0x0029 }, { { 0x0016, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0x0020 }, 0x0029 }, { { 0xfff1, 0x000b, 0x0035 }, 0x0029 }, + { { 0x0001, 0x0013, 0x0020 }, 0x0029 }, { { 0x0016, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0xffe0 }, 0x0029 }, { { 0xfff1, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0xffe0 }, 0x0029 }, { { 0x0016, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0xffe0 }, 0x0029 }, { { 0xfff1, 0x000b, 0x0002 }, 0x0029 }, + { { 0x0001, 0x0013, 0x0016 }, 0x0029 }, { { 0x0007, 0x000b, 0x001f }, 0x0029 }, + { { 0x0007, 0x0013, 0x0030 }, 0x0029 }, { { 0x0007, 0x0013, 0x0035 }, 0x0029 }, + { { 0x0007, 0x0013, 0x0035 }, 0x0029 }, + }, +}; + +SplineData boo7 = { + 0x0017, + { + { { 0x0003, 0x0012, 0xffd0 }, 0x0026 }, { { 0x0017, 0x000e, 0xffd5 }, 0x0026 }, + { { 0x0003, 0x0012, 0xffe5 }, 0x0026 }, { { 0xfff0, 0x000c, 0x0002 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0025 }, 0x0026 }, { { 0x0017, 0x000c, 0x0035 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0039 }, 0x0026 }, { { 0xfff0, 0x000c, 0x0039 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0025 }, 0x0026 }, { { 0xfff0, 0x000c, 0x0020 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0003 }, 0x0026 }, { { 0xfffa, 0x000c, 0x0020 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0030 }, 0x0026 }, { { 0x000e, 0x000b, 0x0039 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0045 }, 0x0026 }, { { 0xfffa, 0x0016, 0x0039 }, 0x0026 }, + { { 0x0003, 0x0010, 0x0030 }, 0x0026 }, { { 0x000e, 0x000d, 0x0025 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0005 }, 0x0026 }, { { 0xfffa, 0x000d, 0x0025 }, 0x0026 }, + { { 0x0003, 0x0012, 0x0030 }, 0x0026 }, { { 0x000e, 0x000d, 0x0039 }, 0x0026 }, + { { 0x0003, 0x000d, 0x0045 }, 0x0026 }, { { 0x0003, 0x0012, 0xffd0 }, 0x0026 }, + }, +}; + +SplineData boo8 = { + 0x0018, + { + { { 0xfff3, 0x000b, 0x0001 }, 0x0015 }, { { 0xfff7, 0x000b, 0xfff7 }, 0x0015 }, + { { 0x0001, 0x000b, 0xfff2 }, 0x0015 }, { { 0x000b, 0x000b, 0xfff7 }, 0x0015 }, + { { 0x000e, 0x000b, 0x0001 }, 0x0015 }, { { 0x000b, 0x000b, 0x000b }, 0x0015 }, + { { 0x0001, 0x000b, 0x000e }, 0x0015 }, { { 0xfff7, 0x000b, 0x000b }, 0x0015 }, + { { 0xfff3, 0x000b, 0x0001 }, 0x0015 }, { { 0xfff7, 0x000b, 0xfff7 }, 0x0015 }, + { { 0x0001, 0x000b, 0xfff2 }, 0x0015 }, { { 0x000b, 0x000b, 0xfff7 }, 0x0015 }, + { { 0x000e, 0x000b, 0x0001 }, 0x0015 }, { { 0x000b, 0x000b, 0x000b }, 0x0015 }, + { { 0x0001, 0x000b, 0x000e }, 0x0015 }, { { 0xfff7, 0x000b, 0x000b }, 0x0015 }, + { { 0xfff3, 0x000b, 0x0001 }, 0x0015 }, { { 0xfff7, 0x000b, 0xfff7 }, 0x0015 }, + { { 0x0001, 0x000b, 0xfff2 }, 0x0015 }, { { 0x000b, 0x000b, 0xfff7 }, 0x0015 }, + { { 0x000e, 0x000b, 0x0001 }, 0x0015 }, { { 0x000b, 0x000b, 0x000b }, 0x0015 }, + { { 0x0001, 0x000b, 0x000e }, 0x0015 }, { { 0xfff7, 0x000b, 0x000b }, 0x0015 }, + { { 0xfff3, 0x000b, 0x0001 }, 0x0015 }, + }, +}; + +SplineData boo9 = { + 0x0016, + { + { { 0x0007, 0x0013, 0x0033 }, 0x001f }, { { 0x0007, 0x0010, 0x0016 }, 0x001f }, + { { 0x0001, 0x0013, 0x0005 }, 0x001f }, { { 0x0016, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0xffe1 }, 0x001f }, { { 0xfff2, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0xffe1 }, 0x001f }, { { 0x0016, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0x0021 }, 0x001f }, { { 0xfff2, 0x000b, 0x0033 }, 0x001f }, + { { 0x0001, 0x0013, 0x0021 }, 0x001f }, { { 0x0016, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0xffe1 }, 0x001f }, { { 0xfff2, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0xffe1 }, 0x001f }, { { 0x0016, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0xffe1 }, 0x001f }, { { 0xfff2, 0x000b, 0x0005 }, 0x001f }, + { { 0x0001, 0x0013, 0x0015 }, 0x001f }, { { 0x0007, 0x000b, 0x001f }, 0x001f }, + { { 0x0007, 0x0013, 0x002f }, 0x001f }, { { 0x0007, 0x0013, 0x0033 }, 0x001f }, + { { 0x0007, 0x0013, 0x0033 }, 0x001f }, + }, +}; + +SplineData boo10 = { + 0x0017, + { + { { 0x0001, 0x0012, 0xffd5 }, 0x001a }, { { 0x0018, 0x000e, 0xffd7 }, 0x001a }, + { { 0x0001, 0x0012, 0xffe7 }, 0x001a }, { { 0xfff2, 0x000c, 0x0004 }, 0x001a }, + { { 0x0001, 0x0012, 0x0026 }, 0x001a }, { { 0x0018, 0x000c, 0x0036 }, 0x001a }, + { { 0x0001, 0x0012, 0x003a }, 0x001a }, { { 0xfff2, 0x000c, 0x003a }, 0x001a }, + { { 0x0001, 0x0012, 0x0026 }, 0x001a }, { { 0xfff2, 0x000c, 0x0021 }, 0x001a }, + { { 0x0001, 0x0012, 0x0004 }, 0x001a }, { { 0xfffb, 0x000c, 0x0021 }, 0x001a }, + { { 0x0001, 0x0012, 0x0031 }, 0x001a }, { { 0x000f, 0x000b, 0x003a }, 0x001a }, + { { 0x0001, 0x0012, 0x0046 }, 0x001a }, { { 0xfffb, 0x0017, 0x003a }, 0x001a }, + { { 0x0001, 0x0010, 0x0031 }, 0x001a }, { { 0x000f, 0x000e, 0x0026 }, 0x001a }, + { { 0x0001, 0x0012, 0x0006 }, 0x001a }, { { 0xfffb, 0x000e, 0x0026 }, 0x001a }, + { { 0x0001, 0x0012, 0x0031 }, 0x001a }, { { 0x000f, 0x000e, 0x003a }, 0x001a }, + { { 0x0001, 0x000e, 0x0046 }, 0x001a }, { { 0x0001, 0x0012, 0xffd5 }, 0x001a }, + }, +}; + +/** The above boo6-10 are generated to allow up to 10 boos **/ + // Only referenced in func_8007D070, which itself is unused SplineData D_800E5D54 = { 0x0004, @@ -427,7 +522,7 @@ SplineData D_800E5D78 = { // Note the use of the plain SplineData type here. Since these are pointers, we don't care // about their internal array size -SplineData* D_800E5D9C[] = { &D_800E5988, &D_800E5A44, &D_800E5B08, &D_800E5BD4, &D_800E5C90 }; +SplineData* D_800E5D9C[] = { &D_800E5988, &D_800E5A44, &D_800E5B08, &D_800E5BD4, &D_800E5C90, &boo6, &boo7, &boo8, &boo9, &boo10 }; // Unused SplineData* D_800E5DB0 = &D_800E5988; diff --git a/src/engine/courses/BansheeBoardwalk.cpp b/src/engine/courses/BansheeBoardwalk.cpp index 83bc1e151..03b4a9bd2 100644 --- a/src/engine/courses/BansheeBoardwalk.cpp +++ b/src/engine/courses/BansheeBoardwalk.cpp @@ -10,6 +10,7 @@ #include "engine/objects/CheepCheep.h" #include "engine/objects/TrashBin.h" #include "engine/objects/Bat.h" +#include "engine/objects/Boos.h" #include "assets/banshee_boardwalk_data.h" #include "assets/boo_frames.h" @@ -171,6 +172,8 @@ void BansheeBoardwalk::SpawnActors() { if ((gGamestate != CREDITS_SEQUENCE) && (gModeSelection != TIME_TRIALS)) { gWorldInstance.AddObject(new OBat(FVector(0,0,0), FRotation(0, 0, 90.0f))); + gWorldInstance.AddObject(new OBoos(5, IPathSpan(180, 190), IPathSpan(200, 210), IPathSpan(280, 290))); + gWorldInstance.AddObject(new OBoos(5, IPathSpan(490, 500), IPathSpan(510, 520), IPathSpan(620, 630))); } } @@ -210,14 +213,14 @@ void BansheeBoardwalk::UpdateCourseObjects() { if (gModeSelection != TIME_TRIALS) { //update_bat(); } - wrapper_update_boos(); + //wrapper_update_boos(); } } void BansheeBoardwalk::RenderCourseObjects(s32 cameraId) { if (gGamestate != CREDITS_SEQUENCE) { //render_object_bat(cameraId); - render_object_boos(cameraId); + //render_object_boos(cameraId); } } diff --git a/src/engine/courses/TestCourse.cpp b/src/engine/courses/TestCourse.cpp index 7e25d3357..cf35a062b 100644 --- a/src/engine/courses/TestCourse.cpp +++ b/src/engine/courses/TestCourse.cpp @@ -24,6 +24,7 @@ #include "engine/objects/Flagpole.h" #include "engine/objects/HotAirBalloon.h" #include "engine/objects/Crab.h" +#include "engine/objects/Boos.h" #include "engine/particles/StarEmitter.h" extern "C" { @@ -216,7 +217,10 @@ void TestCourse::SpawnActors() { // gWorldInstance.AddObject(new OHotAirBalloon(FVector(0.0, 20.0f, -200.0f))); //gWorldInstance.AddObject(new OCrab(FVector2D(0, 0), FVector2D(0, -200))); - gWorldInstance.AddActor(new ABowserStatue(FVector(-200, 0, 0), ABowserStatue::Behaviour::CRUSH)); +// gWorldInstance.AddActor(new ABowserStatue(FVector(-200, 0, 0), ABowserStatue::Behaviour::CRUSH)); + +// gWorldInstance.AddObject(new OBoos(10, IPathSpan(0, 5), IPathSpan(18, 23), IPathSpan(25, 50))); + } // Likely sets minimap boundaries diff --git a/src/engine/objects/Boos.cpp b/src/engine/objects/Boos.cpp new file mode 100644 index 000000000..0e64c673e --- /dev/null +++ b/src/engine/objects/Boos.cpp @@ -0,0 +1,272 @@ +#include "Boos.h" +#include "World.h" +#include "CoreMath.h" + +extern "C" { +#include "render_objects.h" +#include "update_objects.h" +#include "assets/banshee_boardwalk_data.h" +#include "assets/common_data.h" +#include "assets/boo_frames.h" +#include "assets/other_textures.h" +#include "math_util.h" +#include "math_util_2.h" +#include "code_80086E70.h" +#include "code_80057C60.h" +#include "code_800029B0.h" +#include "code_80005FD0.h" +#include "menus.h" +#include "race_logic.h" +#include "external.h" +} + +size_t OBoos::_count = 0; + +OBoos::OBoos(size_t numBoos, const IPathSpan& leftBoundary, const IPathSpan& active, const IPathSpan& rightBoundary) { + // Max five boos allowed due to limited splines + // D_800E5D9C + if (numBoos > 10) { + printf("Boos.cpp: Only 10 boos allowed.\n"); + numBoos = 10; + } + + _indices.resize(numBoos, 0); + + + // Generate objects + for (size_t i = 0; i < numBoos; i++) { + find_unused_obj_index(&_indices[i]); + } + + _numBoos = numBoos; + _leftBoundary = leftBoundary; + _active = active; + _rightBoundary = rightBoundary; +} + +void OBoos::Tick() { + u16 temp_t4; + s32 objectIndex; + Player* player; + Camera* camera; + Object* object; + + OBoos::func_8007CA70(); + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; //indexObjectList3[i]; + object = &gObjectList[objectIndex]; + if (object->state != 0) { + func_8007C684(objectIndex); + func_8008B78C(objectIndex); + player = &gPlayerOne[object->unk_0D1]; + camera = &camera1[object->unk_0D1]; + temp_t4 = (0x8000 - camera->rot[1]); + object->pos[0] = player->pos[0] + (coss(temp_t4) * (object->origin_pos[0] + object->offset[0])) - + (sins(temp_t4) * (object->origin_pos[2] + object->offset[2])); + object->pos[1] = 6.5 + player->unk_074 + object->origin_pos[1] + object->offset[1]; + object->pos[2] = player->pos[2] + (sins(temp_t4) * (object->origin_pos[0] + object->offset[0])) + + (coss(temp_t4) * (object->origin_pos[2] + object->offset[2])); + OBoos::func_8007C550(objectIndex); + if (is_obj_flag_status_active(objectIndex, 0x00000080) != 0) { + object->vertex = D_800E44B0; + } else { + object->vertex = D_800E4470; + } + } + } +} + +void OBoos::Draw(s32 cameraId) { + u32 temp_s2; + s32 objectIndex; + + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; //indexObjectList3[i]; + if (gObjectList[objectIndex].state >= 2) { + temp_s2 = func_8008A364(objectIndex, cameraId, 0x4000U, 0x00000320); + if (CVarGetInteger("gNoCulling", 0) == 1) { + temp_s2 = MIN(temp_s2, 0x15F91U); + } + if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { + func_800523B8(objectIndex, cameraId, temp_s2); + } + } + } +} + +void OBoos::func_800523B8(s32 objectIndex, s32 arg1, u32 arg2) { + UNUSED s32 pad[2]; + Object* object; + Camera* camera = &camera1[arg1]; + + object = &gObjectList[objectIndex]; + object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); + func_800484BC(object->pos, object->orientation, object->sizeScaling, object->primAlpha, (u8*) object->activeTLUT, + (u8*)object->activeTexture, object->vertex, 0x00000030, 0x00000028, 0x00000030, 0x00000028); + if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) && (arg2 < 0x15F91U)) { + func_8004A630(&D_8018C830, object->pos, 0.4f); + } +} + +void OBoos::func_8007CA70(void) { + // wtf is up with this pointer? Its such a dumb way of going about things + u16* point; + + if (_isActive == false) { + _playerId = OBoos::func_8007C9F8(); + point = &gNearestWaypointByPlayerId[_playerId]; + printf("point %d\n", *point); + if ((*point > _active.Start) && (*point < _active.End)) { + // First group entrance + OBoos::BooStart(0, _playerId); + } + } + if (_isActive == true) { + point = &gNearestWaypointByPlayerId[_playerId]; + printf("point %d\n", *point); + + if ((*point > _leftBoundary.Start) && (*point < _leftBoundary.End)) { + // First group exit reverse direction + OBoos::BooExit(0); + } + if ((*point > _rightBoundary.Start) && (*point < _rightBoundary.End)) { + // First group exit + OBoos::BooExit(0); + } + } +} + +void OBoos::func_8007C5B4(s32 objectIndex) { + Object* object; + + init_texture_object(objectIndex, (u8*)d_course_banshee_boardwalk_boo_tlut, gTextureGhosts, 48, 40); + object = &gObjectList[objectIndex]; + object->pos[0] = 0.0f; + object->pos[1] = 0.0f; + object->pos[2] = 0.0f; + set_object_flag(objectIndex, 0x00000020); + object_next_state(objectIndex); + object->primAlpha = 0; + func_80073844(objectIndex); + object->sizeScaling = 0.15f; + object->unk_034 = 1.0f; + func_80073FD4(objectIndex); + func_80086EF0(objectIndex); + set_object_flag(objectIndex, 0x00000800); + object->orientation[0] = 0; + object->orientation[2] = 0x8000; +} + +void OBoos::func_8007C684(s32 objectIndex) { + switch (gObjectList[objectIndex].state) { + case 0: + break; + case 1: + OBoos::func_8007C5B4(objectIndex); + break; + } + if (gObjectList[objectIndex].state >= 2) { + switch (gObjectList[objectIndex].unk_0DC) { + case 0: + break; + case 1: + func_80073998(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 0x00000050, 2, 1, 0); + break; + case 2: + func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x00000050, 0x00000078, 1, 0, -1); + break; + case 3: + func_80073DC0(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 2); + break; + case 4: + func_80072428(objectIndex); + func_80086F60(objectIndex); + func_80073884(objectIndex); + break; + } + func_80073514(objectIndex); + } +} + +void OBoos::func_8007C4A4(s32 objectIndex) { + u16 var_t9; + + var_t9 = gObjectList[objectIndex].direction_angle[1] * 0x24 / 0x10000; + + if (var_t9 < 0x13) { + clear_object_flag(objectIndex, 0x80); + gObjectList[objectIndex].textureListIndex = var_t9; + } else { + set_object_flag(objectIndex, 0x80); + gObjectList[objectIndex].textureListIndex = 0x24 - var_t9; + } +} + +void OBoos::func_8007C550(s32 objectIndex) { + gObjectList[objectIndex].direction_angle[1] = + func_800417B4(gObjectList[objectIndex].direction_angle[1], + atan2s(gObjectList[objectIndex].velocity[0], gObjectList[objectIndex].velocity[2])); + OBoos::func_8007C4A4(objectIndex); +} + +s32 OBoos::func_8007C9F8(void) { + s32 ret; + s32 first, second; + if (gPlayerCount == 1) { + ret = 0; + } else { + if (gPlayerCount == 2) { + if (gModeSelection == 0) { + first = gGPCurrentRaceRankByPlayerId[0]; + second = gGPCurrentRaceRankByPlayerId[1]; + if (first < second) { + ret = 0; + } else { + ret = 1; + } + } else { + ret = gGPCurrentRacePlayerIdByRank[0]; + } + } else { + ret = gGPCurrentRacePlayerIdByRank[0]; + } + } + return ret; +} + +void OBoos::BooStart(s32 group, s32 playerId) { + s32 objectIndex; + s16 temp_s1_2; + s16 temp_s4; + s16 temp_s5; + SplineData* spline; +printf("Boo Start\n"); + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; // indexObjectList3[group + i]; + init_object(objectIndex, 1); + gObjectList[objectIndex].unk_0D1 = playerId; + temp_s1_2 = random_int(0x003CU) - 0x1E; + temp_s4 = random_int(0x0014U) - 0xA; + temp_s5 = random_int(0x0050U) - 0x28; + random_int(0x1000U); + spline = D_800E5D9C[i]; + gObjectList[objectIndex].spline = spline; + gObjectList[objectIndex].origin_pos[0] = (f32) temp_s1_2; + gObjectList[objectIndex].origin_pos[1] = (f32) temp_s4; + gObjectList[objectIndex].origin_pos[2] = (f32) temp_s5; + } + func_800C9060(playerId, 0x1900705AU); + + _isActive = true; +} + +void OBoos::BooExit(s32 group) { + s32 objectIndex; +printf("Boo Exit\n"); + for (size_t i = 0; i < _numBoos; i++) { + objectIndex = _indices[i]; //indexObjectList3[group + temp_a0]; + gObjectList[objectIndex].unk_0DC += 1; + } + + _isActive = false; +} diff --git a/src/engine/objects/Boos.h b/src/engine/objects/Boos.h new file mode 100644 index 000000000..cc49df474 --- /dev/null +++ b/src/engine/objects/Boos.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include "Object.h" + +#include "World.h" +#include "CoreMath.h" + +extern "C" { +#include "macros.h" +#include "main.h" +#include "vehicles.h" +#include "waypoints.h" +#include "common_structs.h" +#include "objects.h" +#include "camera.h" +#include "some_data.h" +} + +/** + * OBoos + * + * Args use path indices or path points. Recommended to use a span of 10 + * for each IPathSpan as that's how the original game did it. Ex. IPathSpan(10, 20) + * + * Once boos are active, they do not deactivate until the player drives into leftBoundary + * or rightBoundary. leftBoundary is really only used to deactivate the boos when the player is + * driving in the reverse direction. + * + * @arg numBoos to show, default 5, maximum 10 allowed due to limited splines + * @arg leftBoundary When the player enters this area, deactivate the boos. + * @arg active When the player enters this area, activate the boos. + * @arg rightBoundary When the player enters this area, deactivate the boos. + * + */ +class OBoos : public OObject { +public: + explicit OBoos(size_t numBoos, const IPathSpan& leftBoundary, const IPathSpan& active, const IPathSpan& rightBoundary); + + ~OBoos() { + _count--; + } + + static size_t GetCount() { + return _count; + } + + virtual void Tick() override; + virtual void Draw(s32 cameraId) override; + void func_800523B8(s32 objectIndex, s32 arg1, u32 arg2); + + void func_8007CA70(void); + void func_8007C5B4(s32 objectIndex); + void func_8007C684(s32 objectIndex); + void func_8007C4A4(s32 objectIndex); + s32 func_8007C9F8(void); + void BooStart(s32 someIndex, s32 arg1); + void BooExit(s32 someIndex); + void func_8007C550(s32 objectIndex); + +private: + FVector _pos; + static size_t _count; + size_t _idx; + std::vector _indices; // indices into gObjectList + size_t _numBoos; + + bool _isActive = false; + s32 _playerId = 0; + + IPathSpan _leftBoundary; + IPathSpan _active; + IPathSpan _rightBoundary; +}; diff --git a/src/main.c b/src/main.c index 0f938721a..c3484a651 100644 --- a/src/main.c +++ b/src/main.c @@ -693,10 +693,6 @@ void calculate_updaterate(void) { } } - - - - void display_debug_info(void) { u16 rotY; if (!gEnableDebugMode) { diff --git a/src/menu_items.c b/src/menu_items.c index 7fa621794..be1aa048c 100644 --- a/src/menu_items.c +++ b/src/menu_items.c @@ -785,10 +785,12 @@ MenuTexture* D_800E7DC4[] = { seg2_mario_raceway_title_texture, D_02005060, D_02005088, D_020050B0, - D_020050D8 }; - -MenuTexture* D_800E7E00[] = { - D_02005100, D_02005128, D_02005150, D_02005178, D_020051A0, + D_020050D8, + D_02005100, + D_02005128, + D_02005150, + D_02005178, + D_020051A0, }; // Unused? diff --git a/src/render_objects.c b/src/render_objects.c index 1e8d58004..ece980b9d 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -3483,39 +3483,6 @@ void func_800520C0(s32 arg0) { } } -void func_800523B8(s32 objectIndex, s32 arg1, u32 arg2) { - UNUSED s32 pad[2]; - Object* object; - Camera* camera = &camera1[arg1]; - - object = &gObjectList[objectIndex]; - object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos); - func_800484BC(object->pos, object->orientation, object->sizeScaling, object->primAlpha, (u8*) object->activeTLUT, - object->activeTexture, object->vertex, 0x00000030, 0x00000028, 0x00000030, 0x00000028); - if ((is_obj_flag_status_active(objectIndex, 0x00000020) != 0) && (arg2 < 0x15F91U)) { - func_8004A630(&D_8018C830, object->pos, 0.4f); - } -} - -void render_object_boos(s32 arg0) { - u32 temp_s2; - s32 someIndex; - s32 objectIndex; - - for (someIndex = 0; someIndex < NUM_BOOS; someIndex++) { - objectIndex = indexObjectList3[someIndex]; - if (gObjectList[objectIndex].state >= 2) { - temp_s2 = func_8008A364(objectIndex, arg0, 0x4000U, 0x00000320); - if (CVarGetInteger("gNoCulling", 0) == 1) { - temp_s2 = MIN(temp_s2, 0x15F91U); - } - if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) { - func_800523B8(objectIndex, arg0, temp_s2); - } - } - } -} - void func_8005285C(s32 arg0) { Player* temp_v0; diff --git a/src/render_objects.h b/src/render_objects.h index a4de1b5e7..bc11ee626 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -329,10 +329,6 @@ void func_80051F9C(void); void func_80052044(void); void func_80052080(void); void func_800520C0(s32); -void func_800523B8(s32, s32, u32); -void render_object_boos(s32); -void render_object_bat(s32); -void render_object_trash_bin(s32); void func_8005285C(s32); void func_800528EC(s32); void render_ice_block(s32); diff --git a/src/update_objects.c b/src/update_objects.c index 803e6b00a..94fb89ce4 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -3565,30 +3565,8 @@ void func_8007BB9C(s32 arg0) { func_8007B34C(arg0); } - - - - - - - - - - - - - - - - - - - - - - void wrapper_update_boos(void) { - update_boos(); + //update_boos(); } // Updates the display status on an object based on its relative direction to the camera @@ -3616,229 +3594,6 @@ void func_8007C420(s32 objectIndex, Player* player, Camera* camera) { func_8007C360(objectIndex, camera); } -UNUSED void func_8007C49C(void) { -} - -void func_8007C4A4(s32 objectIndex) { - u16 var_t9; - - var_t9 = gObjectList[objectIndex].direction_angle[1] * 0x24 / 0x10000; - - if (var_t9 < 0x13) { - clear_object_flag(objectIndex, 0x80); - gObjectList[objectIndex].textureListIndex = var_t9; - } else { - set_object_flag(objectIndex, 0x80); - gObjectList[objectIndex].textureListIndex = 0x24 - var_t9; - } -} - -void func_8007C550(s32 objectIndex) { - gObjectList[objectIndex].direction_angle[1] = - func_800417B4(gObjectList[objectIndex].direction_angle[1], - atan2s(gObjectList[objectIndex].velocity[0], gObjectList[objectIndex].velocity[2])); - func_8007C4A4(objectIndex); -} - -void func_8007C5B4(s32 objectIndex) { - Object* object; - - init_texture_object(objectIndex, d_course_banshee_boardwalk_boo_tlut, gTextureGhosts, 48, 40); - object = &gObjectList[objectIndex]; - object->pos[0] = 0.0f; - object->pos[1] = 0.0f; - object->pos[2] = 0.0f; - set_object_flag(objectIndex, 0x00000020); - object_next_state(objectIndex); - object->primAlpha = 0; - func_80073844(objectIndex); - object->sizeScaling = 0.15f; - object->unk_034 = 1.0f; - func_80073FD4(objectIndex); - func_80086EF0(objectIndex); - set_object_flag(objectIndex, 0x00000800); - object->orientation[0] = 0; - object->orientation[2] = 0x8000; -} - -void func_8007C684(s32 objectIndex) { - switch (gObjectList[objectIndex].state) { - case 0: - break; - case 1: - func_8007C5B4(objectIndex); - break; - } - if (gObjectList[objectIndex].state >= 2) { - switch (gObjectList[objectIndex].unk_0DC) { - case 0: - break; - case 1: - func_80073998(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 0x00000050, 2, 1, 0); - break; - case 2: - func_80073CB0(objectIndex, &gObjectList[objectIndex].primAlpha, 0x00000050, 0x00000078, 1, 0, -1); - break; - case 3: - func_80073DC0(objectIndex, &gObjectList[objectIndex].primAlpha, 0, 2); - break; - case 4: - func_80072428(objectIndex); - func_80086F60(objectIndex); - func_80073884(objectIndex); - break; - } - func_80073514(objectIndex); - } -} - -void func_8007C7B4(s32 someIndex, s32 arg1) { - s32 temp_a0; - s32 objectIndex; - s16 temp_s1_2; - s16 temp_s4; - s16 temp_s5; - SplineData* something; - - for (temp_a0 = 0; temp_a0 < 5; temp_a0++) { - objectIndex = indexObjectList3[someIndex + temp_a0]; - init_object(objectIndex, 1); - gObjectList[objectIndex].unk_0D1 = arg1; - temp_s1_2 = random_int(0x003CU) - 0x1E; - temp_s4 = random_int(0x0014U) - 0xA; - temp_s5 = random_int(0x0050U) - 0x28; - random_int(0x1000U); - something = D_800E5D9C[temp_a0]; - gObjectList[objectIndex].spline = something; - gObjectList[objectIndex].origin_pos[0] = (f32) temp_s1_2; - gObjectList[objectIndex].origin_pos[1] = (f32) temp_s4; - gObjectList[objectIndex].origin_pos[2] = (f32) temp_s5; - } - func_800C9060(arg1, 0x1900705AU); - - if (someIndex == 0) { - D_8018CFF0 = 1; - } else { - D_8018D048 = 1; - } -} - -void func_8007C91C(s32 someIndex) { - s32 temp_a0; - s32 objectIndex; - - for (temp_a0 = 0; temp_a0 < 5; temp_a0++) { - objectIndex = indexObjectList3[someIndex + temp_a0]; - gObjectList[objectIndex].unk_0DC += 1; - } - - if (someIndex == 0) { - D_8018CFF0 = 0; - } else { - D_8018D048 = 0; - } -} - -s32 func_8007C9F8(void) { - s32 ret; - s32 first, second; - if (gPlayerCount == 1) { - ret = 0; - } else { - if (gPlayerCount == 2) { - if (gModeSelection == 0) { - first = gGPCurrentRaceRankByPlayerId[0]; - second = gGPCurrentRaceRankByPlayerId[1]; - if (first < second) { - ret = 0; - } else { - ret = 1; - } - } else { - ret = gGPCurrentRacePlayerIdByRank[0]; - } - } else { - ret = gGPCurrentRacePlayerIdByRank[0]; - } - } - return ret; -} - -void func_8007CA70(void) { - s32 playerId; - // wtf is up with this pointer? Its such a dumb way of going about things - u16* test; - - if (D_8018CFF0 == 0) { - playerId = func_8007C9F8(); - D_8018D018 = playerId; - test = &gNearestWaypointByPlayerId[playerId]; - if ((*test >= 0xC9) && (*test < 0xD2)) { - func_8007C7B4(0, (s32) playerId); - } - } - if (D_8018CFF0 != 0) { - playerId = D_8018D018; - test = &gNearestWaypointByPlayerId[playerId]; - if ((*test >= 0xB5) && (*test < 0xBE)) { - func_8007C91C(0); - } - if ((*test >= 0x119) && (*test < 0x122)) { - func_8007C91C(0); - } - } - if (D_8018D048 == 0) { - playerId = func_8007C9F8(); - D_8018D110 = playerId; - test = &gNearestWaypointByPlayerId[playerId]; - if ((*test >= 0x1FF) && (*test < 0x208)) { - func_8007C7B4(5, (s32) playerId); - } - } - if (D_8018D048 != 0) { - playerId = D_8018D110; - test = &gNearestWaypointByPlayerId[playerId]; - if ((*test >= 0x1EB) && (*test < 0x1F4)) { - func_8007C91C(5); - } - if ((*test >= 0x26D) && (*test < 0x276)) { - func_8007C91C(5); - } - } -} - -void update_boos(void) { - u16 temp_t4; - s32 someIndex; - s32 objectIndex; - Player* player; - Camera* camera; - Object* object; - - func_8007CA70(); - for (someIndex = 0; someIndex < NUM_BOOS; someIndex++) { - objectIndex = indexObjectList3[someIndex]; - object = &gObjectList[objectIndex]; - if (object->state != 0) { - func_8007C684(objectIndex); - func_8008B78C(objectIndex); - player = &gPlayerOne[object->unk_0D1]; - camera = &camera1[object->unk_0D1]; - temp_t4 = (0x8000 - camera->rot[1]); - object->pos[0] = player->pos[0] + (coss(temp_t4) * (object->origin_pos[0] + object->offset[0])) - - (sins(temp_t4) * (object->origin_pos[2] + object->offset[2])); - object->pos[1] = 6.5 + player->unk_074 + object->origin_pos[1] + object->offset[1]; - object->pos[2] = player->pos[2] + (sins(temp_t4) * (object->origin_pos[0] + object->offset[0])) + - (coss(temp_t4) * (object->origin_pos[2] + object->offset[2])); - func_8007C550(objectIndex); - if (is_obj_flag_status_active(objectIndex, 0x00000080) != 0) { - object->vertex = D_800E44B0; - } else { - object->vertex = D_800E4470; - } - } - } -} void func_8007CE0C(s32 objectIndex) { Object* object; diff --git a/src/update_objects.h b/src/update_objects.h index 9e3cd61b7..6f7b840c2 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -221,9 +221,6 @@ void func_8007C4A4(s32); void func_8007C550(s32); void func_8007C5B4(s32); void func_8007C684(s32); -void func_8007C49C(void); -void func_8007C7B4(s32, s32); -void func_8007C91C(s32); s32 func_8007C9F8(void); void func_8007CA70(void); void update_boos(void);