From 77d69c5b00e822eb8253894a2efafe1fb3c90ca4 Mon Sep 17 00:00:00 2001 From: Archez Date: Wed, 27 Nov 2024 15:54:23 -0500 Subject: [PATCH 1/3] Various fixes for interpolation --- mm/src/code/z_actor.c | 20 ++++++++++------- mm/src/code/z_eff_blure.c | 1 + .../overlays/actors/ovl_Boss_02/z_boss_02.c | 22 +++++++++++++++---- .../overlays/actors/ovl_Boss_02/z_boss_02.h | 2 ++ .../overlays/actors/ovl_Boss_03/z_boss_03.c | 9 +++++--- .../overlays/actors/ovl_Boss_07/z_boss_07.c | 5 +++-- .../actors/ovl_Boss_Hakugin/z_boss_hakugin.c | 20 ++++++++--------- .../overlays/actors/ovl_Eff_Dust/z_eff_dust.c | 5 ++++- .../actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 17 +++++++------- .../overlays/actors/ovl_En_Death/z_en_death.c | 6 ++--- .../overlays/actors/ovl_En_Egol/z_en_egol.c | 6 +++-- mm/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 4 ++++ .../actors/ovl_En_Goroiwa/z_en_goroiwa.c | 15 +++++++++++++ .../actors/ovl_En_Tanron1/z_en_tanron1.c | 6 +++++ .../actors/ovl_En_Tanron5/z_en_tanron5.c | 2 ++ .../ovl_En_Water_Effect/z_en_water_effect.c | 11 ++++------ .../actors/ovl_Obj_Grass/z_obj_grass.c | 12 ++++------ .../ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c | 4 +++- 18 files changed, 110 insertions(+), 57 deletions(-) diff --git a/mm/src/code/z_actor.c b/mm/src/code/z_actor.c index b22f2e38fd..b3cf5f3a0a 100644 --- a/mm/src/code/z_actor.c +++ b/mm/src/code/z_actor.c @@ -131,6 +131,9 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, PlayState* play, Gfx* dlist, if ((dlist != gCircleShadowDL) || (actor->scale.x != actor->scale.z)) { Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); + } else { + // Mark non-rotating shadows to ignore the actor mtx prevents interpolation glitches when actor moves + FrameInterpolation_IgnoreActorMtx(); } shadowScale *= actor->shape.shadowScale; @@ -179,6 +182,9 @@ void ActorShadow_DrawFoot(PlayState* play, Light* light, MtxF* arg2, s32 lightNu OPEN_DISPS(play->state.gfxCtx); + // Ignore the players rotation prevents feet shadow from glitching when turning abruptly + FrameInterpolation_IgnoreActorMtx(); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (u8)(CLAMP_MAX(lightNum * 1.3e-05f, 1.0f) * shadowAlpha)); dir0 = light->l.dir[0]; @@ -5089,7 +5095,6 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] Vec3f* bodyPartsPosStart = bodyPartsPos; u32 gameplayFrames = play->gameplayFrames; f32 effectAlphaScaled; - static int effectEpoch = 0; currentMatrix = Matrix_GetCurrent(); @@ -5129,8 +5134,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] // Apply and draw ice over each body part of frozen actor for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) { - // BENTODO is using bodyPartsPos OK here? should actor be used instead? - FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++); + FrameInterpolation_RecordOpenChild(bodyPartsPos, type); alpha = bodyPartIndex & 3; alpha = effectAlphaScaled - (30.0f * alpha); if (effectAlphaScaled < (30.0f * (bodyPartIndex & 3))) { @@ -5177,7 +5181,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] // Apply and draw steam over each body part of frozen actor for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) { - FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++); + FrameInterpolation_RecordOpenChild(bodyPartsPos, type); twoTexScrollParam = ((bodyPartIndex * 3) + gameplayFrames); gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(play->state.gfxCtx, 0, twoTexScrollParam * 3, twoTexScrollParam * -12, @@ -5213,7 +5217,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] // Apply and draw fire on every body part for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) { - FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++); + FrameInterpolation_RecordOpenChild(bodyPartsPos, type); alpha = bodyPartIndex & 3; alpha = effectAlphaScaled - 30.0f * alpha; if (effectAlphaScaled < 30.0f * (bodyPartIndex & 3)) { @@ -5275,7 +5279,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] // Apply and draw a light orb over each body part of frozen actor for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) { - FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++); + FrameInterpolation_RecordOpenChild(bodyPartsPos, type); Matrix_RotateZF(Rand_CenteredFloat(2 * M_PI), MTXMODE_APPLY); currentMatrix->mf[3][0] = bodyPartsPos->x; currentMatrix->mf[3][1] = bodyPartsPos->y; @@ -5315,7 +5319,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] // Every body part draws two electric sparks at random orientations for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) { - FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++); + FrameInterpolation_RecordOpenChild(bodyPartsPos, type); // first electric spark Matrix_RotateXFApply(Rand_ZeroFloat(2 * M_PI)); Matrix_RotateZF(Rand_ZeroFloat(2 * M_PI), MTXMODE_APPLY); @@ -5344,7 +5348,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[] break; } - effectEpoch = 0; + CLOSE_DISPS(play->state.gfxCtx); } } diff --git a/mm/src/code/z_eff_blure.c b/mm/src/code/z_eff_blure.c index 77fb627f4b..e8b8659651 100644 --- a/mm/src/code/z_eff_blure.c +++ b/mm/src/code/z_eff_blure.c @@ -649,6 +649,7 @@ void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx) { interpolationEpoch++; OPEN_DISPS(gfxCtx); + // Force blure effects to never interpolate FrameInterpolation_RecordOpenChild(this, interpolationEpoch); if (this->numElements < 2) { diff --git a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 716c83c4a1..a202805cd6 100644 --- a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -11,6 +11,7 @@ #include "overlays/actors/ovl_En_Tanron5/z_en_tanron5.h" #include "overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h" #include "objects/gameplay_keep/gameplay_keep.h" + #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" #include "2s2h/GameInteractor/GameInteractor.h" @@ -533,6 +534,7 @@ void Boss02_SpawnEffectSand(TwinmoldEffect* effects, Vec3f* pos, f32 scale) { effects->timer = 0; effects->targetScale = 2.0f * scale; effects->accel.x = effects->accel.z = 0.0f; + effects->justSpawned = true; break; } } @@ -555,6 +557,7 @@ void Boss02_SpawnEffectFragment(TwinmoldEffect* effects, Vec3f* pos) { effects->scale = Rand_ZeroFloat(0.04f) + 0.02f; effects->rotY = Rand_ZeroFloat(32767.0f); effects->rotX = Rand_ZeroFloat(32767.0f); + effects->justSpawned = true; break; } } @@ -571,6 +574,7 @@ void Boss02_SpawnEffectFlash(TwinmoldEffect* effects, Vec3f* pos) { Math_Vec3f_Copy(&effects->accel, &gZeroVec3f); effects->alpha = 255; effects->scale = 0.0f; + effects->justSpawned = true; break; } } @@ -1569,7 +1573,10 @@ void Boss02_DrawEffects(PlayState* play) { for (i = 0; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_SAND) { - FrameInterpolation_RecordOpenChild(effect, i); + // Here and below, set a highbit for effects that just spawned to skip interoplating from an old effect + FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_IgnoreActorMtx(); + effect->justSpawned = false; if (!flag) { gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL); gDPSetEnvColor(POLY_XLU_DISP++, 185, 140, 70, 128); @@ -1600,7 +1607,9 @@ void Boss02_DrawEffects(PlayState* play) { effect = (TwinmoldEffect*)play->specialEffects; for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_FRAGMENT) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_IgnoreActorMtx(); + effect->justSpawned = false; if (!flag) { gDPSetCombineLERP(POLY_OPA_DISP++, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0); @@ -1623,7 +1632,9 @@ void Boss02_DrawEffects(PlayState* play) { effect = (TwinmoldEffect*)play->specialEffects; for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_FLASH) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_IgnoreActorMtx(); + effect->justSpawned = false; if (!flag) { //! @bug - dev forgot to set flag to 1, should only apply to first entry? gSPDisplayList(POLY_XLU_DISP++, gLightOrbMaterial1DL); gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); @@ -1645,7 +1656,9 @@ void Boss02_DrawEffects(PlayState* play) { effect = (TwinmoldEffect*)play->specialEffects; for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_BLACK_DUST) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_IgnoreActorMtx(); + effect->justSpawned = false; if (!flag) { gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL); gDPSetEnvColor(POLY_XLU_DISP++, 30, 30, 30, 128); @@ -2352,5 +2365,6 @@ void Boss02_Reset(void) { for (int i = 0; i < TWINMOLD_EFFECT_COUNT; i++) { sTwinmoldEffects[i].type = TWINMOLD_EFFECT_NONE; + sTwinmoldEffects[i].justSpawned = false; } } diff --git a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h index 41f373b522..37efa665b9 100644 --- a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h +++ b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h @@ -22,6 +22,8 @@ typedef struct { /* 0x30 */ s16 rotY; /* 0x34 */ f32 scale; /* 0x38 */ f32 targetScale; + // 2S2H [Port] + /* */ u8 justSpawned; // Tracks when an effect is spawned for use with interpolation skipping } TwinmoldEffect; // size = 0x3C typedef enum { diff --git a/mm/src/overlays/actors/ovl_Boss_03/z_boss_03.c b/mm/src/overlays/actors/ovl_Boss_03/z_boss_03.c index c0268bed55..1beac21bfb 100644 --- a/mm/src/overlays/actors/ovl_Boss_03/z_boss_03.c +++ b/mm/src/overlays/actors/ovl_Boss_03/z_boss_03.c @@ -2418,7 +2418,8 @@ void Boss03_DrawEffects(PlayState* play) { for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { if (eff->type == GYORG_EFFECT_BUBBLE) { - FrameInterpolation_RecordOpenChild(eff, i); + FrameInterpolation_RecordOpenChild(eff, eff->type); + FrameInterpolation_IgnoreActorMtx(); if (!flag) { gSPDisplayList(POLY_OPA_DISP++, gGyorgBubbleMaterialDL); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); @@ -2445,7 +2446,8 @@ void Boss03_DrawEffects(PlayState* play) { for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { if ((eff->type == GYORG_EFFECT_DROPLET) || (eff->type == GYORG_EFFECT_SPLASH)) { - FrameInterpolation_RecordOpenChild(eff, i); + FrameInterpolation_RecordOpenChild(eff, eff->type); + FrameInterpolation_IgnoreActorMtx(); if (!flag) { POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); @@ -2481,7 +2483,8 @@ void Boss03_DrawEffects(PlayState* play) { for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { if (eff->type == GYORG_EFFECT_WET_SPOT) { - FrameInterpolation_RecordOpenChild(eff, i); + FrameInterpolation_RecordOpenChild(eff, eff->type); + FrameInterpolation_IgnoreActorMtx(); if (!flag) { Gfx_SetupDL44_Xlu(gfxCtx); diff --git a/mm/src/overlays/actors/ovl_Boss_07/z_boss_07.c b/mm/src/overlays/actors/ovl_Boss_07/z_boss_07.c index 8648cfa5cf..29e7837440 100644 --- a/mm/src/overlays/actors/ovl_Boss_07/z_boss_07.c +++ b/mm/src/overlays/actors/ovl_Boss_07/z_boss_07.c @@ -11,7 +11,8 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_boss07/object_boss07.h" #include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h" -#include "BenPort.h" + +#include "2s2h/BenPort.h" #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -6080,7 +6081,7 @@ void Boss07_Static_DrawEffects(PlayState* play) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) { if (effect->type > MAJORAS_EFFECT_NONE) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 200, 20, 0, effect->alpha); gDPPipeSync(POLY_XLU_DISP++); gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128); diff --git a/mm/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c b/mm/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c index 7c6d30eb8a..403940f2ac 100644 --- a/mm/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c +++ b/mm/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c @@ -2653,27 +2653,27 @@ void func_80B0C398(BossHakugin* this, PlayState* play) { gSPDisplayList(POLY_OPA_DISP++, gGohtRockMaterialDL); for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { effect = &this->unk_09F8[i]; - FrameInterpolation_RecordOpenChild(effect, i); if ((effect->unk_18 >= 0) && (effect->unk_1A == 0)) { + FrameInterpolation_RecordOpenChild(effect, effect->unk_1A); Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, gGohtRockModelDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteMaterialDL); for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) { effect = &this->unk_09F8[i]; - FrameInterpolation_RecordOpenChild(effect, i); if ((effect->unk_18 >= 0) && (effect->unk_1A == 1)) { + FrameInterpolation_RecordOpenChild(effect, effect->unk_1A); Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C); Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteModelDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(play->state.gfxCtx); @@ -2696,8 +2696,8 @@ void func_80B0C570(BossHakugin* this, PlayState* play) { for (i = 0; i < ARRAY_COUNT(this->unk_3158); i++) { for (j = 0; j < ARRAY_COUNT(this->unk_3158[0]); j++) { iter = &this->unk_3158[i][j]; - FrameInterpolation_RecordOpenChild(iter, j); if (iter->unk_10 > 0) { + FrameInterpolation_RecordOpenChild(iter, j); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, iter->unk_10); gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(play->state.gfxCtx, 0, iter->unk_12 * 3, iter->unk_12 * 15, 32, 64, 1, 0, 0, @@ -2708,8 +2708,8 @@ void func_80B0C570(BossHakugin* this, PlayState* play) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamModelDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } } @@ -2776,8 +2776,8 @@ void func_80B0CAF0(BossHakugin* this, PlayState* play) { for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) { iter = &this->unk_2618[i]; - FrameInterpolation_RecordOpenChild(iter, i); if ((iter->unk_0C > 0) && (iter->unk_0C <= 255)) { + FrameInterpolation_RecordOpenChild(iter, i); Matrix_SetTranslateRotateYXZ(iter->unk_00.x, iter->unk_00.y, iter->unk_00.z, &iter->unk_0E); Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); @@ -2790,8 +2790,8 @@ void func_80B0CAF0(BossHakugin* this, PlayState* play) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gGohtLightningModelDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(play->state.gfxCtx); @@ -2832,7 +2832,7 @@ void func_80B0CCD8(BossHakugin* this, PlayState* play2) { for (; i >= end; i--) { pos = &this->unk_3734[i]; - FrameInterpolation_RecordOpenChild(this, i); + FrameInterpolation_RecordOpenChild(pos, 0); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, alpha); Matrix_Translate(pos->x, pos->y, pos->z, MTXMODE_NEW); Matrix_ReplaceRotation(&play->billboardMtxF); @@ -2840,11 +2840,11 @@ void func_80B0CCD8(BossHakugin* this, PlayState* play2) { Matrix_RotateZS(rotZ, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gGohtLightOrbModelDL); + FrameInterpolation_RecordCloseChild(); scale += 1.5f; alpha += 15; rotZ += 0x1000; - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(play->state.gfxCtx); diff --git a/mm/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c b/mm/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c index bd8533df4a..907a074582 100644 --- a/mm/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c +++ b/mm/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c @@ -7,6 +7,7 @@ #include "z_eff_dust.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "system_malloc.h" + #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -291,7 +292,7 @@ void func_80919768(Actor* thisx, PlayState* play2) { gSPSegment(POLY_XLU_DISP++, 0x08, D_80919DB0); for (i = 0; i < ARRAY_COUNT(this->distanceTraveled); i++) { - FrameInterpolation_RecordOpenChild(this, i); + FrameInterpolation_RecordOpenChild(distanceTraveled, i); if (*distanceTraveled < 1.0f) { aux = 1.0f - SQ(*distanceTraveled); Matrix_Translate(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, MTXMODE_NEW); @@ -349,6 +350,7 @@ void func_809199FC(Actor* thisx, PlayState* play2) { for (i = 0; i < ARRAY_COUNT(this->distanceTraveled); i++) { if (*distanceTraveled < 1.0f) { + FrameInterpolation_RecordOpenChild(distanceTraveled, i); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (*distanceTraveled * 255.0f)); aux = 1.0f - SQ(*distanceTraveled); @@ -367,6 +369,7 @@ void func_809199FC(Actor* thisx, PlayState* play2) { gSPDisplayList(POLY_XLU_DISP++, gEffSparklesDL); gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + FrameInterpolation_RecordCloseChild(); } initialPositions++; diff --git a/mm/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/mm/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index 906aa2d261..4c261ec8db 100644 --- a/mm/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/mm/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -6,6 +6,7 @@ #include "z_en_clear_tag.h" #include "objects/gameplay_keep/gameplay_keep.h" + #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -815,7 +816,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { // Draw all Debris effects. for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_DEBRIS) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Apply the debris effect material if it has not already been applied. if (!isMaterialApplied) { isMaterialApplied++; @@ -838,7 +839,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { if (this->actor.floorPoly != NULL) { for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_SHOCKWAVE) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Draw the shockwave effect. gDPPipeSync(POLY_XLU_DISP++); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, (s8)effect->primColor.a); @@ -859,7 +860,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { if (this->actor.floorPoly != NULL) { for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_FLASH) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Apply the flash ground effect material if it has not already been applied. if (!isMaterialApplied) { gDPPipeSync(POLY_XLU_DISP++); @@ -884,7 +885,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { isMaterialApplied = false; for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if ((effect->type == CLEAR_TAG_EFFECT_SMOKE) || (effect->type == CLEAR_TAG_EFFECT_ISOLATED_SMOKE)) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Apply the smoke effect material if it has not already been applied. if (!isMaterialApplied) { gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectMaterialDL); @@ -914,7 +915,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { isMaterialApplied = false; for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_FIRE) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Apply the fire effect material if it has not already been applied. if (!isMaterialApplied) { gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectMaterialDL); @@ -940,7 +941,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { isMaterialApplied = false; for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_FLASH) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Apply the flash billboard effect material if it has not already been applied. if (!isMaterialApplied) { gDPPipeSync(POLY_XLU_DISP++); @@ -964,7 +965,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { isMaterialApplied = false; for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_LIGHT_RAYS) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); // Apply the light ray effect material if it has not already been applied. if (!isMaterialApplied) { gDPPipeSync(POLY_XLU_DISP++); @@ -993,7 +994,7 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) { effect = firstEffect; for (i = 0; i < ARRAY_COUNT(this->effect); i++, effect++) { if (effect->type == CLEAR_TAG_EFFECT_SPLASH) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); gDPPipeSync(POLY_XLU_DISP++); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 200); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 200); diff --git a/mm/src/overlays/actors/ovl_En_Death/z_en_death.c b/mm/src/overlays/actors/ovl_En_Death/z_en_death.c index 447e080d62..3d54872d7a 100644 --- a/mm/src/overlays/actors/ovl_En_Death/z_en_death.c +++ b/mm/src/overlays/actors/ovl_En_Death/z_en_death.c @@ -1315,7 +1315,7 @@ void EnDeath_DrawScytheSpinning(EnDeath* this, PlayState* play) { dl = POLY_XLU_DISP; for (i = 1; i < this->numScytheAfterImages; i++) { - FrameInterpolation_RecordOpenChild(dl, 0); + FrameInterpolation_RecordOpenChild(this, i); gDPPipeSync(dl++); gDPSetEnvColor(dl++, 30, 30, 0, 255 - i * 35); @@ -1470,7 +1470,7 @@ void EnDeath_DrawBats(EnDeath* this, PlayState* play) { Matrix_Scale(phi_fs2, phi_fs2, phi_fs2, MTXMODE_APPLY); for (phi_s0 = miniDeath->unk_160, j = 0; j < ARRAY_COUNT(miniDeath->unk_160); j++, phi_s0++) { - FrameInterpolation_RecordOpenChild(dl, j); // Kinda out of options for what to pass into `a` + FrameInterpolation_RecordOpenChild(phi_s0, 2); cmf->mf[3][0] = miniDeath->actor.world.pos.x - phi_s0->unk_10.x; cmf->mf[3][1] = miniDeath->actor.world.pos.y + (20.0f - phi_s0->unk_10.y); cmf->mf[3][2] = miniDeath->actor.world.pos.z - phi_s0->unk_10.z; @@ -1559,7 +1559,7 @@ void EnDeath_DrawFlames(EnDeath* this, PlayState* play2) { effect = this->miniDeaths[i]->unk_160; for (j = 0; j < ARRAY_COUNT(this->miniDeaths[i]->unk_160); j++, effect++) { - FrameInterpolation_RecordOpenChild(POLY_XLU_DISP, j); + FrameInterpolation_RecordOpenChild(effect, 3); cmf->mf[3][0] = effect->unk_4.x; cmf->mf[3][1] = effect->unk_4.y - 12.0f; cmf->mf[3][2] = effect->unk_4.z; diff --git a/mm/src/overlays/actors/ovl_En_Egol/z_en_egol.c b/mm/src/overlays/actors/ovl_En_Egol/z_en_egol.c index bd80a27eb9..ae8021d948 100644 --- a/mm/src/overlays/actors/ovl_En_Egol/z_en_egol.c +++ b/mm/src/overlays/actors/ovl_En_Egol/z_en_egol.c @@ -11,6 +11,7 @@ #include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h" #include "overlays/actors/ovl_En_Estone/z_en_estone.h" #include "overlays/effects/ovl_Effect_Ss_Hitmark/z_eff_ss_hitmark.h" + #include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_80000000) @@ -1516,7 +1517,7 @@ void EnEgol_Draw(Actor* thisx, PlayState* play2) { laserLightScaleMod = 10.0f; laserLightAlpha = 80.0f; for (i = 0; i < ARRAY_COUNT(sLightOrbColors); i++) { - FrameInterpolation_RecordOpenChild(this, i); + FrameInterpolation_RecordOpenChild(&sLightOrbColors[i], i); Matrix_Push(); Matrix_Scale(laserLightScaleMod, laserLightScaleMod, laserLightScaleMod, MTXMODE_APPLY); Matrix_ReplaceRotation(&play->billboardMtxF); @@ -1630,7 +1631,8 @@ void EnEgol_DrawEffects(EnEgol* this, PlayState* play) { Gfx_SetupDL25_Opa(play->state.gfxCtx); for (i = 0; i < ARRAY_COUNT(this->effects); i++, effect++) { if (effect->isActive) { - FrameInterpolation_RecordOpenChild(effect, i); + FrameInterpolation_RecordOpenChild(effect, effect->type); + FrameInterpolation_IgnoreActorMtx(); Matrix_Push(); Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); diff --git a/mm/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/mm/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 75b5875339..2f5c5495d7 100644 --- a/mm/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/mm/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -11,6 +11,8 @@ #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "objects/gameplay_keep/gameplay_keep.h" +#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" + #define FLAGS \ (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_2000000 | ACTOR_FLAG_CANT_LOCK_ON) @@ -1490,6 +1492,7 @@ void func_80964950(PlayState* play, EnFuUnkStruct* ptr, s32 len) { for (i = 0; i < len; i++, ptr++) { if (ptr->unk_36 == 1) { + FrameInterpolation_RecordOpenChild(ptr, i); if (!flag) { gSPDisplayList(POLY_OPA_DISP++, gHoneyAndDarlingHeartMaterialDL); flag = true; @@ -1501,6 +1504,7 @@ void func_80964950(PlayState* play, EnFuUnkStruct* ptr, s32 len) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(gDropRecoveryHeartTex)); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, gHoneyAndDarlingHeartModelDL); + FrameInterpolation_RecordCloseChild(); } } diff --git a/mm/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c b/mm/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c index 2abb6784e9..47f5918381 100644 --- a/mm/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c +++ b/mm/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c @@ -9,6 +9,8 @@ #include "objects/object_goroiwa/object_goroiwa.h" #include "objects/gameplay_keep/gameplay_keep.h" +#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" + #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnGoroiwa*)thisx) @@ -1607,9 +1609,22 @@ void EnGoroiwa_Draw(Actor* thisx, PlayState* play) { EnGoroiwa* this = THIS; s32 params = ENGOROIWA_GET_C000(&this->actor); + // #region 2S2H [Interpolation] Track when a boulder resets back to its "home" position and mark + // interpolation to be skipped that frame + bool boulderReset = false; + s32 params300 = ENGOROIWA_GET_300(&this->actor); + if (((params300 == ENGOROIWA_300_0) || (params300 == ENGOROIWA_300_1)) && + ((this->unk_1D6 == 0) || (this->unk_1D6 == this->unk_1D4))) { + boulderReset = true; + } + // #endregion + if (this->actionFunc == func_8094220C) { func_80942B1C(this, play); } else if (this->actionFunc != func_80942604) { + FrameInterpolation_RecordOpenChild(this, boulderReset ? 1 : 0); + FrameInterpolation_IgnoreActorMtx(); Gfx_DrawDListOpa(play, D_80942EB4[params]); + FrameInterpolation_RecordCloseChild(); } } diff --git a/mm/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c b/mm/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c index 18a674a8a7..858c4476ae 100644 --- a/mm/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c +++ b/mm/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c @@ -6,6 +6,8 @@ #include "z_en_tanron1.h" +#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTanron1*)thisx) @@ -373,6 +375,7 @@ void func_80BB5AAC(EnTanron1* this, PlayState* play) { for (i = 0; i < this->actor.params; i++, ptr++) { if (ptr->unk_24 == 1) { + FrameInterpolation_RecordOpenChild(ptr, ptr->unk_24); if (!flag) { gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001888); flag++; @@ -384,6 +387,7 @@ void func_80BB5AAC(EnTanron1* this, PlayState* play) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001900); + FrameInterpolation_RecordCloseChild(); } } @@ -391,6 +395,7 @@ void func_80BB5AAC(EnTanron1* this, PlayState* play) { ptr = ptrBase; for (i = 0; i < this->actor.params; i++, ptr++) { if (ptr->unk_24 == 2) { + FrameInterpolation_RecordOpenChild(ptr, ptr->unk_24); if (!flag) { gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001888); gDPLoadTextureBlock(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001428, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 32, 0, @@ -406,6 +411,7 @@ void func_80BB5AAC(EnTanron1* this, PlayState* play) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001900); + FrameInterpolation_RecordCloseChild(); } } diff --git a/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c b/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c index f1ab9dc492..e978361df3 100644 --- a/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c +++ b/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c @@ -182,6 +182,7 @@ void EnTanron5_SpawnEffectSand(TwinmoldEffect* effect, Vec3f* pos, f32 scale) { effect->timer = 0; effect->scale = scale; effect->targetScale = 2.0f * scale; + effect->justSpawned = true; break; } } @@ -206,6 +207,7 @@ void EnTanron5_SpawnEffectBlackDust(TwinmoldEffect* effect, Vec3f* pos, f32 scal effect->timer = 0; effect->scale = scale; effect->targetScale = 2.0f * scale; + effect->justSpawned = true; break; } } diff --git a/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c b/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c index fbbd2f3778..2ae9964bf2 100644 --- a/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c +++ b/mm/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c @@ -46,7 +46,6 @@ ActorInit En_Water_Effect_InitVars = { static Vec3f D_80A5AFB0 = { 0.0f, 0.0f, 0.0f }; static Vec3f D_80A5AFBC = { 0.0f, -1.0f, 0.0f }; -static uint32_t epoch = 0; void func_80A587A0(EnWaterEffect* this, Vec3f* arg1, u8 arg2) { s16 i; @@ -178,7 +177,6 @@ void EnWaterEffect_Update(Actor* thisx, PlayState* play2) { for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { if (ptr->unk_00 != 0) { - FrameInterpolation_RecordOpenChild(ptr, i); ptr->unk_01++; ptr->unk_04.x += ptr->unk_10.x; @@ -277,7 +275,6 @@ void EnWaterEffect_Update(Actor* thisx, PlayState* play2) { ptr->unk_00 = 0; } } - FrameInterpolation_RecordCloseChild(); } } } @@ -298,7 +295,7 @@ void EnWaterEffect_Draw(Actor* thisx, PlayState* play2) { for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { if ((ptr->unk_00 == 1) || (ptr->unk_00 == 2)) { - FrameInterpolation_RecordOpenChild(ptr, epoch++); + FrameInterpolation_RecordOpenChild(ptr, ptr->unk_00); if (!phi_s4) { POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0); @@ -332,7 +329,7 @@ void EnWaterEffect_Draw(Actor* thisx, PlayState* play2) { for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { if (ptr->unk_00 == 3) { - FrameInterpolation_RecordOpenChild(ptr, i); + FrameInterpolation_RecordOpenChild(ptr, ptr->unk_00); if (!phi_s4) { Gfx_SetupDL44_Xlu(gfxCtx); @@ -538,7 +535,7 @@ void func_80A5A184(Actor* thisx, PlayState* play2) { for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) { if (ptr->unk_00 == 4) { - FrameInterpolation_RecordOpenChild(ptr, epoch++); + FrameInterpolation_RecordOpenChild(ptr, ptr->unk_00); if (!flag) { gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004340); gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, 0); @@ -707,7 +704,7 @@ void func_80A5A6B8(Actor* thisx, PlayState* play2) { for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { if (ptr->unk_00 == 3) { - FrameInterpolation_RecordOpenChild(ptr, epoch++); + FrameInterpolation_RecordOpenChild(ptr, ptr->unk_00); if (!phi_s4) { Gfx_SetupDL44_Xlu(play->state.gfxCtx); diff --git a/mm/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c b/mm/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c index 8cf7e55d8a..2fa6ca192a 100644 --- a/mm/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c +++ b/mm/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c @@ -467,9 +467,8 @@ void ObjGrass_DrawOpa(Actor* thisx, PlayState* play2) { for (j = 0; j < grassGroup->count; j++) { grassElem = &grassGroup->elements[j]; - FrameInterpolation_RecordOpenChild(grassGroup, i + j); - if ((grassElem->flags & OBJ_GRASS_ELEM_DRAW) && (grassElem->alpha == 255)) { + FrameInterpolation_RecordOpenChild(grassElem, 0); rot.y = grassElem->rotY; Matrix_SetTranslateRotateYXZ(grassElem->pos.x, grassElem->pos.y, grassElem->pos.z, &rot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); @@ -480,9 +479,8 @@ void ObjGrass_DrawOpa(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AAAE0); + FrameInterpolation_RecordCloseChild(); } - - FrameInterpolation_RecordCloseChild(); } } } @@ -511,9 +509,8 @@ void ObjGrass_DrawXlu(Actor* thisx, PlayState* play) { for (j = 0; j < grassGroup->count; j++) { grassElem = &grassGroup->elements[j]; - FrameInterpolation_RecordOpenChild(grassGroup, i + j); - if ((grassElem->flags & OBJ_GRASS_ELEM_DRAW) && (grassElem->alpha > 0) && (grassElem->alpha < 255)) { + FrameInterpolation_RecordOpenChild(grassElem, 0); rot.y = grassElem->rotY; Matrix_SetTranslateRotateYXZ(grassElem->pos.x, grassElem->pos.y, grassElem->pos.z, &rot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); @@ -522,9 +519,8 @@ void ObjGrass_DrawXlu(Actor* thisx, PlayState* play) { G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, grassElem->alpha); gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAAE0); + FrameInterpolation_RecordCloseChild(); } - - FrameInterpolation_RecordCloseChild(); } } } diff --git a/mm/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c b/mm/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c index 4cc8ee9ccb..ffa31ef4ef 100644 --- a/mm/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c +++ b/mm/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c @@ -672,11 +672,13 @@ void ObjHugebombiwa_Draw(Actor* thisx, PlayState* play) { ptr = &this->unk_190[i]; if (ptr->unk_24 == 0) { + FrameInterpolation_RecordOpenChild(ptr, i); Matrix_SetTranslateRotateYXZ(ptr->unk_0C.x, ptr->unk_0C.y, ptr->unk_0C.z, &ptr->unk_1C); Matrix_Scale(ptr->unk_00.x, ptr->unk_00.x, ptr->unk_00.x, MTXMODE_APPLY); gSPMatrix(gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(gfx++, object_bombiwa_DL_001990); + FrameInterpolation_RecordCloseChild(); } } @@ -709,8 +711,8 @@ void func_80A55B34(Actor* thisx, PlayState* play) { if (ptr->unk_24 != 0) { continue; } - FrameInterpolation_RecordOpenChild(this, i); + FrameInterpolation_RecordOpenChild(ptr, i); Matrix_SetTranslateRotateYXZ(ptr->unk_0C.x, ptr->unk_0C.y + (325.0f * ptr->unk_00.y), ptr->unk_0C.z, &ptr->unk_1C); Matrix_Scale(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_APPLY); From e7bd18a652276e24a0564f1907f23df3a2d5f501 Mon Sep 17 00:00:00 2001 From: Archez Date: Thu, 28 Nov 2024 09:37:20 -0500 Subject: [PATCH 2/3] fix interpolation for kankyo particles and effects --- .../actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 34 ++++++++++++++--- .../actors/ovl_Demo_Kankyo/z_demo_kankyo.h | 2 + .../ovl_Object_Kankyo/z_object_kankyo.c | 38 ++++++++++++++----- .../ovl_Object_Kankyo/z_object_kankyo.h | 2 + 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 1728f29805..6af0792c61 100644 --- a/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -272,6 +272,9 @@ void DemoKakyo_LostWoodsSparkleActionFunc(DemoKankyo* this, PlayState* play) { this->effects[i].posOffset.z = 0.0f; this->effects[i].posBase.z = posCenterZ + repositionLimit; } + + // 2S2H [Interpolation] Skip particle interpolation on next frame + this->effects[i].epoch++; } break; @@ -396,10 +399,17 @@ void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, PlayState* play) { } if (((this->effects[i].posBase.x + this->effects[i].posOffset.x) - newEye.x) > halfScreenHeight) { + // 2S2H [Interpolation] Here and below, skip particle interpolation on next frame when positionmoves + if (ABS(this->effects[i].posBase.x - (newEye.x - halfScreenHeight)) >= 120.0f) { + this->effects[i].epoch++; + } this->effects[i].posBase.x = newEye.x - halfScreenHeight; } if (((this->effects[i].posBase.x + this->effects[i].posOffset.x) - newEye.x) < -halfScreenHeight) { + if (ABS(this->effects[i].posBase.x - (newEye.x + halfScreenHeight)) >= 120.0f) { + this->effects[i].epoch++; + } this->effects[i].posBase.x = newEye.x + halfScreenHeight; } @@ -413,18 +423,30 @@ void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, PlayState* play) { // I think this code is shifting the effects 1 frame -> half screen at a time to keep it in-view if (halfScreenWidth < ((this->effects[i].posBase.y + this->effects[i].posOffset.y) - newEye.y)) { + if (ABS(this->effects[i].posBase.y - (newEye.y - halfScreenWidth)) >= 120.0f) { + this->effects[i].epoch++; + } this->effects[i].posBase.y = newEye.y - halfScreenWidth; } if (((this->effects[i].posBase.y + this->effects[i].posOffset.y) - newEye.y) < -halfScreenWidth) { + if (ABS(this->effects[i].posBase.y - (newEye.y + halfScreenWidth)) >= 120.0f) { + this->effects[i].epoch++; + } this->effects[i].posBase.y = newEye.y + halfScreenWidth; } if (((this->effects[i].posBase.z + this->effects[i].posOffset.z) - newEye.z) > halfScreenHeight) { + if (ABS(this->effects[i].posBase.z - (newEye.z - halfScreenHeight)) >= 120.0f) { + this->effects[i].epoch++; + } this->effects[i].posBase.z = newEye.z - halfScreenHeight; } if (((this->effects[i].posBase.z + this->effects[i].posOffset.z) - newEye.z) < -halfScreenHeight) { + if (ABS(this->effects[i].posBase.z - (newEye.z + halfScreenHeight)) >= 120.0f) { + this->effects[i].epoch++; + } this->effects[i].posBase.z = newEye.z + halfScreenHeight; } @@ -516,7 +538,6 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) { gSPDisplayList(POLY_XLU_DISP++, gSunSparkleMaterialDL); for (i = 0; i < play->envCtx.precipitation[PRECIP_SNOW_MAX]; i++) { - FrameInterpolation_RecordOpenChild(this, i); worldPos.x = this->effects[i].posBase.x + this->effects[i].posOffset.x; worldPos.y = this->effects[i].posBase.y + this->effects[i].posOffset.y; worldPos.z = this->effects[i].posBase.z + this->effects[i].posOffset.z; @@ -530,11 +551,12 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) { xMin = OTRGetDimensionFromLeftEdge(xMin); xMax = OTRGetDimensionFromRightEdge(xMax); } - // #pragma endregion + // #endregion // checking if particle is on screen if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) && (screenPos.y < SCREEN_HEIGHT)) { + FrameInterpolation_RecordOpenChild(&this->effects[i], this->effects[i].epoch); Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW); scaleAlpha = this->effects[i].alpha / 50.0f; if (scaleAlpha > 1.0f) { @@ -591,8 +613,8 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gSunSparkleModelDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(play->state.gfxCtx); @@ -617,7 +639,6 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) { Gfx_SetupDL25_Xlu(gfxCtx); for (i = 0; i < play->envCtx.precipitation[PRECIP_SNOW_MAX]; i++) { - FrameInterpolation_RecordOpenChild(this, i); worldPos.x = this->effects[i].posBase.x + this->effects[i].posOffset.x; worldPos.y = this->effects[i].posBase.y + this->effects[i].posOffset.y; worldPos.z = this->effects[i].posBase.z + this->effects[i].posOffset.z; @@ -631,11 +652,12 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) { xMin = OTRGetDimensionFromLeftEdge(xMin); xMax = OTRGetDimensionFromRightEdge(xMax); } - // #pragma endregion + // #endregion // checking if effect is on screen if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) && (screenPos.y < SCREEN_HEIGHT)) { + FrameInterpolation_RecordOpenChild(&this->effects[i], this->effects[i].epoch); Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW); alphaScale = this->effects[i].alpha / 50.0f; if (alphaScale > 1.0f) { @@ -680,8 +702,8 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, PlayState* play2) { } else { gSPDisplayList(POLY_XLU_DISP++, gLightOrbModelDL); } + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(gfxCtx); diff --git a/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h b/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h index 6142796ce4..29b79571f4 100644 --- a/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h +++ b/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h @@ -23,6 +23,8 @@ typedef struct { /* 0x4A */ u16 LostWoodsSkyFishPosOffsetMax; // The x-z range the lost woods skyfish oscillates around player. random value between 15-65 /* 0x4C */ f32 LostWoodsSkyFishSpeedY; // the y speed (angular velocity) the lost woods skyfish oscillates around player. /* 0x50 */ u16 pad50; // unused, always assigned to 0, nothing else in this actor uses it + // 2S2H [Port] + /* */ s16 epoch; // Tracks when an effect is reset for use with interpolation skipping } DemoKankyoEffect; // size = 0x54 #define DEMOKANKYO_EFFECT_COUNT 64 diff --git a/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 951419e06a..71bbc75fcd 100644 --- a/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -245,6 +245,7 @@ void func_808DC454(ObjectKankyo* this, PlayState* play) { this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 8.0f; } this->unk_14C[i].unk_1C++; + this->unk_14C[i].epoch++; break; case 1: @@ -280,10 +281,12 @@ void func_808DC454(ObjectKankyo* this, PlayState* play) { if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) > temp_120) { this->unk_14C[i].unk_00 = temp_f24 - temp_120; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) < -temp_120) { this->unk_14C[i].unk_00 = temp_f24 + temp_120; + this->unk_14C[i].epoch++; } sp88.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; @@ -296,18 +299,22 @@ void func_808DC454(ObjectKankyo* this, PlayState* play) { if (temp_f0_4 < (this->unk_14C[i].unk_04 + (this->unk_14C[i].unk_10) - temp_f28)) { this->unk_14C[i].unk_04 = temp_f28 - temp_f0_4; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_f0_4) { this->unk_14C[i].unk_04 = temp_f28 + temp_f0_4; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) > temp_120) { this->unk_14C[i].unk_08 = temp_f30 - temp_120; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) < -temp_120) { this->unk_14C[i].unk_08 = temp_f30 + temp_120; + this->unk_14C[i].epoch++; } if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) < ((play->view.eye.y - temp_f22) - 40.0f)) { @@ -406,6 +413,7 @@ void func_808DCDB4(ObjectKankyo* this, PlayState* play) { this->unk_14C[i].unk_14 = (Rand_ZeroOne() - 0.5f) * (temp_120 * 2.0f); this->unk_14C[i].unk_18 = Rand_ZeroOne() + 0.2f; this->unk_14C[i].unk_1C++; + this->unk_14C[i].epoch++; break; case 1: @@ -447,26 +455,32 @@ void func_808DCDB4(ObjectKankyo* this, PlayState* play) { if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) > temp_80) { this->unk_14C[i].unk_00 = temp_f26 - temp_80; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) < -temp_80) { this->unk_14C[i].unk_00 = temp_f26 + temp_80; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) > temp_80) { this->unk_14C[i].unk_04 = temp_f28 - temp_80; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_80) { this->unk_14C[i].unk_04 = temp_f28 + temp_80; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f18) > temp_80) { this->unk_14C[i].unk_08 = temp_f18 - temp_80; + this->unk_14C[i].epoch++; } if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f18) < -temp_80) { this->unk_14C[i].unk_08 = temp_f18 + temp_80; + this->unk_14C[i].epoch++; } break; } @@ -541,7 +555,7 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) { worldPos.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; worldPos.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; worldPos.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; - FrameInterpolation_RecordOpenChild(this, i); + Play_GetScreenPos(play, &worldPos, &screenPos); // #region 2S2H [Cosmetic] Increase snow render area for widescreen @@ -551,9 +565,10 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) { xMin = OTRGetDimensionFromLeftEdge(xMin); xMax = OTRGetDimensionFromRightEdge(xMax); } - // #pragma endregion + // #endregion if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) && (screenPos.y < SCREEN_HEIGHT)) { + FrameInterpolation_RecordOpenChild(&this->unk_14C[i], this->unk_14C[i].epoch); if (!spB4) { spB4 = true; @@ -573,6 +588,7 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) { Matrix_Scale(0.05f + tempf, 0.05f + tempf, 0.05f + tempf, MTXMODE_APPLY); temp_f2 = Math_Vec3f_DistXYZ(&worldPos, &play->view.eye) / 300.0f; temp_f2 = ((1.0f < temp_f2) ? 0.0f : (((1.0f - temp_f2) > 1.0f) ? 1.0f : 1.0f - temp_f2)); + temp_f2 = 1.59375f; gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(160.0f * temp_f2)); @@ -581,8 +597,8 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gEffDustDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(play->state.gfxCtx); @@ -624,7 +640,7 @@ void func_808DD970(Actor* thisx, PlayState* play2) { worldPos.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; worldPos.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; worldPos.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; - FrameInterpolation_RecordOpenChild(this, i); + Play_GetScreenPos(play, &worldPos, &screenPos); // #region 2S2H [Cosmetic] Increase deep underwater dust render area for widescreen @@ -634,13 +650,15 @@ void func_808DD970(Actor* thisx, PlayState* play2) { xMin = OTRGetDimensionFromLeftEdge(xMin); xMax = OTRGetDimensionFromRightEdge(xMax); } - // #pragma endregion + // #endregion if ((screenPos.x >= xMin) && (screenPos.x < xMax) && (screenPos.y >= 0.0f) && (screenPos.y < SCREEN_HEIGHT)) { + FrameInterpolation_RecordOpenChild(&this->unk_14C[i], this->unk_14C[i].epoch); Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW); Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY); temp_f0 = Math_Vec3f_DistXYZ(&worldPos, &play->view.eye); temp_f0 = (u8)(255.0f * phi_f26) * (1.0f - (temp_f0 / 300.0f)); + temp_f0 = 255; gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 55, temp_f0); @@ -657,8 +675,8 @@ void func_808DD970(Actor* thisx, PlayState* play2) { gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2); gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG); gSPDisplayList(POLY_XLU_DISP++, gEffDustDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } CLOSE_DISPS(play->state.gfxCtx); @@ -693,8 +711,8 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) { temp_f22 = this->unk_14C[0].unk_04 + ((Rand_ZeroOne() - 0.7f) * this->unk_144); temp_f2 = this->unk_14C[0].unk_08 + ((Rand_ZeroOne() - 0.7f) * this->unk_144); - FrameInterpolation_RecordOpenChild(this, i); if (!((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f))) { + FrameInterpolation_RecordOpenChild(this, i); Matrix_Translate(temp_f20, temp_f22, temp_f2, MTXMODE_NEW); gSPMatrix(POLY_XLU_DISP++, D_01000000_TO_SEGMENTED, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); @@ -710,14 +728,13 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gFallingRainDropDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } phi_s5 = false; if (player->actor.floorHeight < play->view.eye.y) { for (i = 0; i < end; i++) { - FrameInterpolation_RecordOpenChild(this, i + end); if (!phi_s5) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); @@ -731,6 +748,7 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) { temp_f2 = this->unk_14C[1].unk_08 + (func_808DDE74() * 220.0f); if (!((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f))) { + FrameInterpolation_RecordOpenChild(this, i + end); Matrix_Translate(temp_f20, temp_f22, temp_f2, MTXMODE_NEW); temp_f12 = (Rand_ZeroOne() * 0.05f) + 0.05f; Matrix_Scale(temp_f12, temp_f12, temp_f12, MTXMODE_APPLY); @@ -738,8 +756,8 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL); + FrameInterpolation_RecordCloseChild(); } - FrameInterpolation_RecordCloseChild(); } } diff --git a/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h b/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h index 8dc8d4d85a..c3df4b89c6 100644 --- a/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h +++ b/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h @@ -16,6 +16,8 @@ typedef struct { /* 0x14 */ f32 unk_14; /* 0x18 */ f32 unk_18; /* 0x1C */ u8 unk_1C; + // 2S2H [Port] + /* */ s16 epoch; // Tracks when an effect is reset for use with interpolation skipping } ObjectKankyoStruct; // size = 0x20 typedef struct ObjectKankyo { From 5defbcce0ca19fdfbf5e7541de63080e44b0ccbe Mon Sep 17 00:00:00 2001 From: Archez Date: Thu, 28 Nov 2024 14:30:15 -0500 Subject: [PATCH 3/3] update twinmold effect tracking --- .../overlays/actors/ovl_Boss_02/z_boss_02.c | 22 ++++++++----------- .../overlays/actors/ovl_Boss_02/z_boss_02.h | 2 +- .../actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 2 +- .../actors/ovl_En_Tanron5/z_en_tanron5.c | 4 ++-- .../ovl_Object_Kankyo/z_object_kankyo.c | 4 ++-- 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c index a202805cd6..5a9194a8cd 100644 --- a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -534,7 +534,7 @@ void Boss02_SpawnEffectSand(TwinmoldEffect* effects, Vec3f* pos, f32 scale) { effects->timer = 0; effects->targetScale = 2.0f * scale; effects->accel.x = effects->accel.z = 0.0f; - effects->justSpawned = true; + effects->epoch++; break; } } @@ -557,7 +557,7 @@ void Boss02_SpawnEffectFragment(TwinmoldEffect* effects, Vec3f* pos) { effects->scale = Rand_ZeroFloat(0.04f) + 0.02f; effects->rotY = Rand_ZeroFloat(32767.0f); effects->rotX = Rand_ZeroFloat(32767.0f); - effects->justSpawned = true; + effects->epoch++; break; } } @@ -574,7 +574,7 @@ void Boss02_SpawnEffectFlash(TwinmoldEffect* effects, Vec3f* pos) { Math_Vec3f_Copy(&effects->accel, &gZeroVec3f); effects->alpha = 255; effects->scale = 0.0f; - effects->justSpawned = true; + effects->epoch++; break; } } @@ -1573,10 +1573,9 @@ void Boss02_DrawEffects(PlayState* play) { for (i = 0; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_SAND) { - // Here and below, set a highbit for effects that just spawned to skip interoplating from an old effect - FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + // Here and below, key by effect type merged with epoch + FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type); FrameInterpolation_IgnoreActorMtx(); - effect->justSpawned = false; if (!flag) { gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL); gDPSetEnvColor(POLY_XLU_DISP++, 185, 140, 70, 128); @@ -1607,9 +1606,8 @@ void Boss02_DrawEffects(PlayState* play) { effect = (TwinmoldEffect*)play->specialEffects; for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_FRAGMENT) { - FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type); FrameInterpolation_IgnoreActorMtx(); - effect->justSpawned = false; if (!flag) { gDPSetCombineLERP(POLY_OPA_DISP++, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0); @@ -1632,9 +1630,8 @@ void Boss02_DrawEffects(PlayState* play) { effect = (TwinmoldEffect*)play->specialEffects; for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_FLASH) { - FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type); FrameInterpolation_IgnoreActorMtx(); - effect->justSpawned = false; if (!flag) { //! @bug - dev forgot to set flag to 1, should only apply to first entry? gSPDisplayList(POLY_XLU_DISP++, gLightOrbMaterial1DL); gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); @@ -1656,9 +1653,8 @@ void Boss02_DrawEffects(PlayState* play) { effect = (TwinmoldEffect*)play->specialEffects; for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) { if (effect->type == TWINMOLD_EFFECT_BLACK_DUST) { - FrameInterpolation_RecordOpenChild(effect, effect->type | (effect->justSpawned ? (1 << 30) : 0)); + FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type); FrameInterpolation_IgnoreActorMtx(); - effect->justSpawned = false; if (!flag) { gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL); gDPSetEnvColor(POLY_XLU_DISP++, 30, 30, 30, 128); @@ -2365,6 +2361,6 @@ void Boss02_Reset(void) { for (int i = 0; i < TWINMOLD_EFFECT_COUNT; i++) { sTwinmoldEffects[i].type = TWINMOLD_EFFECT_NONE; - sTwinmoldEffects[i].justSpawned = false; + sTwinmoldEffects[i].epoch = 0; } } diff --git a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h index 37efa665b9..9cd4fc52d9 100644 --- a/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h +++ b/mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h @@ -23,7 +23,7 @@ typedef struct { /* 0x34 */ f32 scale; /* 0x38 */ f32 targetScale; // 2S2H [Port] - /* */ u8 justSpawned; // Tracks when an effect is spawned for use with interpolation skipping + /* */ s16 epoch; // Tracks when an effect is spawned for use with interpolation skipping } TwinmoldEffect; // size = 0x3C typedef enum { diff --git a/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 6af0792c61..7fd2eef668 100644 --- a/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/mm/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -399,7 +399,7 @@ void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, PlayState* play) { } if (((this->effects[i].posBase.x + this->effects[i].posOffset.x) - newEye.x) > halfScreenHeight) { - // 2S2H [Interpolation] Here and below, skip particle interpolation on next frame when positionmoves + // 2S2H [Interpolation] Here and below, skip particle interp on next frame when position moves if (ABS(this->effects[i].posBase.x - (newEye.x - halfScreenHeight)) >= 120.0f) { this->effects[i].epoch++; } diff --git a/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c b/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c index e978361df3..df1a9b3db3 100644 --- a/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c +++ b/mm/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c @@ -182,7 +182,7 @@ void EnTanron5_SpawnEffectSand(TwinmoldEffect* effect, Vec3f* pos, f32 scale) { effect->timer = 0; effect->scale = scale; effect->targetScale = 2.0f * scale; - effect->justSpawned = true; + effect->epoch++; break; } } @@ -207,7 +207,7 @@ void EnTanron5_SpawnEffectBlackDust(TwinmoldEffect* effect, Vec3f* pos, f32 scal effect->timer = 0; effect->scale = scale; effect->targetScale = 2.0f * scale; - effect->justSpawned = true; + effect->epoch++; break; } } diff --git a/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 71bbc75fcd..7a8222bc99 100644 --- a/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/mm/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -281,6 +281,7 @@ void func_808DC454(ObjectKankyo* this, PlayState* play) { if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) > temp_120) { this->unk_14C[i].unk_00 = temp_f24 - temp_120; + // 2S2H [Interpolation] Here and below, skip particle interp on next frame when position moves this->unk_14C[i].epoch++; } @@ -455,6 +456,7 @@ void func_808DCDB4(ObjectKankyo* this, PlayState* play) { if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) > temp_80) { this->unk_14C[i].unk_00 = temp_f26 - temp_80; + // 2S2H [Interpolation] Here and below, skip particle interp on next frame when position moves this->unk_14C[i].epoch++; } @@ -588,7 +590,6 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) { Matrix_Scale(0.05f + tempf, 0.05f + tempf, 0.05f + tempf, MTXMODE_APPLY); temp_f2 = Math_Vec3f_DistXYZ(&worldPos, &play->view.eye) / 300.0f; temp_f2 = ((1.0f < temp_f2) ? 0.0f : (((1.0f - temp_f2) > 1.0f) ? 1.0f : 1.0f - temp_f2)); - temp_f2 = 1.59375f; gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(160.0f * temp_f2)); @@ -658,7 +659,6 @@ void func_808DD970(Actor* thisx, PlayState* play2) { Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY); temp_f0 = Math_Vec3f_DistXYZ(&worldPos, &play->view.eye); temp_f0 = (u8)(255.0f * phi_f26) * (1.0f - (temp_f0 / 300.0f)); - temp_f0 = 255; gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 55, temp_f0);