diff --git a/rpcs3/Emu/Io/Null/NullPadHandler.h b/rpcs3/Emu/Io/Null/NullPadHandler.h index 7fb25a487fac..0199389e4b67 100644 --- a/rpcs3/Emu/Io/Null/NullPadHandler.h +++ b/rpcs3/Emu/Io/Null/NullPadHandler.h @@ -17,7 +17,7 @@ class NullPadHandler final : public PadHandlerBase return nulllist; } - bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override + bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) override { return true; } diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index c5a9e8cd1a6e..6fb095ff2e76 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -248,36 +248,35 @@ struct Pad } }; -struct pad_config : cfg::node +struct pad_profile final : cfg::node { - std::string cfg_type = ""; - std::string cfg_name = ""; + pad_profile(cfg::node* _this, const std::string& name) : cfg::node(_this, name) {} - cfg::string ls_left { this, "Left Stick Left", "" }; - cfg::string ls_down { this, "Left Stick Down", "" }; + cfg::string ls_left{ this, "Left Stick Left", "" }; + cfg::string ls_down{ this, "Left Stick Down", "" }; cfg::string ls_right{ this, "Left Stick Right", "" }; - cfg::string ls_up { this, "Left Stick Up", "" }; - cfg::string rs_left { this, "Right Stick Left", "" }; - cfg::string rs_down { this, "Right Stick Down", "" }; + cfg::string ls_up{ this, "Left Stick Up", "" }; + cfg::string rs_left{ this, "Right Stick Left", "" }; + cfg::string rs_down{ this, "Right Stick Down", "" }; cfg::string rs_right{ this, "Right Stick Right", "" }; - cfg::string rs_up { this, "Right Stick Up", "" }; - cfg::string start { this, "Start", "" }; - cfg::string select { this, "Select", "" }; - cfg::string ps { this, "PS Button", "" }; - cfg::string square { this, "Square", "" }; - cfg::string cross { this, "Cross", "" }; - cfg::string circle { this, "Circle", "" }; + cfg::string rs_up{ this, "Right Stick Up", "" }; + cfg::string start{ this, "Start", "" }; + cfg::string select{ this, "Select", "" }; + cfg::string ps{ this, "PS Button", "" }; + cfg::string square{ this, "Square", "" }; + cfg::string cross{ this, "Cross", "" }; + cfg::string circle{ this, "Circle", "" }; cfg::string triangle{ this, "Triangle", "" }; - cfg::string left { this, "Left", "" }; - cfg::string down { this, "Down", "" }; - cfg::string right { this, "Right", "" }; - cfg::string up { this, "Up", "" }; - cfg::string r1 { this, "R1", "" }; - cfg::string r2 { this, "R2", "" }; - cfg::string r3 { this, "R3", "" }; - cfg::string l1 { this, "L1", "" }; - cfg::string l2 { this, "L2", "" }; - cfg::string l3 { this, "L3", "" }; + cfg::string left{ this, "Left", "" }; + cfg::string down{ this, "Down", "" }; + cfg::string right{ this, "Right", "" }; + cfg::string up{ this, "Up", "" }; + cfg::string r1{ this, "R1", "" }; + cfg::string r2{ this, "R2", "" }; + cfg::string r3{ this, "R3", "" }; + cfg::string l1{ this, "L1", "" }; + cfg::string l2{ this, "L2", "" }; + cfg::string l3{ this, "L3", "" }; cfg::_int<0, 1000000> lstickdeadzone{ this, "Left Stick Deadzone", 0 }; cfg::_int<0, 1000000> rstickdeadzone{ this, "Right Stick Deadzone", 0 }; @@ -292,6 +291,23 @@ struct pad_config : cfg::node cfg::_bool enable_vibration_motor_large{ this, "Enable Large Vibration Motor", true }; cfg::_bool enable_vibration_motor_small{ this, "Enable Small Vibration Motor", true }; cfg::_bool switch_vibration_motors{ this, "Switch Vibration Motors", false }; +}; + +struct pad_config final : cfg::node +{ + std::string cfg_type = ""; + std::string cfg_name = ""; + + pad_profile profile_0{ this, "Profile 0" }; + pad_profile profile_1{ this, "Profile 1" }; + pad_profile profile_2{ this, "Profile 2" }; + pad_profile profile_3{ this, "Profile 3" }; + pad_profile profile_4{ this, "Profile 4" }; + pad_profile profile_5{ this, "Profile 5" }; + pad_profile profile_6{ this, "Profile 6" }; + pad_profile profile_7{ this, "Profile 7" }; + pad_profile profile_8{ this, "Profile 8" }; + pad_profile profile_9{ this, "Profile 9" }; bool load() { @@ -600,7 +616,7 @@ class PadHandlerBase //Callback called during pad_thread::ThreadFunc virtual void ThreadProc() = 0; //Binds a Pad to a device - virtual bool bindPadToDevice(std::shared_ptr pad, const std::string& device) = 0; + virtual bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) = 0; private: virtual void TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, bool ignore_threshold = false) {}; diff --git a/rpcs3/ds4_pad_handler.cpp b/rpcs3/ds4_pad_handler.cpp index 17cad5b5dc77..d86eb6e15a62 100644 --- a/rpcs3/ds4_pad_handler.cpp +++ b/rpcs3/ds4_pad_handler.cpp @@ -96,44 +96,49 @@ ds4_pad_handler::ds4_pad_handler() : is_init(false) m_pad_config.cfg_type = "ds4"; m_pad_config.cfg_name = fs::get_config_dir() + "/config_ds4.yml"; - // Set default button mapping - m_pad_config.ls_left.def = button_list.at(DS4KeyCodes::LSXNeg); - m_pad_config.ls_down.def = button_list.at(DS4KeyCodes::LSYNeg); - m_pad_config.ls_right.def = button_list.at(DS4KeyCodes::LSXPos); - m_pad_config.ls_up.def = button_list.at(DS4KeyCodes::LSYPos); - m_pad_config.rs_left.def = button_list.at(DS4KeyCodes::RSXNeg); - m_pad_config.rs_down.def = button_list.at(DS4KeyCodes::RSYNeg); - m_pad_config.rs_right.def = button_list.at(DS4KeyCodes::RSXPos); - m_pad_config.rs_up.def = button_list.at(DS4KeyCodes::RSYPos); - m_pad_config.start.def = button_list.at(DS4KeyCodes::Options); - m_pad_config.select.def = button_list.at(DS4KeyCodes::Share); - m_pad_config.ps.def = button_list.at(DS4KeyCodes::PSButton); - m_pad_config.square.def = button_list.at(DS4KeyCodes::Square); - m_pad_config.cross.def = button_list.at(DS4KeyCodes::Cross); - m_pad_config.circle.def = button_list.at(DS4KeyCodes::Circle); - m_pad_config.triangle.def = button_list.at(DS4KeyCodes::Triangle); - m_pad_config.left.def = button_list.at(DS4KeyCodes::Left); - m_pad_config.down.def = button_list.at(DS4KeyCodes::Down); - m_pad_config.right.def = button_list.at(DS4KeyCodes::Right); - m_pad_config.up.def = button_list.at(DS4KeyCodes::Up); - m_pad_config.r1.def = button_list.at(DS4KeyCodes::R1); - m_pad_config.r2.def = button_list.at(DS4KeyCodes::R2); - m_pad_config.r3.def = button_list.at(DS4KeyCodes::R3); - m_pad_config.l1.def = button_list.at(DS4KeyCodes::L1); - m_pad_config.l2.def = button_list.at(DS4KeyCodes::L2); - m_pad_config.l3.def = button_list.at(DS4KeyCodes::L3); - - // Set default misc variables - m_pad_config.lstickdeadzone.def = 40; // between 0 and 255 - m_pad_config.rstickdeadzone.def = 40; // between 0 and 255 - m_pad_config.ltriggerthreshold.def = 0; // between 0 and 255 - m_pad_config.rtriggerthreshold.def = 0; // between 0 and 255 - m_pad_config.padsquircling.def = 8000; - - // Set color value - m_pad_config.colorR.def = 0; - m_pad_config.colorG.def = 0; - m_pad_config.colorB.def = 20; + for (const auto& node : m_pad_config.get_nodes()) + { + pad_profile* profile = static_cast(node.second); + + // Set default button mapping + profile->ls_left.def = button_list.at(DS4KeyCodes::LSXNeg); + profile->ls_down.def = button_list.at(DS4KeyCodes::LSYNeg); + profile->ls_right.def = button_list.at(DS4KeyCodes::LSXPos); + profile->ls_up.def = button_list.at(DS4KeyCodes::LSYPos); + profile->rs_left.def = button_list.at(DS4KeyCodes::RSXNeg); + profile->rs_down.def = button_list.at(DS4KeyCodes::RSYNeg); + profile->rs_right.def = button_list.at(DS4KeyCodes::RSXPos); + profile->rs_up.def = button_list.at(DS4KeyCodes::RSYPos); + profile->start.def = button_list.at(DS4KeyCodes::Options); + profile->select.def = button_list.at(DS4KeyCodes::Share); + profile->ps.def = button_list.at(DS4KeyCodes::PSButton); + profile->square.def = button_list.at(DS4KeyCodes::Square); + profile->cross.def = button_list.at(DS4KeyCodes::Cross); + profile->circle.def = button_list.at(DS4KeyCodes::Circle); + profile->triangle.def = button_list.at(DS4KeyCodes::Triangle); + profile->left.def = button_list.at(DS4KeyCodes::Left); + profile->down.def = button_list.at(DS4KeyCodes::Down); + profile->right.def = button_list.at(DS4KeyCodes::Right); + profile->up.def = button_list.at(DS4KeyCodes::Up); + profile->r1.def = button_list.at(DS4KeyCodes::R1); + profile->r2.def = button_list.at(DS4KeyCodes::R2); + profile->r3.def = button_list.at(DS4KeyCodes::R3); + profile->l1.def = button_list.at(DS4KeyCodes::L1); + profile->l2.def = button_list.at(DS4KeyCodes::L2); + profile->l3.def = button_list.at(DS4KeyCodes::L3); + + // Set default misc variables + profile->lstickdeadzone.def = 40; // between 0 and 255 + profile->rstickdeadzone.def = 40; // between 0 and 255 + profile->ltriggerthreshold.def = 0; // between 0 and 255 + profile->rtriggerthreshold.def = 0; // between 0 and 255 + profile->padsquircling.def = 8000; + + // Set color value + profile->colorR.def = 0; + profile->colorG.def = 0; + profile->colorB.def = 20; + } // apply defaults m_pad_config.from_default(); @@ -259,29 +264,30 @@ void ds4_pad_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& val, { // Update the pad button values based on their type and thresholds. // With this you can use axis or triggers as buttons or vice versa + auto p_profile = m_dev->profile; switch (keyCode) { case DS4KeyCodes::L2: - pressed = val > m_pad_config.ltriggerthreshold; - val = pressed ? NormalizeTriggerInput(val, m_pad_config.ltriggerthreshold) : 0; + pressed = val > p_profile->ltriggerthreshold; + val = pressed ? NormalizeTriggerInput(val, p_profile->ltriggerthreshold) : 0; break; case DS4KeyCodes::R2: - pressed = val > m_pad_config.rtriggerthreshold; - val = pressed ? NormalizeTriggerInput(val, m_pad_config.rtriggerthreshold) : 0; + pressed = val > p_profile->rtriggerthreshold; + val = pressed ? NormalizeTriggerInput(val, p_profile->rtriggerthreshold) : 0; break; case DS4KeyCodes::LSXNeg: case DS4KeyCodes::LSXPos: case DS4KeyCodes::LSYNeg: case DS4KeyCodes::LSYPos: - pressed = val > (ignore_threshold ? 0 : m_pad_config.lstickdeadzone); - val = pressed ? NormalizeStickInput(val, m_pad_config.lstickdeadzone, ignore_threshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->lstickdeadzone); + val = pressed ? NormalizeStickInput(val, p_profile->lstickdeadzone, ignore_threshold) : 0; break; case DS4KeyCodes::RSXNeg: case DS4KeyCodes::RSXPos: case DS4KeyCodes::RSYNeg: case DS4KeyCodes::RSYPos: - pressed = val > (ignore_threshold ? 0 : m_pad_config.rstickdeadzone); - val = pressed ? NormalizeStickInput(val, m_pad_config.rstickdeadzone, ignore_threshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->rstickdeadzone); + val = pressed ? NormalizeStickInput(val, p_profile->rstickdeadzone, ignore_threshold) : 0; break; default: // normal button (should in theory also support sensitive buttons) pressed = val > 0; @@ -406,8 +412,8 @@ void ds4_pad_handler::ProcessDataToPad(const std::shared_ptr& device, pad->m_cable_state = device->cableState; auto buf = device->padData; - auto button_values = GetButtonValues(device); + auto p_profile = device->profile; // Translate any corresponding keycodes to our normal DS3 buttons and triggers for (auto & btn : pad->m_buttons) @@ -452,13 +458,13 @@ void ds4_pad_handler::ProcessDataToPad(const std::shared_ptr& device, u16 lx, ly, rx, ry; // Normalize our two stick's axis based on the thresholds - std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], m_pad_config.lstickdeadzone); - std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], m_pad_config.rstickdeadzone); + std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], p_profile->lstickdeadzone); + std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], p_profile->rstickdeadzone); - if (m_pad_config.padsquircling != 0) + if (p_profile->padsquircling != 0) { - std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, m_pad_config.padsquircling); - std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, m_pad_config.padsquircling); + std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, p_profile->padsquircling); + std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, p_profile->padsquircling); } ly = 255 - ly; @@ -654,6 +660,8 @@ ds4_pad_handler::~ds4_pad_handler() int ds4_pad_handler::SendVibrateData(const std::shared_ptr& device) { + auto p_profile = device->profile; + std::array outputBuf{0}; // write rumble state if (device->btCon) @@ -663,9 +671,9 @@ int ds4_pad_handler::SendVibrateData(const std::shared_ptr& device) outputBuf[3] = 0x07; outputBuf[6] = device->smallVibrate; outputBuf[7] = device->largeVibrate; - outputBuf[8] = m_pad_config.colorR; // red - outputBuf[9] = m_pad_config.colorG; // green - outputBuf[10] = m_pad_config.colorB; // blue + outputBuf[8] = p_profile->colorR; // red + outputBuf[9] = p_profile->colorG; // green + outputBuf[10] = p_profile->colorB; // blue // alternating blink states with values 0-255: only setting both to zero disables blinking // 255 is roughly 2 seconds, so setting both values to 255 results in a 4 second interval @@ -690,9 +698,9 @@ int ds4_pad_handler::SendVibrateData(const std::shared_ptr& device) outputBuf[1] = 0x07; outputBuf[4] = device->smallVibrate; outputBuf[5] = device->largeVibrate; - outputBuf[6] = m_pad_config.colorR; // red - outputBuf[7] = m_pad_config.colorG; // green - outputBuf[8] = m_pad_config.colorB; // blue + outputBuf[6] = p_profile->colorR; // red + outputBuf[7] = p_profile->colorG; // green + outputBuf[8] = p_profile->colorB; // blue outputBuf[9] = device->led_delay_on; outputBuf[10] = device->led_delay_off; @@ -757,7 +765,7 @@ std::vector ds4_pad_handler::ListDevices() return ds4_pads_list; } -bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) +bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) { std::shared_ptr ds4device = GetDevice(device); if (ds4device == nullptr || ds4device->hidDevice == nullptr) @@ -765,6 +773,21 @@ bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::strin m_pad_config.load(); + pad_profile* p_profile = nullptr; + + for (const auto& prof : m_pad_config.get_nodes()) + { + if (prof.first == profile) + { + p_profile = static_cast(prof.second); + ds4device->profile = p_profile; + break; + } + } + + if (p_profile == nullptr) + return false; + pad->Init ( CELL_PAD_STATUS_CONNECTED | CELL_PAD_STATUS_ASSIGN_CHANGES, @@ -774,34 +797,34 @@ bool ds4_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::strin ); // 'keycode' here is just 0 as we have to manually calculate this - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.l2), CELL_PAD_CTRL_L2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.r2), CELL_PAD_CTRL_R2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.up), CELL_PAD_CTRL_UP); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.down), CELL_PAD_CTRL_DOWN); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.left), CELL_PAD_CTRL_LEFT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.right), CELL_PAD_CTRL_RIGHT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.square), CELL_PAD_CTRL_SQUARE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.cross), CELL_PAD_CTRL_CROSS); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.circle), CELL_PAD_CTRL_CIRCLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.triangle), CELL_PAD_CTRL_TRIANGLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.l1), CELL_PAD_CTRL_L1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.r1), CELL_PAD_CTRL_R1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.select), CELL_PAD_CTRL_SELECT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.start), CELL_PAD_CTRL_START); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.l3), CELL_PAD_CTRL_L3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.r3), CELL_PAD_CTRL_R3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->l2), CELL_PAD_CTRL_L2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->r2), CELL_PAD_CTRL_R2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->up), CELL_PAD_CTRL_UP); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->down), CELL_PAD_CTRL_DOWN); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->left), CELL_PAD_CTRL_LEFT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->right), CELL_PAD_CTRL_RIGHT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->square), CELL_PAD_CTRL_SQUARE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->cross), CELL_PAD_CTRL_CROSS); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->circle), CELL_PAD_CTRL_CIRCLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->triangle), CELL_PAD_CTRL_TRIANGLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->l1), CELL_PAD_CTRL_L1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->r1), CELL_PAD_CTRL_R1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->select), CELL_PAD_CTRL_SELECT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->start), CELL_PAD_CTRL_START); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->l3), CELL_PAD_CTRL_L3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->r3), CELL_PAD_CTRL_R3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_X, 512); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_Y, 399); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_Z, 512); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_G, 512); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, FindKeyCode(button_list, m_pad_config.ls_left), FindKeyCode(button_list, m_pad_config.ls_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, FindKeyCode(button_list, m_pad_config.ls_down), FindKeyCode(button_list, m_pad_config.ls_up)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, FindKeyCode(button_list, m_pad_config.rs_left), FindKeyCode(button_list, m_pad_config.rs_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, FindKeyCode(button_list, m_pad_config.rs_down), FindKeyCode(button_list, m_pad_config.rs_up)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, FindKeyCode(button_list, p_profile->ls_left), FindKeyCode(button_list, p_profile->ls_right)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, FindKeyCode(button_list, p_profile->ls_down), FindKeyCode(button_list, p_profile->ls_up)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, FindKeyCode(button_list, p_profile->rs_left), FindKeyCode(button_list, p_profile->rs_right)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, FindKeyCode(button_list, p_profile->rs_down), FindKeyCode(button_list, p_profile->rs_up)); pad->m_vibrateMotors.emplace_back(true, 0); pad->m_vibrateMotors.emplace_back(false, 0); @@ -815,13 +838,14 @@ void ds4_pad_handler::ThreadProc() { for (int i = 0; i < static_cast(bindings.size()); i++) { - std::shared_ptr device = bindings[i].first; + m_dev = bindings[i].first; auto thepad = bindings[i].second; + auto profile = m_dev->profile; - if (device->hidDevice == nullptr) + if (m_dev->hidDevice == nullptr) { // try to reconnect - hid_device* dev = hid_open_path(device->path.c_str()); + hid_device* dev = hid_open_path(m_dev->path.c_str()); if (dev) { if (last_connection_status[i] == false) @@ -831,10 +855,10 @@ void ds4_pad_handler::ThreadProc() connected++; } hid_set_nonblocking(dev, 1); - device->hidDevice = dev; + m_dev->hidDevice = dev; thepad->m_port_status = CELL_PAD_STATUS_CONNECTED|CELL_PAD_STATUS_ASSIGN_CHANGES; - if (!device->hasCalibData) - device->hasCalibData = GetCalibrationData(device); + if (!m_dev->hasCalibData) + m_dev->hasCalibData = GetCalibrationData(m_dev); } else { @@ -856,53 +880,53 @@ void ds4_pad_handler::ThreadProc() connected++; } - DS4DataStatus status = GetRawData(device); + DS4DataStatus status = GetRawData(m_dev); if (status == DS4DataStatus::ReadError) { // this also can mean disconnected, either way deal with it on next loop and reconnect - hid_close(device->hidDevice); - device->hidDevice = nullptr; + hid_close(m_dev->hidDevice); + m_dev->hidDevice = nullptr; continue; } // Attempt to send rumble no matter what - int idx_l = m_pad_config.switch_vibration_motors ? 1 : 0; - int idx_s = m_pad_config.switch_vibration_motors ? 0 : 1; + int idx_l = profile->switch_vibration_motors ? 1 : 0; + int idx_s = profile->switch_vibration_motors ? 0 : 1; - int speed_large = m_pad_config.enable_vibration_motor_large ? thepad->m_vibrateMotors[idx_l].m_value : vibration_min; - int speed_small = m_pad_config.enable_vibration_motor_small ? thepad->m_vibrateMotors[idx_s].m_value : vibration_min; + int speed_large = profile->enable_vibration_motor_large ? thepad->m_vibrateMotors[idx_l].m_value : vibration_min; + int speed_small = profile->enable_vibration_motor_small ? thepad->m_vibrateMotors[idx_s].m_value : vibration_min; - bool wireless = device->cableState < 1; - bool lowBattery = device->batteryLevel < 2; - bool isBlinking = device->led_delay_on > 0 || device->led_delay_off > 0; + bool wireless = m_dev->cableState < 1; + bool lowBattery = m_dev->batteryLevel < 2; + bool isBlinking = m_dev->led_delay_on > 0 || m_dev->led_delay_off > 0; bool newBlinkData = false; // we are now wired or have okay battery level -> stop blinking if (isBlinking && !(wireless && lowBattery)) { - device->led_delay_on = 0; - device->led_delay_off = 0; + m_dev->led_delay_on = 0; + m_dev->led_delay_off = 0; newBlinkData = true; } // we are now wireless and low on battery -> blink if (!isBlinking && wireless && lowBattery) { - device->led_delay_on = 100; - device->led_delay_off = 100; + m_dev->led_delay_on = 100; + m_dev->led_delay_off = 100; newBlinkData = true; } - device->newVibrateData = device->newVibrateData || device->largeVibrate != speed_large || device->smallVibrate != speed_small || newBlinkData; + m_dev->newVibrateData = m_dev->newVibrateData || m_dev->largeVibrate != speed_large || m_dev->smallVibrate != speed_small || newBlinkData; - device->largeVibrate = speed_large; - device->smallVibrate = speed_small; + m_dev->largeVibrate = speed_large; + m_dev->smallVibrate = speed_small; - if (device->newVibrateData) + if (m_dev->newVibrateData) { - if (SendVibrateData(device) >= 0) + if (SendVibrateData(m_dev) >= 0) { - device->newVibrateData = false; + m_dev->newVibrateData = false; } } @@ -911,7 +935,7 @@ void ds4_pad_handler::ThreadProc() continue; else if (status == DS4DataStatus::NewData) - ProcessDataToPad(device, thepad); + ProcessDataToPad(m_dev, thepad); } } diff --git a/rpcs3/ds4_pad_handler.h b/rpcs3/ds4_pad_handler.h index 196a2ffcf9f6..05baa0405a2c 100644 --- a/rpcs3/ds4_pad_handler.h +++ b/rpcs3/ds4_pad_handler.h @@ -109,6 +109,7 @@ class ds4_pad_handler final : public PadHandlerBase struct DS4Device { hid_device* hidDevice{ nullptr }; + pad_profile* profile{ nullptr }; std::string path{ "" }; bool btCon{ false }; bool hasCalibData{ false }; @@ -139,16 +140,17 @@ class ds4_pad_handler final : public PadHandlerBase bool Init() override; std::vector ListDevices() override; - bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; + bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) override; void ThreadProc() override; void GetNextButtonPress(const std::string& padId, const std::function& buttonCallback, bool get_blacklist = false, std::vector buttons = {}) override; void TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) override; private: - bool is_init; + bool is_init = false; std::vector blacklist; std::vector, std::shared_ptr>> bindings; + std::shared_ptr m_dev; private: std::shared_ptr GetDevice(const std::string& padId); diff --git a/rpcs3/evdev_joystick_handler.cpp b/rpcs3/evdev_joystick_handler.cpp index 701ba7655609..e7c2dc11c2be 100644 --- a/rpcs3/evdev_joystick_handler.cpp +++ b/rpcs3/evdev_joystick_handler.cpp @@ -31,39 +31,44 @@ evdev_joystick_handler::evdev_joystick_handler() m_pad_config.cfg_type = "evdev"; m_pad_config.cfg_name = fs::get_config_dir() + "/config_evdev.yml"; - // Set default button mapping - m_pad_config.ls_left.def = rev_axis_list.at(ABS_X); - m_pad_config.ls_down.def = axis_list.at(ABS_Y); - m_pad_config.ls_right.def = axis_list.at(ABS_X); - m_pad_config.ls_up.def = rev_axis_list.at(ABS_Y); - m_pad_config.rs_left.def = rev_axis_list.at(ABS_RX); - m_pad_config.rs_down.def = axis_list.at(ABS_RY); - m_pad_config.rs_right.def = axis_list.at(ABS_RX); - m_pad_config.rs_up.def = rev_axis_list.at(ABS_RY); - m_pad_config.start.def = button_list.at(BTN_START); - m_pad_config.select.def = button_list.at(BTN_SELECT); - m_pad_config.ps.def = button_list.at(BTN_MODE); - m_pad_config.square.def = button_list.at(BTN_X); - m_pad_config.cross.def = button_list.at(BTN_A); - m_pad_config.circle.def = button_list.at(BTN_B); - m_pad_config.triangle.def = button_list.at(BTN_Y); - m_pad_config.left.def = rev_axis_list.at(ABS_HAT0X); - m_pad_config.down.def = axis_list.at(ABS_HAT0Y); - m_pad_config.right.def = axis_list.at(ABS_HAT0X); - m_pad_config.up.def = rev_axis_list.at(ABS_HAT0Y); - m_pad_config.r1.def = button_list.at(BTN_TR); - m_pad_config.r2.def = axis_list.at(ABS_RZ); - m_pad_config.r3.def = button_list.at(BTN_THUMBR); - m_pad_config.l1.def = button_list.at(BTN_TL); - m_pad_config.l2.def = axis_list.at(ABS_Z); - m_pad_config.l3.def = button_list.at(BTN_THUMBL); - - // Set default misc variables - m_pad_config.lstickdeadzone.def = 30; // between 0 and 255 - m_pad_config.rstickdeadzone.def = 30; // between 0 and 255 - m_pad_config.ltriggerthreshold.def = 0; // between 0 and 255 - m_pad_config.rtriggerthreshold.def = 0; // between 0 and 255 - m_pad_config.padsquircling.def = 5000; + for (const auto& node : m_pad_config.get_nodes()) + { + pad_profile* profile = static_cast(node.second); + + // Set default button mapping + profile->ls_left.def = rev_axis_list.at(ABS_X); + profile->ls_down.def = axis_list.at(ABS_Y); + profile->ls_right.def = axis_list.at(ABS_X); + profile->ls_up.def = rev_axis_list.at(ABS_Y); + profile->rs_left.def = rev_axis_list.at(ABS_RX); + profile->rs_down.def = axis_list.at(ABS_RY); + profile->rs_right.def = axis_list.at(ABS_RX); + profile->rs_up.def = rev_axis_list.at(ABS_RY); + profile->start.def = button_list.at(BTN_START); + profile->select.def = button_list.at(BTN_SELECT); + profile->ps.def = button_list.at(BTN_MODE); + profile->square.def = button_list.at(BTN_X); + profile->cross.def = button_list.at(BTN_A); + profile->circle.def = button_list.at(BTN_B); + profile->triangle.def = button_list.at(BTN_Y); + profile->left.def = rev_axis_list.at(ABS_HAT0X); + profile->down.def = axis_list.at(ABS_HAT0Y); + profile->right.def = axis_list.at(ABS_HAT0X); + profile->up.def = rev_axis_list.at(ABS_HAT0Y); + profile->r1.def = button_list.at(BTN_TR); + profile->r2.def = axis_list.at(ABS_RZ); + profile->r3.def = button_list.at(BTN_THUMBR); + profile->l1.def = button_list.at(BTN_TL); + profile->l2.def = axis_list.at(ABS_Z); + profile->l3.def = button_list.at(BTN_THUMBL); + + // Set default misc variables + profile->lstickdeadzone.def = 30; // between 0 and 255 + profile->rstickdeadzone.def = 30; // between 0 and 255 + profile->ltriggerthreshold.def = 0; // between 0 and 255 + profile->rtriggerthreshold.def = 0; // between 0 and 255 + profile->padsquircling.def = 5000; + } // apply defaults m_pad_config.from_default(); @@ -498,6 +503,7 @@ void evdev_joystick_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u1 { // Update the pad button values based on their type and thresholds. // With this you can use axis or triggers as buttons or vice versa + auto profile = m_dev.profile; u32 code = static_cast(keyCode); auto checkButton = [&](const EvdevButton& b) { @@ -510,23 +516,23 @@ void evdev_joystick_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u1 if (checkButton(m_dev.trigger_left)) { - pressed = value > m_pad_config.ltriggerthreshold; - value = pressed ? NormalizeTriggerInput(value, m_pad_config.ltriggerthreshold) : 0; + pressed = value > profile->ltriggerthreshold; + value = pressed ? NormalizeTriggerInput(value, profile->ltriggerthreshold) : 0; } else if (checkButton(m_dev.trigger_right)) { - pressed = value > m_pad_config.rtriggerthreshold; - value = pressed ? NormalizeTriggerInput(value, m_pad_config.rtriggerthreshold) : 0; + pressed = value > profile->rtriggerthreshold; + value = pressed ? NormalizeTriggerInput(value, profile->rtriggerthreshold) : 0; } else if (checkButtons(m_dev.axis_left)) { - pressed = value > (ignore_threshold ? 0 : m_pad_config.lstickdeadzone); - value = pressed ? NormalizeStickInput(value, m_pad_config.lstickdeadzone, ignore_threshold) : 0; + pressed = value > (ignore_threshold ? 0 : profile->lstickdeadzone); + value = pressed ? NormalizeStickInput(value, profile->lstickdeadzone, ignore_threshold) : 0; } else if (checkButtons(m_dev.axis_right)) { - pressed = value > (ignore_threshold ? 0 : m_pad_config.rstickdeadzone); - value = pressed ? NormalizeStickInput(value, m_pad_config.rstickdeadzone, ignore_threshold) : 0; + pressed = value > (ignore_threshold ? 0 : profile->rstickdeadzone); + value = pressed ? NormalizeStickInput(value, profile->rstickdeadzone, ignore_threshold) : 0; } else // normal button (should in theory also support sensitive buttons) { @@ -680,6 +686,7 @@ void evdev_joystick_handler::ThreadProc() for (auto& device : devices) { m_dev = device; + auto profile = device.profile; auto pad = device.pad; auto axis_orientations = device.axis_orientations; auto& dev = device.device; @@ -704,10 +711,10 @@ void evdev_joystick_handler::ThreadProc() padnum++; // Handle vibration - int idx_l = m_pad_config.switch_vibration_motors ? 1 : 0; - int idx_s = m_pad_config.switch_vibration_motors ? 0 : 1; - u16 force_large = m_pad_config.enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : vibration_min; - u16 force_small = m_pad_config.enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : vibration_min; + int idx_l = profile->switch_vibration_motors ? 1 : 0; + int idx_s = profile->switch_vibration_motors ? 0 : 1; + u16 force_large = profile->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : vibration_min; + u16 force_small = profile->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : vibration_min; SetRumble(&device, force_large, force_small); // Try to query the latest event from the joystick. @@ -832,13 +839,13 @@ void evdev_joystick_handler::ThreadProc() u16 lx, ly, rx, ry; // Normalize our two stick's axis based on the thresholds - std::tie(lx, ly) = NormalizeStickDeadzone(device.stick_val[0], device.stick_val[1], m_pad_config.lstickdeadzone); - std::tie(rx, ry) = NormalizeStickDeadzone(device.stick_val[2], device.stick_val[3], m_pad_config.rstickdeadzone); + std::tie(lx, ly) = NormalizeStickDeadzone(device.stick_val[0], device.stick_val[1], profile->lstickdeadzone); + std::tie(rx, ry) = NormalizeStickDeadzone(device.stick_val[2], device.stick_val[3], profile->rstickdeadzone); - if (m_pad_config.padsquircling != 0) + if (profile->padsquircling != 0) { - std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, m_pad_config.padsquircling); - std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, m_pad_config.padsquircling); + std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, profile->padsquircling); + std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, profile->padsquircling); } pad->m_sticks[0].m_value = lx; @@ -858,7 +865,7 @@ int evdev_joystick_handler::FindAxisDirection(const std::unordered_mapsecond; }; -bool evdev_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) +bool evdev_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) { Init(); @@ -866,6 +873,21 @@ bool evdev_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std int i = 0; // increment to know the axis location (17-24). Be careful if you ever add more find_key() calls in here (BUTTON_COUNT = 17) int last_type = EV_ABS; + pad_profile* p_profile = nullptr; + + for (const auto& prof : m_pad_config.get_nodes()) + { + if (prof.first == profile) + { + p_profile = static_cast(prof.second); + m_dev.profile = p_profile; + break; + } + } + + if (p_profile == nullptr) + return false; + auto find_key = [&](const cfg::string& name) { int type = EV_ABS; @@ -909,38 +931,38 @@ bool evdev_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std CELL_PAD_DEV_TYPE_STANDARD ); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.triangle), CELL_PAD_CTRL_TRIANGLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.circle), CELL_PAD_CTRL_CIRCLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.cross), CELL_PAD_CTRL_CROSS); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.square), CELL_PAD_CTRL_SQUARE); - - m_dev.trigger_left = evdevbutton(m_pad_config.l2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, m_dev.trigger_left.code, CELL_PAD_CTRL_L2); - - m_dev.trigger_right = evdevbutton(m_pad_config.r2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, m_dev.trigger_right.code, CELL_PAD_CTRL_R2); - - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.l1), CELL_PAD_CTRL_L1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.r1), CELL_PAD_CTRL_R1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.start), CELL_PAD_CTRL_START); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.select), CELL_PAD_CTRL_SELECT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.l3), CELL_PAD_CTRL_L3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.r3), CELL_PAD_CTRL_R3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.up), CELL_PAD_CTRL_UP); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.down), CELL_PAD_CTRL_DOWN); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.left), CELL_PAD_CTRL_LEFT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.right), CELL_PAD_CTRL_RIGHT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved - - m_dev.axis_left[0] = evdevbutton(m_pad_config.ls_right); - m_dev.axis_left[1] = evdevbutton(m_pad_config.ls_left); - m_dev.axis_left[2] = evdevbutton(m_pad_config.ls_up); - m_dev.axis_left[3] = evdevbutton(m_pad_config.ls_down); - m_dev.axis_right[0] = evdevbutton(m_pad_config.rs_right); - m_dev.axis_right[1] = evdevbutton(m_pad_config.rs_left); - m_dev.axis_right[2] = evdevbutton(m_pad_config.rs_up); - m_dev.axis_right[3] = evdevbutton(m_pad_config.rs_down); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->triangle), CELL_PAD_CTRL_TRIANGLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->circle), CELL_PAD_CTRL_CIRCLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->cross), CELL_PAD_CTRL_CROSS); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->square), CELL_PAD_CTRL_SQUARE); + + m_dev.trigger_left = evdevbutton(p_profile->l2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, m_dev.trigger_left.code, CELL_PAD_CTRL_L2); + + m_dev.trigger_right = evdevbutton(p_profile->r2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, m_dev.trigger_right.code, CELL_PAD_CTRL_R2); + + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->l1), CELL_PAD_CTRL_L1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->r1), CELL_PAD_CTRL_R1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->start), CELL_PAD_CTRL_START); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->select), CELL_PAD_CTRL_SELECT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->l3), CELL_PAD_CTRL_L3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->r3), CELL_PAD_CTRL_R3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->up), CELL_PAD_CTRL_UP); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->down), CELL_PAD_CTRL_DOWN); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->left), CELL_PAD_CTRL_LEFT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->right), CELL_PAD_CTRL_RIGHT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved + + m_dev.axis_left[0] = evdevbutton(p_profile->ls_right); + m_dev.axis_left[1] = evdevbutton(p_profile->ls_left); + m_dev.axis_left[2] = evdevbutton(p_profile->ls_up); + m_dev.axis_left[3] = evdevbutton(p_profile->ls_down); + m_dev.axis_right[0] = evdevbutton(p_profile->rs_right); + m_dev.axis_right[1] = evdevbutton(p_profile->rs_left); + m_dev.axis_right[2] = evdevbutton(p_profile->rs_up); + m_dev.axis_right[3] = evdevbutton(p_profile->rs_down); pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, m_dev.axis_left[1].code, m_dev.axis_left[0].code); pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, m_dev.axis_left[3].code, m_dev.axis_left[2].code); diff --git a/rpcs3/evdev_joystick_handler.h b/rpcs3/evdev_joystick_handler.h index 4e554ba94757..68aea37a7577 100644 --- a/rpcs3/evdev_joystick_handler.h +++ b/rpcs3/evdev_joystick_handler.h @@ -302,7 +302,8 @@ class evdev_joystick_handler final : public PadHandlerBase struct EvdevDevice { - libevdev* device = nullptr; + libevdev* device{ nullptr }; + pad_profile* profile{ nullptr }; std::string path; std::shared_ptr pad; std::unordered_map axis_orientations; // value is true if key was found in rev_axis_list @@ -330,7 +331,7 @@ class evdev_joystick_handler final : public PadHandlerBase bool Init() override; std::vector ListDevices() override; - bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; + bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) override; void ThreadProc() override; void Close(); void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false, std::vector buttons = {}) override; diff --git a/rpcs3/keyboard_pad_handler.cpp b/rpcs3/keyboard_pad_handler.cpp index 073b0e170ed5..4a8ba4083f74 100644 --- a/rpcs3/keyboard_pad_handler.cpp +++ b/rpcs3/keyboard_pad_handler.cpp @@ -20,32 +20,37 @@ keyboard_pad_handler::keyboard_pad_handler() : QObject() m_pad_config.cfg_type = "keyboard"; m_pad_config.cfg_name = fs::get_config_dir() + "/config_kbpad_qt.yml"; - // Set default button mapping - m_pad_config.ls_left.def = GetKeyName(Qt::Key_A); - m_pad_config.ls_down.def = GetKeyName(Qt::Key_S); - m_pad_config.ls_right.def = GetKeyName(Qt::Key_D); - m_pad_config.ls_up.def = GetKeyName(Qt::Key_W); - m_pad_config.rs_left.def = GetKeyName(Qt::Key_Home); - m_pad_config.rs_down.def = GetKeyName(Qt::Key_PageDown); - m_pad_config.rs_right.def = GetKeyName(Qt::Key_End); - m_pad_config.rs_up.def = GetKeyName(Qt::Key_PageUp); - m_pad_config.start.def = GetKeyName(Qt::Key_Return); - m_pad_config.select.def = GetKeyName(Qt::Key_Space); - m_pad_config.ps.def = GetKeyName(Qt::Key_Backspace); - m_pad_config.square.def = GetKeyName(Qt::Key_Z); - m_pad_config.cross.def = GetKeyName(Qt::Key_X); - m_pad_config.circle.def = GetKeyName(Qt::Key_C); - m_pad_config.triangle.def = GetKeyName(Qt::Key_V); - m_pad_config.left.def = GetKeyName(Qt::Key_Left); - m_pad_config.down.def = GetKeyName(Qt::Key_Down); - m_pad_config.right.def = GetKeyName(Qt::Key_Right); - m_pad_config.up.def = GetKeyName(Qt::Key_Up); - m_pad_config.r1.def = GetKeyName(Qt::Key_E); - m_pad_config.r2.def = GetKeyName(Qt::Key_T); - m_pad_config.r3.def = GetKeyName(Qt::Key_G); - m_pad_config.l1.def = GetKeyName(Qt::Key_Q); - m_pad_config.l2.def = GetKeyName(Qt::Key_R); - m_pad_config.l3.def = GetKeyName(Qt::Key_F); + for (const auto& node : m_pad_config.get_nodes()) + { + pad_profile* profile = static_cast(node.second); + + // Set default button mapping + profile->ls_left.def = GetKeyName(Qt::Key_A); + profile->ls_down.def = GetKeyName(Qt::Key_S); + profile->ls_right.def = GetKeyName(Qt::Key_D); + profile->ls_up.def = GetKeyName(Qt::Key_W); + profile->rs_left.def = GetKeyName(Qt::Key_Home); + profile->rs_down.def = GetKeyName(Qt::Key_PageDown); + profile->rs_right.def = GetKeyName(Qt::Key_End); + profile->rs_up.def = GetKeyName(Qt::Key_PageUp); + profile->start.def = GetKeyName(Qt::Key_Return); + profile->select.def = GetKeyName(Qt::Key_Space); + profile->ps.def = GetKeyName(Qt::Key_Backspace); + profile->square.def = GetKeyName(Qt::Key_Z); + profile->cross.def = GetKeyName(Qt::Key_X); + profile->circle.def = GetKeyName(Qt::Key_C); + profile->triangle.def = GetKeyName(Qt::Key_V); + profile->left.def = GetKeyName(Qt::Key_Left); + profile->down.def = GetKeyName(Qt::Key_Down); + profile->right.def = GetKeyName(Qt::Key_Right); + profile->up.def = GetKeyName(Qt::Key_Up); + profile->r1.def = GetKeyName(Qt::Key_E); + profile->r2.def = GetKeyName(Qt::Key_T); + profile->r3.def = GetKeyName(Qt::Key_G); + profile->l1.def = GetKeyName(Qt::Key_Q); + profile->l2.def = GetKeyName(Qt::Key_R); + profile->l3.def = GetKeyName(Qt::Key_F); + } // apply defaults m_pad_config.from_default(); @@ -381,13 +386,24 @@ u32 keyboard_pad_handler::GetKeyCode(const QString& keyName) return keyCode; } -bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) +bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) { if (device != "Keyboard") return false; m_pad_config.load(); + pad_profile* p_profile = nullptr; + + for (const auto& prof : m_pad_config.get_nodes()) + { + if (prof.first == profile) + p_profile = static_cast(prof.second); + } + + if (p_profile == nullptr) + return false; + auto find_key = [&](const cfg::string& name) { int key = FindKeyCode(mouse_list, name, false); @@ -407,29 +423,29 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std:: CELL_PAD_DEV_TYPE_STANDARD ); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.left), CELL_PAD_CTRL_LEFT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.down), CELL_PAD_CTRL_DOWN); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.right), CELL_PAD_CTRL_RIGHT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.up), CELL_PAD_CTRL_UP); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.start), CELL_PAD_CTRL_START); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.r3), CELL_PAD_CTRL_R3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.l3), CELL_PAD_CTRL_L3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.select), CELL_PAD_CTRL_SELECT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.square), CELL_PAD_CTRL_SQUARE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.cross), CELL_PAD_CTRL_CROSS); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.circle), CELL_PAD_CTRL_CIRCLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.triangle), CELL_PAD_CTRL_TRIANGLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.r1), CELL_PAD_CTRL_R1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.l1), CELL_PAD_CTRL_L1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.r2), CELL_PAD_CTRL_R2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.l2), CELL_PAD_CTRL_L2); - - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, find_key(m_pad_config.ls_left), find_key(m_pad_config.ls_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, find_key(m_pad_config.ls_up), find_key(m_pad_config.ls_down)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, find_key(m_pad_config.rs_left), find_key(m_pad_config.rs_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, find_key(m_pad_config.rs_up), find_key(m_pad_config.rs_down)); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->left), CELL_PAD_CTRL_LEFT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->down), CELL_PAD_CTRL_DOWN); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->right), CELL_PAD_CTRL_RIGHT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->up), CELL_PAD_CTRL_UP); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->start), CELL_PAD_CTRL_START); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->r3), CELL_PAD_CTRL_R3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->l3), CELL_PAD_CTRL_L3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->select), CELL_PAD_CTRL_SELECT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->square), CELL_PAD_CTRL_SQUARE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->cross), CELL_PAD_CTRL_CROSS); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->circle), CELL_PAD_CTRL_CIRCLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->triangle), CELL_PAD_CTRL_TRIANGLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->r1), CELL_PAD_CTRL_R1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->l1), CELL_PAD_CTRL_L1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->r2), CELL_PAD_CTRL_R2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->l2), CELL_PAD_CTRL_L2); + + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, find_key(p_profile->ls_left), find_key(p_profile->ls_right)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, find_key(p_profile->ls_up), find_key(p_profile->ls_down)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, find_key(p_profile->rs_left), find_key(p_profile->rs_right)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, find_key(p_profile->rs_up), find_key(p_profile->rs_down)); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_X, 512); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_Y, 399); diff --git a/rpcs3/keyboard_pad_handler.h b/rpcs3/keyboard_pad_handler.h index 79d213ae6a39..613f0ceae5ed 100644 --- a/rpcs3/keyboard_pad_handler.h +++ b/rpcs3/keyboard_pad_handler.h @@ -58,7 +58,7 @@ class keyboard_pad_handler final : public QObject, public PadHandlerBase bool eventFilter(QObject* obj, QEvent* ev) override; std::vector ListDevices() override; - bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; + bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) override; void ThreadProc() override; std::string GetMouseName(const QMouseEvent* event); diff --git a/rpcs3/mm_joystick_handler.cpp b/rpcs3/mm_joystick_handler.cpp index 1e8929823242..c12bcf8ff2d1 100644 --- a/rpcs3/mm_joystick_handler.cpp +++ b/rpcs3/mm_joystick_handler.cpp @@ -16,39 +16,44 @@ mm_joystick_handler::mm_joystick_handler() : is_init(false) m_pad_config.cfg_type = "mmjoystick"; m_pad_config.cfg_name = fs::get_config_dir() + "/config_mmjoystick.yml"; - // Set default button mapping - m_pad_config.ls_left.def = axis_list.at(mmjoy_axis::joy_x_neg); - m_pad_config.ls_down.def = axis_list.at(mmjoy_axis::joy_y_neg); - m_pad_config.ls_right.def = axis_list.at(mmjoy_axis::joy_x_pos); - m_pad_config.ls_up.def = axis_list.at(mmjoy_axis::joy_y_pos); - m_pad_config.rs_left.def = axis_list.at(mmjoy_axis::joy_z_neg); - m_pad_config.rs_down.def = axis_list.at(mmjoy_axis::joy_r_neg); - m_pad_config.rs_right.def = axis_list.at(mmjoy_axis::joy_z_pos); - m_pad_config.rs_up.def = axis_list.at(mmjoy_axis::joy_r_pos); - m_pad_config.start.def = button_list.at(JOY_BUTTON9); - m_pad_config.select.def = button_list.at(JOY_BUTTON10); - m_pad_config.ps.def = button_list.at(JOY_BUTTON17); - m_pad_config.square.def = button_list.at(JOY_BUTTON4); - m_pad_config.cross.def = button_list.at(JOY_BUTTON3); - m_pad_config.circle.def = button_list.at(JOY_BUTTON2); - m_pad_config.triangle.def = button_list.at(JOY_BUTTON1); - m_pad_config.left.def = pov_list.at(JOY_POVLEFT); - m_pad_config.down.def = pov_list.at(JOY_POVBACKWARD); - m_pad_config.right.def = pov_list.at(JOY_POVRIGHT); - m_pad_config.up.def = pov_list.at(JOY_POVFORWARD); - m_pad_config.r1.def = button_list.at(JOY_BUTTON8); - m_pad_config.r2.def = button_list.at(JOY_BUTTON6); - m_pad_config.r3.def = button_list.at(JOY_BUTTON12); - m_pad_config.l1.def = button_list.at(JOY_BUTTON7); - m_pad_config.l2.def = button_list.at(JOY_BUTTON5); - m_pad_config.l3.def = button_list.at(JOY_BUTTON11); - - // Set default misc variables - m_pad_config.lstickdeadzone.def = 0; // between 0 and 255 - m_pad_config.rstickdeadzone.def = 0; // between 0 and 255 - m_pad_config.ltriggerthreshold.def = 0; // between 0 and 255 - m_pad_config.rtriggerthreshold.def = 0; // between 0 and 255 - m_pad_config.padsquircling.def = 8000; + for (const auto& node : m_pad_config.get_nodes()) + { + pad_profile* profile = static_cast(node.second); + + // Set default button mapping + profile->ls_left.def = axis_list.at(mmjoy_axis::joy_x_neg); + profile->ls_down.def = axis_list.at(mmjoy_axis::joy_y_neg); + profile->ls_right.def = axis_list.at(mmjoy_axis::joy_x_pos); + profile->ls_up.def = axis_list.at(mmjoy_axis::joy_y_pos); + profile->rs_left.def = axis_list.at(mmjoy_axis::joy_z_neg); + profile->rs_down.def = axis_list.at(mmjoy_axis::joy_r_neg); + profile->rs_right.def = axis_list.at(mmjoy_axis::joy_z_pos); + profile->rs_up.def = axis_list.at(mmjoy_axis::joy_r_pos); + profile->start.def = button_list.at(JOY_BUTTON9); + profile->select.def = button_list.at(JOY_BUTTON10); + profile->ps.def = button_list.at(JOY_BUTTON17); + profile->square.def = button_list.at(JOY_BUTTON4); + profile->cross.def = button_list.at(JOY_BUTTON3); + profile->circle.def = button_list.at(JOY_BUTTON2); + profile->triangle.def = button_list.at(JOY_BUTTON1); + profile->left.def = pov_list.at(JOY_POVLEFT); + profile->down.def = pov_list.at(JOY_POVBACKWARD); + profile->right.def = pov_list.at(JOY_POVRIGHT); + profile->up.def = pov_list.at(JOY_POVFORWARD); + profile->r1.def = button_list.at(JOY_BUTTON8); + profile->r2.def = button_list.at(JOY_BUTTON6); + profile->r3.def = button_list.at(JOY_BUTTON12); + profile->l1.def = button_list.at(JOY_BUTTON7); + profile->l2.def = button_list.at(JOY_BUTTON5); + profile->l3.def = button_list.at(JOY_BUTTON11); + + // Set default misc variables + profile->lstickdeadzone.def = 0; // between 0 and 255 + profile->rstickdeadzone.def = 0; // between 0 and 255 + profile->ltriggerthreshold.def = 0; // between 0 and 255 + profile->rtriggerthreshold.def = 0; // between 0 and 255 + profile->padsquircling.def = 8000; + } // apply defaults m_pad_config.from_default(); @@ -112,7 +117,7 @@ std::vector mm_joystick_handler::ListDevices() return devices; } -bool mm_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) +bool mm_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) { if (!Init()) return false; @@ -123,6 +128,21 @@ bool mm_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::s std::shared_ptr joy_device = std::make_shared(m_devices.at(id)); + pad_profile* p_profile = nullptr; + + for (const auto& prof : m_pad_config.get_nodes()) + { + if (prof.first == profile) + { + p_profile = static_cast(prof.second); + joy_device->profile = p_profile; + break; + } + } + + if (p_profile == nullptr) + return false; + auto find_key = [=](const cfg::string& name) { long key = FindKeyCode(button_list, name, false); @@ -141,34 +161,34 @@ bool mm_joystick_handler::bindPadToDevice(std::shared_ptr pad, const std::s CELL_PAD_DEV_TYPE_STANDARD ); - joy_device->trigger_left = find_key(m_pad_config.l2); - joy_device->trigger_right = find_key(m_pad_config.r2); - joy_device->axis_left[0] = find_key(m_pad_config.ls_left); - joy_device->axis_left[1] = find_key(m_pad_config.ls_right); - joy_device->axis_left[2] = find_key(m_pad_config.ls_down); - joy_device->axis_left[3] = find_key(m_pad_config.ls_up); - joy_device->axis_right[0] = find_key(m_pad_config.rs_left); - joy_device->axis_right[1] = find_key(m_pad_config.rs_right); - joy_device->axis_right[2] = find_key(m_pad_config.rs_down); - joy_device->axis_right[3] = find_key(m_pad_config.rs_up); - - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.triangle), CELL_PAD_CTRL_TRIANGLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.circle), CELL_PAD_CTRL_CIRCLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.cross), CELL_PAD_CTRL_CROSS); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.square), CELL_PAD_CTRL_SQUARE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, joy_device->trigger_left, CELL_PAD_CTRL_L2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, joy_device->trigger_right, CELL_PAD_CTRL_R2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.l1), CELL_PAD_CTRL_L1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.r1), CELL_PAD_CTRL_R1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.start), CELL_PAD_CTRL_START); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.select), CELL_PAD_CTRL_SELECT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.l3), CELL_PAD_CTRL_L3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.r3), CELL_PAD_CTRL_R3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(m_pad_config.ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.up), CELL_PAD_CTRL_UP); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.down), CELL_PAD_CTRL_DOWN); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.left), CELL_PAD_CTRL_LEFT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(m_pad_config.right), CELL_PAD_CTRL_RIGHT); + joy_device->trigger_left = find_key(p_profile->l2); + joy_device->trigger_right = find_key(p_profile->r2); + joy_device->axis_left[0] = find_key(p_profile->ls_left); + joy_device->axis_left[1] = find_key(p_profile->ls_right); + joy_device->axis_left[2] = find_key(p_profile->ls_down); + joy_device->axis_left[3] = find_key(p_profile->ls_up); + joy_device->axis_right[0] = find_key(p_profile->rs_left); + joy_device->axis_right[1] = find_key(p_profile->rs_right); + joy_device->axis_right[2] = find_key(p_profile->rs_down); + joy_device->axis_right[3] = find_key(p_profile->rs_up); + + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->triangle), CELL_PAD_CTRL_TRIANGLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->circle), CELL_PAD_CTRL_CIRCLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->cross), CELL_PAD_CTRL_CROSS); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->square), CELL_PAD_CTRL_SQUARE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, joy_device->trigger_left, CELL_PAD_CTRL_L2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, joy_device->trigger_right, CELL_PAD_CTRL_R2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->l1), CELL_PAD_CTRL_L1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->r1), CELL_PAD_CTRL_R1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->start), CELL_PAD_CTRL_START); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->select), CELL_PAD_CTRL_SELECT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->l3), CELL_PAD_CTRL_L3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->r3), CELL_PAD_CTRL_R3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, find_key(p_profile->ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->up), CELL_PAD_CTRL_UP); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->down), CELL_PAD_CTRL_DOWN); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->left), CELL_PAD_CTRL_LEFT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, find_key(p_profile->right), CELL_PAD_CTRL_RIGHT); pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, joy_device->axis_left[0], joy_device->axis_left[1]); @@ -197,6 +217,7 @@ void mm_joystick_handler::ThreadProc() { m_dev = bindings[i].first; auto pad = bindings[i].second; + auto profile = m_dev->profile; status = joyGetPosEx(m_dev->device_id, &m_dev->device_info); if (status != JOYERR_NOERROR) @@ -256,13 +277,13 @@ void mm_joystick_handler::ThreadProc() u16 lx, ly, rx, ry; // Normalize our two stick's axis based on the thresholds - std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], m_pad_config.lstickdeadzone); - std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], m_pad_config.rstickdeadzone); + std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], profile->lstickdeadzone); + std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], profile->rstickdeadzone); - if (m_pad_config.padsquircling != 0) + if (profile->padsquircling != 0) { - std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, m_pad_config.padsquircling); - std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, m_pad_config.padsquircling); + std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, profile->padsquircling); + std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, profile->padsquircling); } pad->m_sticks[0].m_value = lx; @@ -415,26 +436,27 @@ void mm_joystick_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& { // Update the pad button values based on their type and thresholds. // With this you can use axis or triggers as buttons or vice versa + auto p_profile = m_dev->profile; if (keyCode == m_dev->trigger_left) { - pressed = val > (ignore_threshold ? 0 : m_pad_config.ltriggerthreshold); - val = pressed ? NormalizeTriggerInput(val, m_pad_config.ltriggerthreshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->ltriggerthreshold); + val = pressed ? NormalizeTriggerInput(val, p_profile->ltriggerthreshold) : 0; } else if (keyCode == m_dev->trigger_right) { - pressed = val > (ignore_threshold ? 0 : m_pad_config.rtriggerthreshold); - val = pressed ? NormalizeTriggerInput(val, m_pad_config.rtriggerthreshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->rtriggerthreshold); + val = pressed ? NormalizeTriggerInput(val, p_profile->rtriggerthreshold) : 0; } else if (std::find(m_dev->axis_left.begin(), m_dev->axis_left.end(), keyCode) != m_dev->axis_left.end()) { - pressed = val > (ignore_threshold ? 0 : m_pad_config.lstickdeadzone); - val = pressed ? NormalizeStickInput(val, m_pad_config.lstickdeadzone, ignore_threshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->lstickdeadzone); + val = pressed ? NormalizeStickInput(val, p_profile->lstickdeadzone, ignore_threshold) : 0; } else if (std::find(m_dev->axis_right.begin(), m_dev->axis_right.end(), keyCode) != m_dev->axis_right.end()) { - pressed = val > (ignore_threshold ? 0 : m_pad_config.rstickdeadzone); - val = pressed ? NormalizeStickInput(val, m_pad_config.rstickdeadzone, ignore_threshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->rstickdeadzone); + val = pressed ? NormalizeStickInput(val, p_profile->rstickdeadzone, ignore_threshold) : 0; } else // normal button (should in theory also support sensitive buttons) { diff --git a/rpcs3/mm_joystick_handler.h b/rpcs3/mm_joystick_handler.h index c397706c77a8..928775b168a6 100644 --- a/rpcs3/mm_joystick_handler.h +++ b/rpcs3/mm_joystick_handler.h @@ -90,6 +90,7 @@ class mm_joystick_handler final : public PadHandlerBase { u32 device_id{ 0 }; std::string device_name{ "" }; + pad_profile* profile{ nullptr }; JOYINFOEX device_info; JOYCAPS device_caps; u64 trigger_left = 0; @@ -105,7 +106,7 @@ class mm_joystick_handler final : public PadHandlerBase bool Init() override; std::vector ListDevices() override; - bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; + bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) override; void ThreadProc() override; void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false, std::vector buttons = {}) override; diff --git a/rpcs3/pad_thread.cpp b/rpcs3/pad_thread.cpp index df648892ffb5..ffed7341d0ba 100644 --- a/rpcs3/pad_thread.cpp +++ b/rpcs3/pad_thread.cpp @@ -87,11 +87,11 @@ void pad_thread::Init(const u32 max_connect) CELL_PAD_CAPABILITY_PS3_CONFORMITY | CELL_PAD_CAPABILITY_PRESS_MODE | CELL_PAD_CAPABILITY_ACTUATOR, CELL_PAD_DEV_TYPE_STANDARD)); - if (cur_pad_handler->bindPadToDevice(m_pads.back(), input_cfg.player_device[i]->to_string()) == false) + if (cur_pad_handler->bindPadToDevice(m_pads.back(), input_cfg.player_device[i]->to_string(), input_cfg.player_profile[i]->to_string()) == false) { //Failed to bind the device to cur_pad_handler so binds to NullPadHandler LOG_ERROR(GENERAL, "Failed to bind device %s to handler %s", input_cfg.player_device[i]->to_string(), handler_type.to_string()); - nullpad->bindPadToDevice(m_pads.back(), input_cfg.player_device[i]->to_string()); + nullpad->bindPadToDevice(m_pads.back(), input_cfg.player_device[i]->to_string(), input_cfg.player_profile[i]->to_string()); } } diff --git a/rpcs3/rpcs3qt/gamepads_settings_dialog.cpp b/rpcs3/rpcs3qt/gamepads_settings_dialog.cpp index c69789064377..49a738604152 100644 --- a/rpcs3/rpcs3qt/gamepads_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/gamepads_settings_dialog.cpp @@ -80,6 +80,12 @@ gamepads_settings_dialog::gamepads_settings_dialog(QWidget* parent) co_deviceID[i]->view()->setTextElideMode(Qt::ElideNone); ppad_layout->addWidget(co_deviceID[i]); + co_profile[i] = new QComboBox(); + co_profile[i]->setEnabled(false); + co_profile[i]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + co_profile[i]->view()->setTextElideMode(Qt::ElideNone); + ppad_layout->addWidget(co_profile[i]); + QHBoxLayout *button_layout = new QHBoxLayout(); bu_config[i] = new QPushButton(tr("Config")); bu_config[i]->setEnabled(false); @@ -100,6 +106,12 @@ gamepads_settings_dialog::gamepads_settings_dialog(QWidget* parent) } resizeComboBoxView(co_inputtype[i]); + for (int index = 0; index < 10; index++) + { + co_profile[i]->addItem("Profile " + QString::number(index)); + } + resizeComboBoxView(co_profile[i]); + all_players->addWidget(grp_player); if (i == 3) @@ -151,6 +163,16 @@ gamepads_settings_dialog::gamepads_settings_dialog(QWidget* parent) return; } }); + connect(co_profile[i], &QComboBox::currentTextChanged, [=](const QString& prof) + { + std::string profile = sstr(prof); + if (!input_cfg.player_profile[i]->from_string(profile)) + { + //Something went wrong + LOG_ERROR(GENERAL, "Failed to convert profile string: %s", profile); + return; + } + }); connect(bu_config[i], &QAbstractButton::clicked, [=] { ClickConfigButton(i); }); } connect(ok_button, &QPushButton::pressed, this, &gamepads_settings_dialog::SaveExit); @@ -169,6 +191,7 @@ void gamepads_settings_dialog::SaveExit() { input_cfg.player_input[i].from_default(); input_cfg.player_device[i]->from_default(); + input_cfg.player_profile[i]->from_default(); } } @@ -258,9 +281,25 @@ void gamepads_settings_dialog::ChangeInputType(int player) co_deviceID[player]->addItem(tr("No Device Detected"), -1); } - // Update view and enable configuration if possible + // enable configuration and profile list if possible + bool config_enabled = device_found && cur_pad_handler->has_config(); + bu_config[player]->setEnabled(config_enabled); + co_profile[player]->setEnabled(config_enabled); + + // update profile list if possible + if (config_enabled) + { + co_profile[player]->clear(); + for (const auto& node : cur_pad_handler->GetConfig()->get_nodes()) + { + co_profile[player]->addItem(qstr(node.first)); + } + co_profile[player]->setCurrentText(qstr(input_cfg.player_profile[player]->to_string())); + } + + // update view resizeComboBoxView(co_deviceID[player]); - bu_config[player]->setEnabled(device_found && cur_pad_handler->has_config()); + resizeComboBoxView(co_profile[player]); } void gamepads_settings_dialog::ClickConfigButton(int player) @@ -270,7 +309,8 @@ void gamepads_settings_dialog::ClickConfigButton(int player) if (cur_pad_handler->has_config()) { std::string device = sstr(co_deviceID[player]->currentText()); - pad_settings_dialog dlg(device, cur_pad_handler); + std::string profile = sstr(co_profile[player]->currentText()); + pad_settings_dialog dlg(device, profile, cur_pad_handler); dlg.exec(); } } diff --git a/rpcs3/rpcs3qt/gamepads_settings_dialog.h b/rpcs3/rpcs3qt/gamepads_settings_dialog.h index 08ff5c7e85c0..02cb269c42ef 100644 --- a/rpcs3/rpcs3qt/gamepads_settings_dialog.h +++ b/rpcs3/rpcs3qt/gamepads_settings_dialog.h @@ -35,6 +35,16 @@ struct input_config final : cfg::node cfg::string *player_device[7]{ &player1, &player2, &player3, &player4, &player5, &player6, &player7 }; // Thanks gcc! + cfg::string profile1{ this, "Player 1 Profile", "Profile 0" }; + cfg::string profile2{ this, "Player 2 Profile", "Profile 0" }; + cfg::string profile3{ this, "Player 3 Profile", "Profile 0" }; + cfg::string profile4{ this, "Player 4 Profile", "Profile 0" }; + cfg::string profile5{ this, "Player 5 Profile", "Profile 0" }; + cfg::string profile6{ this, "Player 6 Profile", "Profile 0" }; + cfg::string profile7{ this, "Player 7 Profile", "Profile 0" }; + + cfg::string *player_profile[7]{ &profile1, &profile2, &profile3, &profile4, &profile5, &profile6, &profile7 }; + bool load() { if (fs::file cfg_file{ cfg_name, fs::read }) @@ -72,6 +82,7 @@ class gamepads_settings_dialog : public QDialog protected: QComboBox *co_inputtype[7]; QComboBox *co_deviceID[7]; + QComboBox *co_profile[7]; QPushButton *bu_config[7]; public: diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index 22d816164921..0497f278c7bf 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -13,11 +13,26 @@ inline std::string sstr(const QString& _in) { return _in.toStdString(); } constexpr auto qstr = QString::fromStdString; -pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ptr handler, QWidget *parent) +pad_settings_dialog::pad_settings_dialog(const std::string& device, const std::string& profile, std::shared_ptr handler, QWidget *parent) : QDialog(parent), ui(new Ui::pad_settings_dialog), m_handler_cfg(handler->GetConfig()), m_device_name(device), m_handler(handler) { m_handler_cfg->load(); + for (const auto& node : m_handler_cfg->get_nodes()) + { + if (node.first == profile) + { + m_handler_profile = static_cast(node.second); + break; + } + } + + if (m_handler_profile == nullptr) + { + LOG_ERROR(GENERAL, "pad_settings_dialog: Could not find profile %s for device %s", profile, device); + close(); + } + ui->setupUi(this); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -28,9 +43,9 @@ pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ m_padButtons = new QButtonGroup(this); m_palette = ui->b_left->palette(); // save normal palette - ui->chb_vibration_large->setChecked((bool)m_handler_cfg->enable_vibration_motor_large); - ui->chb_vibration_small->setChecked((bool)m_handler_cfg->enable_vibration_motor_small); - ui->chb_vibration_switch->setChecked((bool)m_handler_cfg->switch_vibration_motors); + ui->chb_vibration_large->setChecked((bool)m_handler_profile->enable_vibration_motor_large); + ui->chb_vibration_small->setChecked((bool)m_handler_profile->enable_vibration_motor_small); + ui->chb_vibration_switch->setChecked((bool)m_handler_profile->switch_vibration_motors); // Adjust to the different pad handlers if (m_handler_cfg->cfg_type == "keyboard") @@ -185,14 +200,14 @@ pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ }; // Enable Trigger Thresholds - initSlider(ui->slider_trigger_left, m_handler_cfg->ltriggerthreshold, 0, m_handler->trigger_max); - initSlider(ui->slider_trigger_right, m_handler_cfg->rtriggerthreshold, 0, m_handler->trigger_max); + initSlider(ui->slider_trigger_left, m_handler_profile->ltriggerthreshold, 0, m_handler->trigger_max); + initSlider(ui->slider_trigger_right, m_handler_profile->rtriggerthreshold, 0, m_handler->trigger_max); ui->preview_trigger_left->setRange(0, m_handler->trigger_max); ui->preview_trigger_right->setRange(0, m_handler->trigger_max); // Enable Stick Deadzones - initSlider(ui->slider_stick_left, m_handler_cfg->lstickdeadzone, 0, m_handler->thumb_max); - initSlider(ui->slider_stick_right, m_handler_cfg->rstickdeadzone, 0, m_handler->thumb_max); + initSlider(ui->slider_stick_left, m_handler_profile->lstickdeadzone, 0, m_handler->thumb_max); + initSlider(ui->slider_stick_right, m_handler_profile->rstickdeadzone, 0, m_handler->thumb_max); RepaintPreviewLabel(ui->preview_stick_left, ui->slider_stick_left->value(), ui->slider_stick_left->sizeHint().width(), lx, ly); connect(ui->slider_stick_left, &QSlider::valueChanged, [&](int value) @@ -224,37 +239,37 @@ pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ button->installEventFilter(this); }; - insertButton(button_ids::id_pad_lstick_left, ui->b_lstick_left, &m_handler_cfg->ls_left); - insertButton(button_ids::id_pad_lstick_down, ui->b_lstick_down, &m_handler_cfg->ls_down); - insertButton(button_ids::id_pad_lstick_right, ui->b_lstick_right, &m_handler_cfg->ls_right); - insertButton(button_ids::id_pad_lstick_up, ui->b_lstick_up, &m_handler_cfg->ls_up); + insertButton(button_ids::id_pad_lstick_left, ui->b_lstick_left, &m_handler_profile->ls_left); + insertButton(button_ids::id_pad_lstick_down, ui->b_lstick_down, &m_handler_profile->ls_down); + insertButton(button_ids::id_pad_lstick_right, ui->b_lstick_right, &m_handler_profile->ls_right); + insertButton(button_ids::id_pad_lstick_up, ui->b_lstick_up, &m_handler_profile->ls_up); - insertButton(button_ids::id_pad_left, ui->b_left, &m_handler_cfg->left); - insertButton(button_ids::id_pad_down, ui->b_down, &m_handler_cfg->down); - insertButton(button_ids::id_pad_right, ui->b_right, &m_handler_cfg->right); - insertButton(button_ids::id_pad_up, ui->b_up, &m_handler_cfg->up); + insertButton(button_ids::id_pad_left, ui->b_left, &m_handler_profile->left); + insertButton(button_ids::id_pad_down, ui->b_down, &m_handler_profile->down); + insertButton(button_ids::id_pad_right, ui->b_right, &m_handler_profile->right); + insertButton(button_ids::id_pad_up, ui->b_up, &m_handler_profile->up); - insertButton(button_ids::id_pad_l1, ui->b_shift_l1, &m_handler_cfg->l1); - insertButton(button_ids::id_pad_l2, ui->b_shift_l2, &m_handler_cfg->l2); - insertButton(button_ids::id_pad_l3, ui->b_shift_l3, &m_handler_cfg->l3); + insertButton(button_ids::id_pad_l1, ui->b_shift_l1, &m_handler_profile->l1); + insertButton(button_ids::id_pad_l2, ui->b_shift_l2, &m_handler_profile->l2); + insertButton(button_ids::id_pad_l3, ui->b_shift_l3, &m_handler_profile->l3); - insertButton(button_ids::id_pad_start, ui->b_start, &m_handler_cfg->start); - insertButton(button_ids::id_pad_select, ui->b_select, &m_handler_cfg->select); - insertButton(button_ids::id_pad_ps, ui->b_ps, &m_handler_cfg->ps); + insertButton(button_ids::id_pad_start, ui->b_start, &m_handler_profile->start); + insertButton(button_ids::id_pad_select, ui->b_select, &m_handler_profile->select); + insertButton(button_ids::id_pad_ps, ui->b_ps, &m_handler_profile->ps); - insertButton(button_ids::id_pad_r1, ui->b_shift_r1, &m_handler_cfg->r1); - insertButton(button_ids::id_pad_r2, ui->b_shift_r2, &m_handler_cfg->r2); - insertButton(button_ids::id_pad_r3, ui->b_shift_r3, &m_handler_cfg->r3); + insertButton(button_ids::id_pad_r1, ui->b_shift_r1, &m_handler_profile->r1); + insertButton(button_ids::id_pad_r2, ui->b_shift_r2, &m_handler_profile->r2); + insertButton(button_ids::id_pad_r3, ui->b_shift_r3, &m_handler_profile->r3); - insertButton(button_ids::id_pad_square, ui->b_square, &m_handler_cfg->square); - insertButton(button_ids::id_pad_cross, ui->b_cross, &m_handler_cfg->cross); - insertButton(button_ids::id_pad_circle, ui->b_circle, &m_handler_cfg->circle); - insertButton(button_ids::id_pad_triangle, ui->b_triangle, &m_handler_cfg->triangle); + insertButton(button_ids::id_pad_square, ui->b_square, &m_handler_profile->square); + insertButton(button_ids::id_pad_cross, ui->b_cross, &m_handler_profile->cross); + insertButton(button_ids::id_pad_circle, ui->b_circle, &m_handler_profile->circle); + insertButton(button_ids::id_pad_triangle, ui->b_triangle, &m_handler_profile->triangle); - insertButton(button_ids::id_pad_rstick_left, ui->b_rstick_left, &m_handler_cfg->rs_left); - insertButton(button_ids::id_pad_rstick_down, ui->b_rstick_down, &m_handler_cfg->rs_down); - insertButton(button_ids::id_pad_rstick_right, ui->b_rstick_right, &m_handler_cfg->rs_right); - insertButton(button_ids::id_pad_rstick_up, ui->b_rstick_up, &m_handler_cfg->rs_up); + insertButton(button_ids::id_pad_rstick_left, ui->b_rstick_left, &m_handler_profile->rs_left); + insertButton(button_ids::id_pad_rstick_down, ui->b_rstick_down, &m_handler_profile->rs_down); + insertButton(button_ids::id_pad_rstick_right, ui->b_rstick_right, &m_handler_profile->rs_right); + insertButton(button_ids::id_pad_rstick_up, ui->b_rstick_up, &m_handler_profile->rs_up); m_padButtons->addButton(ui->b_reset, button_ids::id_reset_parameters); m_padButtons->addButton(ui->b_blacklist, button_ids::id_blacklist); @@ -407,17 +422,17 @@ void pad_settings_dialog::UpdateLabel(bool is_reset) { if (m_handler->has_rumble()) { - ui->chb_vibration_large->setChecked((bool)m_handler_cfg->enable_vibration_motor_large); - ui->chb_vibration_small->setChecked((bool)m_handler_cfg->enable_vibration_motor_small); - ui->chb_vibration_switch->setChecked((bool)m_handler_cfg->switch_vibration_motors); + ui->chb_vibration_large->setChecked((bool)m_handler_profile->enable_vibration_motor_large); + ui->chb_vibration_small->setChecked((bool)m_handler_profile->enable_vibration_motor_small); + ui->chb_vibration_switch->setChecked((bool)m_handler_profile->switch_vibration_motors); } if (m_handler->has_deadzones()) { - ui->slider_trigger_left->setValue(m_handler_cfg->ltriggerthreshold); - ui->slider_trigger_right->setValue(m_handler_cfg->rtriggerthreshold); - ui->slider_stick_left->setValue(m_handler_cfg->lstickdeadzone); - ui->slider_stick_right->setValue(m_handler_cfg->rstickdeadzone); + ui->slider_trigger_left->setValue(m_handler_profile->ltriggerthreshold); + ui->slider_trigger_right->setValue(m_handler_profile->rtriggerthreshold); + ui->slider_stick_left->setValue(m_handler_profile->lstickdeadzone); + ui->slider_stick_right->setValue(m_handler_profile->rstickdeadzone); } } @@ -450,17 +465,17 @@ void pad_settings_dialog::SaveConfig() if (m_handler->has_rumble()) { - m_handler_cfg->enable_vibration_motor_large.set(ui->chb_vibration_large->isChecked()); - m_handler_cfg->enable_vibration_motor_small.set(ui->chb_vibration_small->isChecked()); - m_handler_cfg->switch_vibration_motors.set(ui->chb_vibration_switch->isChecked()); + m_handler_profile->enable_vibration_motor_large.set(ui->chb_vibration_large->isChecked()); + m_handler_profile->enable_vibration_motor_small.set(ui->chb_vibration_small->isChecked()); + m_handler_profile->switch_vibration_motors.set(ui->chb_vibration_switch->isChecked()); } if (m_handler->has_deadzones()) { - m_handler_cfg->ltriggerthreshold.set(ui->slider_trigger_left->value()); - m_handler_cfg->rtriggerthreshold.set(ui->slider_trigger_right->value()); - m_handler_cfg->lstickdeadzone.set(ui->slider_stick_left->value()); - m_handler_cfg->rstickdeadzone.set(ui->slider_stick_right->value()); + m_handler_profile->ltriggerthreshold.set(ui->slider_trigger_left->value()); + m_handler_profile->rtriggerthreshold.set(ui->slider_trigger_right->value()); + m_handler_profile->lstickdeadzone.set(ui->slider_stick_left->value()); + m_handler_profile->rstickdeadzone.set(ui->slider_stick_right->value()); } m_handler_cfg->save(); diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.h b/rpcs3/rpcs3qt/pad_settings_dialog.h index 1f767388d515..cafc17e72796 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.h +++ b/rpcs3/rpcs3qt/pad_settings_dialog.h @@ -109,9 +109,10 @@ private Q_SLOTS: QPalette m_palette; // Pad Handlers - std::shared_ptr m_handler; handler_type m_handler_type; - pad_config* m_handler_cfg; + std::shared_ptr m_handler; + pad_config* m_handler_cfg{ nullptr }; + pad_profile* m_handler_profile{ nullptr }; std::string m_device_name; // Remap Timer @@ -129,7 +130,7 @@ private Q_SLOTS: void RepaintPreviewLabel(QLabel* l, int dz, int w, int x, int y); public: - explicit pad_settings_dialog(const std::string& device, std::shared_ptr handler, QWidget *parent = nullptr); + explicit pad_settings_dialog(const std::string& device, const std::string& profile, std::shared_ptr handler, QWidget *parent = nullptr); ~pad_settings_dialog(); /** Handle keyboard handler input */ diff --git a/rpcs3/xinput_pad_handler.cpp b/rpcs3/xinput_pad_handler.cpp index 3f81f5be35bf..6a11106e91d3 100644 --- a/rpcs3/xinput_pad_handler.cpp +++ b/rpcs3/xinput_pad_handler.cpp @@ -19,39 +19,44 @@ xinput_pad_handler::xinput_pad_handler() : m_pad_config.cfg_type = "xinput"; m_pad_config.cfg_name = fs::get_config_dir() + "/config_xinput.yml"; - // Set default button mapping - m_pad_config.ls_left.def = button_list.at(XInputKeyCodes::LSXNeg); - m_pad_config.ls_down.def = button_list.at(XInputKeyCodes::LSYNeg); - m_pad_config.ls_right.def = button_list.at(XInputKeyCodes::LSXPos); - m_pad_config.ls_up.def = button_list.at(XInputKeyCodes::LSYPos); - m_pad_config.rs_left.def = button_list.at(XInputKeyCodes::RSXNeg); - m_pad_config.rs_down.def = button_list.at(XInputKeyCodes::RSYNeg); - m_pad_config.rs_right.def = button_list.at(XInputKeyCodes::RSXPos); - m_pad_config.rs_up.def = button_list.at(XInputKeyCodes::RSYPos); - m_pad_config.start.def = button_list.at(XInputKeyCodes::Start); - m_pad_config.select.def = button_list.at(XInputKeyCodes::Back); - m_pad_config.ps.def = button_list.at(XInputKeyCodes::Guide); - m_pad_config.square.def = button_list.at(XInputKeyCodes::X); - m_pad_config.cross.def = button_list.at(XInputKeyCodes::A); - m_pad_config.circle.def = button_list.at(XInputKeyCodes::B); - m_pad_config.triangle.def = button_list.at(XInputKeyCodes::Y); - m_pad_config.left.def = button_list.at(XInputKeyCodes::Left); - m_pad_config.down.def = button_list.at(XInputKeyCodes::Down); - m_pad_config.right.def = button_list.at(XInputKeyCodes::Right); - m_pad_config.up.def = button_list.at(XInputKeyCodes::Up); - m_pad_config.r1.def = button_list.at(XInputKeyCodes::RB); - m_pad_config.r2.def = button_list.at(XInputKeyCodes::RT); - m_pad_config.r3.def = button_list.at(XInputKeyCodes::RS); - m_pad_config.l1.def = button_list.at(XInputKeyCodes::LB); - m_pad_config.l2.def = button_list.at(XInputKeyCodes::LT); - m_pad_config.l3.def = button_list.at(XInputKeyCodes::LS); - - // Set default misc variables - m_pad_config.lstickdeadzone.def = XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; // between 0 and 32767 - m_pad_config.rstickdeadzone.def = XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; // between 0 and 32767 - m_pad_config.ltriggerthreshold.def = XINPUT_GAMEPAD_TRIGGER_THRESHOLD; // between 0 and 255 - m_pad_config.rtriggerthreshold.def = XINPUT_GAMEPAD_TRIGGER_THRESHOLD; // between 0 and 255 - m_pad_config.padsquircling.def = 8000; + for (const auto& node : m_pad_config.get_nodes()) + { + pad_profile* profile = static_cast(node.second); + + // Set default button mapping + profile->ls_left.def = button_list.at(XInputKeyCodes::LSXNeg); + profile->ls_down.def = button_list.at(XInputKeyCodes::LSYNeg); + profile->ls_right.def = button_list.at(XInputKeyCodes::LSXPos); + profile->ls_up.def = button_list.at(XInputKeyCodes::LSYPos); + profile->rs_left.def = button_list.at(XInputKeyCodes::RSXNeg); + profile->rs_down.def = button_list.at(XInputKeyCodes::RSYNeg); + profile->rs_right.def = button_list.at(XInputKeyCodes::RSXPos); + profile->rs_up.def = button_list.at(XInputKeyCodes::RSYPos); + profile->start.def = button_list.at(XInputKeyCodes::Start); + profile->select.def = button_list.at(XInputKeyCodes::Back); + profile->ps.def = button_list.at(XInputKeyCodes::Guide); + profile->square.def = button_list.at(XInputKeyCodes::X); + profile->cross.def = button_list.at(XInputKeyCodes::A); + profile->circle.def = button_list.at(XInputKeyCodes::B); + profile->triangle.def = button_list.at(XInputKeyCodes::Y); + profile->left.def = button_list.at(XInputKeyCodes::Left); + profile->down.def = button_list.at(XInputKeyCodes::Down); + profile->right.def = button_list.at(XInputKeyCodes::Right); + profile->up.def = button_list.at(XInputKeyCodes::Up); + profile->r1.def = button_list.at(XInputKeyCodes::RB); + profile->r2.def = button_list.at(XInputKeyCodes::RT); + profile->r3.def = button_list.at(XInputKeyCodes::RS); + profile->l1.def = button_list.at(XInputKeyCodes::LB); + profile->l2.def = button_list.at(XInputKeyCodes::LT); + profile->l3.def = button_list.at(XInputKeyCodes::LS); + + // Set default misc variables + profile->lstickdeadzone.def = XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE; // between 0 and 32767 + profile->rstickdeadzone.def = XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE; // between 0 and 32767 + profile->ltriggerthreshold.def = XINPUT_GAMEPAD_TRIGGER_THRESHOLD; // between 0 and 255 + profile->rtriggerthreshold.def = XINPUT_GAMEPAD_TRIGGER_THRESHOLD; // between 0 and 255 + profile->padsquircling.def = 8000; + } // apply defaults m_pad_config.from_default(); @@ -152,29 +157,30 @@ void xinput_pad_handler::TranslateButtonPress(u64 keyCode, bool& pressed, u16& v { // Update the pad button values based on their type and thresholds. // With this you can use axis or triggers as buttons or vice versa + auto p_profile = m_dev->profile; switch (keyCode) { case XInputKeyCodes::LT: - pressed = val > m_pad_config.ltriggerthreshold; - val = pressed ? NormalizeTriggerInput(val, m_pad_config.ltriggerthreshold) : 0; + pressed = val > p_profile->ltriggerthreshold; + val = pressed ? NormalizeTriggerInput(val, p_profile->ltriggerthreshold) : 0; break; case XInputKeyCodes::RT: - pressed = val > m_pad_config.rtriggerthreshold; - val = pressed ? NormalizeTriggerInput(val, m_pad_config.rtriggerthreshold) : 0; + pressed = val > p_profile->rtriggerthreshold; + val = pressed ? NormalizeTriggerInput(val, p_profile->rtriggerthreshold) : 0; break; case XInputKeyCodes::LSXNeg: case XInputKeyCodes::LSXPos: case XInputKeyCodes::LSYPos: case XInputKeyCodes::LSYNeg: - pressed = val > (ignore_threshold ? 0 : m_pad_config.lstickdeadzone); - val = pressed ? NormalizeStickInput(val, m_pad_config.lstickdeadzone, ignore_threshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->lstickdeadzone); + val = pressed ? NormalizeStickInput(val, p_profile->lstickdeadzone, ignore_threshold) : 0; break; case XInputKeyCodes::RSXNeg: case XInputKeyCodes::RSXPos: case XInputKeyCodes::RSYPos: case XInputKeyCodes::RSYNeg: - pressed = val > (ignore_threshold ? 0 : m_pad_config.rstickdeadzone); - val = pressed ? NormalizeStickInput(val, m_pad_config.rstickdeadzone, ignore_threshold) : 0; + pressed = val > (ignore_threshold ? 0 : p_profile->rstickdeadzone); + val = pressed ? NormalizeStickInput(val, p_profile->rstickdeadzone, ignore_threshold) : 0; break; default: // normal button (should in theory also support sensitive buttons) pressed = val > 0; @@ -316,8 +322,9 @@ void xinput_pad_handler::ThreadProc() { for (auto &bind : bindings) { - auto device = bind.first; - auto padnum = device->deviceNumber; + m_dev = bind.first; + auto padnum = m_dev->deviceNumber; + auto profile = m_dev->profile; auto pad = bind.second; result = (*xinputGetState)(padnum, &state); @@ -388,13 +395,13 @@ void xinput_pad_handler::ThreadProc() u16 lx, ly, rx, ry; // Normalize our two stick's axis based on the thresholds - std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], m_pad_config.lstickdeadzone); - std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], m_pad_config.rstickdeadzone); + std::tie(lx, ly) = NormalizeStickDeadzone(stick_val[0], stick_val[1], profile->lstickdeadzone); + std::tie(rx, ry) = NormalizeStickDeadzone(stick_val[2], stick_val[3], profile->rstickdeadzone); - if (m_pad_config.padsquircling != 0) + if (profile->padsquircling != 0) { - std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, m_pad_config.padsquircling); - std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, m_pad_config.padsquircling); + std::tie(lx, ly) = ConvertToSquirclePoint(lx, ly, profile->padsquircling); + std::tie(rx, ry) = ConvertToSquirclePoint(rx, ry, profile->padsquircling); } pad->m_sticks[0].m_value = lx; @@ -410,19 +417,19 @@ void xinput_pad_handler::ThreadProc() // The left motor is the low-frequency rumble motor. The right motor is the high-frequency rumble motor. // The two motors are not the same, and they create different vibration effects. Values range between 0 to 65535. - int idx_l = m_pad_config.switch_vibration_motors ? 1 : 0; - int idx_s = m_pad_config.switch_vibration_motors ? 0 : 1; + int idx_l = profile->switch_vibration_motors ? 1 : 0; + int idx_s = profile->switch_vibration_motors ? 0 : 1; - int speed_large = m_pad_config.enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : vibration_min; - int speed_small = m_pad_config.enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : vibration_min; + int speed_large = profile->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : vibration_min; + int speed_small = profile->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : vibration_min; - device->newVibrateData = device->newVibrateData || device->largeVibrate != speed_large || device->smallVibrate != speed_small; + m_dev->newVibrateData = m_dev->newVibrateData || m_dev->largeVibrate != speed_large || m_dev->smallVibrate != speed_small; - device->largeVibrate = speed_large; - device->smallVibrate = speed_small; + m_dev->largeVibrate = speed_large; + m_dev->smallVibrate = speed_small; // XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse. So I'll use 20ms to be on the safe side. No lag was noticable. - if (device->newVibrateData && (clock() - device->last_vibration > 20)) + if (m_dev->newVibrateData && (clock() - m_dev->last_vibration > 20)) { XINPUT_VIBRATION vibrate; vibrate.wLeftMotorSpeed = speed_large; @@ -430,8 +437,8 @@ void xinput_pad_handler::ThreadProc() if ((*xinputSetState)(padnum, &vibrate) == ERROR_SUCCESS) { - device->newVibrateData = false; - device->last_vibration = clock(); + m_dev->newVibrateData = false; + m_dev->last_vibration = clock(); } } @@ -457,18 +464,33 @@ std::vector xinput_pad_handler::ListDevices() return xinput_pads_list; } -bool xinput_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device) +bool xinput_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) { //Convert device string to u32 representing xinput device number int device_number = GetDeviceNumber(device); if (device_number < 0) return false; - std::shared_ptr device_id = std::make_shared(); - device_id->deviceNumber = static_cast(device_number); + std::shared_ptr x_device = std::make_shared(); + x_device->deviceNumber = static_cast(device_number); m_pad_config.load(); + pad_profile* p_profile = nullptr; + + for (const auto& prof : m_pad_config.get_nodes()) + { + if (prof.first == profile) + { + p_profile = static_cast(prof.second); + x_device->profile = p_profile; + break; + } + } + + if (p_profile == nullptr) + return false; + pad->Init ( CELL_PAD_STATUS_CONNECTED | CELL_PAD_STATUS_ASSIGN_CHANGES, @@ -477,29 +499,29 @@ bool xinput_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::st CELL_PAD_DEV_TYPE_STANDARD ); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.up), CELL_PAD_CTRL_UP); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.down), CELL_PAD_CTRL_DOWN); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.left), CELL_PAD_CTRL_LEFT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.right), CELL_PAD_CTRL_RIGHT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.start), CELL_PAD_CTRL_START); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.select), CELL_PAD_CTRL_SELECT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.l3), CELL_PAD_CTRL_L3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, m_pad_config.r3), CELL_PAD_CTRL_R3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.l1), CELL_PAD_CTRL_L1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.r1), CELL_PAD_CTRL_R1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.cross), CELL_PAD_CTRL_CROSS); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.circle), CELL_PAD_CTRL_CIRCLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.square), CELL_PAD_CTRL_SQUARE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.triangle), CELL_PAD_CTRL_TRIANGLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.l2), CELL_PAD_CTRL_L2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, m_pad_config.r2), CELL_PAD_CTRL_R2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->up), CELL_PAD_CTRL_UP); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->down), CELL_PAD_CTRL_DOWN); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->left), CELL_PAD_CTRL_LEFT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->right), CELL_PAD_CTRL_RIGHT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->start), CELL_PAD_CTRL_START); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->select), CELL_PAD_CTRL_SELECT); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->l3), CELL_PAD_CTRL_L3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, FindKeyCode(button_list, p_profile->r3), CELL_PAD_CTRL_R3); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->l1), CELL_PAD_CTRL_L1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->r1), CELL_PAD_CTRL_R1); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->ps), 0x100/*CELL_PAD_CTRL_PS*/);// TODO: PS button support + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->cross), CELL_PAD_CTRL_CROSS); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->circle), CELL_PAD_CTRL_CIRCLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->square), CELL_PAD_CTRL_SQUARE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->triangle), CELL_PAD_CTRL_TRIANGLE); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->l2), CELL_PAD_CTRL_L2); + pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, FindKeyCode(button_list, p_profile->r2), CELL_PAD_CTRL_R2); pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, 0, 0x0); // Reserved - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, FindKeyCode(button_list, m_pad_config.ls_left), FindKeyCode(button_list, m_pad_config.ls_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, FindKeyCode(button_list, m_pad_config.ls_down), FindKeyCode(button_list, m_pad_config.ls_up)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, FindKeyCode(button_list, m_pad_config.rs_left), FindKeyCode(button_list, m_pad_config.rs_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, FindKeyCode(button_list, m_pad_config.rs_down), FindKeyCode(button_list, m_pad_config.rs_up)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, FindKeyCode(button_list, p_profile->ls_left), FindKeyCode(button_list, p_profile->ls_right)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, FindKeyCode(button_list, p_profile->ls_down), FindKeyCode(button_list, p_profile->ls_up)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, FindKeyCode(button_list, p_profile->rs_left), FindKeyCode(button_list, p_profile->rs_right)); + pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, FindKeyCode(button_list, p_profile->rs_down), FindKeyCode(button_list, p_profile->rs_up)); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_X, 512); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_Y, 399); @@ -509,7 +531,7 @@ bool xinput_pad_handler::bindPadToDevice(std::shared_ptr pad, const std::st pad->m_vibrateMotors.emplace_back(true, 0); pad->m_vibrateMotors.emplace_back(false, 0); - bindings.emplace_back(device_id, pad); + bindings.emplace_back(x_device, pad); return true; } diff --git a/rpcs3/xinput_pad_handler.h b/rpcs3/xinput_pad_handler.h index 93ddead64382..24da63275f19 100644 --- a/rpcs3/xinput_pad_handler.h +++ b/rpcs3/xinput_pad_handler.h @@ -95,6 +95,7 @@ class xinput_pad_handler final : public PadHandlerBase u8 largeVibrate{ 0 }; u8 smallVibrate{ 0 }; clock_t last_vibration{ 0 }; + pad_profile* profile{ nullptr }; }; public: @@ -105,7 +106,7 @@ class xinput_pad_handler final : public PadHandlerBase void Close(); std::vector ListDevices() override; - bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; + bool bindPadToDevice(std::shared_ptr pad, const std::string& device, const std::string& profile) override; void ThreadProc() override; void GetNextButtonPress(const std::string& padId, const std::function& callback, bool get_blacklist = false, std::vector buttons = {}) override; void TestVibration(const std::string& padId, u32 largeMotor, u32 smallMotor) override; @@ -130,6 +131,7 @@ class xinput_pad_handler final : public PadHandlerBase std::vector blacklist; std::vector, std::shared_ptr>> bindings; + std::shared_ptr m_dev; // holds internal controller state change XINPUT_STATE state;