diff --git a/rpcs3/keyboard_pad_handler.cpp b/rpcs3/keyboard_pad_handler.cpp index 5e73fd0ef8..bebb0c20a7 100644 --- a/rpcs3/keyboard_pad_handler.cpp +++ b/rpcs3/keyboard_pad_handler.cpp @@ -80,27 +80,15 @@ void keyboard_pad_handler::Key(const u32 code, bool pressed, u16 value) } } - for (AnalogStick& stick : pad->m_sticks) + for (int i = 0; i < static_cast(pad->m_sticks.size()); i++) { - if (stick.m_keyCodeMax != code && stick.m_keyCodeMin != code) - continue; + if (pad->m_sticks[i].m_keyCodeMax == code) + m_stick_max[i] = pressed ? 255 : 128; - //slightly less hack job for key based analog stick - // should also fix/make transitions when using keys smoother - // the logic here is that when a key is released, - // if we are at the opposite end of the axis, dont reset to middle - if (stick.m_keyCodeMax == code) - { - if (pressed) stick.m_value = 255; - else if (stick.m_value == 0) stick.m_value = 0; - else stick.m_value = 128; - } - if (stick.m_keyCodeMin == code) - { - if (pressed) stick.m_value = 0; - else if (stick.m_value == 255) stick.m_value = 255; - else stick.m_value = 128; - } + if (pad->m_sticks[i].m_keyCodeMin == code) + m_stick_min[i] = pressed ? 128 : 0; + + pad->m_sticks[i].m_value = m_stick_max[i] - m_stick_min[i]; } } } @@ -140,13 +128,22 @@ bool keyboard_pad_handler::eventFilter(QObject* target, QEvent* ev) // !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target) if (!m_target || !m_target->isVisible()|| target == m_target) { - if (ev->type() == QEvent::KeyPress) + switch (ev->type()) { + case QEvent::KeyPress: keyPressEvent(static_cast(ev)); - } - else if (ev->type() == QEvent::KeyRelease) - { + break; + case QEvent::KeyRelease: keyReleaseEvent(static_cast(ev)); + break; + case QEvent::MouseButtonPress: + mousePressEvent(static_cast(ev)); + break; + case QEvent::MouseButtonRelease: + mouseReleaseEvent(static_cast(ev)); + break; + default: + break; } } return false; @@ -169,51 +166,61 @@ void keyboard_pad_handler::SetTargetWindow(QWindow* target) } } -void keyboard_pad_handler::keyPressEvent(QKeyEvent* event) +void keyboard_pad_handler::processKeyEvent(QKeyEvent* event, bool pressed) { if (event->isAutoRepeat()) { event->ignore(); return; } - switch (event->key()) + + int key = event->key(); + switch (key) { - case Qt::Key_L: - if (!(event->modifiers() == Qt::AltModifier)) { Key(event->key(), 1); } - break; - case Qt::Key_Return: - if (!(event->modifiers() == Qt::AltModifier)) { Key(event->key(), 1); } - break; - case Qt::Key_Escape: - break; - case Qt::Key_P: - if (!(event->modifiers() == Qt::ControlModifier)) { Key(event->key(), 1); } - break; - case Qt::Key_S: - if (!(event->modifiers() == Qt::ControlModifier)) { Key(event->key(), 1); } - break; - case Qt::Key_R: - if (!(event->modifiers() == Qt::ControlModifier)) { Key(event->key(), 1); } - break; - case Qt::Key_E: - if (!(event->modifiers() == Qt::ControlModifier)) { Key(event->key(), 1); } - break; - default: - Key(event->key() + GetModifierCode(event), 1); - break; + case Qt::Key_L: + case Qt::Key_Return: + if (!(event->modifiers() == Qt::AltModifier)) + Key(key, pressed); + break; + case Qt::Key_Escape: + break; + case Qt::Key_P: + case Qt::Key_S: + case Qt::Key_R: + case Qt::Key_E: + if (!(event->modifiers() == Qt::ControlModifier)) + Key(key, pressed); + break; + default: + int keymod = key + GetModifierCode(event); + if (keymod == key) + Key(keymod, pressed); + else + Key(key, pressed); + break; } event->ignore(); } +void keyboard_pad_handler::keyPressEvent(QKeyEvent* event) +{ + processKeyEvent(event, 1); +} + void keyboard_pad_handler::keyReleaseEvent(QKeyEvent* event) { - if (event->isAutoRepeat()) - { - event->ignore(); - return; - } + processKeyEvent(event, 0); +} - Key(event->key() + GetModifierCode(event), 0); +void keyboard_pad_handler::mousePressEvent(QMouseEvent* event) +{ + Key(event->button(), 1); + event->ignore(); +} + +void keyboard_pad_handler::mouseReleaseEvent(QMouseEvent* event) +{ + Key(event->button(), 0, 0); event->ignore(); } @@ -224,10 +231,21 @@ std::vector keyboard_pad_handler::ListDevices() return list_devices; } +std::string keyboard_pad_handler::GetMouseName(const QMouseEvent* event) +{ + return GetMouseName(event->button()); +} + +std::string keyboard_pad_handler::GetMouseName(u32 button) +{ + auto it = mouse_list.find(button); + if (it != mouse_list.end()) + return it->second; + return "FAIL"; +} + std::string keyboard_pad_handler::GetKeyName(const QKeyEvent* keyEvent) { - //TODO what about numpad? - // Fix some unknown button names switch (keyEvent->key()) { case Qt::Key_Alt: @@ -303,6 +321,16 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std:: m_pad_config.load(); + auto find_key = [&](const cfg::string& name) + { + int key = FindKeyCode(mouse_list, name, false); + if (key < 0) + key = GetKeyCode(name); + if (key < 0) + key = 0; + return key; + }; + //Fixed assign change, default is both sensor and press off pad->Init ( @@ -312,29 +340,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, GetKeyCode(m_pad_config.left), CELL_PAD_CTRL_LEFT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.down), CELL_PAD_CTRL_DOWN); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.right), CELL_PAD_CTRL_RIGHT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.up), CELL_PAD_CTRL_UP); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.start), CELL_PAD_CTRL_START); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.r3), CELL_PAD_CTRL_R3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.l3), CELL_PAD_CTRL_L3); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL1, GetKeyCode(m_pad_config.select), CELL_PAD_CTRL_SELECT); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(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, GetKeyCode(m_pad_config.square), CELL_PAD_CTRL_SQUARE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.cross), CELL_PAD_CTRL_CROSS); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.circle), CELL_PAD_CTRL_CIRCLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.triangle), CELL_PAD_CTRL_TRIANGLE); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.r1), CELL_PAD_CTRL_R1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.l1), CELL_PAD_CTRL_L1); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.r2), CELL_PAD_CTRL_R2); - pad->m_buttons.emplace_back(CELL_PAD_BTN_OFFSET_DIGITAL2, GetKeyCode(m_pad_config.l2), CELL_PAD_CTRL_L2); + 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, GetKeyCode(m_pad_config.ls_left), GetKeyCode(m_pad_config.ls_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, GetKeyCode(m_pad_config.ls_up), GetKeyCode(m_pad_config.ls_down)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, GetKeyCode(m_pad_config.rs_left), GetKeyCode(m_pad_config.rs_right)); - pad->m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, GetKeyCode(m_pad_config.rs_up), GetKeyCode(m_pad_config.rs_down)); + 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_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_X, 512); pad->m_sensors.emplace_back(CELL_PAD_BTN_OFFSET_SENSOR_Y, 399); @@ -351,5 +379,4 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr pad, const std:: void keyboard_pad_handler::ThreadProc() { - } diff --git a/rpcs3/keyboard_pad_handler.h b/rpcs3/keyboard_pad_handler.h index d680b39104..27d84f6d4d 100644 --- a/rpcs3/keyboard_pad_handler.h +++ b/rpcs3/keyboard_pad_handler.h @@ -10,14 +10,50 @@ class keyboard_pad_handler final : public QObject, public PadHandlerBase { + // Unique button names for the config files and our pad settings dialog + const std::unordered_map mouse_list = + { + { Qt::NoButton , "" }, + { Qt::LeftButton , "Mouse Left" }, + { Qt::RightButton , "Mouse Right" }, + { Qt::MiddleButton , "Mouse Middle" }, + { Qt::BackButton , "Mouse Back" }, + { Qt::ForwardButton , "Mouse Fwd" }, + { Qt::TaskButton , "Mouse Task" }, + { Qt::ExtraButton4 , "Mouse 4" }, + { Qt::ExtraButton5 , "Mouse 5" }, + { Qt::ExtraButton6 , "Mouse 6" }, + { Qt::ExtraButton7 , "Mouse 7" }, + { Qt::ExtraButton8 , "Mouse 8" }, + { Qt::ExtraButton9 , "Mouse 9" }, + { Qt::ExtraButton10 , "Mouse 10" }, + { Qt::ExtraButton11 , "Mouse 11" }, + { Qt::ExtraButton12 , "Mouse 12" }, + { Qt::ExtraButton13 , "Mouse 13" }, + { Qt::ExtraButton14 , "Mouse 14" }, + { Qt::ExtraButton15 , "Mouse 15" }, + { Qt::ExtraButton16 , "Mouse 16" }, + { Qt::ExtraButton17 , "Mouse 17" }, + { Qt::ExtraButton18 , "Mouse 18" }, + { Qt::ExtraButton19 , "Mouse 19" }, + { Qt::ExtraButton20 , "Mouse 20" }, + { Qt::ExtraButton21 , "Mouse 21" }, + { Qt::ExtraButton22 , "Mouse 22" }, + { Qt::ExtraButton23 , "Mouse 23" }, + { Qt::ExtraButton24 , "Mouse 24" }, + }; + public: bool Init() override; keyboard_pad_handler(); void SetTargetWindow(QWindow* target); + void processKeyEvent(QKeyEvent* event, bool pressed); void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); bool eventFilter(QObject* obj, QEvent* ev) override; @@ -25,6 +61,8 @@ public: bool bindPadToDevice(std::shared_ptr pad, const std::string& device) override; void ThreadProc() override; + std::string GetMouseName(const QMouseEvent* event); + std::string GetMouseName(u32 button); std::string GetKeyName(const QKeyEvent* keyEvent); std::string GetKeyName(const u32& keyCode); u32 GetKeyCode(const std::string& keyName); @@ -36,4 +74,6 @@ protected: private: QWindow* m_target = nullptr; std::vector> bindings; + u8 m_stick_min[4] = { 0, 0, 0, 0 }; + u8 m_stick_max[4] = { 128, 128, 128, 128 }; }; diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index e4afa5559c..22d8161649 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -221,6 +221,7 @@ pad_settings_dialog::pad_settings_dialog(const std::string& device, std::shared_ m_cfg_entries.insert(std::make_pair(id, pad_button{ cfg_name, *cfg_name, name })); m_padButtons->addButton(button, id); button->setText(name); + button->installEventFilter(this); }; insertButton(button_ids::id_pad_lstick_left, ui->b_lstick_left, &m_handler_cfg->ls_left); @@ -367,6 +368,39 @@ void pad_settings_dialog::keyPressEvent(QKeyEvent *keyEvent) ReactivateButtons(); } +void pad_settings_dialog::mousePressEvent(QMouseEvent* event) +{ + if (m_handler_type != handler_type::handler_type_keyboard) + { + return; + } + + if (m_button_id == button_ids::id_pad_begin) + { + return; + } + + if (m_button_id <= button_ids::id_pad_begin || m_button_id >= button_ids::id_pad_end) + { + LOG_NOTICE(HLE, "Pad Settings: Handler Type: %d, Unknown button ID: %d", static_cast(m_handler_type), m_button_id); + } + else + { + m_cfg_entries[m_button_id].key = ((keyboard_pad_handler*)m_handler.get())->GetMouseName(event); + m_cfg_entries[m_button_id].text = qstr(m_cfg_entries[m_button_id].key); + } + + ReactivateButtons(); +} + +bool pad_settings_dialog::eventFilter(QObject* object, QEvent* event) +{ + // Disabled buttons should not absorb mouseclicks + if (event->type() == QEvent::MouseButtonPress) + event->ignore(); + return QDialog::eventFilter(object, event); +} + void pad_settings_dialog::UpdateLabel(bool is_reset) { if (is_reset) diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.h b/rpcs3/rpcs3qt/pad_settings_dialog.h index 61fd585fcb..1f767388d5 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.h +++ b/rpcs3/rpcs3qt/pad_settings_dialog.h @@ -134,6 +134,8 @@ public: /** Handle keyboard handler input */ void keyPressEvent(QKeyEvent *keyEvent) override; + void mousePressEvent(QMouseEvent *event) override; + bool eventFilter(QObject* object, QEvent* event) override; /** Update all the Button Labels with current button mapping */ void UpdateLabel(bool is_reset = false);