|
|
|
@@ -75,8 +75,25 @@ void keyboard_pad_handler::Key(const u32 code, bool pressed, u16 value)
|
|
|
|
|
if (button.m_keyCode != code)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
button.m_pressed = pressed;
|
|
|
|
|
button.m_value = pressed ? value : 0;
|
|
|
|
|
button.m_actual_value = pressed ? value : 0;
|
|
|
|
|
|
|
|
|
|
bool update_button = true;
|
|
|
|
|
|
|
|
|
|
// to get the fastest response time possible we don't wanna use any lerp with factor 1
|
|
|
|
|
if (button.m_analog)
|
|
|
|
|
{
|
|
|
|
|
update_button = m_analog_lerp_factor >= 1.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (button.m_trigger)
|
|
|
|
|
{
|
|
|
|
|
update_button = m_trigger_lerp_factor >= 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update_button)
|
|
|
|
|
{
|
|
|
|
|
button.m_value = pressed ? value : 0;
|
|
|
|
|
button.m_pressed = pressed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < static_cast<int>(pad->m_sticks.size()); i++)
|
|
|
|
@@ -576,6 +593,8 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr<Pad> pad, const std::
|
|
|
|
|
m_multi_y = p_profile->mouse_acceleration_y / 100.0;
|
|
|
|
|
m_l_stick_lerp_factor = p_profile->l_stick_lerp_factor / 100.0f;
|
|
|
|
|
m_r_stick_lerp_factor = p_profile->r_stick_lerp_factor / 100.0f;
|
|
|
|
|
m_analog_lerp_factor = p_profile->analog_lerp_factor / 100.0f;
|
|
|
|
|
m_trigger_lerp_factor = p_profile->trigger_lerp_factor / 100.0f;
|
|
|
|
|
|
|
|
|
|
auto find_key = [&](const cfg::string& name)
|
|
|
|
|
{
|
|
|
|
@@ -635,6 +654,63 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr<Pad> pad, const std::
|
|
|
|
|
|
|
|
|
|
void keyboard_pad_handler::ThreadProc()
|
|
|
|
|
{
|
|
|
|
|
static const double mouse_interval = 30.0;
|
|
|
|
|
static const double stick_interval = 10.0;
|
|
|
|
|
static const double button_interval = 10.0;
|
|
|
|
|
|
|
|
|
|
const auto now = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
|
|
const double elapsed_left = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_left).count() / 1000.0;
|
|
|
|
|
const double elapsed_right = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_right).count() / 1000.0;
|
|
|
|
|
const double elapsed_up = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_up).count() / 1000.0;
|
|
|
|
|
const double elapsed_down = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_down).count() / 1000.0;
|
|
|
|
|
const double elapsed_stick = std::chrono::duration_cast<std::chrono::microseconds>(now - m_stick_time).count() / 1000.0;
|
|
|
|
|
const double elapsed_button = std::chrono::duration_cast<std::chrono::microseconds>(now - m_button_time).count() / 1000.0;
|
|
|
|
|
|
|
|
|
|
const bool update_sticks = elapsed_stick > stick_interval;
|
|
|
|
|
const bool update_buttons = elapsed_button > button_interval;
|
|
|
|
|
|
|
|
|
|
if (update_sticks)
|
|
|
|
|
{
|
|
|
|
|
m_stick_time = now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update_buttons)
|
|
|
|
|
{
|
|
|
|
|
m_button_time = now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// roughly 1-2 frames to process the next mouse move
|
|
|
|
|
if (elapsed_left > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_left, false);
|
|
|
|
|
m_last_mouse_move_left = now;
|
|
|
|
|
}
|
|
|
|
|
if (elapsed_right > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_right, false);
|
|
|
|
|
m_last_mouse_move_right = now;
|
|
|
|
|
}
|
|
|
|
|
if (elapsed_up > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_up, false);
|
|
|
|
|
m_last_mouse_move_up = now;
|
|
|
|
|
}
|
|
|
|
|
if (elapsed_down > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_down, false);
|
|
|
|
|
m_last_mouse_move_down = now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto get_lerped = [](f32 v0, f32 v1, f32 lerp_factor)
|
|
|
|
|
{
|
|
|
|
|
// linear interpolation from the current value v0 to the desired value v1
|
|
|
|
|
const f32 res = std::lerp(v0, v1, lerp_factor);
|
|
|
|
|
|
|
|
|
|
// round to the correct direction to prevent sticky values on small factors
|
|
|
|
|
return (v0 <= v1) ? std::ceil(res) : std::floor(res);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < bindings.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (last_connection_status[i] == false)
|
|
|
|
@@ -646,41 +722,7 @@ void keyboard_pad_handler::ThreadProc()
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
static std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
|
|
|
|
now = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
|
|
const double elapsed_left = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_left).count() / 1000.0;
|
|
|
|
|
const double elapsed_right = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_right).count() / 1000.0;
|
|
|
|
|
const double elapsed_up = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_up).count() / 1000.0;
|
|
|
|
|
const double elapsed_down = std::chrono::duration_cast<std::chrono::microseconds>(now - m_last_mouse_move_down).count() / 1000.0;
|
|
|
|
|
const double elapsed_stick = std::chrono::duration_cast<std::chrono::microseconds>(now - m_stick_time).count() / 1000.0;
|
|
|
|
|
|
|
|
|
|
const double mouse_interval = 30.0;
|
|
|
|
|
const double stick_interval = 10.0;
|
|
|
|
|
|
|
|
|
|
// roughly 1-2 frames to process the next mouse move
|
|
|
|
|
if (elapsed_left > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_left, false);
|
|
|
|
|
m_last_mouse_move_left = now;
|
|
|
|
|
}
|
|
|
|
|
if (elapsed_right > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_right, false);
|
|
|
|
|
m_last_mouse_move_right = now;
|
|
|
|
|
}
|
|
|
|
|
if (elapsed_up > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_up, false);
|
|
|
|
|
m_last_mouse_move_up = now;
|
|
|
|
|
}
|
|
|
|
|
if (elapsed_down > mouse_interval)
|
|
|
|
|
{
|
|
|
|
|
Key(mouse::move_down, false);
|
|
|
|
|
m_last_mouse_move_down = now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (elapsed_stick > stick_interval)
|
|
|
|
|
if (update_sticks)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < static_cast<int>(bindings[i]->m_sticks.size()); j++)
|
|
|
|
|
{
|
|
|
|
@@ -691,25 +733,50 @@ void keyboard_pad_handler::ThreadProc()
|
|
|
|
|
{
|
|
|
|
|
const f32 v0 = static_cast<f32>(bindings[i]->m_sticks[j].m_value);
|
|
|
|
|
const f32 v1 = static_cast<f32>(m_stick_val[j]);
|
|
|
|
|
|
|
|
|
|
// linear interpolation from the current stick value v0 to the desired stick value v1
|
|
|
|
|
f32 res = std::lerp(v0, v1, stick_lerp_factor);
|
|
|
|
|
|
|
|
|
|
// round to the correct direction to prevent sticky sticks on small factors
|
|
|
|
|
res = (v0 <= v1) ? std::ceil(res) : std::floor(res);
|
|
|
|
|
const f32 res = get_lerped(v0, v1, stick_lerp_factor);
|
|
|
|
|
|
|
|
|
|
bindings[i]->m_sticks[j].m_value = static_cast<u16>(res);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_stick_time = now;
|
|
|
|
|
if (update_buttons)
|
|
|
|
|
{
|
|
|
|
|
for (auto& button : bindings[i]->m_buttons)
|
|
|
|
|
{
|
|
|
|
|
if (button.m_analog)
|
|
|
|
|
{
|
|
|
|
|
// we already applied the following values on keypress if we used factor 1
|
|
|
|
|
if (m_analog_lerp_factor < 1.0f)
|
|
|
|
|
{
|
|
|
|
|
const f32 v0 = static_cast<f32>(button.m_value);
|
|
|
|
|
const f32 v1 = static_cast<f32>(button.m_actual_value);
|
|
|
|
|
const f32 res = get_lerped(v0, v1, m_analog_lerp_factor);
|
|
|
|
|
|
|
|
|
|
button.m_value = static_cast<u16>(res);
|
|
|
|
|
button.m_pressed = button.m_value > 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (button.m_trigger)
|
|
|
|
|
{
|
|
|
|
|
// we already applied the following values on keypress if we used factor 1
|
|
|
|
|
if (m_trigger_lerp_factor < 1.0f)
|
|
|
|
|
{
|
|
|
|
|
const f32 v0 = static_cast<f32>(button.m_value);
|
|
|
|
|
const f32 v1 = static_cast<f32>(button.m_actual_value);
|
|
|
|
|
const f32 res = get_lerped(v0, v1, m_trigger_lerp_factor);
|
|
|
|
|
|
|
|
|
|
button.m_value = static_cast<u16>(res);
|
|
|
|
|
button.m_pressed = button.m_value > 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Releases the wheel buttons 0,1 sec after they've been triggered
|
|
|
|
|
// Next activation is set to distant future to avoid activating this on every proc
|
|
|
|
|
const auto now = std::chrono::steady_clock::now();
|
|
|
|
|
const auto update_threshold = now - std::chrono::milliseconds(100);
|
|
|
|
|
const auto distant_future = now + std::chrono::hours(24);
|
|
|
|
|
if (update_threshold >= m_last_wheel_move_up)
|
|
|
|
|