Fix World Map cursor threshold and touchpad issues (#190)

* input_patches: fix cursor threshold and SFX during tutorial

* input_patches: fix touchpad flag magnetism
This commit is contained in:
Hyper 2025-01-25 18:51:25 +00:00 committed by GitHub
parent 470d8f797b
commit 5441075c5e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 45 deletions

View file

@ -4,10 +4,12 @@
#include <app.h> #include <app.h>
#include <exports.h> #include <exports.h>
constexpr double WORLD_MAP_ROTATE_DEADZONE = 0.69999999;
constexpr double WORLD_MAP_CURSOR_DEADZONE = 0.30000001;
class WorldMapTouchParams class WorldMapTouchParams
{ {
public: public:
float CancelDeadzone{ 0.31f };
float Damping{ 0.99f }; float Damping{ 0.99f };
float FlickAccelX{ 0.25f }; float FlickAccelX{ 0.25f };
float FlickAccelY{ 0.1f }; float FlickAccelY{ 0.1f };
@ -149,7 +151,7 @@ g_sdlEventListenerForInputPatches;
// -------------- COMMON --------------- // // -------------- COMMON --------------- //
static bool IsDPadActive(SWA::SPadState* pPadState) static bool IsDPadThreshold(const SWA::SPadState* pPadState)
{ {
return pPadState->IsDown(SWA::eKeyState_DpadUp) || return pPadState->IsDown(SWA::eKeyState_DpadUp) ||
pPadState->IsDown(SWA::eKeyState_DpadDown) || pPadState->IsDown(SWA::eKeyState_DpadDown) ||
@ -157,6 +159,23 @@ static bool IsDPadActive(SWA::SPadState* pPadState)
pPadState->IsDown(SWA::eKeyState_DpadRight); pPadState->IsDown(SWA::eKeyState_DpadRight);
} }
static bool IsLeftStickThreshold(const SWA::SPadState* pPadState, double deadzone = 0)
{
return sqrtl((pPadState->LeftStickHorizontal * pPadState->LeftStickHorizontal) +
(pPadState->LeftStickVertical * pPadState->LeftStickVertical)) > deadzone;
}
static bool IsTouchThreshold(double deadzone = 0, bool isBelowThreshold = false)
{
auto sqrt = sqrtl((g_worldMapTouchVelocityX * g_worldMapTouchVelocityX) +
(g_worldMapTouchVelocityY * g_worldMapTouchVelocityY));
if (isBelowThreshold)
return sqrt < deadzone;
return sqrt >= deadzone;
}
static void SetDPadAnalogDirectionX(PPCRegister& pPadState, PPCRegister& x, bool invert, float max = 1.0f) static void SetDPadAnalogDirectionX(PPCRegister& pPadState, PPCRegister& x, bool invert, float max = 1.0f)
{ {
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32); auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
@ -227,48 +246,55 @@ void PostureSpaceHurrierDPadSupportYMidAsmHook(PPCRegister& pPadState, PPCVRegis
// ------------- WORLD MAP ------------- // // ------------- WORLD MAP ------------- //
bool WorldMapTouchSupportMidAsmHook() bool WorldMapDeadzoneMidAsmHook(PPCRegister& pPadState)
{ {
SDLEventListenerForInputPatches::Update(App::s_deltaTime); auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
auto vxAbs = fabs(g_worldMapTouchVelocityX); if (IsLeftStickThreshold(pGuestPadState))
auto vyAbs = fabs(g_worldMapTouchVelocityY); {
g_worldMapTouchVelocityX = 0;
g_worldMapTouchVelocityY = 0;
}
else
{
SDLEventListenerForInputPatches::Update(App::s_deltaTime);
/* Reduce touch noise if the player has /* Reduce touch noise if the player has their finger
their finger resting on the touchpad, resting on the touchpad, but allow much precise values
but allow much precise values without without touch for proper interpolation to zero. */
touch for proper interpolation to zero. */ if (IsTouchThreshold(0.05, true))
if (vxAbs < 0.05f || vyAbs < 0.05f) return !g_isTouchActive;
return !g_isTouchActive;
return vxAbs > 0 || vyAbs > 0; return IsTouchThreshold();
}
return IsDPadThreshold(pGuestPadState) || IsLeftStickThreshold(pGuestPadState, WORLD_MAP_ROTATE_DEADZONE);
} }
bool WorldMapTouchMagnetismSupportMidAsmHook(PPCRegister& f0) bool WorldMapMagnetismMidAsmHook(PPCRegister& f0)
{ {
return fabs(g_worldMapTouchVelocityX) > f0.f64 || fabs(g_worldMapTouchVelocityY) > f0.f64; if (IsTouchThreshold(f0.f64, true))
{
g_worldMapTouchVelocityX = 0;
g_worldMapTouchVelocityY = 0;
return true;
}
return false;
} }
void TouchAndDPadSupportWorldMapXMidAsmHook(PPCRegister& pPadState, PPCRegister& x) void TouchAndDPadSupportWorldMapXMidAsmHook(PPCRegister& pPadState, PPCRegister& x)
{ {
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32); auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (fabs(pGuestPadState->LeftStickHorizontal) > g_worldMapTouchParams.CancelDeadzone || if (IsDPadThreshold(pGuestPadState))
fabs(pGuestPadState->LeftStickVertical) > g_worldMapTouchParams.CancelDeadzone)
{ {
g_worldMapTouchVelocityX = 0;
}
if (IsDPadActive(pGuestPadState))
{
g_worldMapTouchVelocityX = 0;
SetDPadAnalogDirectionX(pPadState, x, false); SetDPadAnalogDirectionX(pPadState, x, false);
} }
else else if (fabs(g_worldMapTouchVelocityX) > 0)
{ {
if (fabs(g_worldMapTouchVelocityX) > 0) x.f64 = -g_worldMapTouchVelocityX;
x.f64 = -g_worldMapTouchVelocityX;
} }
} }
@ -276,22 +302,13 @@ void TouchAndDPadSupportWorldMapYMidAsmHook(PPCRegister& pPadState, PPCRegister&
{ {
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32); auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (fabs(pGuestPadState->LeftStickHorizontal) > g_worldMapTouchParams.CancelDeadzone || if (IsDPadThreshold(pGuestPadState))
fabs(pGuestPadState->LeftStickVertical) > g_worldMapTouchParams.CancelDeadzone)
{ {
g_worldMapTouchVelocityY = 0;
}
if (IsDPadActive(pGuestPadState))
{
g_worldMapTouchVelocityY = 0;
SetDPadAnalogDirectionY(pPadState, y, false); SetDPadAnalogDirectionY(pPadState, y, false);
} }
else else if (fabs(g_worldMapTouchVelocityY) > 0)
{ {
if (fabs(g_worldMapTouchVelocityY) > 0) y.f64 = g_worldMapTouchVelocityY;
y.f64 = g_worldMapTouchVelocityY;
} }
} }
@ -313,7 +330,7 @@ PPC_FUNC(sub_8256C938)
{ {
auto pWorldMapCursor = (SWA::CWorldMapCursor*)g_memory.Translate(ctx.r3.u32); auto pWorldMapCursor = (SWA::CWorldMapCursor*)g_memory.Translate(ctx.r3.u32);
pWorldMapCursor->m_IsCursorMoving = g_isTouchActive; pWorldMapCursor->m_IsCursorMoving = g_isTouchActive && IsTouchThreshold(1.0);
if (ctx.r4.u8) if (ctx.r4.u8)
{ {
@ -339,8 +356,8 @@ PPC_FUNC(sub_8256C938)
if (rPadState.IsDown(SWA::eKeyState_DpadRight)) if (rPadState.IsDown(SWA::eKeyState_DpadRight))
pWorldMapCursor->m_LeftStickHorizontal = 1.0f; pWorldMapCursor->m_LeftStickHorizontal = 1.0f;
if (sqrtf((pWorldMapCursor->m_LeftStickHorizontal * pWorldMapCursor->m_LeftStickHorizontal) + if (sqrtl((pWorldMapCursor->m_LeftStickHorizontal * pWorldMapCursor->m_LeftStickHorizontal) +
(pWorldMapCursor->m_LeftStickVertical * pWorldMapCursor->m_LeftStickVertical)) > 0.7f) (pWorldMapCursor->m_LeftStickVertical * pWorldMapCursor->m_LeftStickVertical)) > WORLD_MAP_ROTATE_DEADZONE)
{ {
pWorldMapCursor->m_IsCursorMoving = true; pWorldMapCursor->m_IsCursorMoving = true;
} }

View file

@ -647,16 +647,18 @@ after_instruction = true
# SWA::CWorldMapCamera - disable rotation deadzone for touch # SWA::CWorldMapCamera - disable rotation deadzone for touch
[[midasm_hook]] [[midasm_hook]]
name = "WorldMapTouchSupportMidAsmHook" name = "WorldMapDeadzoneMidAsmHook"
address = 0x824862EC address = 0x824862EC
registers = ["r30"]
jump_address_on_true = 0x824862F0 jump_address_on_true = 0x824862F0
# SWA::CWorldMapCamera - disable flag magnetism for touch # SWA::CWorldMapCamera - disable flag magnetism for touch
[[midasm_hook]] [[midasm_hook]]
name = "WorldMapTouchMagnetismSupportMidAsmHook" name = "WorldMapMagnetismMidAsmHook"
address = 0x824866D4 address = 0x824866D4
registers = ["f0"] registers = ["f0"]
jump_address_on_true = 0x82486838 jump_address_on_true = 0x824866D8
jump_address_on_false = 0x82486838
# SWA::CWorldMapCamera - touch and D-Pad support for camera adjustment threshold on the X axis # SWA::CWorldMapCamera - touch and D-Pad support for camera adjustment threshold on the X axis
[[midasm_hook]] [[midasm_hook]]