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,47 +246,54 @@ void PostureSpaceHurrierDPadSupportYMidAsmHook(PPCRegister& pPadState, PPCVRegis
// ------------- WORLD MAP ------------- // // ------------- WORLD MAP ------------- //
bool WorldMapTouchSupportMidAsmHook() bool WorldMapDeadzoneMidAsmHook(PPCRegister& pPadState)
{ {
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
if (IsLeftStickThreshold(pGuestPadState))
{
g_worldMapTouchVelocityX = 0;
g_worldMapTouchVelocityY = 0;
}
else
{
SDLEventListenerForInputPatches::Update(App::s_deltaTime); SDLEventListenerForInputPatches::Update(App::s_deltaTime);
auto vxAbs = fabs(g_worldMapTouchVelocityX); /* Reduce touch noise if the player has their finger
auto vyAbs = fabs(g_worldMapTouchVelocityY); resting on the touchpad, but allow much precise values
without touch for proper interpolation to zero. */
/* Reduce touch noise if the player has if (IsTouchThreshold(0.05, true))
their finger resting on the touchpad,
but allow much precise values without
touch for proper interpolation to zero. */
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,21 +302,12 @@ 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]]