From 89fc0f03556c975fb4c7cacb4dba7826d7773075 Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 24 Dec 2024 12:15:48 -0500 Subject: [PATCH 1/6] Fix ignore actor mtx interpolation flag persisting through skipped frames (#903) --- .../FrameInterpolation/FrameInterpolation.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp index 7ac739626c..6e982130e8 100644 --- a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp +++ b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp @@ -474,6 +474,10 @@ void FrameInterpolation_StartRecord(void) { current_recording = {}; current_path.clear(); current_path.push_back(¤t_recording.root_path); + has_inv_actor_mtx = false; + interpolate_wider_angles = false; + ignore_inv_actor_mtx = false; + if (!camera_interpolation) { // default to interpolating camera_interpolation = true; @@ -523,12 +527,16 @@ int FrameInterpolation_GetCameraEpoch(void) { // Marks the current record path and its children to not apply the matrix result // against the recorded actor inverted matrix void FrameInterpolation_IgnoreActorMtx() { + if (!is_recording) + return; 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() { + if (!is_recording) + return; interpolate_wider_angles = true; } From 3e133f1ea361cd689de565e6650135ceafb84fea Mon Sep 17 00:00:00 2001 From: Archez Date: Thu, 26 Dec 2024 14:08:00 -0500 Subject: [PATCH 2/6] Add patch for fixing depth render on the transition wipe effect (#906) --- .../Enhancements/GfxPatcher/AuthenticGfxPatches.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm/2s2h/Enhancements/GfxPatcher/AuthenticGfxPatches.cpp b/mm/2s2h/Enhancements/GfxPatcher/AuthenticGfxPatches.cpp index 875f8d6349..1ef05f6495 100644 --- a/mm/2s2h/Enhancements/GfxPatcher/AuthenticGfxPatches.cpp +++ b/mm/2s2h/Enhancements/GfxPatcher/AuthenticGfxPatches.cpp @@ -7,6 +7,7 @@ extern "C" { #include "objects/object_fz/object_fz.h" #include "objects/object_ik/object_ik.h" #include "overlays/ovl_En_Syateki_Okuta/ovl_En_Syateki_Okuta.h" +#include "overlays/ovl_fbdemo_wipe1/ovl_fbdemo_wipe1.h" #include "overlays/ovl_Obj_Jgame_Light/ovl_Obj_Jgame_Light.h" void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); @@ -312,6 +313,13 @@ void GfxPatcher_ApplyGeometryIssuePatches() { PatchClockTownBuildingGeometry(); } +void GfxPatcher_ApplyTransitionWipePatch() { + // Removing G_ZBUFFER as gsDPSetPrimDepth is unimplemented in LUS. + // This should have the same effect of using a depth test value of 0, and allows it to render over everything. + // LUSTODO: Remove patch once gsDPSetPrimDepth is implemented properly. + ResourceMgr_PatchGfxByName(sTransWipe1DL, "zbufferRemoval", 4, gsSPSetGeometryMode(G_SHADE | G_SHADING_SMOOTH)); +} + // Applies required patches for authentic bugs to allow the game to play and render properly void GfxPatcher_ApplyNecessaryAuthenticPatches() { PatchMiniGameCrossAndCircleSymbols(); @@ -319,4 +327,6 @@ void GfxPatcher_ApplyNecessaryAuthenticPatches() { GfxPatcher_ApplyOverflowTexturePatches(); GfxPatcher_ApplyGeometryIssuePatches(); + + GfxPatcher_ApplyTransitionWipePatch(); } From 4dfdf5d2a80b8966359c9de9471b7eef73e2ac9a Mon Sep 17 00:00:00 2001 From: Eblo <7004497+Eblo@users.noreply.github.com> Date: Fri, 27 Dec 2024 22:24:30 -0500 Subject: [PATCH 3/6] Add reset func for EnSob1 (#908) --- mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c b/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c index 60fd05a4cc..464def8d07 100644 --- a/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c +++ b/mm/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c @@ -17,6 +17,7 @@ void EnSob1_Init(Actor* thisx, PlayState* play); void EnSob1_Destroy(Actor* thisx, PlayState* play); void EnSob1_Update(Actor* thisx, PlayState* play); +void EnSob1_Reset(void); void EnSob1_ZoraShopkeeper_Draw(Actor* thisx, PlayState* play); void EnSob1_GoronShopkeeper_Draw(Actor* thisx, PlayState* play); @@ -75,6 +76,7 @@ ActorInit En_Sob1_InitVars = { /**/ EnSob1_Destroy, /**/ EnSob1_Update, /**/ NULL, + /**/ EnSob1_Reset, }; static s16 sObjectIds[][3] = { @@ -1751,3 +1753,7 @@ void EnSob1_BombShopkeeper_Draw(Actor* thisx, PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } + +void EnSob1_Reset(void) { + sShops[BOMB_SHOP][0].shopItemId = SI_BOMB_BAG_20_2; +} From 41f13e198ed164892d26b07b49c0685fe2bffc9f Mon Sep 17 00:00:00 2001 From: Archez Date: Fri, 27 Dec 2024 23:14:34 -0500 Subject: [PATCH 4/6] Fix bow reticle showing on certain collisions (#907) * Fix bow reticle showing on certain collisions * better arrow matrix math --- mm/2s2h/Enhancements/Enhancements.cpp | 1 + mm/2s2h/Enhancements/Graphics/BowReticle.cpp | 71 ++++++++++++++++++++ mm/2s2h/Enhancements/Graphics/Graphics.h | 1 + mm/src/code/z_player_lib.c | 15 ----- 4 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 mm/2s2h/Enhancements/Graphics/BowReticle.cpp diff --git a/mm/2s2h/Enhancements/Enhancements.cpp b/mm/2s2h/Enhancements/Enhancements.cpp index 411d0cd15a..24884d7313 100644 --- a/mm/2s2h/Enhancements/Enhancements.cpp +++ b/mm/2s2h/Enhancements/Enhancements.cpp @@ -37,6 +37,7 @@ void InitEnhancements() { RegisterTwoHandedSwordSpinAttack(); // Graphics + RegisterBowReticle(); RegisterDisableBlackBars(); Register3DItemDrops(); diff --git a/mm/2s2h/Enhancements/Graphics/BowReticle.cpp b/mm/2s2h/Enhancements/Graphics/BowReticle.cpp new file mode 100644 index 0000000000..e24d83fd2b --- /dev/null +++ b/mm/2s2h/Enhancements/Graphics/BowReticle.cpp @@ -0,0 +1,71 @@ +#include "libultraship/libultraship.h" +#include "2s2h/GameInteractor/GameInteractor.h" +#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" + +extern "C" { +#include "functions.h" +#include "variables.h" +#include "objects/gameplay_keep/gameplay_keep.h" +} + +void DrawBowReticle(PlayState* play, Player* player, f32 bowDistance) { + static Vec3f D_801C094C = { -500.0f, -100.0f, 0.0f }; + CollisionPoly* poly; + s32 bgId; + Vec3f posA; + Vec3f posB; + Vec3f pos; + Vec3f projectedPos; + f32 projectedW; + f32 scale; + + D_801C094C.z = 0.0f; + Matrix_MultVec3f(&D_801C094C, &posA); + D_801C094C.z = bowDistance; + Matrix_MultVec3f(&D_801C094C, &posB); + + // If the line test doesn't hit a valid polygon, use the "farthest" point as the reticle position. + // This ensures that the reticle is always visible even when looking at the sky + if (!BgCheck_ProjectileLineTest(&play->colCtx, &posA, &posB, &pos, &poly, true, true, true, true, &bgId)) { + pos = posB; + } + + OPEN_DISPS(play->state.gfxCtx); + + OVERLAY_DISP = Gfx_SetupDL(OVERLAY_DISP, SETUPDL_7); + + SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &pos, &projectedPos, &projectedW); + + scale = (projectedW < 500.0f) ? 0.075f : (projectedW / 500.0f) * 0.075f; + + Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + + gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPSegment(OVERLAY_DISP++, 0x06, (uintptr_t)play->objectCtx.slots[player->actor.objectSlot].segment); + gSPDisplayList(OVERLAY_DISP++, (Gfx*)gHookshotReticleDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void RegisterBowReticle() { + GameInteractor::Instance->RegisterGameHookForID( + PLAYER_LIMB_RIGHT_HAND, [](Player* player, s32 limbIndex) { + if (player->actor.scale.y >= 0.0f && + ((player->heldItemAction == PLAYER_IA_BOW_FIRE) || (player->heldItemAction == PLAYER_IA_BOW_ICE) || + (player->heldItemAction == PLAYER_IA_BOW_LIGHT) || (player->heldItemAction == PLAYER_IA_BOW)) && + CVarGetInteger("gEnhancements.Graphics.BowReticle", 0)) { + + if (func_800B7128(player) != 0) { + // Rotation from link's right hand that aligns with arrow projection + Matrix_RotateZYX(0, -0x3B33, -0x4423, MTXMODE_APPLY); + Matrix_Translate(575.0f, 345.0f, 0.0f, MTXMODE_APPLY); + + // 341000 as a value is selected roughly as a ratio of the hookshot value to maximum hookshot + // distance from player, multiplied by maximum arrow distance from player -- (77600 / 770) * 3385 + DrawBowReticle(gPlayState, player, 341000.0f); + } + } + }); +} diff --git a/mm/2s2h/Enhancements/Graphics/Graphics.h b/mm/2s2h/Enhancements/Graphics/Graphics.h index 917c6aa74a..d4b4348f66 100644 --- a/mm/2s2h/Enhancements/Graphics/Graphics.h +++ b/mm/2s2h/Enhancements/Graphics/Graphics.h @@ -3,6 +3,7 @@ void Register3DItemDrops(); void Register3DSClock(); +void RegisterBowReticle(); void RegisterDisableBlackBars(); void MotionBlur_RenderMenuOptions(); void RegisterPlayAsKafei(); diff --git a/mm/src/code/z_player_lib.c b/mm/src/code/z_player_lib.c index 12c6e86e95..6c1d4ae61f 100644 --- a/mm/src/code/z_player_lib.c +++ b/mm/src/code/z_player_lib.c @@ -3681,21 +3681,6 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList1, G Player_DrawHookshotReticle(play, player, 77600.0f); } } - } else if (CVarGetInteger("gEnhancements.Graphics.BowReticle", 0) && - ((player->heldItemAction == PLAYER_IA_BOW_FIRE) || - (player->heldItemAction == PLAYER_IA_BOW_ICE) || - (player->heldItemAction == PLAYER_IA_BOW_LIGHT) || (player->heldItemAction == PLAYER_IA_BOW))) { - if (heldActor != NULL) { - MtxF sp44; - - Matrix_RotateZYX(0, -15216, -17496, MTXMODE_APPLY); - Matrix_Get(&sp44); - - if (func_800B7128(player) != 0) { - Matrix_Translate(500.0f, 300.0f, 0.0f, MTXMODE_APPLY); - Player_DrawHookshotReticle(play, player, 776000.0f); - } - } } else if (player->meleeWeaponState != PLAYER_MELEE_WEAPON_STATE_0) { if (player->meleeWeaponAnimation == PLAYER_MWA_GORON_PUNCH_RIGHT) { func_80126B8C(play, player); From 082d11ab2c927b617e37256ce6110cd48ab5f6e8 Mon Sep 17 00:00:00 2001 From: lightmanLP Date: Wed, 1 Jan 2025 03:36:27 +0700 Subject: [PATCH 5/6] Fix invalid menu name in rumble testing (#905) * fix invalid menu name * uncomment --- mm/2s2h/BenPort.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mm/2s2h/BenPort.cpp b/mm/2s2h/BenPort.cpp index f4baacad26..21fdd0acaf 100644 --- a/mm/2s2h/BenPort.cpp +++ b/mm/2s2h/BenPort.cpp @@ -1637,15 +1637,15 @@ extern "C" void OTRControllerCallback(uint8_t rumble) { static std::shared_ptr controllerConfigWindow = nullptr; if (controllerConfigWindow == nullptr) { controllerConfigWindow = std::dynamic_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Input Editor")); - // TODO: Add SoH Controller Config window rumble testing to upstream LUS config window - // note: the current implementation may not be desired in LUS, as "true" rumble support - // using osMotor calls is planned: https://github.com/Kenix3/libultraship/issues/9 - // - // } else if (controllerConfigWindow->TestingRumble()) { - // return; + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("2S2H Input Editor")); + // note: the current implementation may not be desired in LUS, as "true" rumble support + // using osMotor calls is planned: https://github.com/Kenix3/libultraship/issues/9 + } + if (controllerConfigWindow->TestingRumble()) { + return; } + // TODO: other ports? if (rumble) { Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0)->GetRumble()->StartRumble(); } else { From a72c0981bd35a7e3a04f29c5c972c2aac2f9f398 Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 31 Dec 2024 18:06:25 -0500 Subject: [PATCH 6/6] fix interpolation on treasure chest game walls (#914) --- .../actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c b/mm/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c index 3218c3050d..9214a7e36a 100644 --- a/mm/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c +++ b/mm/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c @@ -27,6 +27,8 @@ #include "z_obj_takaraya_wall.h" #include "objects/object_takaraya_objects/object_takaraya_objects.h" +#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h" + #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjTakarayaWall*)thisx) @@ -468,6 +470,7 @@ void ObjTakarayaWall_Draw(Actor* thisx, PlayState* play) { for (i = 0; i < TAKARAYA_WALL_ROWS; i++) { for (j = 0; j < TAKARAYA_WALL_COLUMNS; j++) { if (sTakarayaWallHeights[i][j] > 0.0f) { + FrameInterpolation_RecordOpenChild(this, i * TAKARAYA_WALL_COLUMNS + j); mtx->xw = (i * 120) - 1620; mtx->yw = sTakarayaWallHeights[i][j] + (this->actor.world.pos.y - 120.0f); mtx->zw = (j * 120) + 60; @@ -494,6 +497,8 @@ void ObjTakarayaWall_Draw(Actor* thisx, PlayState* play) { Audio_PlaySfx_AtPos(&sTakarayaWallAudioPositions[i][j], NA_SE_EV_ROCK_CUBE_FALL - SFX_FLAG); } } + + FrameInterpolation_RecordCloseChild(); } } }