diff options
| author | Archez <Archez@users.noreply.github.com> | 2024-12-18 23:32:43 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-18 23:32:43 -0500 |
| commit | 8ed597a1f0293d7a199527be659842402be07bf4 (patch) | |
| tree | 26a216e4dc940ae1c3a560f76740ca9c13227d67 | |
| parent | fb8e8765245d5e14a7a2f0fdefff116f7aef5463 (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.cpp | 29 | ||||
| -rw-r--r-- | mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h | 2 | ||||
| -rw-r--r-- | mm/2s2h/Enhancements/Graphics/3DItemDrops.cpp | 9 | ||||
| -rw-r--r-- | mm/src/code/z_actor.c | 11 | ||||
| -rw-r--r-- | mm/src/code/z_en_item00.c | 11 | ||||
| -rw-r--r-- | mm/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 6 | ||||
| -rw-r--r-- | mm/src/overlays/actors/ovl_En_Dai/z_en_dai.c | 4 | ||||
| -rw-r--r-- | mm/src/overlays/actors/ovl_En_Go/z_en_go.c | 8 | ||||
| -rw-r--r-- | mm/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c | 4 | ||||
| -rw-r--r-- | mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c | 14 |
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); |
