mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-02 02:52:30 +02:00
Merge pull request #7777 from jordan-woyak/input-rounding
ControllerEmu: Round input floats instead of casting.
This commit is contained in:
commit
cfbc852fb0
@ -68,7 +68,7 @@ GCPad::GCPad(const unsigned int index) : m_index(index)
|
|||||||
groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick(
|
groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick(
|
||||||
"Main Stick", _trans("Control Stick"), main_gate_radius));
|
"Main Stick", _trans("Control Stick"), main_gate_radius));
|
||||||
|
|
||||||
constexpr auto c_gate_radius = ControlState(C_STICK_GATE_RADIUS) / GCPadStatus::MAIN_STICK_RADIUS;
|
constexpr auto c_gate_radius = ControlState(C_STICK_GATE_RADIUS) / GCPadStatus::C_STICK_RADIUS;
|
||||||
groups.emplace_back(m_c_stick = new ControllerEmu::OctagonAnalogStick(
|
groups.emplace_back(m_c_stick = new ControllerEmu::OctagonAnalogStick(
|
||||||
"C-Stick", _trans("C Stick"), c_gate_radius));
|
"C-Stick", _trans("C Stick"), c_gate_radius));
|
||||||
|
|
||||||
@ -160,23 +160,19 @@ GCPadStatus GCPad::GetInput() const
|
|||||||
m_dpad->GetState(&pad.button, dpad_bitmasks);
|
m_dpad->GetState(&pad.button, dpad_bitmasks);
|
||||||
|
|
||||||
// sticks
|
// sticks
|
||||||
const ControllerEmu::AnalogStick::StateData main_stick_state = m_main_stick->GetState();
|
const auto main_stick_state = m_main_stick->GetState();
|
||||||
pad.stickX = static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_X +
|
pad.stickX = MapFloat<u8>(main_stick_state.x, GCPadStatus::MAIN_STICK_CENTER_X);
|
||||||
(main_stick_state.x * GCPadStatus::MAIN_STICK_RADIUS));
|
pad.stickY = MapFloat<u8>(main_stick_state.y, GCPadStatus::MAIN_STICK_CENTER_Y);
|
||||||
pad.stickY = static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_Y +
|
|
||||||
(main_stick_state.y * GCPadStatus::MAIN_STICK_RADIUS));
|
|
||||||
|
|
||||||
const ControllerEmu::AnalogStick::StateData c_stick_state = m_c_stick->GetState();
|
const auto c_stick_state = m_c_stick->GetState();
|
||||||
pad.substickX = static_cast<u8>(GCPadStatus::C_STICK_CENTER_X +
|
pad.substickX = MapFloat<u8>(c_stick_state.x, GCPadStatus::C_STICK_CENTER_X);
|
||||||
(c_stick_state.x * GCPadStatus::C_STICK_RADIUS));
|
pad.substickY = MapFloat<u8>(c_stick_state.y, GCPadStatus::C_STICK_CENTER_Y);
|
||||||
pad.substickY = static_cast<u8>(GCPadStatus::C_STICK_CENTER_Y +
|
|
||||||
(c_stick_state.y * GCPadStatus::C_STICK_RADIUS));
|
|
||||||
|
|
||||||
// triggers
|
// triggers
|
||||||
std::array<ControlState, 2> triggers;
|
std::array<ControlState, 2> triggers;
|
||||||
m_triggers->GetState(&pad.button, trigger_bitmasks, triggers.data());
|
m_triggers->GetState(&pad.button, trigger_bitmasks, triggers.data());
|
||||||
pad.triggerLeft = static_cast<u8>(triggers[0] * 0xFF);
|
pad.triggerLeft = MapFloat<u8>(triggers[0], 0);
|
||||||
pad.triggerRight = static_cast<u8>(triggers[1] * 0xFF);
|
pad.triggerRight = MapFloat<u8>(triggers[1], 0);
|
||||||
|
|
||||||
return pad;
|
return pad;
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
@ -50,6 +52,29 @@ public:
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<ControlGroup>> groups;
|
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:
|
private:
|
||||||
ciface::Core::DeviceQualifier m_default_device;
|
ciface::Core::DeviceQualifier m_default_device;
|
||||||
bool m_default_device_is_connected{false};
|
bool m_default_device_is_connected{false};
|
||||||
|
Loading…
Reference in New Issue
Block a user