Simplify the tilt code, tweak a bit

This commit is contained in:
Henrik Rydgård
2023-02-16 11:07:57 +01:00
parent 3e286b7a27
commit 64e80423a6
5 changed files with 92 additions and 86 deletions
+1
View File
@@ -1663,6 +1663,7 @@ void VulkanDeleteList::PerformDeletes(VulkanContext *vulkan, VmaAllocator alloca
}
imagesWithAllocs_.clear();
for (auto &imageView : imageViews_) {
INFO_LOG(G3D, "deleting imageview %p", imageView);
vkDestroyImageView(device, imageView, nullptr);
}
imageViews_.clear();
+2 -3
View File
@@ -975,10 +975,9 @@ static const ConfigSetting controlSettings[] = {
ConfigSetting("TiltBaseAngleY", &g_Config.fTiltBaseAngleY, 0.9f, true, true),
ConfigSetting("TiltInvertX", &g_Config.bInvertTiltX, false, true, true),
ConfigSetting("TiltInvertY", &g_Config.bInvertTiltY, false, true, true),
ConfigSetting("TiltSensitivityX", &g_Config.iTiltSensitivityX, 70, true, true),
ConfigSetting("TiltSensitivityY", &g_Config.iTiltSensitivityY, 70, true, true),
ConfigSetting("TiltSensitivityX", &g_Config.iTiltSensitivityX, 60, true, true),
ConfigSetting("TiltSensitivityY", &g_Config.iTiltSensitivityY, 60, true, true),
ConfigSetting("TiltAnalogDeadzoneRadius", &g_Config.fTiltAnalogDeadzoneRadius, 0.0f, true, true),
ConfigSetting("TiltDigitalDeadzoneRadius", &g_Config.fTiltDigitalDeadzoneRadius, 0.15f, true, true),
ConfigSetting("TiltInputType", &g_Config.iTiltInputType, 0, true, true),
#endif
+5 -7
View File
@@ -284,20 +284,18 @@ public:
bool bShowGpuProfile;
// Analog stick tilting
// This is the held base angle, that we compute the tilt relative from.
// This is the held base angle (from the horizon), that we compute the tilt relative from.
float fTiltBaseAngleY;
// whether the x axes and y axes should invert directions (left becomes right, top becomes bottom.)
// Inverts the direction of the x axes and y axes for the purposes of tilt input.
bool bInvertTiltX;
bool bInvertTiltY;
// The sensitivity of the tilt in the X and Y directions, separately.
int iTiltSensitivityX;
int iTiltSensitivityY;
// The deadzone radius of the tilt.
// Separate settings for analog vs digital since the usable ranges differ.
// The deadzone radius of the tilt. Only used in the analog mapping.
float fTiltAnalogDeadzoneRadius;
float fTiltDigitalDeadzoneRadius;
//type of tilt input currently selected: Defined in TiltEventProcessor.h
//0 - no tilt, 1 - analog stick, 2 - D-Pad, 3 - Action Buttons (Tri, Cross, Square, Circle)
// Type of tilt input currently selected: Defined in TiltEventProcessor.h
// 0 - no tilt, 1 - analog stick, 2 - D-Pad, 3 - Action Buttons (Tri, Cross, Square, Circle)
int iTiltInputType;
// The three tabs.
+83 -73
View File
@@ -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;
}
+1 -3
View File
@@ -121,9 +121,7 @@ void TiltAnalogSettingsScreen::CreateViews() {
settings->Add(calibrate);
settings->Add(new ItemHeader(co->T("Sensitivity")));
if (g_Config.iTiltInputType > 1) {
settings->Add(new PopupSliderChoiceFloat(&g_Config.fTiltDigitalDeadzoneRadius, 0.05f, 0.5f, co->T("Deadzone radius"), 0.01f, screenManager(), "/ 1.0"))->SetEnabledFunc(enabledFunc);
} else {
if (g_Config.iTiltInputType == 1) {
settings->Add(new PopupSliderChoiceFloat(&g_Config.fTiltAnalogDeadzoneRadius, 0.0f, 0.8f, co->T("Deadzone radius"), 0.01f, screenManager(), "/ 1.0"))->SetEnabledFunc(enabledFunc);
}
settings->Add(new PopupSliderChoice(&g_Config.iTiltSensitivityX, 0, 100, co->T("Tilt Sensitivity along X axis"), screenManager(), "%"))->SetEnabledFunc(enabledFunc);