summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArchez <Archez@users.noreply.github.com>2024-12-18 23:32:43 -0500
committerGitHub <noreply@github.com>2024-12-18 23:32:43 -0500
commit8ed597a1f0293d7a199527be659842402be07bf4 (patch)
tree26a216e4dc940ae1c3a560f76740ca9c13227d67
parentfb8e8765245d5e14a7a2f0fdefff116f7aef5463 (diff)
Adds even more interpolation fixes (#894)
* interpolate biggoron ice breath * interpolate fix pause cursor * interpolate goron snow/steam effects * adjust clear tag interpolation * skip interpolation on touching item00 items * interpolate keaton grass disappear * Apply ignore act mtx to current and children paths * Interpolate wider angles for deku link spin and flower dive animations * refactor for pr feedback
-rw-r--r--mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp29
-rw-r--r--mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h2
-rw-r--r--mm/2s2h/Enhancements/Graphics/3DItemDrops.cpp9
-rw-r--r--mm/src/code/z_actor.c11
-rw-r--r--mm/src/code/z_en_item00.c11
-rw-r--r--mm/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c6
-rw-r--r--mm/src/overlays/actors/ovl_En_Dai/z_en_dai.c4
-rw-r--r--mm/src/overlays/actors/ovl_En_Go/z_en_go.c8
-rw-r--r--mm/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c4
-rw-r--r--mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c14
10 files changed, 91 insertions, 7 deletions
diff --git a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp
index b8c43b63f..7ac739626 100644
--- a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp
+++ b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp
@@ -146,6 +146,7 @@ union Data {
Vec3s rot;
// MtxF mtx;
bool has_mtx;
+ bool interpolate_wider_angles;
} matrix_set_translate_rotate_yxz;
struct {
@@ -192,9 +193,12 @@ uint32_t previous_camera_epoch;
Recording current_recording;
Recording previous_recording;
+bool interpolate_wider_angles = false;
+
bool next_is_actor_pos_rot_matrix;
bool has_inv_actor_mtx;
bool ignore_inv_actor_mtx;
+size_t ignore_inv_actor_mtx_path_index;
MtxF inv_actor_mtx;
size_t inv_actor_mtx_path_index;
@@ -268,7 +272,10 @@ struct InterpolateCtx {
int diff = o - n;
if (-0x8000 <= diff && diff <= 0x8000) {
if (diff < -0x4000 || diff > 0x4000) {
- return ns;
+ // Wider angle cut off values are just slightly larger than when Deku Link enters a flower
+ if (!interpolate_wider_angles || diff < -0x5700 || diff > 0x5700) {
+ return ns;
+ }
}
res = (u16)(w * o + step * n);
} else {
@@ -279,7 +286,9 @@ struct InterpolateCtx {
}
diff = o - n;
if (diff < -0x4000 || diff > 0x4000) {
- return ns;
+ if (!interpolate_wider_angles || diff < -0x5700 || diff > 0x5700) {
+ return ns;
+ }
}
res = (u16)(w * o + step * n);
}
@@ -387,6 +396,7 @@ struct InterpolateCtx {
break;
case Op::MatrixSetTranslateRotateYXZ:
+ interpolate_wider_angles = new_op.matrix_set_translate_rotate_yxz.interpolate_wider_angles;
interpolate_angles(&tmp_vec3s, &old_op.matrix_set_translate_rotate_yxz.rot,
&new_op.matrix_set_translate_rotate_yxz.rot);
Matrix_SetTranslateRotateYXZ(lerp(old_op.matrix_set_translate_rotate_yxz.translateX,
@@ -400,6 +410,7 @@ struct InterpolateCtx {
old_op.matrix_set_translate_rotate_yxz.has_mtx) {
actor_mtx = *Matrix_GetCurrent();
}
+ interpolate_wider_angles = false;
break;
case Op::MatrixMtxFToMtx:
@@ -495,7 +506,9 @@ void FrameInterpolation_RecordCloseChild(void) {
if (has_inv_actor_mtx && current_path.size() == inv_actor_mtx_path_index) {
has_inv_actor_mtx = false;
}
- ignore_inv_actor_mtx = false;
+ if (ignore_inv_actor_mtx && current_path.size() == ignore_inv_actor_mtx_path_index) {
+ ignore_inv_actor_mtx = false;
+ }
current_path.pop_back();
}
@@ -507,8 +520,16 @@ int FrameInterpolation_GetCameraEpoch(void) {
return (int)camera_epoch;
}
+// Marks the current record path and its children to not apply the matrix result
+// against the recorded actor inverted matrix
void FrameInterpolation_IgnoreActorMtx() {
ignore_inv_actor_mtx = true;
+ ignore_inv_actor_mtx_path_index = current_path.size();
+}
+
+// Allows interpolating from angle changes that are up to 123º for the next SetTranslateRotateYXZ
+void FrameInterpolation_InterpolateWiderAngles() {
+ interpolate_wider_angles = true;
}
void FrameInterpolation_RecordActorPosRotMatrix(void) {
@@ -578,6 +599,8 @@ void FrameInterpolation_RecordMatrixSetTranslateRotateYXZ(f32 translateX, f32 tr
translateZ, *rot };
if (next_is_actor_pos_rot_matrix) {
d.has_mtx = true;
+ d.interpolate_wider_angles = interpolate_wider_angles;
+ interpolate_wider_angles = false;
// d.mtx = *Matrix_GetCurrent();
invert_matrix((const float*)Matrix_GetCurrent()->mf, (float*)inv_actor_mtx.mf);
next_is_actor_pos_rot_matrix = false;
diff --git a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h
index c7b94ba83..a805b5290 100644
--- a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h
+++ b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h
@@ -28,6 +28,8 @@ int FrameInterpolation_GetCameraEpoch(void);
void FrameInterpolation_IgnoreActorMtx(void);
+void FrameInterpolation_InterpolateWiderAngles();
+
void FrameInterpolation_RecordActorPosRotMatrix(void);
void FrameInterpolation_RecordMatrixPush(void);
diff --git a/mm/2s2h/Enhancements/Graphics/3DItemDrops.cpp b/mm/2s2h/Enhancements/Graphics/3DItemDrops.cpp
index e5b4de102..22a2844ee 100644
--- a/mm/2s2h/Enhancements/Graphics/3DItemDrops.cpp
+++ b/mm/2s2h/Enhancements/Graphics/3DItemDrops.cpp
@@ -1,5 +1,6 @@
#include "libultraship/libultraship.h"
#include "2s2h/GameInteractor/GameInteractor.h"
+#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
extern "C" {
#include "z64.h"
@@ -27,6 +28,12 @@ void EnItem00_3DItemsDraw(Actor* actor, PlayState* play) {
EnItem00* enItem00 = (EnItem00*)actor;
if (!(enItem00->unk14E & enItem00->unk150)) {
+ Player* player = GET_PLAYER(play);
+ bool itemOnPlayer = player->actor.home.pos.x == enItem00->actor.world.pos.x &&
+ player->actor.home.pos.z == enItem00->actor.world.pos.z;
+ FrameInterpolation_RecordOpenChild(enItem00, itemOnPlayer ? 1 : 0);
+ FrameInterpolation_IgnoreActorMtx();
+
switch (enItem00->actor.params) {
case ITEM00_RUPEE_GREEN:
Matrix_Scale(25.0f, 25.0f, 25.0f, MTXMODE_APPLY);
@@ -110,6 +117,8 @@ void EnItem00_3DItemsDraw(Actor* actor, PlayState* play) {
GetItem_Draw(play, GID_COMPASS);
break;
}
+
+ FrameInterpolation_RecordCloseChild();
}
}
diff --git a/mm/src/code/z_actor.c b/mm/src/code/z_actor.c
index 4eb27d4aa..1b3d2e20a 100644
--- a/mm/src/code/z_actor.c
+++ b/mm/src/code/z_actor.c
@@ -2794,6 +2794,10 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
DynaPoly_UpdateBgActorTransforms(play, &play->colCtx.dyna);
}
+// 2S2H [Port] Extern these for use below in interpolation checks
+extern void Player_Action_93(Player* this, PlayState* play);
+extern void Player_Action_95(Player* this, PlayState* play);
+
void Actor_Draw(PlayState* play, Actor* actor) {
Lights* light;
@@ -2809,6 +2813,13 @@ void Actor_Draw(PlayState* play, Actor* actor) {
(actor->flags & (ACTOR_FLAG_10000000 | ACTOR_FLAG_400000)) ? NULL : &actor->world.pos, play);
Lights_Draw(light, play->state.gfxCtx);
+ // If the player is performing a Deku spin or entering a Deku flower, set it so that interpolation allows for >90
+ // angle changes to be interpolated smoothly
+ if (actor->id == ACTOR_PLAYER &&
+ (((Player*)actor)->actionFunc == Player_Action_93 || ((Player*)actor)->actionFunc == Player_Action_95)) {
+ FrameInterpolation_InterpolateWiderAngles();
+ }
+
FrameInterpolation_RecordActorPosRotMatrix();
if (actor->flags & ACTOR_FLAG_IGNORE_QUAKE) {
Matrix_SetTranslateRotateYXZ(actor->world.pos.x + play->mainCamera.quakeOffset.x,
diff --git a/mm/src/code/z_en_item00.c b/mm/src/code/z_en_item00.c
index d22576ad7..548b21fa8 100644
--- a/mm/src/code/z_en_item00.c
+++ b/mm/src/code/z_en_item00.c
@@ -5,6 +5,8 @@
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h"
+#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
+
#define FLAGS 0x00000000
#define THIS ((EnItem00*)thisx)
@@ -705,6 +707,13 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
EnItem00* this = THIS;
if (!(this->unk14E & this->unk150)) {
+ // 2S2H [Interpolation] Skip interpolation when the item moves from the ground to over the player head
+ Player* player = GET_PLAYER(play);
+ bool itemOnPlayer =
+ player->actor.home.pos.x == this->actor.world.pos.x && player->actor.home.pos.z == this->actor.world.pos.z;
+ FrameInterpolation_RecordOpenChild(this, itemOnPlayer ? 1 : 0);
+ FrameInterpolation_IgnoreActorMtx();
+
switch (this->actor.params) {
case ITEM00_RUPEE_GREEN:
case ITEM00_RUPEE_BLUE:
@@ -774,6 +783,8 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
case ITEM00_BIG_FAIRY:
break;
}
+
+ FrameInterpolation_RecordCloseChild();
}
}
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 4c261ec8d..a3b104501 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
@@ -994,7 +994,6 @@ 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, effect->type);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 200);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 200);
@@ -1005,8 +1004,8 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) {
// Apply material 16 times along a circle to give the appearance of a splash
for (j = 0; j < 16; j++) {
- // BENTODO not sure if I did the math right.
- FrameInterpolation_RecordOpenChild(effect, (i + ARRAY_COUNT(this->effect) + j));
+ // Bit math to combine index with effect type
+ FrameInterpolation_RecordOpenChild(effect, effect->type + (j << 4));
Matrix_RotateYF(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_NEW);
Matrix_MultVecZ(effect->maxScale, &vec);
/**
@@ -1029,7 +1028,6 @@ void EnClearTag_DrawEffects(Actor* thisx, PlayState* play) {
}
FrameInterpolation_RecordCloseChild();
}
- FrameInterpolation_RecordCloseChild();
}
}
diff --git a/mm/src/overlays/actors/ovl_En_Dai/z_en_dai.c b/mm/src/overlays/actors/ovl_En_Dai/z_en_dai.c
index bbb8d0ed9..b634a526a 100644
--- a/mm/src/overlays/actors/ovl_En_Dai/z_en_dai.c
+++ b/mm/src/overlays/actors/ovl_En_Dai/z_en_dai.c
@@ -6,6 +6,8 @@
#include "z_en_dai.h"
+#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
+
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000)
#define THIS ((EnDai*)thisx)
@@ -65,6 +67,7 @@ void func_80B3E168(EnDaiEffect* effect, PlayState* play2) {
for (i = 0; i < EN_DAI_EFFECT_COUNT; i++, effect++) {
if (effect->isEnabled == true) {
+ FrameInterpolation_RecordOpenChild(effect, 0);
gDPPipeSync(POLY_XLU_DISP++);
if (!isDisplayListSet) {
@@ -91,6 +94,7 @@ void func_80B3E168(EnDaiEffect* effect, PlayState* play2) {
gSPDisplayList(POLY_XLU_DISP++, object_dai_DL_0002E8);
Matrix_Pop();
+ FrameInterpolation_RecordCloseChild();
}
}
diff --git a/mm/src/overlays/actors/ovl_En_Go/z_en_go.c b/mm/src/overlays/actors/ovl_En_Go/z_en_go.c
index c6598dd7a..d2cd21880 100644
--- a/mm/src/overlays/actors/ovl_En_Go/z_en_go.c
+++ b/mm/src/overlays/actors/ovl_En_Go/z_en_go.c
@@ -20,6 +20,8 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h"
+#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
+
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_2000000)
#define THIS ((EnGo*)thisx)
@@ -783,6 +785,7 @@ void EnGo_DrawSteam(EnGoEffect effect[ENGO_EFFECT_COUNT], PlayState* play2) {
isMaterialSet = true;
}
+ FrameInterpolation_RecordOpenChild(effect, effect->type);
Matrix_Push();
alpha = (f32)effect->alphaNumer / effect->alphaDenom;
@@ -800,6 +803,7 @@ void EnGo_DrawSteam(EnGoEffect effect[ENGO_EFFECT_COUNT], PlayState* play2) {
gSPDisplayList(POLY_XLU_DISP++, gGoronSteamModelDL);
Matrix_Pop();
+ FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(play->state.gfxCtx);
@@ -877,6 +881,7 @@ void EnGo_DrawDust(EnGoEffect effect[ENGO_EFFECT_COUNT], PlayState* play2) {
isMaterialSet = true;
}
+ FrameInterpolation_RecordOpenChild(effect, effect->type);
Matrix_Push();
alpha = (f32)effect->alphaNumer / effect->alphaDenom;
@@ -896,6 +901,7 @@ void EnGo_DrawDust(EnGoEffect effect[ENGO_EFFECT_COUNT], PlayState* play2) {
gSPDisplayList(POLY_XLU_DISP++, gGoronDustModelDL);
Matrix_Pop();
+ FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(play->state.gfxCtx);
@@ -1045,6 +1051,7 @@ void EnGo_DrawSnow(EnGoEffect effect[ENGO_SNOW_EFFECT_COUNT], PlayState* play, G
isMaterialSet = true;
}
+ FrameInterpolation_RecordOpenChild(effect, effect->type);
Matrix_Push();
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_Scale(0.08f, 0.08f, 0.08f, MTXMODE_APPLY);
@@ -1056,6 +1063,7 @@ void EnGo_DrawSnow(EnGoEffect effect[ENGO_SNOW_EFFECT_COUNT], PlayState* play, G
gSPDisplayList(POLY_OPA_DISP++, model);
Matrix_Pop();
+ FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(play->state.gfxCtx);
diff --git a/mm/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c b/mm/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c
index 313c0863b..9ead62c53 100644
--- a/mm/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c
+++ b/mm/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c
@@ -9,6 +9,7 @@
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
#include "2s2h/ShipUtils.h"
#include <string.h>
@@ -1344,11 +1345,14 @@ void func_80A5E6F0(Actor* thisx, PlayState* play) {
EnKusa2UnkBssSubStruct2* s = &D_80A5F1C0.unk_0480[i];
if (s->unk_2C > 0) {
+ FrameInterpolation_RecordOpenChild(s, 0);
+ FrameInterpolation_IgnoreActorMtx();
Matrix_SetTranslateRotateYXZ(s->unk_04.x, s->unk_04.y, s->unk_04.z, &s->unk_20);
Matrix_Scale(s->unk_00, s->unk_00, s->unk_00, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, D_80A5EB68[i & 1]);
+ FrameInterpolation_RecordCloseChild();
}
}
diff --git a/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
index 078491f2a..6df5ba5f1 100644
--- a/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
+++ b/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
@@ -3025,6 +3025,18 @@ void KaleidoScope_DrawCursor(PlayState* play) {
PauseContext* pauseCtx = &play->pauseCtx;
s16 i;
+ // #region 2S2H [Port] Track cursor position so we can skip interpolation for one frame whenever it moves
+ static f32 prevX = 0;
+ static f32 prevY = 0;
+ static u8 cursorInterpState = 0;
+
+ if (prevX != pauseCtx->cursorX || prevY != pauseCtx->cursorY) {
+ cursorInterpState ^= 1; // Flip state
+ }
+ prevX = pauseCtx->cursorX;
+ prevY = pauseCtx->cursorY;
+ // #endregion
+
OPEN_DISPS(play->state.gfxCtx);
if ((pauseCtx->mainState == PAUSE_MAIN_STATE_IDLE) ||
@@ -3032,6 +3044,7 @@ void KaleidoScope_DrawCursor(PlayState* play) {
((pauseCtx->pageIndex == PAUSE_QUEST) && ((pauseCtx->mainState <= PAUSE_MAIN_STATE_SONG_PLAYBACK) ||
(pauseCtx->mainState == PAUSE_MAIN_STATE_SONG_PROMPT) ||
(pauseCtx->mainState == PAUSE_MAIN_STATE_IDLE_CURSOR_ON_SONG)))) {
+ FrameInterpolation_RecordOpenChild("Pause cursor", cursorInterpState ? 1 : 0);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
@@ -3056,6 +3069,7 @@ void KaleidoScope_DrawCursor(PlayState* play) {
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ FrameInterpolation_RecordCloseChild();
}
CLOSE_DISPS(play->state.gfxCtx);