mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-11 05:26:24 +02:00
Simplify the tilt code, tweak a bit
This commit is contained in:
1 parent
3e286b7a27
commit
64e80423a6
5 files changed
+92
-86
No files matched your search
+83
-73
@@ -19,19 +19,12 @@ static u32 tiltButtonsDown = 0;
|
||||
float rawTiltAnalogX;
|
||||
float rawTiltAnalogY;
|
||||
|
||||
// Represents a generic Tilt event
|
||||
struct Tilt {
|
||||
Tilt() : x_(0), y_(0) {}
|
||||
Tilt(const float x, const float y) : x_(x), y_(y) {}
|
||||
float x_, y_;
|
||||
};
|
||||
|
||||
// These functions generate tilt events given the current Tilt amount,
|
||||
// and the deadzone radius.
|
||||
void GenerateAnalogStickEvent(const Tilt &tilt);
|
||||
void GenerateDPadEvent(const Tilt &tilt);
|
||||
void GenerateActionButtonEvent(const Tilt &tilt);
|
||||
void GenerateTriggerButtonEvent(const Tilt &tilt);
|
||||
void GenerateAnalogStickEvent(float analogX, float analogY);
|
||||
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
|
||||
@@ -47,66 +40,85 @@ inline float ApplyDeadzone(float x, float deadzone) {
|
||||
}
|
||||
}
|
||||
|
||||
// dampen the tilt according to the given deadzone amount.
|
||||
inline Tilt DampenTilt(const Tilt &tilt, float deadzone, float xSensitivity, float ySensitivity) {
|
||||
//multiply sensitivity by 2 so that "overshoot" is possible. I personally prefer a
|
||||
//sensitivity >1 for kingdom hearts and < 1 for Gods Eater. so yes, overshoot is nice
|
||||
//to have.
|
||||
return Tilt(
|
||||
ApplyDeadzone(tilt.x_ * xSensitivity, deadzone),
|
||||
ApplyDeadzone(tilt.y_ * ySensitivity, deadzone)
|
||||
);
|
||||
}
|
||||
|
||||
void ProcessTilt(bool landscape, float calibrationAngle, float x, float y, float z, bool invertX, bool invertY, float xSensitivity, float ySensitivity) {
|
||||
if (g_Config.iTiltInputType == TILT_NULL) {
|
||||
// Turned off - nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
if (landscape) {
|
||||
std::swap(x, y);
|
||||
} else {
|
||||
x *= -1.0f;
|
||||
}
|
||||
|
||||
float deadzone = g_Config.iTiltInputType > 1 ? g_Config.fTiltDigitalDeadzoneRadius : g_Config.fTiltAnalogDeadzoneRadius;
|
||||
|
||||
Lin::Vec3 down = Lin::Vec3(x, y, z).normalized();
|
||||
|
||||
float angleAroundX = atan2(down.z, down.y);
|
||||
float yAngle = angleAroundX - calibrationAngle;
|
||||
float xAngle = asinf(down.x);
|
||||
|
||||
Tilt transformedTilt(xAngle, yAngle);
|
||||
float tiltX = xAngle;
|
||||
float tiltY = yAngle;
|
||||
|
||||
// invert x and y axes if requested. Can probably remove this.
|
||||
if (invertX) {
|
||||
transformedTilt.x_ *= -1.0f;
|
||||
tiltX = -tiltX;
|
||||
}
|
||||
|
||||
if (invertY) {
|
||||
transformedTilt.y_ *= -1.0f;
|
||||
tiltY = -tiltY;
|
||||
}
|
||||
|
||||
// finally, dampen the tilt according to our curve.
|
||||
Tilt tilt = DampenTilt(transformedTilt, deadzone, xSensitivity * 2.0f, ySensitivity * 2.0f);
|
||||
// It's not obvious what the factor for converting from tilt angle to value should be,
|
||||
// but there's nothing that says that 1 would make sense. The important thing is that
|
||||
// the sensitivity sliders get a range of values that makes sense.
|
||||
const float tiltFactor = 3.0f;
|
||||
|
||||
tiltX *= xSensitivity * tiltFactor;
|
||||
tiltY *= ySensitivity * tiltFactor;
|
||||
|
||||
if (g_Config.iTiltInputType == TILT_ANALOG) {
|
||||
// Only analog mappings use the deadzone.
|
||||
|
||||
float adjustedTiltX = ApplyDeadzone(tiltX, g_Config.fTiltAnalogDeadzoneRadius);
|
||||
float adjustedTiltY = ApplyDeadzone(tiltY, g_Config.fTiltAnalogDeadzoneRadius);
|
||||
rawTiltAnalogX = adjustedTiltX;
|
||||
rawTiltAnalogY = adjustedTiltY;
|
||||
GenerateAnalogStickEvent(adjustedTiltX, adjustedTiltY);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remaining are digital now so do the digital check here.
|
||||
// We use a fixed 0.3 threshold instead of a deadzone since you can simply use sensitivity to set it -
|
||||
// these parameters were never independent. It should feel similar to analog that way.
|
||||
int digitalX = 0;
|
||||
int digitalY = 0;
|
||||
const float threshold = 0.5f;
|
||||
if (tiltX < -threshold) {
|
||||
digitalX = -1;
|
||||
} else if (tiltX > threshold) {
|
||||
digitalX = 1;
|
||||
}
|
||||
if (tiltY < -threshold) {
|
||||
digitalY = -1;
|
||||
} else if (tiltY > threshold) {
|
||||
digitalY = 1;
|
||||
}
|
||||
|
||||
switch (g_Config.iTiltInputType) {
|
||||
case TILT_NULL:
|
||||
break;
|
||||
|
||||
case TILT_ANALOG:
|
||||
rawTiltAnalogX = tilt.x_;
|
||||
rawTiltAnalogY = tilt.y_;
|
||||
GenerateAnalogStickEvent(tilt);
|
||||
break;
|
||||
|
||||
case TILT_DPAD:
|
||||
GenerateDPadEvent(tilt);
|
||||
GenerateDPadEvent(digitalX, digitalY);
|
||||
break;
|
||||
|
||||
case TILT_ACTION_BUTTON:
|
||||
GenerateActionButtonEvent(tilt);
|
||||
GenerateActionButtonEvent(digitalX, digitalY);
|
||||
break;
|
||||
|
||||
case TILT_TRIGGER_BUTTONS:
|
||||
GenerateTriggerButtonEvent(tilt);
|
||||
GenerateTriggerButtonEvent(digitalX, digitalY);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,80 +129,78 @@ inline float clamp(float f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
void GenerateAnalogStickEvent(const Tilt &tilt) {
|
||||
__CtrlSetAnalogXY(CTRL_STICK_LEFT, clamp(tilt.x_), clamp(tilt.y_));
|
||||
void GenerateAnalogStickEvent(float tiltX, float tiltY) {
|
||||
__CtrlSetAnalogXY(CTRL_STICK_LEFT, clamp(tiltX), clamp(tiltY));
|
||||
}
|
||||
|
||||
void GenerateDPadEvent(const Tilt &tilt) {
|
||||
void GenerateDPadEvent(int digitalX, int digitalY) {
|
||||
static const int dir[4] = { CTRL_RIGHT, CTRL_DOWN, CTRL_LEFT, CTRL_UP };
|
||||
|
||||
if (tilt.x_ == 0) {
|
||||
if (digitalX == 0) {
|
||||
__CtrlButtonUp(tiltButtonsDown & (CTRL_RIGHT | CTRL_LEFT));
|
||||
tiltButtonsDown &= ~(CTRL_LEFT | CTRL_RIGHT);
|
||||
}
|
||||
|
||||
if (tilt.y_ == 0) {
|
||||
if (digitalY == 0) {
|
||||
__CtrlButtonUp(tiltButtonsDown & (CTRL_UP | CTRL_DOWN));
|
||||
tiltButtonsDown &= ~(CTRL_UP | CTRL_DOWN);
|
||||
}
|
||||
|
||||
if (tilt.x_ == 0 && tilt.y_ == 0) {
|
||||
if (digitalX == 0 && digitalY == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ctrlMask = 0;
|
||||
int direction = (int)(floorf((atan2f(-tilt.y_, tilt.x_) / (2.0f * (float)M_PI) * 8.0f) + 0.5f)) & 7;
|
||||
switch (direction) {
|
||||
case 0: ctrlMask |= CTRL_RIGHT; break;
|
||||
case 1: ctrlMask |= CTRL_RIGHT | CTRL_DOWN; break;
|
||||
case 2: ctrlMask |= CTRL_DOWN; break;
|
||||
case 3: ctrlMask |= CTRL_DOWN | CTRL_LEFT; break;
|
||||
case 4: ctrlMask |= CTRL_LEFT; break;
|
||||
case 5: ctrlMask |= CTRL_UP | CTRL_LEFT; break;
|
||||
case 6: ctrlMask |= CTRL_UP; break;
|
||||
case 7: ctrlMask |= CTRL_UP | CTRL_RIGHT; break;
|
||||
}
|
||||
if (digitalX == -1) ctrlMask |= CTRL_LEFT;
|
||||
if (digitalX == 1) ctrlMask |= CTRL_RIGHT;
|
||||
if (digitalY == -1) ctrlMask |= CTRL_DOWN;
|
||||
if (digitalY == 1) ctrlMask |= CTRL_UP;
|
||||
|
||||
ctrlMask &= ~__CtrlPeekButtons();
|
||||
__CtrlButtonDown(ctrlMask);
|
||||
tiltButtonsDown |= ctrlMask;
|
||||
}
|
||||
|
||||
void GenerateActionButtonEvent(const Tilt &tilt) {
|
||||
void GenerateActionButtonEvent(int digitalX, int digitalY) {
|
||||
static const int buttons[4] = { CTRL_CIRCLE, CTRL_CROSS, CTRL_SQUARE, CTRL_TRIANGLE };
|
||||
|
||||
if (tilt.x_ == 0) {
|
||||
if (digitalX == 0) {
|
||||
__CtrlButtonUp(tiltButtonsDown & (CTRL_SQUARE | CTRL_CIRCLE));
|
||||
tiltButtonsDown &= ~(CTRL_SQUARE | CTRL_CIRCLE);
|
||||
}
|
||||
|
||||
if (tilt.y_ == 0) {
|
||||
if (digitalY == 0) {
|
||||
__CtrlButtonUp(tiltButtonsDown & (CTRL_TRIANGLE | CTRL_CROSS));
|
||||
tiltButtonsDown &= ~(CTRL_TRIANGLE | CTRL_CROSS);
|
||||
}
|
||||
|
||||
if (tilt.x_ == 0 && tilt.y_ == 0) {
|
||||
if (digitalX == 0 && digitalY == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int direction = (int)(floorf((atan2f(-tilt.y_, tilt.x_) / (2.0f * (float)M_PI) * 4.0f) + 0.5f)) & 3;
|
||||
int downButtons = buttons[direction] & ~__CtrlPeekButtons();
|
||||
__CtrlButtonDown(downButtons);
|
||||
tiltButtonsDown |= downButtons;
|
||||
int ctrlMask = 0;
|
||||
if (digitalX == -1) ctrlMask |= CTRL_SQUARE;
|
||||
if (digitalX == 1) ctrlMask |= CTRL_CIRCLE;
|
||||
if (digitalY == -1) ctrlMask |= CTRL_CROSS;
|
||||
if (digitalY == 1) ctrlMask |= CTRL_TRIANGLE;
|
||||
|
||||
ctrlMask &= ~__CtrlPeekButtons();
|
||||
__CtrlButtonDown(ctrlMask);
|
||||
tiltButtonsDown |= ctrlMask;
|
||||
}
|
||||
|
||||
void GenerateTriggerButtonEvent(const Tilt &tilt) {
|
||||
void GenerateTriggerButtonEvent(int digitalX, int digitalY) {
|
||||
u32 upButtons = 0;
|
||||
u32 downButtons = 0;
|
||||
// Y axis for both
|
||||
if (tilt.y_ < 0.0f) {
|
||||
// Y axis up for both
|
||||
if (digitalY == 1) {
|
||||
downButtons = CTRL_LTRIGGER | CTRL_RTRIGGER;
|
||||
} else if (tilt.x_ == 0.0f) {
|
||||
} else if (digitalX == 0) {
|
||||
upButtons = CTRL_LTRIGGER | CTRL_RTRIGGER;
|
||||
} else if (tilt.x_ < 0.0f) {
|
||||
} else if (digitalX == -1) {
|
||||
downButtons = CTRL_LTRIGGER;
|
||||
upButtons = CTRL_RTRIGGER;
|
||||
} else if (tilt.x_ > 0.0f) {
|
||||
} else if (digitalX == 1) {
|
||||
downButtons = CTRL_RTRIGGER;
|
||||
upButtons = CTRL_LTRIGGER;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user