summaryrefslogtreecommitdiffstats
path: root/src/input_common/helpers/stick_from_buttons.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/helpers/stick_from_buttons.cpp')
-rw-r--r--src/input_common/helpers/stick_from_buttons.cpp67
1 files changed, 29 insertions, 38 deletions
diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp
index 82aa6ac2f..a6be6dac1 100644
--- a/src/input_common/helpers/stick_from_buttons.cpp
+++ b/src/input_common/helpers/stick_from_buttons.cpp
@@ -11,13 +11,21 @@ namespace InputCommon {
class Stick final : public Common::Input::InputDevice {
public:
+ // Some games such as EARTH DEFENSE FORCE: WORLD BROTHERS
+ // do not play nicely with the theoretical maximum range.
+ // Using a value one lower from the maximum emulates real stick behavior.
+ static constexpr float MAX_RANGE = 32766.0f / 32767.0f;
+ static constexpr float TAU = Common::PI * 2.0f;
+ // Use wider angle to ease the transition.
+ static constexpr float APERTURE = TAU * 0.15f;
+
using Button = std::unique_ptr<Common::Input::InputDevice>;
- Stick(Button up_, Button down_, Button left_, Button right_, Button modifier_,
+ Stick(Button up_, Button down_, Button left_, Button right_, Button modifier_, Button updater_,
float modifier_scale_, float modifier_angle_)
: up(std::move(up_)), down(std::move(down_)), left(std::move(left_)),
- right(std::move(right_)), modifier(std::move(modifier_)), modifier_scale(modifier_scale_),
- modifier_angle(modifier_angle_) {
+ right(std::move(right_)), modifier(std::move(modifier_)), updater(std::move(updater_)),
+ modifier_scale(modifier_scale_), modifier_angle(modifier_angle_) {
up->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback_) {
@@ -48,35 +56,31 @@ public:
UpdateModButtonStatus(callback_);
},
});
+ updater->SetCallback({
+ .on_change = [this](const Common::Input::CallbackStatus& callback_) { SoftUpdate(); },
+ });
last_x_axis_value = 0.0f;
last_y_axis_value = 0.0f;
}
bool IsAngleGreater(float old_angle, float new_angle) const {
- constexpr float TAU = Common::PI * 2.0f;
- // Use wider angle to ease the transition.
- constexpr float aperture = TAU * 0.15f;
- const float top_limit = new_angle + aperture;
+ const float top_limit = new_angle + APERTURE;
return (old_angle > new_angle && old_angle <= top_limit) ||
(old_angle + TAU > new_angle && old_angle + TAU <= top_limit);
}
bool IsAngleSmaller(float old_angle, float new_angle) const {
- constexpr float TAU = Common::PI * 2.0f;
- // Use wider angle to ease the transition.
- constexpr float aperture = TAU * 0.15f;
- const float bottom_limit = new_angle - aperture;
+ const float bottom_limit = new_angle - APERTURE;
return (old_angle >= bottom_limit && old_angle < new_angle) ||
(old_angle - TAU >= bottom_limit && old_angle - TAU < new_angle);
}
float GetAngle(std::chrono::time_point<std::chrono::steady_clock> now) const {
- constexpr float TAU = Common::PI * 2.0f;
float new_angle = angle;
auto time_difference = static_cast<float>(
- std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count());
- time_difference /= 1000.0f * 1000.0f;
+ std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update).count());
+ time_difference /= 1000.0f;
if (time_difference > 0.5f) {
time_difference = 0.5f;
}
@@ -193,8 +197,6 @@ public:
}
void UpdateStatus() {
- const float coef = modifier_status.value ? modifier_scale : 1.0f;
-
bool r = right_status;
bool l = left_status;
bool u = up_status;
@@ -212,7 +214,7 @@ public:
// Move if a key is pressed
if (r || l || u || d) {
- amplitude = coef;
+ amplitude = modifier_status.value ? modifier_scale : MAX_RANGE;
} else {
amplitude = 0;
}
@@ -248,7 +250,7 @@ public:
modifier->ForceUpdate();
}
- void SoftUpdate() override {
+ void SoftUpdate() {
Common::Input::CallbackStatus status{
.type = Common::Input::InputType::Stick,
.stick_status = GetStatus(),
@@ -266,30 +268,17 @@ public:
Common::Input::StickStatus status{};
status.x.properties = properties;
status.y.properties = properties;
+
if (Settings::values.emulate_analog_keyboard) {
const auto now = std::chrono::steady_clock::now();
- float angle_ = GetAngle(now);
+ const float angle_ = GetAngle(now);
status.x.raw_value = std::cos(angle_) * amplitude;
status.y.raw_value = std::sin(angle_) * amplitude;
return status;
}
- constexpr float SQRT_HALF = 0.707106781f;
- int x = 0, y = 0;
- if (right_status) {
- ++x;
- }
- if (left_status) {
- --x;
- }
- if (up_status) {
- ++y;
- }
- if (down_status) {
- --y;
- }
- const float coef = modifier_status.value ? modifier_scale : 1.0f;
- status.x.raw_value = static_cast<float>(x) * coef * (y == 0 ? 1.0f : SQRT_HALF);
- status.y.raw_value = static_cast<float>(y) * coef * (x == 0 ? 1.0f : SQRT_HALF);
+
+ status.x.raw_value = std::cos(goal_angle) * amplitude;
+ status.y.raw_value = std::sin(goal_angle) * amplitude;
return status;
}
@@ -308,6 +297,7 @@ private:
Button left;
Button right;
Button modifier;
+ Button updater;
float modifier_scale{};
float modifier_angle{};
float angle{};
@@ -331,11 +321,12 @@ std::unique_ptr<Common::Input::InputDevice> StickFromButton::Create(
auto left = Common::Input::CreateInputDeviceFromString(params.Get("left", null_engine));
auto right = Common::Input::CreateInputDeviceFromString(params.Get("right", null_engine));
auto modifier = Common::Input::CreateInputDeviceFromString(params.Get("modifier", null_engine));
+ auto updater = Common::Input::CreateInputDeviceFromString("engine:updater,button:0");
auto modifier_scale = params.Get("modifier_scale", 0.5f);
auto modifier_angle = params.Get("modifier_angle", 5.5f);
return std::make_unique<Stick>(std::move(up), std::move(down), std::move(left),
- std::move(right), std::move(modifier), modifier_scale,
- modifier_angle);
+ std::move(right), std::move(modifier), std::move(updater),
+ modifier_scale, modifier_angle);
}
} // namespace InputCommon