mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Mouse input: Approximate the old smoothing function
This commit is contained in:
parent
7b0ee5440d
commit
d397635e49
@ -34,6 +34,8 @@ void GenerateDPadEvent(int digitalX, int digitalY);
|
||||
void GenerateActionButtonEvent(int digitalX, int digitalY);
|
||||
void GenerateTriggerButtonEvent(int digitalX, int digitalY);
|
||||
|
||||
}
|
||||
|
||||
// deadzone is normalized - 0 to 1
|
||||
// sensitivity controls how fast the deadzone reaches max value
|
||||
inline float ApplyDeadzoneAxis(float x, float deadzone) {
|
||||
@ -51,32 +53,35 @@ inline float ApplyDeadzoneAxis(float x, float deadzone) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void ApplyDeadzoneXY(float tiltX, float tiltY, float *adjustedTiltX, float *adjustedTiltY, float deadzone, bool circular) {
|
||||
|
||||
inline void ApplyDeadzoneXY(float x, float y, float *adjustedX, float *adjustedY, float deadzone, bool circular) {
|
||||
if (circular) {
|
||||
if (tiltX == 0.0f && tiltY == 0.0f) {
|
||||
*adjustedTiltX = 0.0f;
|
||||
*adjustedTiltY = 0.0f;
|
||||
if (x == 0.0f && y == 0.0f) {
|
||||
*adjustedX = 0.0f;
|
||||
*adjustedY = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
float magnitude = sqrtf(tiltX * tiltX + tiltY * tiltY);
|
||||
float magnitude = sqrtf(x * x + y * y);
|
||||
if (magnitude <= deadzone + 0.00001f) {
|
||||
*adjustedTiltX = 0.0f;
|
||||
*adjustedTiltY = 0.0f;
|
||||
*adjustedX = 0.0f;
|
||||
*adjustedY = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
float factor = 1.0f / (1.0f - deadzone);
|
||||
float newMagnitude = (magnitude - deadzone) * factor;
|
||||
|
||||
*adjustedTiltX = (tiltX / magnitude) * newMagnitude;
|
||||
*adjustedTiltY = (tiltY / magnitude) * newMagnitude;
|
||||
*adjustedX = (x / magnitude) * newMagnitude;
|
||||
*adjustedY = (y / magnitude) * newMagnitude;
|
||||
} else {
|
||||
*adjustedTiltX = ApplyDeadzoneAxis(tiltX, deadzone);
|
||||
*adjustedTiltY = ApplyDeadzoneAxis(tiltY, deadzone);
|
||||
*adjustedX = ApplyDeadzoneAxis(x, deadzone);
|
||||
*adjustedY = ApplyDeadzoneAxis(y, deadzone);
|
||||
}
|
||||
}
|
||||
|
||||
namespace TiltEventProcessor {
|
||||
|
||||
// Also clamps to -1.0..1.0.
|
||||
// This applies a (circular if desired) inverse deadzone.
|
||||
inline void ApplyInverseDeadzone(float x, float y, float *outX, float *outY, float inverseDeadzone, bool circular) {
|
||||
@ -310,39 +315,64 @@ namespace MouseEventProcessor {
|
||||
// But, the cost isn't high.
|
||||
std::mutex g_mouseMutex;
|
||||
|
||||
float g_mouseDeltaX = 0;
|
||||
float g_mouseDeltaY = 0;
|
||||
float g_mouseDeltaXAccum = 0;
|
||||
float g_mouseDeltaYAccum = 0;
|
||||
|
||||
void ProcessDelta(float dx, float dy) {
|
||||
std::unique_lock<std::mutex> lock(g_mouseMutex);
|
||||
// Accumulate mouse deltas, for some kind of smoothing.
|
||||
g_mouseDeltaX += dx;
|
||||
g_mouseDeltaY += dy;
|
||||
}
|
||||
float g_mouseDeltaX;
|
||||
float g_mouseDeltaY;
|
||||
|
||||
void MouseDeltaToAxes(double now, float *mx, float *my) {
|
||||
std::unique_lock<std::mutex> lock(g_mouseMutex);
|
||||
void DecayMouse(double now) {
|
||||
g_mouseDeltaX = g_mouseDeltaXAccum;
|
||||
g_mouseDeltaY = g_mouseDeltaYAccum;
|
||||
|
||||
const float decay = g_Config.fMouseSmoothing;
|
||||
|
||||
static double lastTime = 0.0f;
|
||||
if (lastTime == 0.0) {
|
||||
lastTime = now;
|
||||
*mx = 0.0f;
|
||||
*my = 0.0f;
|
||||
return;
|
||||
}
|
||||
double dt = now - lastTime;
|
||||
lastTime = now;
|
||||
|
||||
// Decay the mouse deltas. We do an approximation of the old polling.
|
||||
// Should be able to use a smooth exponential here, when I get around to doing
|
||||
// the math.
|
||||
static double accumDt = 0.0;
|
||||
accumDt += dt;
|
||||
const double oldPollInterval = 1.0 / 250.0; // See Windows "PollControllers".
|
||||
while (accumDt > oldPollInterval) {
|
||||
accumDt -= oldPollInterval;
|
||||
g_mouseDeltaXAccum *= decay;
|
||||
g_mouseDeltaYAccum *= decay;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessDelta(double now, float dx, float dy) {
|
||||
std::unique_lock<std::mutex> lock(g_mouseMutex);
|
||||
|
||||
// Accumulate mouse deltas, for some kind of smoothing.
|
||||
g_mouseDeltaXAccum += dx;
|
||||
g_mouseDeltaYAccum += dy;
|
||||
|
||||
DecayMouse(now);
|
||||
}
|
||||
|
||||
void MouseDeltaToAxes(double now, float *mx, float *my) {
|
||||
std::unique_lock<std::mutex> lock(g_mouseMutex);
|
||||
|
||||
float scaleFactor_x = g_display.dpi_scale_x * 0.1 * g_Config.fMouseSensitivity;
|
||||
float scaleFactor_y = g_display.dpi_scale_y * 0.1 * g_Config.fMouseSensitivity;
|
||||
|
||||
*mx = clamp_value(g_mouseDeltaX * scaleFactor_x, -1.0f, 1.0f);
|
||||
*my = clamp_value(g_mouseDeltaY * scaleFactor_y, -1.0f, 1.0f);
|
||||
DecayMouse(now);
|
||||
|
||||
// Decay the mouse deltas. This is where we should use dt.
|
||||
float decay = expf(-dt * 50.0f * (1.0f - g_Config.fMouseSmoothing));
|
||||
g_mouseDeltaX *= decay;
|
||||
g_mouseDeltaY *= decay;
|
||||
// TODO: Make configurable.
|
||||
float mouseDeadZone = 0.1f;
|
||||
|
||||
float outX = clamp_value(g_mouseDeltaX * scaleFactor_x, -1.0f, 1.0f);
|
||||
float outY = clamp_value(g_mouseDeltaY * scaleFactor_y, -1.0f, 1.0f);
|
||||
|
||||
ApplyDeadzoneXY(outX, outY, mx, my, mouseDeadZone, true);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -19,7 +19,7 @@ extern float rawTiltAnalogY;
|
||||
|
||||
namespace MouseEventProcessor {
|
||||
|
||||
void ProcessDelta(float dx, float dy);
|
||||
void ProcessDelta(double now, float dx, float dy);
|
||||
void MouseDeltaToAxes(double now, float *mx, float *my);
|
||||
|
||||
} // namespace
|
||||
|
@ -1329,7 +1329,7 @@ void NativeMouseDelta(float dx, float dy) {
|
||||
if (!g_Config.bMouseControl)
|
||||
return;
|
||||
|
||||
MouseEventProcessor::ProcessDelta(dx, dy);
|
||||
MouseEventProcessor::ProcessDelta(time_now_d(), dx, dy);
|
||||
}
|
||||
|
||||
// Called from NativeFrame.
|
||||
|
@ -77,7 +77,7 @@ void WindowsInputManager::Init() {
|
||||
}
|
||||
|
||||
void WindowsInputManager::PollControllers() {
|
||||
static const int CHECK_FREQUENCY = 71;
|
||||
static const int CHECK_FREQUENCY = 71; // Just an arbitrary prime to try to not collide with other periodic checks.
|
||||
if (checkCounter_++ > CHECK_FREQUENCY) {
|
||||
#ifndef _M_ARM
|
||||
size_t newCount = DinputDevice::getNumPads();
|
||||
|
Loading…
Reference in New Issue
Block a user