diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2019-02-02 14:25:48 -0600 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2019-02-02 15:12:07 -0600 |
| commit | 3bc4968c1173eee90813fd9b34656e4933de60e9 (patch) | |
| tree | 3ad031d9dda0c6139ccd8bd6d20109c508e25383 /Source/Core/InputCommon/ControllerEmu | |
| parent | 28c0b5338ee4c0ef1fc30c557e27e896c135c1ca (diff) | |
ControllerEmu: Round input floats instead of casting to prevent almost-neutral values from being rounded down.
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu')
| -rw-r--r-- | Source/Core/InputCommon/ControllerEmu/ControllerEmu.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h b/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h index 4f734e2824..1cc9f5fd1e 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h +++ b/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h @@ -4,9 +4,11 @@ #pragma once +#include <cmath> #include <memory> #include <mutex> #include <string> +#include <type_traits> #include <vector> #include "Common/Common.h" @@ -50,6 +52,29 @@ public: std::vector<std::unique_ptr<ControlGroup>> groups; + // Maps a float from -1.0..+1.0 to an integer of the provided values. + template <typename T, typename F> + static T MapFloat(F input_value, T zero_value, T neg_1_value = std::numeric_limits<T>::min(), + T pos_1_value = std::numeric_limits<T>::max()) + { + static_assert(std::is_integral<T>(), "T is only sane for int types."); + static_assert(std::is_floating_point<F>(), "F is only sane for float types."); + + static_assert(std::numeric_limits<long>::min() <= std::numeric_limits<T>::min() && + std::numeric_limits<long>::max() >= std::numeric_limits<T>::max(), + "long is not a superset of T. use of std::lround is not sane."); + + // Here we round when converting from float to int. + // After applying our deadzone, resizing, and reshaping math + // we sometimes have a near-zero value which is slightly negative. (e.g. -0.0001) + // Casting would round down but rounding will yield our "zero_value". + + if (input_value > 0) + return T(std::lround((pos_1_value - zero_value) * input_value + zero_value)); + else + return T(std::lround((zero_value - neg_1_value) * input_value + zero_value)); + } + private: ciface::Core::DeviceQualifier m_default_device; bool m_default_device_is_connected{false}; |
