summaryrefslogtreecommitdiff
path: root/src/engine/objects
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-06-07 21:38:12 -0600
committerGitHub <noreply@github.com>2025-06-07 21:38:12 -0600
commit44db9bab773cc3b14c8f944a9411673b6fe08b01 (patch)
tree8ad796dac5ec3f42eca1220efe1e054b576374e8 /src/engine/objects
parenta67fbb6442d76016397c67f2cb7831687cdda91a (diff)
Add Interpolation (#204)
* initial work * more work * progress * Fixed slow fps * Add Lywx changes * Interp Works * Test default tick/logic update * Added missing include (#202) * Added missing include * More missing includes --------- Co-authored-by: MegaMech <MegaMech@users.noreply.github.com> * test * Revert "test" This reverts commit 1a810d74cc8531ce486bcb1c399cc6798fa1b51d. * Interp Item box * Actually interpolate item box * fix clouds * interp player? * Test 2 * Fix mistake * tag and fix item boxes * tag fake item box and whatever func_800696CC is * these aren't needed * tag karts * Slightly better falling rocks(still needs work) * Tag Smoke and Dust * Removed unneeded code from falling_rock * tag whatever func_80051ABC is * add missing rotate x coord * GrandPrixBallon/kart shadow * Green shells tag, and added comments I neglected to add before. * doesn't compile on win * Fixes * Disabled camera interpolation * Balloons fixes * progress * set_transform_matrix compiles * Compile setTransformMatrix * More transforms interp * Add more interps * matrix * Matrix multi interp * Fix interpolation camera bug * Missing includes needed for Linux. * Excluded access to HM64 Labs on Switch. * interpolation tags for various objects * Bowser castle statue flame interpolated. * tag hedgehogs * cloud interpolation * Interpolated smoke particles from shells * cloud interpolation refactor * Interpolated snowflakes * Interpolated penguins, also added comment tags to places I missed. * tag Snowman interpolation * Interpolated player reflection(sherbet land) * Forgot to uncomment stuff while testing * better tag * tag leaves * Set the default FPS to 30 * tag hud * Fixed "Match Refresh Rate" option * adjust draw distance * remove innecessary rock tag * rag rocks * better tag * Tagged player rank placement in HUD * Tagged Bat, Boos, and TrashBin(Banshee Boardwalk objects) * Refactor render_screens and fix editor raycast * better object interpolation * shift is not needed here * fix tag * fix tags * mole comments * comment * Changed how shell flames are interpolated. * interpolated ended scene fireworks. * Tagged star particles in the ending scene * Shell flames handled better. * this isn't needed * Fix multiplayer cameras * Fixed loading battle maps. * Tagged battle balloons * Some fixes for battle mode * No longer needed changes toAFinishline with the changes mega made. * Tag finishline * fix to make it compile with cmake 3.31 * changed mtxf_multiplication() to fix vert explosion in Desert & DK parkway.(provided by Coco.) * fix memory leaks, avoid invalidate texture (#207) * Fixed macos * More stupid fixes * update with main and update torch and lus and enable action on this branch * Update FrameInterpolation.h * Update FrameInterpolation.cpp * fix some memory leak * Update torch * Update torch * update torch and lus * reduce texture import * don't use fork of torch and lus * Update torch * Update torch --------- Co-authored-by: Lywx <kiritodev01@gmail.com> * Refactor World::Courses to unique_ptr (#211) * wip course unique ptr * Track unique_ptr : This probably compiles * Finish impl Courses as unique_ptr * Fix error * Fixes * More fixes * Cleanup * Remove old vars --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com> * particle boat and train * fix player particle interpolation * add modify interpolation target fps in menu * fix windows * Update libultraship * Fix logo interp * Interp SetTextMatrix * Fix freecam camera * Clarify comment * Clarify func * fix linux compilation * Update Thwomp.cpp * Update Thwomp.h * Update render.inc.c * Update render.inc.c * Update gbiMacro.c * interp falling rock shadow * Revert change that has no explanation * Update code_80057C60.c * Update code_80057C60.c * Update GrandPrixBalloons.cpp * Update Lakitu.cpp * Update framebuffer_effects.c * Update render_courses.c --------- Co-authored-by: Sonic Dreamcaster <alejandro.asenjo88@gmail.com> Co-authored-by: KiritoDv <kiritodev01@gmail.com> Co-authored-by: sitton76 <58642183+sitton76@users.noreply.github.com> Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com> Co-authored-by: coco875 <59367621+coco875@users.noreply.github.com> Co-authored-by: coco875 <pereira.jannin@gmail.com>
Diffstat (limited to 'src/engine/objects')
-rw-r--r--src/engine/objects/Bat.cpp48
-rw-r--r--src/engine/objects/BombKart.cpp8
-rw-r--r--src/engine/objects/Boos.cpp8
-rw-r--r--src/engine/objects/GrandPrixBalloons.cpp36
-rw-r--r--src/engine/objects/Hedgehog.cpp22
-rw-r--r--src/engine/objects/HotAirBalloon.cpp2
-rw-r--r--src/engine/objects/Lakitu.cpp10
-rw-r--r--src/engine/objects/Mole.cpp107
-rw-r--r--src/engine/objects/Snowman.cpp59
-rw-r--r--src/engine/objects/Thwomp.cpp54
-rw-r--r--src/engine/objects/Thwomp.h1
-rw-r--r--src/engine/objects/TrashBin.cpp10
12 files changed, 232 insertions, 133 deletions
diff --git a/src/engine/objects/Bat.cpp b/src/engine/objects/Bat.cpp
index 764476064..e4f3a2086 100644
--- a/src/engine/objects/Bat.cpp
+++ b/src/engine/objects/Bat.cpp
@@ -1,6 +1,7 @@
#include "Bat.h"
#include "World.h"
#include "CoreMath.h"
+#include "port/interpolation/FrameInterpolation.h"
extern "C" {
#include "render_objects.h"
@@ -22,7 +23,7 @@ OBat::OBat(const FVector& pos, const IRotator& rot) {
Name = "Bat";
find_unused_obj_index(&_objectIndex);
- init_texture_object(_objectIndex, (uint8_t*)d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
+ init_texture_object(_objectIndex, (uint8_t*) d_course_banshee_boardwalk_bat_tlut, sBoardwalkTexList, 0x20U,
(u16) 0x00000040);
gObjectList[_objectIndex].orientation[0] = rot.pitch;
gObjectList[_objectIndex].orientation[1] = rot.roll;
@@ -101,43 +102,56 @@ void OBat::Tick() {
}
void OBat::Draw(s32 cameraId) {
- s32 var_s2;
- s32 objectIndex;
- Camera* temp_s7;
+ s32 i;
+ s32 objectIndex = _objectIndex;
+ Camera* cam = &camera1[cameraId];
- objectIndex = _objectIndex;
- temp_s7 = &camera1[cameraId];
- OBat::func_80046F60((u8*)gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture, 0x00000020, 0x00000040,
- 5);
+ OBat::func_80046F60((u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture,
+ 0x00000020, 0x00000040, 5);
D_80183E80[0] = gObjectList[objectIndex].orientation[0];
D_80183E80[2] = gObjectList[objectIndex].orientation[2];
+
if ((D_8018CFB0 != 0) || (D_8018CFC8 != 0)) {
- for (var_s2 = 0; var_s2 < 40; var_s2++) {
- objectIndex = gObjectParticle2[var_s2];
+ for (i = 0; i < 40; i++) {
+ objectIndex = gObjectParticle2[i];
if (objectIndex == -1) {
continue;
}
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("Bat set 1", (uintptr_t) &gObjectList[objectIndex]);
+
D_80183E80[1] =
- func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
+ func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], cam->pos);
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
- (Vtx*)D_0D0062B0);
+ (Vtx*) D_0D0062B0);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
+
if ((D_8018CFE8 != 0) || (D_8018D000 != 0)) {
- for (var_s2 = 0; var_s2 < 30; var_s2++) {
- objectIndex = gObjectParticle3[var_s2];
+ for (i = 0; i < 30; i++) {
+
+ objectIndex = gObjectParticle3[i];
if (objectIndex == -1) {
continue;
}
if ((gObjectList[objectIndex].state >= 2) && (gMatrixHudCount < 0x2EF)) {
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("Bat set 2", (uintptr_t) &gObjectList[objectIndex]);
+
D_80183E80[1] =
- func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], temp_s7->pos);
+ func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], cam->pos);
func_800431B0(gObjectList[objectIndex].pos, D_80183E80, gObjectList[objectIndex].sizeScaling,
- (Vtx*)D_0D0062B0);
+ (Vtx*) D_0D0062B0);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
@@ -145,7 +159,7 @@ void OBat::Draw(s32 cameraId) {
}
void OBat::func_80046F60(u8* tlut, u8* arg1, s32 arg2, s32 arg3, s32 arg4) {
- gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007D78);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007D78);
gDPLoadTLUT_pal256(gDisplayListHead++, tlut);
rsp_load_texture_mask(arg1, arg2, arg3, arg4);
}
diff --git a/src/engine/objects/BombKart.cpp b/src/engine/objects/BombKart.cpp
index 53b4a4262..8aaaae6cf 100644
--- a/src/engine/objects/BombKart.cpp
+++ b/src/engine/objects/BombKart.cpp
@@ -118,7 +118,7 @@ void OBombKart::Tick() {
return;
}
- if (((Unk_4A != 1) || (GetCourse() == GetPodiumCeremony()))) {
+ if (((Unk_4A != 1) || (IsPodiumCeremony()))) {
newPos[0] = Pos[0];
newPos[1] = Pos[1];
newPos[2] = Pos[2];
@@ -128,7 +128,7 @@ void OBombKart::Tick() {
bounceTimer = BounceTimer;
circleTimer = CircleTimer;
if ((state != States::DISABLED) && (state != States::EXPLODE)) {
- if (GetCourse() == GetPodiumCeremony()) {
+ if (IsPodiumCeremony()) {
if (D_8016347E == 1) {
player = gPlayerFour;
temp_f0 = newPos[0] - player->pos[0];
@@ -152,7 +152,7 @@ void OBombKart::Tick() {
if ((((temp_f0 * temp_f0) + (temp_f2 * temp_f2)) + (temp_f12 * temp_f12)) < 25.0f) {
state = States::EXPLODE;
circleTimer = 0;
- if (GetCourse() == GetFrappeSnowland()) {
+ if (IsFrappeSnowland()) {
player->soundEffects |= 0x01000000;
} else {
player->soundEffects |= 0x400000;
@@ -346,7 +346,7 @@ void OBombKart::Draw(s32 cameraId) {
return;
}
- if (GetCourse() == GetPodiumCeremony()) {
+ if (IsPodiumCeremony()) {
if ((_idx == 0) && (WaypointIndex < 16)) {
return;
} else {
diff --git a/src/engine/objects/Boos.cpp b/src/engine/objects/Boos.cpp
index 5bdbd41cf..5f02d7876 100644
--- a/src/engine/objects/Boos.cpp
+++ b/src/engine/objects/Boos.cpp
@@ -1,6 +1,7 @@
#include "Boos.h"
#include "World.h"
#include "CoreMath.h"
+#include "port/interpolation/FrameInterpolation.h"
extern "C" {
#include "render_objects.h"
@@ -88,9 +89,16 @@ void OBoos::Draw(s32 cameraId) {
if (CVarGetInteger("gNoCulling", 0) == 1) {
temp_s2 = MIN(temp_s2, 0x15F91U);
}
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("Boo", (uintptr_t)&gObjectList[objectIndex]);
+
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
func_800523B8(objectIndex, cameraId, temp_s2);
}
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
diff --git a/src/engine/objects/GrandPrixBalloons.cpp b/src/engine/objects/GrandPrixBalloons.cpp
index 819bde1c6..1315589f2 100644
--- a/src/engine/objects/GrandPrixBalloons.cpp
+++ b/src/engine/objects/GrandPrixBalloons.cpp
@@ -3,6 +3,7 @@
#include "port/Game.h"
#include "assets/other_textures.h"
#include "assets/common_data.h"
+#include "port/interpolation/FrameInterpolation.h"
extern "C" {
#include "update_objects.h"
@@ -73,7 +74,7 @@ void OGrandPrixBalloons::Draw(s32 cameraId) {
return;
}
- gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007E98);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007E98);
gDPLoadTLUT_pal256(gDisplayListHead++, gTLUTOnomatopoeia);
func_8004B614(0, 0, 0, 0, 0, 0, 0);
gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD);
@@ -84,14 +85,14 @@ void OGrandPrixBalloons::Draw(s32 cameraId) {
GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA));
D_80183E80[0] = 0;
D_80183E80[1] = 0x8000;
- rsp_load_texture((uint8_t*)gTextureBalloon1, 64, 32);
+ rsp_load_texture((uint8_t*) gTextureBalloon1, 64, 32);
for (var_s1 = 0; var_s1 < _numBalloons; var_s1++) {
objectIndex = gObjectParticle3[var_s1];
if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) {
OGrandPrixBalloons::func_80053D74(objectIndex, cameraId, 0);
}
}
- rsp_load_texture((uint8_t*)gTextureBalloon2, 64, 32);
+ rsp_load_texture((uint8_t*) gTextureBalloon2, 64, 32);
for (var_s1 = 0; var_s1 < _numBalloons; var_s1++) {
objectIndex = gObjectParticle3[var_s1];
if ((objectIndex != NULL_OBJECT_ID) && (gObjectList[objectIndex].state >= 2)) {
@@ -105,15 +106,24 @@ void OGrandPrixBalloons::func_80053D74(s32 objectIndex, UNUSED s32 arg1, s32 ver
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
+ size_t i = 0;
if (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX) {
object = &gObjectList[objectIndex];
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("Balloon",
+ TAG_ITEM_ADDR((objectIndex << 32) + i++)); // Not working properly just yet
+
D_80183E80[2] = (s16) (object->unk_084[6] + 0x8000);
rsp_set_matrix_transformation(object->pos, (u16*) D_80183E80, object->sizeScaling);
set_color_render((s32) object->unk_084[0], (s32) object->unk_084[1], (s32) object->unk_084[2],
(s32) object->unk_084[3], (s32) object->unk_084[4], (s32) object->unk_084[5],
(s32) object->primAlpha);
- gSPVertex(gDisplayListHead++, (uintptr_t)&vtx[vertexIndex], 4, 0);
- gSPDisplayList(gDisplayListHead++, (Gfx*)common_rectangle_display);
+ gSPVertex(gDisplayListHead++, (uintptr_t) &vtx[vertexIndex], 4, 0);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) common_rectangle_display);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
@@ -128,7 +138,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
object = &gObjectList[objectIndex];
object->sizeScaling = 0.15f;
- if (GetCourse() == GetMarioRaceway()) {
+ if (IsMarioRaceway()) {
sp2C = random_int(0x00C8U);
sp28 = random_int(_numBalloons3);
sp24 = random_int(0x0096U);
@@ -136,7 +146,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
object->origin_pos[0] = (f32) ((((f64) Pos.x + 100.0) - (f64) sp2C) * (f64) xOrientation);
object->origin_pos[1] = (f32) (Pos.y + sp28);
object->origin_pos[2] = (f32) (((f64) Pos.z + 200.0) - (f64) sp24);
- } else if (GetCourse() == GetRoyalRaceway()) {
+ } else if (IsRoyalRaceway()) {
sp2C = random_int(0x0168U);
sp28 = random_int(_numBalloons3);
sp24 = random_int(0x00B4U);
@@ -144,7 +154,7 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
object->origin_pos[0] = (f32) ((((f64) Pos.x + 180.0) - (f64) sp2C) * (f64) xOrientation);
object->origin_pos[1] = (f32) (Pos.y + sp28);
object->origin_pos[2] = (f32) (((f64) Pos.z + 200.0) - (f64) sp24);
- } else if (GetCourse() == GetLuigiRaceway()) {
+ } else if (IsLuigiRaceway()) {
sp2C = random_int(0x012CU);
sp28 = random_int(_numBalloons3);
sp24 = random_int(0x0096U);
@@ -187,7 +197,10 @@ void OGrandPrixBalloons::func_80074924(s32 objectIndex) {
void OGrandPrixBalloons::func_80074D94(s32 objectIndex) {
if (gObjectList[objectIndex].unk_0AE == 1) {
- if ((_numBalloons2 <= gObjectList[objectIndex].offset[1]) &&
+ //! @warning this fades out the balloons. Original game uses _numBalloons3 here but they disappear before
+ //! off-screen.
+ // So _numBalloons replaces it for now.
+ if ((_numBalloons <= gObjectList[objectIndex].offset[1]) &&
(s16_step_down_towards(&gObjectList[objectIndex].primAlpha, 0, 8) != 0)) {
func_80086F60(objectIndex);
}
@@ -209,7 +222,8 @@ void OGrandPrixBalloons::func_80074E28(s32 objectIndex) {
case 0:
break;
case 3:
- OGrandPrixBalloons::func_80041480(&gObjectList[objectIndex].unk_084[6], -0x1000, 0x1000, &gObjectList[objectIndex].unk_084[7]);
+ OGrandPrixBalloons::func_80041480(&gObjectList[objectIndex].unk_084[6], -0x1000, 0x1000,
+ &gObjectList[objectIndex].unk_084[7]);
if (gObjectList[objectIndex].unk_0AE == 0) {
func_80072428(objectIndex);
}
@@ -228,4 +242,4 @@ void OGrandPrixBalloons::func_80041480(s16* arg0, s16 arg1, s16 arg2, s16* arg3)
*arg0 = arg1;
*arg3 = -*arg3;
}
-} \ No newline at end of file
+}
diff --git a/src/engine/objects/Hedgehog.cpp b/src/engine/objects/Hedgehog.cpp
index ebc5b30bb..1c2aada9d 100644
--- a/src/engine/objects/Hedgehog.cpp
+++ b/src/engine/objects/Hedgehog.cpp
@@ -11,6 +11,7 @@ extern "C" {
#include "code_80086E70.h"
#include "code_80057C60.h"
}
+#include "port/interpolation/FrameInterpolation.h"
size_t OHedgehog::_count = 0;
@@ -25,7 +26,7 @@ OHedgehog::OHedgehog(const FVector& pos, const FVector2D& patrolPoint, s16 unk)
gObjectList[objectId].pos[0] = gObjectList[objectId].origin_pos[0] = pos.x * xOrientation;
gObjectList[objectId].pos[1] = gObjectList[objectId].surfaceHeight = pos.y + 6.0;
gObjectList[objectId].pos[2] = gObjectList[objectId].origin_pos[2] = pos.z;
- gObjectList[objectId].unk_0D5 = (u8)unk;
+ gObjectList[objectId].unk_0D5 = (u8) unk;
gObjectList[objectId].unk_09C = patrolPoint.x * xOrientation;
gObjectList[objectId].unk_09E = patrolPoint.z;
@@ -38,10 +39,10 @@ void OHedgehog::Tick() {
OHedgehog::func_800833D0(objectIndex, _idx);
OHedgehog::func_80083248(objectIndex);
OHedgehog::func_80083474(objectIndex);
-
+
// This func clears a bit from all hedgehogs. This results in setting the height of all hedgehogs to zero.
// The solution is to only clear the bit from the current instance; `self` or `this`
- //func_80072120(indexObjectList2, NUM_HEDGEHOGS);
+ // func_80072120(indexObjectList2, NUM_HEDGEHOGS);
clear_object_flag(objectIndex, 0x00600000); // The fix
}
@@ -78,7 +79,8 @@ void OHedgehog::func_800555BC(s32 objectIndex, s32 cameraId) {
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
draw_2d_texture_at(gObjectList[objectIndex].pos, gObjectList[objectIndex].orientation,
gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
- (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64, 32);
+ (u8*) gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 64, 64, 64,
+ 32);
}
}
@@ -92,13 +94,20 @@ void OHedgehog::func_8004A870(s32 objectIndex, f32 arg1) {
D_80183E50[0] = object->pos[0];
D_80183E50[1] = object->surfaceHeight + 0.8;
D_80183E50[2] = object->pos[2];
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("hedgehog", (uintptr_t) &gObjectList[objectIndex]);
+
set_transform_matrix(mtx, object->unk_01C, D_80183E50, 0U, arg1);
// convert_to_fixed_point_matrix(&gGfxPool->mtxHud[gMatrixHudCount], mtx);
// gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&gGfxPool->mtxHud[gMatrixHudCount++]),
// G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
AddHudMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D007B98);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D007B98);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
@@ -108,7 +117,8 @@ void OHedgehog::func_8008311C(s32 objectIndex, s32 arg1) {
Object* object;
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
- init_texture_object(objectIndex, (u8*)d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U, (u16) 0x00000040);
+ init_texture_object(objectIndex, (u8*) d_course_yoshi_valley_hedgehog_tlut, sHedgehogTexList, 0x40U,
+ (u16) 0x00000040);
object = &gObjectList[objectIndex];
object->activeTLUT = d_course_yoshi_valley_hedgehog_tlut;
object->activeTexture = d_course_yoshi_valley_hedgehog;
diff --git a/src/engine/objects/HotAirBalloon.cpp b/src/engine/objects/HotAirBalloon.cpp
index 4e337d98e..f1e367d8d 100644
--- a/src/engine/objects/HotAirBalloon.cpp
+++ b/src/engine/objects/HotAirBalloon.cpp
@@ -21,7 +21,7 @@ OHotAirBalloon::OHotAirBalloon(const FVector& pos) {
D_80165898 = 0;
// Spawn balloon on second lap.
- if (GetCourse() == GetLuigiRaceway()) {
+ if (IsLuigiRaceway()) {
_visible = (bool*)&D_80165898;
} else { // Spawn balloon on race start
bool mod = true;
diff --git a/src/engine/objects/Lakitu.cpp b/src/engine/objects/Lakitu.cpp
index 12ca2d7db..28159b7b3 100644
--- a/src/engine/objects/Lakitu.cpp
+++ b/src/engine/objects/Lakitu.cpp
@@ -2,6 +2,7 @@
#include <libultra/gbi.h>
#include "Lakitu.h"
#include <vector>
+#include "port/interpolation/FrameInterpolation.h"
#include "port/Game.h"
@@ -10,6 +11,7 @@ extern "C" {
#include "main.h"
#include "actors.h"
#include "math_util.h"
+#include "math_util_2.h"
#include "sounds.h"
#include "update_objects.h"
#include "render_player.h"
@@ -21,7 +23,6 @@ extern "C" {
#include "code_80057C60.h"
#include "defines.h"
#include "code_80005FD0.h"
-#include "math_util_2.h"
#include "collision.h"
#include "assets/bowsers_castle_data.h"
#include "ceremony_and_credits.h"
@@ -95,6 +96,8 @@ void OLakitu::Draw(s32 cameraId) {
s32 objectIndex;
Object* object;
+ FrameInterpolation_RecordOpenChild("Lakitu",(uintptr_t) this);
+
objectIndex = gIndexLakituList[cameraId];
camera = &camera1[cameraId];
if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) {
@@ -126,6 +129,7 @@ void OLakitu::Draw(s32 cameraId) {
}
}
}
+ FrameInterpolation_RecordCloseChild();
}
void OLakitu::func_80079114(s32 objectIndex, s32 playerId, s32 arg2) {
@@ -293,7 +297,7 @@ void OLakitu::func_800729EC(s32 objectIndex) {
D_8018D2BC = 1;
D_8018D2A4 = 1;
- if (GetCourse() != GetYoshiValley()) {
+ if (!IsYoshiValley()) {
for (i = 0; i < gPlayerCount; i++) {
playerHUD[i].unk_81 = temp_v1;
}
@@ -362,7 +366,7 @@ void OLakitu::func_800797AC(s32 playerId) {
objectIndex = gIndexLakituList[playerId];
player = &gPlayerOne[playerId];
- //if ((GetCourse() == GetSherbetLand()) && (player->unk_0CA & 1)) {
+ //if ((IsSherbetLand()) && (player->unk_0CA & 1)) {
if ((CM_GetProps()->LakituTowType == LakituTowType::ICE) && (player->unk_0CA & 1)) {
init_object(objectIndex, 7);
player->unk_0CA |= 0x10;
diff --git a/src/engine/objects/Mole.cpp b/src/engine/objects/Mole.cpp
index 06bd5f56c..f623b1f52 100644
--- a/src/engine/objects/Mole.cpp
+++ b/src/engine/objects/Mole.cpp
@@ -21,6 +21,7 @@ extern "C" {
#include "sounds.h"
#include "external.h"
}
+#include "port/interpolation/FrameInterpolation.h"
size_t OMole::_count = 0;
@@ -145,7 +146,7 @@ void OMole::func_80081AFC(s32 objectIndex, s32 arg1) {
// sp2C = D_8018D1B8;
// break;
// }
- //sp2C[object->type] = 0;
+ // sp2C[object->type] = 0;
}
break;
case 0:
@@ -179,20 +180,20 @@ void OMole::func_8008153C(s32 objectIndex) {
}
u8* mole = (u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt);
- init_object(loopObjectIndex, 0);
- 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] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8;
- gObjectList[loopObjectIndex].unk_034 = random_int(5U);
- 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];
- gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0;
- gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2];
- break;
- }
+ init_object(loopObjectIndex, 0);
+ 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] = (gObjectList[loopObjectIndex].velocity[1] * 0.1) + 4.8;
+ gObjectList[loopObjectIndex].unk_034 = random_int(5U);
+ 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];
+ gObjectList[loopObjectIndex].origin_pos[1] = gObjectList[objectIndex].origin_pos[1] - 13.0;
+ gObjectList[loopObjectIndex].origin_pos[2] = gObjectList[objectIndex].origin_pos[2];
+ break;
+ }
}
}
@@ -243,21 +244,15 @@ void OMole::func_80081D34(s32 objectIndex) {
}
static const char* frames[] = {
- gTextureMole1,
- gTextureMole2,
- gTextureMole3,
- gTextureMole4,
- gTextureMole5,
- gTextureMole6,
- gTextureMole7,
- d_course_moo_moo_farm_mole_dirt,
+ gTextureMole1, gTextureMole2, gTextureMole3, gTextureMole4,
+ gTextureMole5, gTextureMole6, gTextureMole7, d_course_moo_moo_farm_mole_dirt,
};
-
void OMole::func_80081848(s32 objectIndex) {
- init_texture_object(objectIndex, (u8*)d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U, (u16) 0x00000040);
- //gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames;
- //gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut;
+ init_texture_object(objectIndex, (u8*) d_course_moo_moo_farm_mole_tlut, (const char**) frames, 0x20U,
+ (u16) 0x00000040);
+ // gObjectList[objectIndex].activeTexture = (const char*)d_course_moo_moo_farm_mole_frames;
+ // gObjectList[objectIndex].activeTLUT = (const char*)d_course_moo_moo_farm_mole_tlut;
gObjectList[objectIndex].sizeScaling = 0.15f;
gObjectList[objectIndex].textureListIndex = 0;
@@ -270,7 +265,6 @@ void OMole::func_80081848(s32 objectIndex) {
object_next_state(objectIndex);
}
-
void OMole::func_80081924(s32 objectIndex) {
switch (gObjectList[objectIndex].unk_0AE) {
case 1:
@@ -307,7 +301,6 @@ void OMole::func_80081924(s32 objectIndex) {
}
}
-
void OMole::func_80081A88(s32 objectIndex) {
switch (gObjectList[objectIndex].unk_0DD) { /* irregular */
case 0:
@@ -330,9 +323,14 @@ void OMole::func_800821AC(s32 objectIndex, s32 arg1) {
}
}
+// Holes
void OMole::func_80054E10(s32 objectIndex) {
if (gObjectList[objectIndex].state > 0) {
if (is_obj_flag_status_active(objectIndex, 0x00800000) != 0) {
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("func_80054E10", TAG_OBJECT(&gObjectList[objectIndex]));
+
D_80183E50[0] = gObjectList[objectIndex].pos[0];
D_80183E50[1] = gObjectList[objectIndex].surfaceHeight + 0.8;
D_80183E50[2] = gObjectList[objectIndex].pos[2];
@@ -340,6 +338,9 @@ void OMole::func_80054E10(s32 objectIndex) {
D_80183E70[1] = gObjectList[objectIndex].velocity[1];
D_80183E70[2] = gObjectList[objectIndex].velocity[2];
func_8004A9B8(gObjectList[objectIndex].sizeScaling);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
@@ -348,8 +349,8 @@ void OMole::func_80054E10(s32 objectIndex) {
void OMole::func_80054EB8() {
s32 someIndex;
- //for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) {
- func_80054E10(_moleIndex);
+ // for (someIndex = 0; someIndex < NUM_TOTAL_MOLES; someIndex++) {
+ func_80054E10(_moleIndex);
//}
}
@@ -360,36 +361,52 @@ void OMole::func_80054D00(s32 objectIndex, s32 cameraId) {
if (gObjectList[objectIndex].state >= 3) {
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x0000012C);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("func_80054D00", (uintptr_t)&gObjectList[objectIndex]);
+
D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
func_80048130(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling,
- (u8*) gObjectList[objectIndex].activeTLUT, (u8*)gObjectList[objectIndex].activeTexture,
- (Vtx*)LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5);
+ (u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture,
+ (Vtx*) LOAD_ASSET_RAW(D_0D0062B0), 0x00000020, 0x00000040, 0x00000020, 0x00000040, 5);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
+// Mole rocks
void OMole::func_80054F04(s32 cameraId) {
Camera* camera = &camera1[cameraId];
- gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0079C8);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0079C8);
load_texture_block_rgba16_mirror((u8*) LOAD_ASSET_RAW(d_course_moo_moo_farm_mole_dirt), 0x00000010, 0x00000010);
-if (_idx == 0) {
- for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
- s32 objectIndex = gObjectParticle2[i];
- Object* object = &gObjectList[objectIndex];
- if (object->state > 0) {
- func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8);
- if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) && (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) {
- object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
- rsp_set_matrix_gObjectList(objectIndex);
- gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D006980);
+ if (_idx == 0) {
+ for (size_t i = 0; i < gObjectParticle2_SIZE; i++) {
+ s32 objectIndex = gObjectParticle2[i];
+ Object* object = &gObjectList[objectIndex];
+ if (object->state > 0) {
+ func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000000C8);
+ if ((is_obj_flag_status_active(objectIndex, VISIBLE) != 0) &&
+ (gMatrixHudCount <= MTX_HUD_POOL_SIZE_MAX)) {
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("func_80054F04", TAG_OBJECT(object) | (i << 32));
+
+ object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], camera->pos);
+ rsp_set_matrix_gObjectList(objectIndex);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D006980);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
+ }
}
}
}
-}
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
}
diff --git a/src/engine/objects/Snowman.cpp b/src/engine/objects/Snowman.cpp
index 12beb9e47..7cbfc691d 100644
--- a/src/engine/objects/Snowman.cpp
+++ b/src/engine/objects/Snowman.cpp
@@ -11,6 +11,7 @@ extern "C" {
#include "code_80086E70.h"
#include "code_80057C60.h"
}
+#include "port/interpolation/FrameInterpolation.h"
static const char* sSnowmanHeadList[] = { d_course_frappe_snowland_snowman_head };
@@ -27,7 +28,7 @@ OSnowman::OSnowman(const FVector& pos) {
gObjectList[_headIndex].origin_pos[0] = pos.x * xOrientation;
gObjectList[_headIndex].origin_pos[1] = pos.y + 5.0 + 3.0;
gObjectList[_headIndex].origin_pos[2] = pos.z;
- gObjectList[_headIndex].pos[0] = pos.x * xOrientation;
+ gObjectList[_headIndex].pos[0] = pos.x * xOrientation;
gObjectList[_headIndex].pos[1] = pos.y + 5.0 + 3.0;
gObjectList[_headIndex].pos[2] = pos.z;
@@ -38,7 +39,7 @@ OSnowman::OSnowman(const FVector& pos) {
gObjectList[_bodyIndex].origin_pos[2] = pos.z;
gObjectList[_bodyIndex].unk_0D5 = 0; // Section Id no longer used.
- gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation;
+ gObjectList[_bodyIndex].pos[0] = pos.x * xOrientation;
gObjectList[_bodyIndex].pos[1] = pos.y + 3.0;
gObjectList[_bodyIndex].pos[2] = pos.z;
@@ -71,14 +72,15 @@ void OSnowman::Tick() {
}
}
- //for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) {
+ // for (var_s0 = 0; var_s0 < NUM_SNOWMEN; var_s0++) {
var_s4 = _bodyIndex;
var_s3 = _headIndex;
OSnowman::func_80083A94(var_s3); // snowman head
OSnowman::func_80083C04(var_s4); // snowman body
if (is_obj_index_flag_status_inactive(var_s4, 0x00001000) != 0) {
object = &gObjectList[var_s4];
- if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) && (func_80089B50(var_s4) != 0)) {
+ if ((are_players_in_course_section(object->unk_0D5 - 1, object->unk_0D5 + 1) != 0) &&
+ (func_80089B50(var_s4) != 0)) {
set_object_flag(var_s4, 0x00001000);
clear_object_flag(var_s4, 0x00000010);
func_800726CC(var_s4, 0x0000000A);
@@ -93,6 +95,7 @@ void OSnowman::Tick() {
}
void OSnowman::Draw(s32 cameraId) {
+
OSnowman::DrawHead(cameraId);
OSnowman::DrawBody(cameraId);
}
@@ -117,23 +120,29 @@ void OSnowman::DrawHead(s32 cameraId) {
if (gObjectList[objectIndex].state >= 2) {
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x00000258);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("OSnowman::DrawHead", (uintptr_t) &gObjectList[objectIndex]);
+
D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
D_80183E80[1] =
func_800418AC(gObjectList[objectIndex].pos[0], gObjectList[objectIndex].pos[2], camera->pos);
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
if (is_obj_flag_status_active(objectIndex, 0x00000010) != 0) {
draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80,
- gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
- (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex,
- 0x00000040, 0x00000040, 0x00000040, 0x00000020);
+ gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
+ (u8*) gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex,
+ 0x00000040, 0x00000040, 0x00000040, 0x00000020);
}
objectIndex = _headIndex;
D_80183E80[0] = (s16) gObjectList[objectIndex].orientation[0];
D_80183E80[2] = (u16) gObjectList[objectIndex].orientation[2];
- draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80,
- gObjectList[objectIndex].sizeScaling, (u8*) gObjectList[objectIndex].activeTLUT,
- (u8*)gObjectList[objectIndex].activeTexture, gObjectList[objectIndex].vertex, 0x00000040,
- 0x00000040, 0x00000040, 0x00000020);
+ draw_2d_texture_at(gObjectList[objectIndex].pos, (u16*) D_80183E80, gObjectList[objectIndex].sizeScaling,
+ (u8*) gObjectList[objectIndex].activeTLUT, (u8*) gObjectList[objectIndex].activeTexture,
+ gObjectList[objectIndex].vertex, 0x00000040, 0x00000040, 0x00000040, 0x00000020);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
@@ -146,7 +155,8 @@ void OSnowman::DrawBody(s32 cameraId) {
Object* object;
sp44 = &camera1[cameraId];
- load_texture_and_tlut((u8*)d_course_frappe_snowland_snow_tlut, (u8*)d_course_frappe_snowland_snow, 0x00000020, 0x00000020);
+ load_texture_and_tlut((u8*) d_course_frappe_snowland_snow_tlut, (u8*) d_course_frappe_snowland_snow, 0x00000020,
+ 0x00000020);
//! @todo quick hack to add the snow particles on hit. Need to separate into its own class
if (_idx == 0) {
@@ -157,9 +167,16 @@ void OSnowman::DrawBody(s32 cameraId) {
if (object->state > 0) {
func_8008A364(objectIndex, cameraId, 0x2AABU, 0x000001F4);
if (is_obj_flag_status_active(objectIndex, VISIBLE) != 0) {
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("OSnowman::DrawBody", (uintptr_t) object);
+
object->orientation[1] = func_800418AC(object->pos[0], object->pos[2], sp44->pos);
rsp_set_matrix_gObjectList(objectIndex);
- gSPDisplayList(gDisplayListHead++, (Gfx*)D_0D0069E0);
+ gSPDisplayList(gDisplayListHead++, (Gfx*) D_0D0069E0);
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}
@@ -215,7 +232,8 @@ void OSnowman::func_80083BE4(s32 objectIndex) {
void OSnowman::func_80083868(s32 objectIndex) {
Object* object;
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(D_0D0061B0);
- init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanHeadList, 0x40U, (u16) 0x00000040);
+ init_texture_object(objectIndex, (u8*) d_course_frappe_snowland_snowman_tlut, (const char**) sSnowmanHeadList,
+ 0x40U, (u16) 0x00000040);
object = &gObjectList[objectIndex];
object->vertex = vtx;
object->sizeScaling = 0.1f;
@@ -259,7 +277,8 @@ void OSnowman::func_80083948(s32 objectIndex) {
break;
}
object_calculate_new_pos_offset(objectIndex);
- OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1, -1);
+ OSnowman::func_80073D0C(objectIndex, &gObjectList[objectIndex].primAlpha, -0x00001000, 0x00001000, 0x00000400, 1,
+ -1);
gObjectList[objectIndex].orientation[2] = gObjectList[objectIndex].primAlpha + 0x8000;
}
@@ -285,7 +304,8 @@ static const char* sSnowmanBodyList[] = { d_course_frappe_snowland_snowman_body
void OSnowman::func_80083B0C(s32 objectIndex) {
Vtx* vtx = (Vtx*) LOAD_ASSET_RAW(common_vtx_hedgehog);
- init_texture_object(objectIndex, (u8*)d_course_frappe_snowland_snowman_tlut, (const char**)sSnowmanBodyList, 0x40U, (u16) 0x00000040);
+ init_texture_object(objectIndex, (u8*) d_course_frappe_snowland_snowman_tlut, (const char**) sSnowmanBodyList,
+ 0x40U, (u16) 0x00000040);
gObjectList[objectIndex].vertex = vtx;
gObjectList[objectIndex].sizeScaling = 0.1f;
gObjectList[objectIndex].textureListIndex = 0;
@@ -299,16 +319,15 @@ void OSnowman::func_80083B0C(s32 objectIndex) {
set_object_flag(objectIndex, 0x04000210);
}
-
void OSnowman::func_80083538(s32 objectIndex, Vec3f arg1, s32 arg2, s32 arg3) {
Object* object;
init_object(objectIndex, 0);
object = &gObjectList[objectIndex];
- object->activeTexture = (const char*)d_course_frappe_snowland_snow;
- object->textureList = (const char**)d_course_frappe_snowland_snow;
+ object->activeTexture = (const char*) d_course_frappe_snowland_snow;
+ object->textureList = (const char**) d_course_frappe_snowland_snow;
object->activeTLUT = d_course_frappe_snowland_snow_tlut;
- object->tlutList = (u8*)d_course_frappe_snowland_snow_tlut;
+ object->tlutList = (u8*) d_course_frappe_snowland_snow_tlut;
object->sizeScaling = random_int(0x0064U);
object->sizeScaling = (object->sizeScaling * 0.001) + 0.05;
object->velocity[1] = random_int(0x0014U);
diff --git a/src/engine/objects/Thwomp.cpp b/src/engine/objects/Thwomp.cpp
index d3f99a8d9..9cee27c50 100644
--- a/src/engine/objects/Thwomp.cpp
+++ b/src/engine/objects/Thwomp.cpp
@@ -45,6 +45,7 @@ f32 D_800E594C[][2] = {
s16 D_800E597C[] = { 0x0000, 0x0000, 0x4000, 0x8000, 0x8000, 0xc000 };
size_t OThwomp::_count = 0;
+size_t OThwomp::_rand = 0;
OThwomp::OThwomp(s16 x, s16 z, s16 direction, f32 scale, s16 behaviour, s16 primAlpha, u16 boundingBoxSize) {
Name = "Thwomp";
@@ -88,6 +89,7 @@ void OThwomp::Tick60fps() { // func_80081210
if (_idx == 0) {
D_80165834[0] += 0x100;
D_80165834[1] += 0x200;
+ _rand += 1;
}
if (gObjectList[_objectIndex].state != 0) {
@@ -131,26 +133,26 @@ void OThwomp::Tick60fps() { // func_80081210
}
OThwomp::func_8007542C(3);
- if (func_80072320(_objectIndex, 0x00000020) == 0) {
- return;
+ if (func_80072320(_objectIndex, 0x00000020)) {
+ func_800722CC(_objectIndex, 0x00000020);
+ OThwomp::AddParticles(_objectIndex);
}
- func_800722CC(_objectIndex, 0x00000020);
- OThwomp::AddParticles(_objectIndex);
-
- for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) {
- objectIndex = gObjectParticle2[var_s4];
- if (objectIndex == DELETED_OBJECT_ID) {
- return;
- }
- if (gObjectList[objectIndex].state == 0) {
- return;
- }
- OThwomp::func_800810F4(objectIndex);
- if (gObjectList[objectIndex].state != 0) {
- return;
+ if (_idx == 0) {
+ for (var_s4 = 0; var_s4 < gObjectParticle2_SIZE; var_s4++) {
+ objectIndex = gObjectParticle2[var_s4];
+ if (objectIndex == DELETED_OBJECT_ID) {
+ continue;
+ }
+ if (gObjectList[objectIndex].state == 0) {
+ continue;
+ }
+ OThwomp::func_800810F4(objectIndex);
+ if (gObjectList[objectIndex].state != 0) {
+ continue;
+ }
+ delete_object_wrapper(&gObjectParticle2[var_s4]);
}
- delete_object_wrapper(&gObjectParticle2[var_s4]);
}
}
@@ -361,14 +363,16 @@ void OThwomp::func_8007F8D8() {
s32 OThwomp::func_8007F75C(s32 playerId) {
s32 someIndex;
- s32 temp_s7;
+ static s32 temp_s7 = 0; // Must be static to sync far travelling thwomp instances
s32 var_s6;
s32 waypoint;
waypoint = gNearestWaypointByPlayerId[playerId];
var_s6 = 0;
if ((waypoint >= 0xAA) && (waypoint < 0xB5)) {
- temp_s7 = random_int(0x0032U) + 0x32;
+ if (_idx == 0) {
+ temp_s7 = random_int(0x0032U) + 0x32;
+ }
if (gObjectList[_objectIndex].unk_0D5 == 3) {
var_s6 = 1;
OThwomp::func_8007F660(_objectIndex, playerId, temp_s7);
@@ -928,9 +932,9 @@ void OThwomp::func_8007FA08(s32 objectIndex) {
set_obj_origin_offset(objectIndex, 0.0f, 0.0f, 0.0f);
set_obj_direction_angle(objectIndex, 0U, 0U, 0U);
if (gIsMirrorMode != 0) {
- set_obj_orientation(objectIndex, 0U, 0xC000U, 0U);
+ set_obj_orientation(objectIndex, 0U, _faceDirection, 0U);
} else {
- set_obj_orientation(objectIndex, 0U, 0x4000U, 0U);
+ set_obj_orientation(objectIndex, 0U, -_faceDirection, 0U);
}
object->velocity[0] = 0.0f;
object->direction_angle[1] = object->orientation[1];
@@ -970,7 +974,7 @@ void OThwomp::func_8007FB48(s32 objectIndex) {
gObjectList[objectIndex].velocity[0] = player->unk_094 * xOrientation * 1.25;
if (gObjectList[objectIndex].unk_048 >= gObjectList[objectIndex].unk_0B0) {
if (gObjectList[objectIndex].unk_0B0 == gObjectList[objectIndex].unk_048) {
- if (D_8018D400 & 1) {
+ if (_rand & 1) { // D_8018D400 & 1
gObjectList[objectIndex].velocity[2] = 1.5f;
} else {
gObjectList[objectIndex].velocity[2] = -1.5f;
@@ -1169,9 +1173,9 @@ void OThwomp::func_800802C0(s32 objectIndex) {
object->offset[1] = 10.0f;
object->unk_01C[1] = 10.0f;
if (gIsMirrorMode != 0) {
- set_obj_orientation(objectIndex, 0U, 0x4000U, 0U);
+ set_obj_orientation(objectIndex, 0U, -_faceDirection, 0U);
} else {
- set_obj_orientation(objectIndex, 0U, 0xC000U, 0U);
+ set_obj_orientation(objectIndex, 0U, _faceDirection, 0U);
}
object->offset[0] = 0.0f;
object->offset[2] = 0.0f;
@@ -1195,7 +1199,7 @@ void OThwomp::SlidingBehaviour(s32 objectIndex) { // func_800808CC
OThwomp::func_8008085C(objectIndex);
func_80073514(objectIndex);
if (gGamestate != 9) {
- if ((D_8018D40C == 0) && (gObjectList[objectIndex].state == 2)) {
+ if (((_rand & 0x3F) == 0) && (gObjectList[objectIndex].state == 2)) { // D_8018D40C == 0 &&
func_800C98B8(gObjectList[objectIndex].pos, gObjectList[objectIndex].velocity,
SOUND_ARG_LOAD(0x19, 0x03, 0x60, 0x45));
}
diff --git a/src/engine/objects/Thwomp.h b/src/engine/objects/Thwomp.h
index 22c674bb5..647ef126a 100644
--- a/src/engine/objects/Thwomp.h
+++ b/src/engine/objects/Thwomp.h
@@ -112,6 +112,7 @@ public:
void func_8007E63C(s32 objectIndex);
private:
static size_t _count;
+ static size_t _rand;
s32 _idx;
s16 _faceDirection;
//! @todo Write this better. This effects the squish size and the bounding box size.
diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp
index c94d0352f..57c702275 100644
--- a/src/engine/objects/TrashBin.cpp
+++ b/src/engine/objects/TrashBin.cpp
@@ -3,6 +3,7 @@
#include "TrashBin.h"
#include "World.h"
#include "port/Game.h"
+#include "port/interpolation/FrameInterpolation.h"
extern "C" {
#include "main.h"
@@ -31,7 +32,7 @@ OTrashBin::OTrashBin(const FVector& pos, const IRotator& rotation, f32 scale, OT
init_object(_objectIndex, 0);
- if (GetCourse() != GetBansheeBoardwalk()) {
+ if (!IsBansheeBoardwalk()) {
_drawBin = true;
}
}
@@ -62,11 +63,18 @@ void OTrashBin::Draw(s32 cameraId) {
Mat4 mtx;
Vec3f Pos = { _pos.x + 63, _pos.y + 12, _pos.z + 25 };
Vec3s Rot = { 0, 0x4000, 0 };
+
+ // @port: Tag the transform.
+ FrameInterpolation_RecordOpenChild("OTrashBin", (uintptr_t) object);
+
mtxf_pos_rotation_xyz(mtx, Pos, Rot);
//mtxf_scale(mtx, 1.0f);
if (render_set_position(mtx, 0) != 0) {
gSPDisplayList(gDisplayListHead++, BinMod);
}
+
+ // @port Pop the transform id.
+ FrameInterpolation_RecordCloseChild();
}
}
}