From cae7cc7f6f5c66bca929427efaaf1f7847ca8105 Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Sun, 24 Nov 2024 11:29:46 -0700 Subject: [PATCH] Finish implementing Thwomp --- src/engine/World.cpp | 3 +- src/engine/World.h | 2 +- src/engine/courses/BowsersCastle.cpp | 63 ++++++++++++++-------------- src/engine/vehicles/OThwomp.cpp | 47 +++++++++++---------- src/engine/vehicles/OThwomp.h | 2 +- src/port/Game.cpp | 7 ++++ src/render_objects.c | 13 +++--- src/render_objects.h | 6 ++- 8 files changed, 76 insertions(+), 67 deletions(-) diff --git a/src/engine/World.cpp b/src/engine/World.cpp index ed122af56..800cafb58 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -97,9 +97,10 @@ void World::AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointInd BombKarts.push_back(std::make_unique(pos, waypoint, waypointIndex, state, unk_3C)); } -void World::AddThwomp(f32 x, f32 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha) { +void World::AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha) { Thwomps.push_back(std::make_unique(thwomps, x, z, direction, scale, behaviour, primAlpha)); thwomps++; + gNumActiveThwomps = thwomps; } u32 World::GetCupIndex() { diff --git a/src/engine/World.h b/src/engine/World.h index d396d4854..1bb78923e 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -143,7 +143,7 @@ public: void AddBombKart(Vec3f pos, TrackWaypoint* waypoint, uint16_t waypointIndex, uint16_t state, f32 unk_3C); std::vector> Thwomps; - void AddThwomp(f32 x, f32 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha); + void AddThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha); TrainCrossing* AddCrossing(Vec3f position, u32 waypointMin, u32 waypointMax, f32 approachRadius, f32 exitRadius); std::vector> Crossings; diff --git a/src/engine/courses/BowsersCastle.cpp b/src/engine/courses/BowsersCastle.cpp index 483442c2d..a12b233a8 100644 --- a/src/engine/courses/BowsersCastle.cpp +++ b/src/engine/courses/BowsersCastle.cpp @@ -152,41 +152,41 @@ void BowsersCastle::InitCourseObjects() { switch (gCCSelection) { case CC_100: case CC_EXTRA: - gWorldInstance.AddThwomp(0x0320, 0xf92a, 0x8000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x044c, 0xf92a, 0x8000, 1.0f, 1, 1); - gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0x8000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0x8000, 1.0f, 2, 1); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0x8000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0x8000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5bf, 0x8000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x091a, 0xf597, 0x8000, 1.0f, 4, 1); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0x8000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x8000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x8000, 1.0f, 5, 1); + gWorldInstance.AddThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0); + gWorldInstance.AddThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1); + gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0); + gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1); + gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); + gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); + gWorldInstance.AddThwomp(0x091a, 0xf5bf, 0xC000, 1.0f, 4, 0); + gWorldInstance.AddThwomp(0x091a, 0xf597, 0xC000, 1.0f, 4, 1); + gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); + gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); + gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); break; case CC_50: - gWorldInstance.AddThwomp(0x3B6, 0xF92A, 0x8000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x0352, 0xf95c, 0x8000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0x8000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0x8000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5b0, 0x8000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0x8000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x8000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x8000, 1.0f, 5, 1); + gWorldInstance.AddThwomp(0x3B6, 0xF92A, 0xC000, 1.0f, 1, 0); + gWorldInstance.AddThwomp(0x0352, 0xf95c, 0xC000, 1.0f, 2, 0); + gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); + gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); + gWorldInstance.AddThwomp(0x091a, 0xf5b0, 0xC000, 1.0f, 4, 0); + gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); + gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); + gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); break; case CC_150: - gWorldInstance.AddThwomp(0x0320, 0xf92a, 0x8000, 1.0f, 1, 0); - gWorldInstance.AddThwomp(0x044c, 0xf92a, 0x8000, 1.0f, 1, 1); - gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0x8000, 1.0f, 2, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0x8000, 1.0f, 2, 1); - gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0x8000, 1.0f, 3, 0); - gWorldInstance.AddThwomp(0x04b0, 0xf592, 0x8000, 1.0f, 3, 1); - gWorldInstance.AddThwomp(0x091a, 0xf5c9, 0x8000, 1.0f, 4, 0); - gWorldInstance.AddThwomp(0x091a, 0xf5ab, 0x8000, 1.0f, 4, 1); - gWorldInstance.AddThwomp(0x091a, 0xf58d, 0x8000, 1.0f, 4, 2); - gWorldInstance.AddThwomp(0x0596, 0xf92f, 0x8000, 1.5f, 6, 0); - gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x8000, 1.0f, 5, 0); - gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x8000, 1.0f, 5, 1); + gWorldInstance.AddThwomp(0x0320, 0xf92a, 0xC000, 1.0f, 1, 0); + gWorldInstance.AddThwomp(0x044c, 0xf92a, 0xC000, 1.0f, 1, 1); + gWorldInstance.AddThwomp(0x02bc, 0xf95c, 0xC000, 1.0f, 2, 0); + gWorldInstance.AddThwomp(0x04b0, 0xf8f8, 0xC000, 1.0f, 2, 1); + gWorldInstance.AddThwomp(0x04b0, 0xf5ba, 0xC000, 1.0f, 3, 0); + gWorldInstance.AddThwomp(0x04b0, 0xf592, 0xC000, 1.0f, 3, 1); + gWorldInstance.AddThwomp(0x091a, 0xf5c9, 0xC000, 1.0f, 4, 0); + gWorldInstance.AddThwomp(0x091a, 0xf5ab, 0xC000, 1.0f, 4, 1); + gWorldInstance.AddThwomp(0x091a, 0xf58d, 0xC000, 1.0f, 4, 2); + gWorldInstance.AddThwomp(0x0596, 0xf92f, 0xC000, 1.5f, 6, 0); + gWorldInstance.AddThwomp(0x082a, 0xf9f2, 0x4000, 1.0f, 5, 0); + gWorldInstance.AddThwomp(0x073a, 0xf9f2, 0x4000, 1.0f, 5, 1); break; } @@ -214,7 +214,6 @@ void BowsersCastle::InitCourseObjects() { } void BowsersCastle::UpdateCourseObjects() { - func_80081208(); update_flame_particle(); } diff --git a/src/engine/vehicles/OThwomp.cpp b/src/engine/vehicles/OThwomp.cpp index 7835c150d..a0bb42ab6 100644 --- a/src/engine/vehicles/OThwomp.cpp +++ b/src/engine/vehicles/OThwomp.cpp @@ -31,7 +31,7 @@ extern "C" { extern s8 gPlayerCount; } -OThwomp::OThwomp(s32 i, f32 x, f32 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha) { +OThwomp::OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha) { if (i >= 32) { printf("MAX THWOMPS REACHED (32), skipping\n"); return; @@ -46,8 +46,8 @@ OThwomp::OThwomp(s32 i, f32 x, f32 z, s16 direction, f32 scale, s16 behaviour, s gObjectList[objectId].unk_0D5 = behaviour; gObjectList[objectId].primAlpha = primAlpha; - if (scale == 0) { - scale = 1; + if (scale == 0.0f) { + scale = 1.0f; } gObjectList[objectId].sizeScaling = scale; @@ -59,8 +59,6 @@ void OThwomp::Tick() { // func_80081210 s32 var_s2_3; s32 var_s4; - D_80165834[0] += 0x100; - D_80165834[1] += 0x200; objectIndex = indexObjectList1[_idx]; func_800722CC(objectIndex, 0x00000010); func_8008A4CC(objectIndex); @@ -193,8 +191,6 @@ s32 OThwomp::func_8007F75C(s32 playerId) { return var_s6; } -Lights1 thwompLight = gdSPDefLights1(85, 85, 85, 255, 255, 255, -66, 82, -55); - void OThwomp::Draw(s32 cameraId) { s32 objectIndex = 0; s32 i; @@ -202,7 +198,6 @@ void OThwomp::Draw(s32 cameraId) { s16 minusone, plusone; Camera* camera; Object* object; - // Lights1 *thwompLightl = (Lights1 *) LOAD_ASSET(thwompLight); camera = &camera1[cameraId]; if (cameraId == PLAYER_ONE) { @@ -211,31 +206,35 @@ void OThwomp::Draw(s32 cameraId) { func_800722CC(objectIndex, 0x00000110); } - func_800534A4(objectIndex); + translate_thwomp_lights(objectIndex); objectIndex = indexObjectList1[_idx]; minusone = gObjectList[objectIndex].unk_0DF - 1; plusone = gObjectList[objectIndex].unk_0DF + 1; //! @todo Fix this quick hack fix to allow thwomps to render in custom courses - OThwomp::DrawModel(objectIndex); - if (GetCourse() != GetBowsersCastle()) { - } else { - if (gGamestate != CREDITS_SEQUENCE) { - if ((D_8018CF68[cameraId] >= minusone) && (plusone >= D_8018CF68[cameraId]) && - (is_object_visible_on_camera(objectIndex, camera, 0x8000) != 0)) { - OThwomp::DrawModel(objectIndex); - } - } else { // CREDITS_SEQUENCE - OThwomp::DrawModel(objectIndex); - } + OThwomp::DrawModel(objectIndex); + if ((D_8018CF68[cameraId] >= minusone) && (plusone >= D_8018CF68[cameraId]) && + (is_object_visible_on_camera(objectIndex, camera, 0x8000) != 0)) { } + // if (GetCourse() != GetBowsersCastle()) { + // OThwomp::DrawModel(objectIndex); + // } else { + // if (gGamestate != CREDITS_SEQUENCE) { + // if ((D_8018CF68[cameraId] >= minusone) && (plusone >= D_8018CF68[cameraId]) && + // (is_object_visible_on_camera(objectIndex, camera, 0x8000) != 0)) { + // OThwomp::DrawModel(objectIndex); + // } + // } else { // CREDITS_SEQUENCE + // OThwomp::DrawModel(objectIndex); + // } + // } gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8); gDPSetCombineMode(gDisplayListHead++, G_CC_MODULATEIA, G_CC_MODULATEIA); gSPNumLights(gDisplayListHead++, 1); - gSPLight(gDisplayListHead++, &thwompLight.l[0], LIGHT_1); - gSPLight(gDisplayListHead++, &thwompLight.a, LIGHT_2); + gSPLight(gDisplayListHead++, &D_800E4668.l[0], LIGHT_1); + gSPLight(gDisplayListHead++, &D_800E4668.a, LIGHT_2); gSPClearGeometryMode(gDisplayListHead++, G_CULL_BOTH); gSPSetGeometryMode(gDisplayListHead++, G_SHADE | G_LIGHTING | G_SHADING_SMOOTH); load_texture_block_rgba16_mirror((u8*)d_course_bowsers_castle_thwomp_side, 0x00000020, 0x00000020); @@ -276,7 +275,7 @@ void OThwomp::DrawModel(s32 objectIndex) { func_8004A7AC(objectIndex, 1.75f); rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling); - func_800534E8(objectIndex); + thwomp_lights(objectIndex); gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007828); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); gDPLoadTLUT_pal256(gDisplayListHead++, d_course_bowsers_castle_thwomp_tlut); @@ -285,6 +284,8 @@ void OThwomp::DrawModel(s32 objectIndex) { } } +/** Behaviours **/ + void OThwomp::StationaryBehaviour(s32 objectIndex) { // func_8007ED6C UNUSED s32 stackPadding[4]; switch (gObjectList[objectIndex].state) { diff --git a/src/engine/vehicles/OThwomp.h b/src/engine/vehicles/OThwomp.h index dee64044d..f1da5c97c 100644 --- a/src/engine/vehicles/OThwomp.h +++ b/src/engine/vehicles/OThwomp.h @@ -33,7 +33,7 @@ private: public: States State = States::DISABLED; - explicit OThwomp(s32 i, f32 x, f32 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha); + explicit OThwomp(s32 i, s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha); void Tick(); void Draw(s32 playerId); diff --git a/src/port/Game.cpp b/src/port/Game.cpp index 5b79f29c9..ba3a68390 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -473,7 +473,14 @@ extern "C" { } } + extern Vec3su D_80165834; void CourseManager_TickThwomps() { + // TickLights + if (gWorldInstance.Thwomps.size()) { + D_80165834[0] += 0x100; + D_80165834[1] += 0x200; + } + for (auto& thwomp : gWorldInstance.Thwomps) { if (thwomp) { thwomp->Tick(); diff --git a/src/render_objects.c b/src/render_objects.c index bc7728fe2..7a34c47b5 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -1624,7 +1624,6 @@ void func_8004B7DC_wide(s32 x, s32 y, s32 width, s32 height, s32 arg4, s32 arg5, coordX = (s32)OTRGetDimensionFromRightEdge(xl) << 2; coordX2 = (s32)OTRGetDimensionFromRightEdge(xh2) << 2; } - gSPWideTextureRectangle(gDisplayListHead++, coordX, yl, coordX2, yh2, G_TX_RENDERTILE, arg4 << 5, (arg5 << 5), 1 << 10, 1 << 10); @@ -3759,7 +3758,7 @@ void render_lakitu(s32 cameraId) { } } -void func_800534A4(UNUSED s32 arg0) { +void translate_thwomp_lights(UNUSED s32 arg0) { func_800419F8(); // Lights1 *D_800E4638l = (Lights1 *) LOAD_ASSET(D_800E4638); D_800E4638.l[0].l.dir[0] = D_80165840[0]; @@ -3767,7 +3766,7 @@ void func_800534A4(UNUSED s32 arg0) { D_800E4638.l[0].l.dir[2] = D_80165840[2]; } -void func_800534E8(s32 objectIndex) { +void thwomp_lights(s32 objectIndex) { // Lights1 *D_800E4638l = (Lights1 *) LOAD_ASSET(D_800E4638); // Lights1 *D_800E4650l = (Lights1 *) LOAD_ASSET(D_800E4650); @@ -3807,7 +3806,7 @@ void render_object_thwomps_model(s32 objectIndex) { func_8004A7AC(objectIndex, 1.75f); rsp_set_matrix_transformation(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation, gObjectList[objectIndex].sizeScaling); - func_800534E8(objectIndex); + thwomp_lights(objectIndex); gSPDisplayList(gDisplayListHead++, D_0D007828); gDPSetTextureLUT(gDisplayListHead++, G_TT_RGBA16); gDPLoadTLUT_pal256(gDisplayListHead++, d_course_bowsers_castle_thwomp_tlut); @@ -3834,17 +3833,17 @@ void render_object_thwomps(s32 cameraId) { } } - func_800534A4(objectIndex); + translate_thwomp_lights(objectIndex); for (i = 0; i < gNumActiveThwomps; i++) { objectIndex = indexObjectList1[i]; minusone = gObjectList[objectIndex].unk_0DF - 1; plusone = gObjectList[objectIndex].unk_0DF + 1; - if (gGamestate != 9) { + if (gGamestate != CREDITS_SEQUENCE) { if ((D_8018CF68[cameraId] >= minusone) && (plusone >= D_8018CF68[cameraId]) && (is_object_visible_on_camera(objectIndex, camera, 0x8000U) != 0)) { render_object_thwomps_model(objectIndex); } - } else { + } else { // CREDITS_SEQUENCE render_object_thwomps_model(objectIndex); } } diff --git a/src/render_objects.h b/src/render_objects.h index 8dfcb12e3..9a6ffd1e9 100644 --- a/src/render_objects.h +++ b/src/render_objects.h @@ -345,8 +345,8 @@ void render_object_snowmans_list_2(s32); void render_object_snowmans_list_1(s32); void render_object_snowmans(s32); void render_lakitu(s32); -void func_800534A4(s32); -void func_800534E8(s32); +void translate_thwomp_lights(s32); +void thwomp_lights(s32); void render_object_thwomps_model(s32); void render_object_thwomps(s32); void func_80053D74(s32, s32, s32); @@ -431,6 +431,8 @@ void func_80057B14(s32, s32, char*, u32); void func_80057B80(s32, s32, char*, u32); void func_80057BEC(s32, s32, char*, u32); +extern Lights1 D_800E4668; + extern f32 D_801637C4; extern s32 D_801637E8; extern f32 D_801637F0;