From a836be11bccbd7c583309bca744c6a0c86cd0b94 Mon Sep 17 00:00:00 2001 From: Pheenoh Date: Sun, 12 Apr 2026 12:32:27 -0600 Subject: [PATCH 1/3] Add Move Link tool from decompgz --- include/dusk/settings.h | 2 ++ src/d/actor/d_a_alink.cpp | 32 +++++++----------------- src/dusk/imgui/ImGuiConsole.cpp | 14 +++++++++++ src/dusk/imgui/ImGuiMenuEnhancements.cpp | 2 ++ src/dusk/settings.cpp | 2 ++ 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index 8418602251..edd8d1bc15 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -71,6 +71,7 @@ struct UserSettings { // Controls ConfigVar enableTurboKeybind; + ConfigVar enableMoveLink; } game; struct { @@ -102,6 +103,7 @@ struct CollisionViewSettings { struct TransientSettings { CollisionViewSettings collisionView; bool skipFrameRateLimit; + bool moveLinkActive; }; TransientSettings& getTransientSettings(); diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index e754d7522f..82ed2d7d7b 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -51,6 +51,7 @@ #include "d/actor/d_a_ni.h" #include "d/d_s_play.h" +#include "dusk/settings.h" #include "res/Object/Alink.h" #include @@ -18048,17 +18049,9 @@ int daAlink_c::execute() { } BOOL isTrigDebugMoveInput = FALSE; - #if DEBUG - if (daPy_getPlayerActorClass() == this && checkDebugMoveInput()) { - isTrigDebugMoveInput = TRUE; - if (l_debugMode) { - l_debugMode = FALSE; - } else { - l_debugMode = TRUE; - } - } - if (l_debugMode) { + if (dusk::getTransientSettings().moveLinkActive && daPy_getPlayerActorClass() == this) { + isTrigDebugMoveInput = TRUE; if (checkModeFlg(0x400) && !checkBoardRide() && !checkSpinnerRide()) { if (checkCanoeRide()) { setSyncCanoePos(); @@ -18067,16 +18060,15 @@ int daAlink_c::execute() { } } else { f32 moveSpeed; - if (mDoCPd_c::getHoldLockR(PAD_1)) { + if (mDoCPd_c::getHoldZ(PAD_1)) { moveSpeed = 100.0f; } else { moveSpeed = 50.0f; } - if (mDoCPd_c::getHoldY(PAD_1)) { - current.pos.y += moveSpeed; - } else if (mDoCPd_c::getHoldX(PAD_1)) { - current.pos.y -= moveSpeed; + f32 cStickY = mDoCPd_c::getSubStickY(PAD_1); + if (cStickY > 0.3f || cStickY < -0.3f) { + current.pos.y += moveSpeed * cStickY; } current.pos.x += moveSpeed * mStickValue * cM_ssin(mMoveAngle); @@ -18094,9 +18086,7 @@ int daAlink_c::execute() { setBodyPartPos(); setAttentionPos(); - } else - #endif - { + } else { if (isTrigDebugMoveInput) { mItemButton = 0; mItemTrigger = 0; @@ -18562,11 +18552,7 @@ int daAlink_c::execute() { if (checkDeadHP()) { eventInfo.offCondition(fopAcCnd_NOEXEC_e); - } else - #if DEBUG - if (!l_debugMode) - #endif - { + } else if (!dusk::getTransientSettings().moveLinkActive) { if (!checkMagneBootsOn()) { f32 gnd_nrm_y; if (mLinkAcch.ChkGroundHit()) { diff --git a/src/dusk/imgui/ImGuiConsole.cpp b/src/dusk/imgui/ImGuiConsole.cpp index 6e917761f6..09a6141d8c 100644 --- a/src/dusk/imgui/ImGuiConsole.cpp +++ b/src/dusk/imgui/ImGuiConsole.cpp @@ -13,6 +13,7 @@ #include "JSystem/JUtility/JUTGamePad.h" #include "SDL3/SDL_mouse.h" +#include "m_Do/m_Do_controller_pad.h" #include "dusk/config.hpp" #include "dusk/main.h" #include "dusk/settings.h" @@ -202,6 +203,19 @@ namespace dusk { void ImGuiConsole::UpdateSettings() { getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind && ImGui::IsKeyDown(ImGuiKey_Tab); + + if (getSettings().game.enableMoveLink) { + static bool comboHeld = false; + constexpr u32 combo = PAD_TRIGGER_L | PAD_TRIGGER_R | PAD_BUTTON_Y; + u32 rawHold = mDoCPd_c::getHold(PAD_1); + bool held = (rawHold & combo) == combo; + if (held && !comboHeld) { + getTransientSettings().moveLinkActive = !getTransientSettings().moveLinkActive; + } + comboHeld = held; + } else { + getTransientSettings().moveLinkActive = false; + } } void ImGuiConsole::PreDraw() { diff --git a/src/dusk/imgui/ImGuiMenuEnhancements.cpp b/src/dusk/imgui/ImGuiMenuEnhancements.cpp index b505d84345..3b62eec7aa 100644 --- a/src/dusk/imgui/ImGuiMenuEnhancements.cpp +++ b/src/dusk/imgui/ImGuiMenuEnhancements.cpp @@ -156,6 +156,8 @@ namespace dusk { "This will not work with the \"Unlock Framerate\" enhancement."); } + config::ImGuiCheckbox("Move Link (L+R+Y)", getSettings().game.enableMoveLink); + ImGui::EndMenu(); } diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index dabed72f19..1760345004 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -59,6 +59,7 @@ UserSettings g_userSettings = { // Controls .enableTurboKeybind {"game.enableTurboKeybind", false}, + .enableMoveLink {"game.enableMoveLink", false}, }, .backend = { @@ -113,6 +114,7 @@ void registerSettings() { Register(g_userSettings.game.noLowHpSound); Register(g_userSettings.game.midnasLamentNonStop); Register(g_userSettings.game.enableTurboKeybind); + Register(g_userSettings.game.enableMoveLink); Register(g_userSettings.game.fastSpinner); Register(g_userSettings.game.enableFrameInterpolation); From ad10ddf7a9eaa9f84ef0bf35275aaf9376120a8f Mon Sep 17 00:00:00 2001 From: Pheenoh Date: Sun, 12 Apr 2026 15:46:36 -0600 Subject: [PATCH 2/3] Address PR feedback for Move Link tool - Gate on developmentMode instead of dedicated setting - Simplify combo check to getHoldL + getHoldR + getTrigY - Use #if TARGET_PC ifdefs, preserve original #if DEBUG code - Remove enableMoveLink ConfigVar and menu checkbox --- include/dusk/settings.h | 1 - src/d/actor/d_a_alink.cpp | 62 ++++++++++++++++++++++-- src/dusk/imgui/ImGuiConsole.cpp | 15 ++---- src/dusk/imgui/ImGuiMenuEnhancements.cpp | 2 - src/dusk/settings.cpp | 2 - 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index edd8d1bc15..3634d41577 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -71,7 +71,6 @@ struct UserSettings { // Controls ConfigVar enableTurboKeybind; - ConfigVar enableMoveLink; } game; struct { diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 82ed2d7d7b..73a4eff741 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -18049,7 +18049,7 @@ int daAlink_c::execute() { } BOOL isTrigDebugMoveInput = FALSE; - +#if TARGET_PC if (dusk::getTransientSettings().moveLinkActive && daPy_getPlayerActorClass() == this) { isTrigDebugMoveInput = TRUE; if (checkModeFlg(0x400) && !checkBoardRide() && !checkSpinnerRide()) { @@ -18086,7 +18086,57 @@ int daAlink_c::execute() { setBodyPartPos(); setAttentionPos(); - } else { + } else +#endif + #if DEBUG + if (daPy_getPlayerActorClass() == this && checkDebugMoveInput()) { + isTrigDebugMoveInput = TRUE; + if (l_debugMode) { + l_debugMode = FALSE; + } else { + l_debugMode = TRUE; + } + } + + if (l_debugMode) { + if (checkModeFlg(0x400) && !checkBoardRide() && !checkSpinnerRide()) { + if (checkCanoeRide()) { + setSyncCanoePos(); + } else { + setSyncRide(0); + } + } else { + f32 moveSpeed; + if (mDoCPd_c::getHoldLockR(PAD_1)) { + moveSpeed = 100.0f; + } else { + moveSpeed = 50.0f; + } + + if (mDoCPd_c::getHoldY(PAD_1)) { + current.pos.y += moveSpeed; + } else if (mDoCPd_c::getHoldX(PAD_1)) { + current.pos.y -= moveSpeed; + } + + current.pos.x += moveSpeed * mStickValue * cM_ssin(mMoveAngle); + current.pos.z += moveSpeed * mStickValue * cM_scos(mMoveAngle); + } + + setMatrix(); + mpLinkModel->calc(); + + if (!checkWolf()) { + setItemMatrix(0); + } else { + setWolfItemMatrix(); + } + + setBodyPartPos(); + setAttentionPos(); + } else + #endif + { if (isTrigDebugMoveInput) { mItemButton = 0; mItemTrigger = 0; @@ -18552,7 +18602,13 @@ int daAlink_c::execute() { if (checkDeadHP()) { eventInfo.offCondition(fopAcCnd_NOEXEC_e); - } else if (!dusk::getTransientSettings().moveLinkActive) { + } else +#if TARGET_PC + if (!dusk::getTransientSettings().moveLinkActive) +#elif DEBUG + if (!l_debugMode) +#endif + { if (!checkMagneBootsOn()) { f32 gnd_nrm_y; if (mLinkAcch.ChkGroundHit()) { diff --git a/src/dusk/imgui/ImGuiConsole.cpp b/src/dusk/imgui/ImGuiConsole.cpp index 09a6141d8c..1bff5da458 100644 --- a/src/dusk/imgui/ImGuiConsole.cpp +++ b/src/dusk/imgui/ImGuiConsole.cpp @@ -14,6 +14,7 @@ #include "JSystem/JUtility/JUTGamePad.h" #include "SDL3/SDL_mouse.h" #include "m_Do/m_Do_controller_pad.h" +#include "m_Do/m_Do_main.h" #include "dusk/config.hpp" #include "dusk/main.h" #include "dusk/settings.h" @@ -204,16 +205,10 @@ namespace dusk { void ImGuiConsole::UpdateSettings() { getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind && ImGui::IsKeyDown(ImGuiKey_Tab); - if (getSettings().game.enableMoveLink) { - static bool comboHeld = false; - constexpr u32 combo = PAD_TRIGGER_L | PAD_TRIGGER_R | PAD_BUTTON_Y; - u32 rawHold = mDoCPd_c::getHold(PAD_1); - bool held = (rawHold & combo) == combo; - if (held && !comboHeld) { - getTransientSettings().moveLinkActive = !getTransientSettings().moveLinkActive; - } - comboHeld = held; - } else { + if (mDoMain::developmentMode == 1 && mDoCPd_c::getHoldL(PAD_1) && mDoCPd_c::getHoldR(PAD_1) && mDoCPd_c::getTrigY(PAD_1)) { + getTransientSettings().moveLinkActive = !getTransientSettings().moveLinkActive; + } + if (mDoMain::developmentMode != 1) { getTransientSettings().moveLinkActive = false; } } diff --git a/src/dusk/imgui/ImGuiMenuEnhancements.cpp b/src/dusk/imgui/ImGuiMenuEnhancements.cpp index 3b62eec7aa..b505d84345 100644 --- a/src/dusk/imgui/ImGuiMenuEnhancements.cpp +++ b/src/dusk/imgui/ImGuiMenuEnhancements.cpp @@ -156,8 +156,6 @@ namespace dusk { "This will not work with the \"Unlock Framerate\" enhancement."); } - config::ImGuiCheckbox("Move Link (L+R+Y)", getSettings().game.enableMoveLink); - ImGui::EndMenu(); } diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 1760345004..dabed72f19 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -59,7 +59,6 @@ UserSettings g_userSettings = { // Controls .enableTurboKeybind {"game.enableTurboKeybind", false}, - .enableMoveLink {"game.enableMoveLink", false}, }, .backend = { @@ -114,7 +113,6 @@ void registerSettings() { Register(g_userSettings.game.noLowHpSound); Register(g_userSettings.game.midnasLamentNonStop); Register(g_userSettings.game.enableTurboKeybind); - Register(g_userSettings.game.enableMoveLink); Register(g_userSettings.game.fastSpinner); Register(g_userSettings.game.enableFrameInterpolation); From 1ec8a2309a667e438d3c8c0875a4a7c4508dd18b Mon Sep 17 00:00:00 2001 From: Pheenoh Date: Sun, 12 Apr 2026 15:59:51 -0600 Subject: [PATCH 3/3] Address PR feedback for Move Link tool --- src/d/actor/d_a_alink.cpp | 73 ++++++++++++++------------------------- 1 file changed, 25 insertions(+), 48 deletions(-) diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 73a4eff741..b218a8f1ee 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -18052,6 +18052,19 @@ int daAlink_c::execute() { #if TARGET_PC if (dusk::getTransientSettings().moveLinkActive && daPy_getPlayerActorClass() == this) { isTrigDebugMoveInput = TRUE; +#elif DEBUG + if (daPy_getPlayerActorClass() == this && checkDebugMoveInput()) { + isTrigDebugMoveInput = TRUE; + if (l_debugMode) { + l_debugMode = FALSE; + } else { + l_debugMode = TRUE; + } + } + + if (l_debugMode) { +#endif +#if TARGET_PC || DEBUG if (checkModeFlg(0x400) && !checkBoardRide() && !checkSpinnerRide()) { if (checkCanoeRide()) { setSyncCanoePos(); @@ -18060,16 +18073,28 @@ int daAlink_c::execute() { } } else { f32 moveSpeed; +#if TARGET_PC if (mDoCPd_c::getHoldZ(PAD_1)) { +#else + if (mDoCPd_c::getHoldLockR(PAD_1)) { +#endif moveSpeed = 100.0f; } else { moveSpeed = 50.0f; } +#if TARGET_PC f32 cStickY = mDoCPd_c::getSubStickY(PAD_1); if (cStickY > 0.3f || cStickY < -0.3f) { current.pos.y += moveSpeed * cStickY; } +#else + if (mDoCPd_c::getHoldY(PAD_1)) { + current.pos.y += moveSpeed; + } else if (mDoCPd_c::getHoldX(PAD_1)) { + current.pos.y -= moveSpeed; + } +#endif current.pos.x += moveSpeed * mStickValue * cM_ssin(mMoveAngle); current.pos.z += moveSpeed * mStickValue * cM_scos(mMoveAngle); @@ -18088,54 +18113,6 @@ int daAlink_c::execute() { setAttentionPos(); } else #endif - #if DEBUG - if (daPy_getPlayerActorClass() == this && checkDebugMoveInput()) { - isTrigDebugMoveInput = TRUE; - if (l_debugMode) { - l_debugMode = FALSE; - } else { - l_debugMode = TRUE; - } - } - - if (l_debugMode) { - if (checkModeFlg(0x400) && !checkBoardRide() && !checkSpinnerRide()) { - if (checkCanoeRide()) { - setSyncCanoePos(); - } else { - setSyncRide(0); - } - } else { - f32 moveSpeed; - if (mDoCPd_c::getHoldLockR(PAD_1)) { - moveSpeed = 100.0f; - } else { - moveSpeed = 50.0f; - } - - if (mDoCPd_c::getHoldY(PAD_1)) { - current.pos.y += moveSpeed; - } else if (mDoCPd_c::getHoldX(PAD_1)) { - current.pos.y -= moveSpeed; - } - - current.pos.x += moveSpeed * mStickValue * cM_ssin(mMoveAngle); - current.pos.z += moveSpeed * mStickValue * cM_scos(mMoveAngle); - } - - setMatrix(); - mpLinkModel->calc(); - - if (!checkWolf()) { - setItemMatrix(0); - } else { - setWolfItemMatrix(); - } - - setBodyPartPos(); - setAttentionPos(); - } else - #endif { if (isTrigDebugMoveInput) { mItemButton = 0;