mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-26 12:21:39 +00:00
Improved touchpad sensitivity
This commit is contained in:
parent
60104dbe99
commit
5e0ed3e20c
5 changed files with 157 additions and 27 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#include <SDL.h>
|
||||
#include <user/config.h>
|
||||
#include <hid/hid.h>
|
||||
#include <os/logger.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <kernel/xdm.h>
|
||||
#include <app.h>
|
||||
|
|
@ -170,6 +171,15 @@ static void SetControllerInputDevice(Controller* controller)
|
|||
|
||||
hid::g_inputDevice = controller->GetInputDevice();
|
||||
hid::g_inputDeviceController = hid::g_inputDevice;
|
||||
|
||||
auto controllerType = (hid::EInputDeviceExplicit)controller->GetControllerType();
|
||||
|
||||
if (hid::g_inputDeviceExplicit != controllerType)
|
||||
{
|
||||
hid::g_inputDeviceExplicit = controllerType;
|
||||
|
||||
LOGFN("Detected controller: {}", hid::GetInputDeviceName());
|
||||
}
|
||||
}
|
||||
|
||||
int HID_OnSDLEvent(void*, SDL_Event* event)
|
||||
|
|
@ -199,6 +209,7 @@ int HID_OnSDLEvent(void*, SDL_Event* event)
|
|||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
{
|
||||
auto* controller = FindController(event->cdevice.which);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
hid::EInputDevice hid::g_inputDevice;
|
||||
hid::EInputDevice hid::g_inputDeviceController;
|
||||
hid::EInputDeviceExplicit hid::g_inputDeviceExplicit;
|
||||
|
||||
uint16_t hid::g_prohibitedButtons;
|
||||
|
||||
|
|
@ -15,3 +16,59 @@ bool hid::IsInputDeviceController()
|
|||
return hid::g_inputDevice != hid::EInputDevice::Keyboard &&
|
||||
hid::g_inputDevice != hid::EInputDevice::Mouse;
|
||||
}
|
||||
|
||||
std::string hid::GetInputDeviceName()
|
||||
{
|
||||
switch (g_inputDevice)
|
||||
{
|
||||
case EInputDevice::Keyboard:
|
||||
return "Keyboard";
|
||||
|
||||
case EInputDevice::Mouse:
|
||||
return "Mouse";
|
||||
}
|
||||
|
||||
switch (g_inputDeviceExplicit)
|
||||
{
|
||||
case EInputDeviceExplicit::Xbox360:
|
||||
return "Xbox 360";
|
||||
|
||||
case EInputDeviceExplicit::XboxOne:
|
||||
return "Xbox One";
|
||||
|
||||
case EInputDeviceExplicit::DualShock3:
|
||||
return "DualShock 3";
|
||||
|
||||
case EInputDeviceExplicit::DualShock4:
|
||||
return "DualShock 4";
|
||||
|
||||
case EInputDeviceExplicit::SwitchPro:
|
||||
return "Nintendo Switch Pro";
|
||||
|
||||
case EInputDeviceExplicit::Virtual:
|
||||
return "Virtual";
|
||||
|
||||
case EInputDeviceExplicit::DualSense:
|
||||
return "DualSense";
|
||||
|
||||
case EInputDeviceExplicit::Luna:
|
||||
return "Amazon Luna";
|
||||
|
||||
case EInputDeviceExplicit::Stadia:
|
||||
return "Google Stadia";
|
||||
|
||||
case EInputDeviceExplicit::NvShield:
|
||||
return "NVIDIA Shield";
|
||||
|
||||
case EInputDeviceExplicit::SwitchJCLeft:
|
||||
return "Nintendo Switch Joy-Con (Left)";
|
||||
|
||||
case EInputDeviceExplicit::SwitchJCRight:
|
||||
return "Nintendo Switch Joy-Con (Right)";
|
||||
|
||||
case EInputDeviceExplicit::SwitchJCPair:
|
||||
return "Nintendo Switch Joy-Con (Pair)";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,27 @@ namespace hid
|
|||
PlayStation
|
||||
};
|
||||
|
||||
enum class EInputDeviceExplicit
|
||||
{
|
||||
Unknown,
|
||||
Xbox360,
|
||||
XboxOne,
|
||||
DualShock3,
|
||||
DualShock4,
|
||||
SwitchPro,
|
||||
Virtual,
|
||||
DualSense,
|
||||
Luna,
|
||||
Stadia,
|
||||
NvShield,
|
||||
SwitchJCLeft,
|
||||
SwitchJCRight,
|
||||
SwitchJCPair
|
||||
};
|
||||
|
||||
extern EInputDevice g_inputDevice;
|
||||
extern EInputDevice g_inputDeviceController;
|
||||
extern EInputDeviceExplicit g_inputDeviceExplicit;
|
||||
|
||||
extern uint16_t g_prohibitedButtons;
|
||||
|
||||
|
|
@ -23,4 +42,5 @@ namespace hid
|
|||
uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps);
|
||||
|
||||
bool IsInputDeviceController();
|
||||
std::string GetInputDeviceName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,46 @@
|
|||
#include <api/SWA.h>
|
||||
#include <hid/hid.h>
|
||||
#include <ui/sdl_listener.h>
|
||||
#include <app.h>
|
||||
#include <exports.h>
|
||||
|
||||
constexpr float WORLD_MAP_TOUCH_CANCEL_DEADZONE = 0.31f;
|
||||
constexpr float WORLD_MAP_TOUCH_DAMPING_FACTOR = 0.99f;
|
||||
constexpr float WORLD_MAP_TOUCH_FLICK_ACCELERATION_X = 0.4f;
|
||||
constexpr float WORLD_MAP_TOUCH_FLICK_ACCELERATION_Y = 0.2f;
|
||||
constexpr float WORLD_MAP_TOUCH_FLICK_TERMINAL_VELOCITY = 40.0f;
|
||||
constexpr float WORLD_MAP_TOUCH_FLICK_THRESHOLD = 2.25f;
|
||||
constexpr float WORLD_MAP_TOUCH_SENSITIVITY_MULTIPLIER = 1.35f;
|
||||
constexpr float WORLD_MAP_TOUCH_SMOOTHING_FACTOR = 0.8f;
|
||||
class WorldMapTouchParams
|
||||
{
|
||||
public:
|
||||
float CancelDeadzone{ 0.31f };
|
||||
float Damping{ 0.99f };
|
||||
float FlickAccelX{ 0.25f };
|
||||
float FlickAccelY{ 0.1f };
|
||||
float FlickTerminalVelocity{ 40.0f };
|
||||
float FlickThreshold{ 2.25f };
|
||||
float SensitivityX{};
|
||||
float SensitivityY{};
|
||||
float Smoothing{ 0.8f };
|
||||
};
|
||||
|
||||
class WorldMapTouchParamsProspero : public WorldMapTouchParams
|
||||
{
|
||||
public:
|
||||
WorldMapTouchParamsProspero()
|
||||
{
|
||||
SensitivityX = 1.15f;
|
||||
SensitivityY = 1.05f;
|
||||
}
|
||||
}
|
||||
g_worldMapTouchParamsProspero;
|
||||
|
||||
class WorldMapTouchParamsOrbis : public WorldMapTouchParams
|
||||
{
|
||||
public:
|
||||
WorldMapTouchParamsOrbis()
|
||||
{
|
||||
SensitivityX = 0.95f;
|
||||
SensitivityY = 1.0f;
|
||||
}
|
||||
}
|
||||
g_worldMapTouchParamsOrbis;
|
||||
|
||||
WorldMapTouchParams g_worldMapTouchParams{};
|
||||
|
||||
static bool g_isTouchActive;
|
||||
|
||||
|
|
@ -39,37 +69,32 @@ public:
|
|||
|
||||
if (g_isTouchActive)
|
||||
{
|
||||
constexpr auto sensitivity = WORLD_MAP_TOUCH_SENSITIVITY_MULTIPLIER;
|
||||
|
||||
auto dxNorm = ms_touchpadDeltaX / referenceDeltaTime;
|
||||
auto dyNorm = ms_touchpadDeltaY / referenceDeltaTime;
|
||||
auto dxSens = dxNorm * sensitivity;
|
||||
auto dySens = dyNorm * sensitivity;
|
||||
auto dxSens = dxNorm * g_worldMapTouchParams.SensitivityX;
|
||||
auto dySens = dyNorm * g_worldMapTouchParams.SensitivityY;
|
||||
|
||||
auto smoothing = powf(WORLD_MAP_TOUCH_SMOOTHING_FACTOR, deltaTime / referenceDeltaTime);
|
||||
auto smoothing = powf(g_worldMapTouchParams.Smoothing, deltaTime / referenceDeltaTime);
|
||||
|
||||
g_worldMapTouchVelocityX = smoothing * g_worldMapTouchVelocityX + (1.0f - smoothing) * dxSens;
|
||||
g_worldMapTouchVelocityY = smoothing * g_worldMapTouchVelocityY + (1.0f - smoothing) * dySens;
|
||||
|
||||
constexpr auto flickThreshold = WORLD_MAP_TOUCH_FLICK_THRESHOLD;
|
||||
auto flickThreshold = g_worldMapTouchParams.FlickThreshold;
|
||||
|
||||
if (fabs(dxSens) > flickThreshold || fabs(dySens) > flickThreshold)
|
||||
{
|
||||
constexpr auto flickAccelX = WORLD_MAP_TOUCH_FLICK_ACCELERATION_X;
|
||||
constexpr auto flickAccelY = WORLD_MAP_TOUCH_FLICK_ACCELERATION_Y;
|
||||
|
||||
g_worldMapTouchVelocityX += dxNorm * flickAccelX * (deltaTime / referenceDeltaTime);
|
||||
g_worldMapTouchVelocityY += dyNorm * flickAccelY * (deltaTime / referenceDeltaTime);
|
||||
g_worldMapTouchVelocityX += dxNorm * g_worldMapTouchParams.FlickAccelX * (deltaTime / referenceDeltaTime);
|
||||
g_worldMapTouchVelocityY += dyNorm * g_worldMapTouchParams.FlickAccelY * (deltaTime / referenceDeltaTime);
|
||||
}
|
||||
|
||||
constexpr auto terminalVelocity = WORLD_MAP_TOUCH_FLICK_TERMINAL_VELOCITY;
|
||||
auto terminalVelocity = g_worldMapTouchParams.FlickTerminalVelocity;
|
||||
|
||||
g_worldMapTouchVelocityX = std::clamp(g_worldMapTouchVelocityX, -terminalVelocity, terminalVelocity);
|
||||
g_worldMapTouchVelocityY = std::clamp(g_worldMapTouchVelocityY, -terminalVelocity, terminalVelocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto dampingFactor = powf(WORLD_MAP_TOUCH_DAMPING_FACTOR, deltaTime / referenceDeltaTime);
|
||||
auto dampingFactor = powf(g_worldMapTouchParams.Damping, deltaTime / referenceDeltaTime);
|
||||
|
||||
g_worldMapTouchVelocityX *= dampingFactor;
|
||||
g_worldMapTouchVelocityY *= dampingFactor;
|
||||
|
|
@ -101,10 +126,17 @@ public:
|
|||
}
|
||||
|
||||
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||
{
|
||||
g_worldMapTouchParams = hid::g_inputDeviceExplicit == hid::EInputDeviceExplicit::DualSense
|
||||
? (WorldMapTouchParams)g_worldMapTouchParamsProspero
|
||||
: (WorldMapTouchParams)g_worldMapTouchParamsOrbis;
|
||||
|
||||
ms_touchpadFingerCount++;
|
||||
ms_touchpadPrevX = event->ctouchpad.x;
|
||||
ms_touchpadPrevY = event->ctouchpad.y;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLERTOUCHPADUP:
|
||||
g_isTouchActive = false;
|
||||
|
|
@ -199,7 +231,17 @@ bool WorldMapTouchSupportMidAsmHook()
|
|||
{
|
||||
SDLEventListenerForInputPatches::Update(App::s_deltaTime);
|
||||
|
||||
return fabs(g_worldMapTouchVelocityX) > 0 || fabs(g_worldMapTouchVelocityY) > 0;
|
||||
auto vxAbs = fabs(g_worldMapTouchVelocityX);
|
||||
auto vyAbs = fabs(g_worldMapTouchVelocityY);
|
||||
|
||||
/* Reduce touch noise if the player has
|
||||
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 vxAbs > 0 || vyAbs > 0;
|
||||
}
|
||||
|
||||
bool WorldMapTouchMagnetismSupportMidAsmHook(PPCRegister& f0)
|
||||
|
|
@ -211,8 +253,8 @@ void TouchAndDPadSupportWorldMapXMidAsmHook(PPCRegister& pPadState, PPCRegister&
|
|||
{
|
||||
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
|
||||
|
||||
if (fabs(pGuestPadState->LeftStickHorizontal) > WORLD_MAP_TOUCH_CANCEL_DEADZONE ||
|
||||
fabs(pGuestPadState->LeftStickVertical) > WORLD_MAP_TOUCH_CANCEL_DEADZONE)
|
||||
if (fabs(pGuestPadState->LeftStickHorizontal) > g_worldMapTouchParams.CancelDeadzone ||
|
||||
fabs(pGuestPadState->LeftStickVertical) > g_worldMapTouchParams.CancelDeadzone)
|
||||
{
|
||||
g_worldMapTouchVelocityX = 0;
|
||||
}
|
||||
|
|
@ -234,8 +276,8 @@ void TouchAndDPadSupportWorldMapYMidAsmHook(PPCRegister& pPadState, PPCRegister&
|
|||
{
|
||||
auto pGuestPadState = (SWA::SPadState*)g_memory.Translate(pPadState.u32);
|
||||
|
||||
if (fabs(pGuestPadState->LeftStickHorizontal) > WORLD_MAP_TOUCH_CANCEL_DEADZONE ||
|
||||
fabs(pGuestPadState->LeftStickVertical) > WORLD_MAP_TOUCH_CANCEL_DEADZONE)
|
||||
if (fabs(pGuestPadState->LeftStickHorizontal) > g_worldMapTouchParams.CancelDeadzone ||
|
||||
fabs(pGuestPadState->LeftStickVertical) > g_worldMapTouchParams.CancelDeadzone)
|
||||
{
|
||||
g_worldMapTouchVelocityY = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3280a7cf9f3be293ff051b9d56d5dccff79f45ba
|
||||
Subproject commit 73b75e197a6b9e8c1ad693f926c044d0f8f23a0b
|
||||
Loading…
Add table
Reference in a new issue