diff options
| author | robojumper <robojumper@gmail.com> | 2025-07-26 18:08:58 +0200 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2025-07-26 18:11:18 +0200 |
| commit | 58866f517f5cb0c2eb138d334a43b8e3da4f9b76 (patch) | |
| tree | 366c55a3a70db54139b8081426c970544ce1bf0d /src/d/d_pad_nav.cpp | |
| parent | 4ec5128eb4f6cdc8985f83f4c8b540115daf47fb (diff) | |
d_pad_nav OK
Diffstat (limited to 'src/d/d_pad_nav.cpp')
| -rw-r--r-- | src/d/d_pad_nav.cpp | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/d/d_pad_nav.cpp b/src/d/d_pad_nav.cpp new file mode 100644 index 00000000..62f28216 --- /dev/null +++ b/src/d/d_pad_nav.cpp @@ -0,0 +1,241 @@ +#include "d/d_pad_nav.h" + +#include "d/d_pad.h" +#include "m/m_vec.h" + +namespace dPadNav { + +bool sIsNavEnabled = false; +bool sIsMplsNavLeftGesture = false; +bool sIsMplsNavRightGesture = false; +static bool sDisableAutoReturnToPointerNav = false; + +bool sIsPointerVisible = true; +bool sPrevIsPointerVisible = true; +bool sUnkCursorRelated = true; + +s32 sFSStickDirection; +s32 sFSStickNavDirection; + +static s32 sFSStickNavActiveTimer = 0; +static s32 sFSStickDirectionStableTimer = 0; +static s32 sMPLSNavGestureTimer = 0; + +void init() { + sIsNavEnabled = false; + sIsPointerVisible = true; + sIsMplsNavLeftGesture = false; + sIsMplsNavRightGesture = false; + sDisableAutoReturnToPointerNav = false; + sPrevIsPointerVisible = true; + sFSStickDirection = FS_STICK_NONE; + sFSStickNavDirection = FS_STICK_NONE; + sFSStickNavActiveTimer = 0; + sFSStickDirectionStableTimer = 0; + sMPLSNavGestureTimer = 0; + offUnkCursorRelated(); +} + +void calc() { + sPrevIsPointerVisible = sIsPointerVisible; + sFSStickNavDirection = FS_STICK_NONE; + + if (!sIsNavEnabled) { + return; + } + + mVec3_c vel = dPad::ex_c::getInstance()->getMPLSVelocity(); + if (sMPLSNavGestureTimer != 0) { + sMPLSNavGestureTimer--; + sIsMplsNavLeftGesture = false; + sIsMplsNavRightGesture = false; + } else { + checkForNavLeftGesture(); + checkForNavRightGesture(); + } + + if (vel.squareMagXY() > 1.5f) { + // Large MPLS movement - stop FS stick navigation + stopFSStickNav(); + return; + } + + if (sIsPointerVisible) { + if (dPad::ex_c::getInstance()->getFSStickTrig()) { + // starting FS stick navigation - immediate nav event, with delay of + // 8 frames (267ms) for repeat nav event + sFSStickDirection = getFSStickDirectionTrig(); + sFSStickNavDirection = sFSStickDirection; + sFSStickNavActiveTimer = 120; + sFSStickDirectionStableTimer = 8; + sIsPointerVisible = false; + } + } else { + s32 direction = getFSStickDirection(); + if (sFSStickDirection != FS_STICK_NONE && direction == sFSStickDirection) { + // no change in FS stick direction + sFSStickNavActiveTimer = 120; + if (sFSStickDirectionStableTimer == 0) { + // repeat event - now with a delay of 3 frames (100ms) + sFSStickNavDirection = sFSStickDirection; + sFSStickDirectionStableTimer = 3; + } else { + sFSStickDirectionStableTimer--; + } + } else { + if (dPad::ex_c::getInstance()->getFSStickTrig()) { + // change in FS stick direction - same as if started navigation + direction = getFSStickDirectionTrig(); + sFSStickDirectionStableTimer = 8; + sFSStickDirection = direction; + sFSStickNavDirection = direction; + sFSStickNavActiveTimer = 120; + } else { + // let go of FS stick + sFSStickDirection = FS_STICK_NONE; + sFSStickDirectionStableTimer = 0; + } + } + + if (!sDisableAutoReturnToPointerNav) { + if (sFSStickNavActiveTimer == 0) { + // FS stick nav timer expired (or was set to 0 via explicit call), + // check if we need to return to pointer nav + if (direction != FS_STICK_NONE && sFSStickDirection == direction) { + sFSStickNavActiveTimer = 120; + } else { + if (direction == FS_STICK_NONE) { + // No direction, return to pointer nav + sFSStickDirection = FS_STICK_NONE; + sIsPointerVisible = true; + } else { + sFSStickDirectionStableTimer = 8; + // Note: Redundant check + if (!sDisableAutoReturnToPointerNav) { + sFSStickDirection = direction; + } + sFSStickNavDirection = sFSStickDirection; + sFSStickNavActiveTimer = 120; + } + } + } else { + sFSStickNavActiveTimer--; + } + } + } +} + +void setNavEnabled(bool navEnabled, bool disableAutoReturnToPointerNav) { + sIsNavEnabled = navEnabled; + sIsPointerVisible = true; + if (navEnabled) { + onUnkCursorRelated(); + sDisableAutoReturnToPointerNav = disableAutoReturnToPointerNav; + } else { + offUnkCursorRelated(); + sDisableAutoReturnToPointerNav = false; + } +} + +s32 getFSStickDirectionTrig() { + if (dPad::ex_c::getInstance()->getFSStickTrig(0x1)) { + return FS_STICK_UP; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x80)) { + return FS_STICK_UP_RIGHT; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x40)) { + return FS_STICK_RIGHT; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x20)) { + return FS_STICK_DOWN_RIGHT; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x10)) { + return FS_STICK_DOWN; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x8)) { + return FS_STICK_DOWN_LEFT; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x4)) { + return FS_STICK_LEFT; + } + + if (dPad::ex_c::getInstance()->getFSStickTrig(0x2)) { + return FS_STICK_UP_LEFT; + } + + return FS_STICK_NONE; +} + +s32 getFSStickDirection() { + switch (dPad::ex_c::getInstance()->mFSStickMask) { + case 0x1: return FS_STICK_UP; + case 0x80: return FS_STICK_UP_RIGHT; + case 0x40: return FS_STICK_RIGHT; + case 0x20: return FS_STICK_DOWN_RIGHT; + case 0x10: return FS_STICK_DOWN; + case 0x8: return FS_STICK_DOWN_LEFT; + case 0x4: return FS_STICK_LEFT; + case 0x2: return FS_STICK_UP_LEFT; + } + + return FS_STICK_NONE; +} + +void stopFSStickNav() { + sFSStickNavActiveTimer = 0; + sIsPointerVisible = true; +} + +void hidePointer() { + sIsPointerVisible = false; +} + +void offUnkCursorRelated() { + sUnkCursorRelated = false; +} + +void onUnkCursorRelated() { + sUnkCursorRelated = true; +} + +void checkForNavLeftGesture() { + mVec3_c vel = dPad::ex_c::getInstance()->getMPLSVelocity(); + if (vel.y <= 0.0f && vel.squareMagXY() > 1.5f) { + if (!sIsPointerVisible) { + sMPLSNavGestureTimer = 10; + sIsMplsNavLeftGesture = false; + } else { + sIsMplsNavLeftGesture = true; + } + } else { + sIsMplsNavLeftGesture = false; + } +} + +void checkForNavRightGesture() { + mVec3_c vel = dPad::ex_c::getInstance()->getMPLSVelocity(); + if (vel.y >= 0.0f && vel.squareMagXY() > 1.5f) { + if (!sIsPointerVisible) { + sMPLSNavGestureTimer = 10; + sIsMplsNavRightGesture = false; + } else { + sIsMplsNavRightGesture = true; + } + } else { + sIsMplsNavRightGesture = false; + } +} + +void scrollRelated() { + sFSStickDirectionStableTimer = 3; + sFSStickNavActiveTimer = 120; +} + +} // namespace dPadNav |
