mirror of
https://github.com/zeldaret/ss
synced 2026-06-06 03:28:56 -04:00
242 lines
7.0 KiB
C++
242 lines
7.0 KiB
C++
#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 sIsCursorStickVisible = 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;
|
|
setCursorStickInvisible();
|
|
}
|
|
|
|
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) {
|
|
setCursorStickVisible();
|
|
sDisableAutoReturnToPointerNav = disableAutoReturnToPointerNav;
|
|
} else {
|
|
setCursorStickInvisible();
|
|
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 setCursorStickInvisible() {
|
|
sIsCursorStickVisible = false;
|
|
}
|
|
|
|
void setCursorStickVisible() {
|
|
sIsCursorStickVisible = 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
|