diff --git a/rpcs3/xinput_pad_handler.cpp b/rpcs3/xinput_pad_handler.cpp index 12c204c441..fc196fd7f1 100644 --- a/rpcs3/xinput_pad_handler.cpp +++ b/rpcs3/xinput_pad_handler.cpp @@ -3,6 +3,8 @@ #ifdef _MSC_VER #include "xinput_pad_handler.h" +xinput_config xinput_cfg; + namespace { const DWORD THREAD_TIMEOUT = 1000; const DWORD THREAD_SLEEP = 10; @@ -112,6 +114,13 @@ void xinput_pad_handler::Init(const u32 max_connect) pad.m_vibrateMotors.emplace_back(false, 0); } + xinput_cfg.load(); + if (!xinput_cfg.exist()) xinput_cfg.save(); + + squircle_factor = xinput_cfg.padsquircling / 1000.f; + left_stick_deadzone = xinput_cfg.lstickdeadzone; + right_stick_deadzone = xinput_cfg.rstickdeadzone; + active = true; thread = CreateThread(NULL, 0, &xinput_pad_handler::ThreadProcProxy, this, 0, NULL); } @@ -158,7 +167,7 @@ std::tuple xinput_pad_handler::ConvertToSquirclePoint(u16 inX, u16 inY // now find len/point on the given squircle from our current angle and radius in polar coords // https://thatsmaths.com/2016/07/14/squircles/ - const f32 newLen = (1 + std::pow(std::sin(2 * angle), 2.f) / 8.f) * r; + const f32 newLen = (1 + std::pow(std::sin(2 * angle), 2.f) / squircle_factor) * r; // we now have len and angle, convert to cartisian @@ -241,16 +250,19 @@ DWORD xinput_pad_handler::ThreadProcedure() } }; - normalize_input(LX, LY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); - normalize_input(RX, RY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); + normalize_input(LX, LY, left_stick_deadzone); + normalize_input(RX, RY, right_stick_deadzone); pad.m_sticks[0].m_value = ConvertAxis(LX); pad.m_sticks[1].m_value = 255 - ConvertAxis(LY); pad.m_sticks[2].m_value = ConvertAxis(RX); pad.m_sticks[3].m_value = 255 - ConvertAxis(RY); - std::tie(pad.m_sticks[0].m_value, pad.m_sticks[1].m_value) = ConvertToSquirclePoint(pad.m_sticks[0].m_value, pad.m_sticks[1].m_value); - std::tie(pad.m_sticks[2].m_value, pad.m_sticks[3].m_value) = ConvertToSquirclePoint(pad.m_sticks[2].m_value, pad.m_sticks[3].m_value); + if (squircle_factor != 0.f) + { + std::tie(pad.m_sticks[0].m_value, pad.m_sticks[1].m_value) = ConvertToSquirclePoint(pad.m_sticks[0].m_value, pad.m_sticks[1].m_value); + std::tie(pad.m_sticks[2].m_value, pad.m_sticks[3].m_value) = ConvertToSquirclePoint(pad.m_sticks[2].m_value, pad.m_sticks[3].m_value); + } XINPUT_VIBRATION vibrate; diff --git a/rpcs3/xinput_pad_handler.h b/rpcs3/xinput_pad_handler.h index d2221cda64..52e859db7f 100644 --- a/rpcs3/xinput_pad_handler.h +++ b/rpcs3/xinput_pad_handler.h @@ -1,10 +1,40 @@ #ifndef X_INPUT_PAD_HANDLER #define X_INPUT_PAD_HANDLER +#include "Utilities/Config.h" #include "Emu/Io/PadHandler.h" #include #include +struct xinput_config final : cfg::node +{ + const std::string cfg_name = fs::get_config_dir() + "/config_xinput.yml"; + + cfg::_int<0, 1000000> lstickdeadzone{ this, "Left Stick Deadzone", 7849 }; + cfg::_int<0, 1000000> rstickdeadzone{ this, "Right Stick Deadzone", 8689 }; + cfg::_int<0, 1000000> padsquircling{ this, "Pad Squircling Factor", 8000 }; + + bool load() + { + if (fs::file cfg_file{ cfg_name, fs::read }) + { + return from_string(cfg_file.to_string()); + } + + return false; + } + + void save() + { + fs::file(cfg_name, fs::rewrite).write(to_string()); + } + + bool exist() + { + return fs::is_file(cfg_name); + } +}; + class xinput_pad_handler final : public PadHandlerBase { public: @@ -27,6 +57,8 @@ private: private: mutable bool active; + float squircle_factor; + u32 left_stick_deadzone, right_stick_deadzone; HANDLE thread; HMODULE library; PFN_XINPUTGETSTATE xinputGetState; @@ -35,4 +67,6 @@ private: }; +extern xinput_config xinput_cfg; + #endif