diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp index 9ee4db7e7..9bc470f90 100644 --- a/src/engine/objects/Mole.cpp +++ b/src/engine/objects/Mole.cpp @@ -51,15 +51,12 @@ OMole::OMole(FVector pos, OMoleGroup* group) { _count++; } +/** + * Moles are ticked from OMoleGroup + * OMoleTick is func_800821AC + * Dirt particle tick is func_80081790 + */ void OMole::Tick() { - if (_idx == 0) { - for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { - s32 objectIndex = gObjectParticle2[i]; - if (gObjectList[objectIndex].state != 0) { - OMole::func_80081790(objectIndex); - } - } - } } void OMole::Draw(s32 cameraId) { @@ -184,9 +181,9 @@ void OMole::func_8008153C(s32 objectIndex) { gObjectList[loopObjectIndex].activeTLUT = d_course_moo_moo_farm_mole_dirt; gObjectList[loopObjectIndex].tlutList = mole; gObjectList[loopObjectIndex].sizeScaling = 0.15f; - gObjectList[loopObjectIndex].velocity[1] = random_int(0x000AU); + gObjectList[loopObjectIndex].velocity[1] = random_int(10); gObjectList[loopObjectIndex].velocity[1] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8; - gObjectList[loopObjectIndex].unk_034 = random_int(5U); + gObjectList[loopObjectIndex].unk_034 = random_int(5); gObjectList[loopObjectIndex].unk_034 = (gObjectList[loopObjectIndex].unk_034 * 0.01) + 0.8; gObjectList[loopObjectIndex].orientation[1] = (0x10000 / sp70) * var_s1; gObjectList[loopObjectIndex].origin_pos[0] = gObjectList[objectIndex].origin_pos[0]; diff --git a/src/engine/objects/MoleGroup.cpp b/src/engine/objects/MoleGroup.cpp index 6e98edbbb..af936ed3f 100644 --- a/src/engine/objects/MoleGroup.cpp +++ b/src/engine/objects/MoleGroup.cpp @@ -8,12 +8,17 @@ extern "C" { #include "math_util_2.h" } -OMoleGroup::OMoleGroup(std::vector spawns) { +size_t OMoleGroup::_count = 0; + +OMoleGroup::OMoleGroup(std::vector& spawns) { + _idx = _count; for (auto& pos : spawns) { pos.x * xOrientation; OMole* ptr = reinterpret_cast(gWorldInstance.AddObject(new OMole(pos, this))); _moles.push_back({ptr, pos, false}); } + + _count += 1; } void OMoleGroup::Tick() { @@ -24,14 +29,32 @@ void OMoleGroup::Tick() { mole.Mole->func_800821AC(mole.Mole->_objectIndex, 1); } } + + /** + * This ticks the mole dirt particles. It must be ran *after* MoleGroup is done ticking. Otherwise, the dirt particle directions will not randomize + * The best solution would be for particles to be its own class. But that takes effort + * Instead, we wait until the last MoleGroup has ticked, then we tick the particles one time. + * + * Warning: Calling this more than one time per frame, will result in doubling the speed + */ + if (_idx == _count - 1) { + for (size_t i = 0; i < gObjectParticle2_SIZE; i++) { + s32 objectIndex = gObjectParticle2[i]; + if (gObjectList[objectIndex].state != 0) { + if (nullptr != _moles[0].Mole) { + _moles[0].Mole->func_80081790(objectIndex); + } + } + } + } } void OMoleGroup::func_80081FF4(s32 objectIndex) { init_object(objectIndex, 0); gObjectList[objectIndex].unk_04C = random_int(30) + 5; - s16 mole = random_int(_moles.size() - 1); - for (size_t i = 0; i < _moles.size() - 1; i++) { + s16 mole = random_int(_moles.size()); + for (size_t i = 0; i < _moles.size(); i++) { if (_moles[mole].Active == true) { mole++; if (mole == _moles.size()) { diff --git a/src/engine/objects/MoleGroup.h b/src/engine/objects/MoleGroup.h index dfb920985..db14432cd 100644 --- a/src/engine/objects/MoleGroup.h +++ b/src/engine/objects/MoleGroup.h @@ -16,7 +16,7 @@ public: bool Active; }; - explicit OMoleGroup(std::vector moles); + explicit OMoleGroup(std::vector& moles); virtual void Tick() override; @@ -24,4 +24,7 @@ public: std::vector _moles; +private: + static size_t _count; + size_t _idx; }; diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 320bd0f21..7ca85eca0 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -20,12 +20,14 @@ extern "C" { #define TAG_ITEM_ADDR(x) ((u32) 0x10000000 | (u32)x) #define TAG_SMOKE_DUST(x) ((u32) 0x20000000 | (u32) (x)) -#define TAG_LETTER(x) ((u32)0x30000000 | ((u32)(x) & 0x0FFFFFFF)) -#define TAG_OBJECT(x) ((u32)0x40000000 | (u32) (uintptr_t) (x)) -#define TAG_CLOUDS(x) ((u32)0x50000000 | (u32) (uintptr_t) (x)) -#define TAG_THWOMP(x) ((u32)0x60000000 | ((u32)(x) & 0x0FFFFFFF)) +#define TAG_LETTER(x) ((u32)0x30000000 | ((u32) (uintptr_t) (x) & 0x0FFFFFFF)) +#define TAG_OBJECT(x) ((u32)0x40000000 | (u32) (uintptr_t) (x)) +#define TAG_CLOUDS(x) ((u32)0x50000000 | (u32) (uintptr_t) (x)) +#define TAG_THWOMP(x) ((u32)0x60000000 | ((u32) (uintptr_t) (x) & 0x0FFFFFFF)) // Mask the bits so that the 7 can't get overridden #define TAG_TRACK(x) ((u32)0x70000000 | ((u32)(x) & 0x0FFFFFFF)) +#define TAG_MINIMAP_DOTS(x) ((u32)0x80000000 | ((u32)(x) & 0x0FFFFFFF)) +#define TAG_PORTRAITS(x) ((u32)0x90000000 | ((u32)(x) & 0x0FFFFFFF)) void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c index 129b55b11..185ac0068 100644 --- a/src/racing/skybox_and_splitscreen.c +++ b/src/racing/skybox_and_splitscreen.c @@ -884,7 +884,7 @@ void render_screens(s32 mode, s32 cameraId, s32 playerId) { // Draw dynamic game objects render_course_actors(screen); - CM_DrawActors(D_800DC5EC->camera); + CM_DrawActors(camera); CM_DrawStaticMeshActors(); render_object(mode); diff --git a/src/render_objects.c b/src/render_objects.c index 3b0758dc9..f2ea3fa4a 100644 --- a/src/render_objects.c +++ b/src/render_objects.c @@ -2655,6 +2655,7 @@ void func_8004E800(s32 playerId) { void func_8004E998(s32 playerId) { if (playerHUD[playerId].unk_81 != 0) { + FrameInterpolation_RecordOpenChild("Player place HUD2", playerId); if (playerHUD[playerId].lapCount != 3) { func_8004A384(playerHUD[playerId].rankX + playerHUD[playerId].slideRankX, playerHUD[playerId].rankY + playerHUD[playerId].slideRankY, 0U, @@ -2669,6 +2670,7 @@ void func_8004E998(s32 playerId) { D_0D015258[gGPCurrentRaceRankByPlayerId[playerId]], D_0D006030, 0x00000040, 0x00000040, 0x00000040, 0x00000040); } + FrameInterpolation_RecordCloseChild(); } } @@ -2809,9 +2811,6 @@ void draw_minimap_character(s32 arg0, s32 playerId, s32 characterId) { s32 center = 0; Player* player = &gPlayerOne[playerId]; - // @port Skip Interpolation, if interpolated later remove this tag - FrameInterpolation_ShouldInterpolateFrame(false); - if (player->type & (1 << 15)) { thing0 = player->pos[0] * CM_GetProps()->Minimap.PlayerScaleFactor; // gMinimapPlayerScale; thing1 = player->pos[2] * CM_GetProps()->Minimap.PlayerScaleFactor; // gMinimapPlayerScale; @@ -2827,6 +2826,7 @@ void draw_minimap_character(s32 arg0, s32 playerId, s32 characterId) { y = (CM_GetProps()->Minimap.Pos[arg0].Y - (CM_GetProps()->Minimap.Height / 2)) + CM_GetProps()->Minimap.PlayerY + (s16) (thing1); if (characterId != 8) { + FrameInterpolation_RecordOpenChild("minimap_dots", TAG_MINIMAP_DOTS( ((arg0 & 0x1) << 6) | ((playerId & 0x7) << 3) | (characterId & 0x7) )); if ((gGPCurrentRaceRankByPlayerId[playerId] == 0) && (gModeSelection != 3) && (gModeSelection != 1)) { func_80046424(x, y, player->rotation[1] + 0x8000, 1.0f, (u8*) common_texture_minimap_kart_character[characterId], common_vtx_player_minimap_icon, @@ -2836,17 +2836,17 @@ void draw_minimap_character(s32 arg0, s32 playerId, s32 characterId) { (u8*) common_texture_minimap_kart_character[characterId], common_vtx_player_minimap_icon, 8, 8, 8, 8); } + FrameInterpolation_RecordCloseChild(); } else { + FrameInterpolation_RecordOpenChild("minimap_dots2", TAG_MINIMAP_DOTS( ((arg0 & 0x1) << 6) | ((playerId & 0x7) << 3) | (characterId & 0x7) )); if (gGPCurrentRaceRankByPlayerId[playerId] == 0) { func_8004C450(x, y, 8, 8, (u8*) common_texture_minimap_progress[player->characterId]); } else { draw_hud_2d_texture_wide(x, y, 8, 8, (u8*) common_texture_minimap_progress[player->characterId]); } + FrameInterpolation_RecordCloseChild(); } } - - // @port Resume Interpolation, if interpolated later remove this tag - FrameInterpolation_ShouldInterpolateFrame(true); } #else GLOBAL_ASM("asm/non_matchings/render_objects/draw_minimap_character.s") @@ -3308,25 +3308,18 @@ void func_80050C68(void) { } } -#ifdef NON_MATCHING - -// Something about the handling of the `player` variable is weird. -// All commands are present and correct, 2 of them are out of position -// https://decomp.me/scratch/PvJ5D void func_80050E34(s32 playerId, s32 arg1) { s32 objectIndex; s32 spD0; s32 spCC; - UNUSED s32 stackPadding; s32 spC4; s32 lapCount; s32 characterId; s32 spB8; - s32 temp_v0_2; + s32 result; Object* object; - Player* player; + Player *player = &gPlayerOne[playerId]; - player = &gPlayerOne[playerId]; lapCount = gLapCountByPlayerId[playerId]; characterId = player->characterId; objectIndex = D_8018CE10[playerId].objectIndex; @@ -3337,13 +3330,14 @@ void func_80050E34(s32 playerId, s32 arg1) { spC4 = 0x00000078; } - temp_v0_2 = func_80050644(playerId, &spD0, &spCC); - if ((temp_v0_2 == 2) || (temp_v0_2 == 3)) { + result = func_80050644(playerId, &spD0, &spCC); + if ((result == 2) || (result == 3)) { spB8 = 1; } else { spB8 = 0; } + FrameInterpolation_RecordOpenChild("progress_portraits", TAG_PORTRAITS( ((playerId & 0x7) << 8) | ((characterId & 0x7) << 5) | (objectIndex & 0x1F) )); if ((IsYoshiValley()) && (lapCount < 3)) { gSPDisplayList(gDisplayListHead++, D_0D007DB8); gDPLoadTLUT_pal256(gDisplayListHead++, common_tlut_portrait_bomb_kart_and_question_mark); @@ -3390,10 +3384,8 @@ void func_80050E34(s32 playerId, s32 arg1) { gSPDisplayList(gDisplayListHead++, D_0D0069E0); } } + FrameInterpolation_RecordCloseChild(); } -#else -GLOBAL_ASM("asm/non_matchings/render_objects/func_80050E34.s") -#endif void func_800514BC(void) { s32 temp_a0;