From cefae44db1a5bdcb3d34b844c88d283723d1a37b Mon Sep 17 00:00:00 2001 From: MegaMech Date: Wed, 4 Feb 2026 21:28:22 -0700 Subject: [PATCH] FrameInterpolation For Kart (#639) * Update BombKart.cpp * Update BombKart.h * Update PlayerBombKart.cpp * Update PlayerBombKart.cpp * Update PlayerBombKart.h * Update PlayerBombKart.h * Update PlayerBombKart.cpp * Update PlayerBombKart.cpp * Update PlayerBombKart.h * Update PlayerBombKart.h * Update PlayerBombKart.cpp * Update PlayerBombKart.cpp --- src/engine/PlayerBombKart.cpp | 51 +++++++++++++++++++++++++++++---- src/engine/PlayerBombKart.h | 17 ++++++++++- src/engine/objects/BombKart.cpp | 25 ++++------------ src/engine/objects/BombKart.h | 2 +- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/src/engine/PlayerBombKart.cpp b/src/engine/PlayerBombKart.cpp index 7b571d003..9c17a2742 100644 --- a/src/engine/PlayerBombKart.cpp +++ b/src/engine/PlayerBombKart.cpp @@ -1,5 +1,6 @@ #include "PlayerBombKart.h" #include "Matrix.h" +#include "port/interpolation/FrameInterpolation.h" extern "C" { #include "common_structs.h" @@ -12,6 +13,13 @@ extern "C" { #include "menus.h" } +size_t PlayerBombKart::_count = 0; + +PlayerBombKart::PlayerBombKart() { + _idx = _count; + _count++; +} + void PlayerBombKart::Draw(size_t playerId, s32 cameraId) { // render_player_bomb_kart Player* player = &gPlayerOne[playerId]; if (state != PlayerBombKartState::DISABLED) { @@ -20,7 +28,7 @@ void PlayerBombKart::Draw(size_t playerId, s32 cameraId) { // render_player_bomb pos.z = player->pos[2]; surfaceHeight = player->unk_074; PlayerBombKart::func_800563DC(cameraId, _primAlpha); - PlayerBombKart::func_8005669C(_primAlpha); + PlayerBombKart::func_8005669C(cameraId, _primAlpha); PlayerBombKart::func_800568A0(cameraId); } } @@ -38,6 +46,7 @@ void PlayerBombKart::func_800563DC(s32 cameraId, s32 arg2) { D_80183E80[0] = 0; D_80183E80[1] = func_800418AC(pos.x, pos.z, camera->pos); D_80183E80[2] = 0x8000; + FrameInterpolation_RecordOpenChild("player_bomb_kart2", (_idx << 4) | cameraId); rsp_set_matrix_transformation(D_80183E40, D_80183E80, 0.2f); gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007E98); func_8004B310(arg2); @@ -53,36 +62,64 @@ void PlayerBombKart::func_800563DC(s32 cameraId, s32 arg2) { temp_s0 = D_8018D400; gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007B00); + FrameInterpolation_RecordCloseChild(); func_8004B414(0, 0, 0, arg2); D_80183E40[1] = D_80183E40[1] + 4.0; D_80183E80[2] = 0; - func_800562E4(temp_s0 % 3, temp_s0 % 4, arg2); + PlayerBombKart::func_800562E4(cameraId, temp_s0 % 3, temp_s0 % 4, arg2, 0); temp_v0 = temp_s0 + 1; D_80183E80[2] = 0x6000; - func_800562E4(temp_v0 % 3, temp_v0 % 4, arg2); + PlayerBombKart::func_800562E4(cameraId, temp_v0 % 3, temp_v0 % 4, arg2, 1); temp_v0 = temp_s0 + 2; D_80183E80[2] = 0xA000; - func_800562E4(temp_v0 % 3, temp_v0 % 4, arg2); + PlayerBombKart::func_800562E4(cameraId, temp_v0 % 3, temp_v0 % 4, arg2, 2); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } -void PlayerBombKart::func_8005669C(s32 arg2) { +u32 PlayerBombKart::vec[3][3] = { + { 255, 255, 255 }, + { 255, 255, 0 }, + { 255, 0, 0 }, +}; + +void PlayerBombKart::func_800562E4(s32 cameraId, s32 arg0, s32 arg1, s32 arg2, s32 id) { + D_80165860 = PlayerBombKart::vec[arg0][0]; + D_8016586C = PlayerBombKart::vec[arg0][1]; + D_80165878 = PlayerBombKart::vec[arg0][2]; + func_8004B138(D_80165860, D_8016586C, D_80165878, arg2); + FrameInterpolation_RecordOpenChild("player_bomb_kart_spark", (id << 12) | (_idx << 5) | cameraId); + rsp_set_matrix_transformation(D_80183E40, D_80183E80, 0.2f); + func_80044BF8((uint8_t*)common_texture_particle_spark[arg1], 32, 32); + gSPVertex(gDisplayListHead++, (uintptr_t)D_0D005AE0, 4, 0); + gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display); + FrameInterpolation_RecordCloseChild(); +} + +void PlayerBombKart::func_8005669C(s32 cameraId, s32 arg2) { gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0079E8); func_8004B310(arg2); load_texture_block_rgba16_mirror((u8*) D_0D02AA58, 0x00000010, 0x00000010); D_80183E40[1] = pos.y - 2.0; D_80183E40[0] = pos.x + 2.0; D_80183E40[2] = pos.z + 2.0; + FrameInterpolation_RecordOpenChild("player_bomb_kart_rect", (0 << 12) | (_idx << 5) | cameraId); func_800431B0(D_80183E40, D_80183E80, 0.15f, (Vtx*) common_vtx_rectangle); + FrameInterpolation_RecordCloseChild(); D_80183E40[0] = pos.x + 2.0; D_80183E40[2] = pos.z - 2.0; + FrameInterpolation_RecordOpenChild("player_bomb_kart_rect", (1 << 12) | (_idx << 5) | cameraId); func_800431B0(D_80183E40, D_80183E80, 0.15f, (Vtx*) common_vtx_rectangle); + FrameInterpolation_RecordCloseChild(); D_80183E40[0] = pos.x - 2.0; D_80183E40[2] = pos.z - 2.0; + FrameInterpolation_RecordOpenChild("player_bomb_kart_rect", (2 << 12) | (_idx << 5) | cameraId); func_800431B0(D_80183E40, D_80183E80, 0.15f, (Vtx*) common_vtx_rectangle); + FrameInterpolation_RecordCloseChild(); D_80183E40[0] = pos.x - 2.0; D_80183E40[2] = pos.z + 2.0; + FrameInterpolation_RecordOpenChild("player_bomb_kart_rect", (3 << 12) | (_idx << 5) | cameraId); func_800431B0(D_80183E40, D_80183E80, 0.15f, (Vtx*) common_vtx_rectangle); + FrameInterpolation_RecordCloseChild(); gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } @@ -94,6 +131,7 @@ void PlayerBombKart::func_800568A0(s32 cameraId) { D_80183E50[0] = pos.x; D_80183E50[1] = surfaceHeight + 0.8; D_80183E50[2] = pos.z; + FrameInterpolation_RecordOpenChild("player_bomb_kart", (_idx << 4) | cameraId); set_transform_matrix(mtx, player->collision.orientationVector, D_80183E50, 0U, 0.5f); // convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx); // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), @@ -101,4 +139,5 @@ void PlayerBombKart::func_800568A0(s32 cameraId) { AddHudMatrix(mtx, G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007B98); -} \ No newline at end of file + FrameInterpolation_RecordCloseChild(); +} diff --git a/src/engine/PlayerBombKart.h b/src/engine/PlayerBombKart.h index c1e58d815..eb10bc856 100644 --- a/src/engine/PlayerBombKart.h +++ b/src/engine/PlayerBombKart.h @@ -11,6 +11,16 @@ public: ACTIVE, }; + PlayerBombKart(); + + ~PlayerBombKart() { + _count--; + } + + static size_t GetCount() { + return _count; + } + s16 state = PlayerBombKartState::DISABLED; FVector pos = {0, 0, 0}; f32 surfaceHeight = 0; @@ -18,6 +28,11 @@ public: void Draw(size_t playerId, s32 cameraId); void func_800563DC(s32 cameraId, s32 arg2); - void func_8005669C(s32 arg2); + void func_800562E4(s32 cameraId, s32 arg0, s32 arg1, s32 arg2, s32 id); + void func_8005669C(s32 cameraId, s32 arg2); void func_800568A0(s32 cameraId); +private: + static u32 vec[3][3]; + static size_t _count; + size_t _idx; }; diff --git a/src/engine/objects/BombKart.cpp b/src/engine/objects/BombKart.cpp index f5a9f701b..8a0afdb95 100644 --- a/src/engine/objects/BombKart.cpp +++ b/src/engine/objects/BombKart.cpp @@ -4,6 +4,7 @@ #include #include "port/Game.h" +#include "port/interpolation/FrameInterpolation.h" #include "engine/Matrix.h" extern "C" { @@ -346,24 +347,6 @@ void OBombKart::Tick() { } void OBombKart::Draw(s32 cameraId) { - if (gModeSelection == BATTLE) { - for (size_t playerId = 0; playerId < NUM_BOMB_KARTS_BATTLE; playerId++) { - Object* object = &gObjectList[_objectIndex]; - if (object->state != 0) { - s32 primAlpha = object->primAlpha; - Player* player = &gPlayerOne[playerId]; - object->pos[0] = player->pos[0]; - object->pos[1] = player->pos[1] - 2.0; - object->pos[2] = player->pos[2]; - object->surfaceHeight = player->unk_074; - func_800563DC(_objectIndex, cameraId, primAlpha); - func_8005669C(_objectIndex, cameraId, primAlpha); - func_800568A0(_objectIndex, cameraId); - } - } - return; - } - if (IsPodiumCeremony()) { if ((_idx == 0) && (WaypointIndex < 16)) { return; @@ -400,7 +383,7 @@ void OBombKart::Draw(s32 cameraId) { func_800563DC(_objectIndex, cameraId, 0x000000FF); OBombKart::SomeRender(camera->pos); if (((u32) temp_s4 < 0x4E21U) && (state != OBombKart::States::EXPLODE)) { - OBombKart::LoadMtx(); + OBombKart::LoadMtx(cameraId); } } } @@ -426,12 +409,13 @@ void OBombKart::SomeRender(Vec3f arg1) { gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF); } -void OBombKart::LoadMtx() { +void OBombKart::LoadMtx(s32 cameraId) { Mat4 mat; D_80183E50[0] = Pos[0]; D_80183E50[1] = CenterY + 1.0; D_80183E50[2] = Pos[2]; + FrameInterpolation_RecordOpenChild("object_bomb_kart", (_idx << 4) | cameraId); set_transform_matrix(mat, _Collision.orientationVector, D_80183E50, 0U, 0.5f); //convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mat); @@ -440,6 +424,7 @@ void OBombKart::LoadMtx() { // gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]), // G_MTX_LOAD | G_MTX_NOPUSH | G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98); + FrameInterpolation_RecordCloseChild(); } void OBombKart::Waypoint(s32 screenId) { diff --git a/src/engine/objects/BombKart.h b/src/engine/objects/BombKart.h index 3ce2d35b2..3f4a7a28e 100644 --- a/src/engine/objects/BombKart.h +++ b/src/engine/objects/BombKart.h @@ -86,7 +86,7 @@ class OBombKart : public OObject { virtual void DrawEditorProperties() override; void DrawBattle(s32 cameraId); void SomeRender(Vec3f arg1); - void LoadMtx(); + void LoadMtx(s32 cameraId); void Waypoint(s32 screenId); OBombKart::States Behaviour = OBombKart::States::COUNTERCLOCKWISE;