diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 99c085b015..596ee78640 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -67,7 +67,7 @@ struct pad_ensemble std::shared_ptr buddy_device; explicit pad_ensemble(std::shared_ptr _pad, std::shared_ptr _device, std::shared_ptr _buddy_device) - : pad(_pad), device(_device), buddy_device(_buddy_device) + : pad(std::move(_pad)), device(std::move(_device)), buddy_device(std::move(_buddy_device)) {} }; diff --git a/rpcs3/Emu/Io/pad_config_types.cpp b/rpcs3/Emu/Io/pad_config_types.cpp index e09be8a4e0..481fe7078a 100644 --- a/rpcs3/Emu/Io/pad_config_types.cpp +++ b/rpcs3/Emu/Io/pad_config_types.cpp @@ -25,6 +25,7 @@ void fmt_class_string::format(std::string& out, u64 arg) #ifdef HAVE_LIBEVDEV case pad_handler::evdev: return "Evdev"; #endif + case pad_handler::virtual_pad: return "Virtual"; } return unknown; diff --git a/rpcs3/Emu/Io/pad_config_types.h b/rpcs3/Emu/Io/pad_config_types.h index 36fc8328fa..dd4cd98d14 100644 --- a/rpcs3/Emu/Io/pad_config_types.h +++ b/rpcs3/Emu/Io/pad_config_types.h @@ -21,6 +21,7 @@ enum class pad_handler #ifdef HAVE_LIBEVDEV evdev, #endif + virtual_pad }; enum class mouse_movement_mode : s32 diff --git a/rpcs3/Input/virtual_pad_handler.cpp b/rpcs3/Input/virtual_pad_handler.cpp new file mode 100644 index 0000000000..c446a49327 --- /dev/null +++ b/rpcs3/Input/virtual_pad_handler.cpp @@ -0,0 +1,41 @@ +#include "virtual_pad_handler.h" +#include "pad_thread.h" +#include "Emu/Io/pad_config.h" + +virtual_pad_handler::on_connect_cb virtual_pad_handler::mOnConnect = [](auto...) +{ + return false; +}; + +virtual_pad_handler::virtual_pad_handler() + : PadHandlerBase(pad_handler::virtual_pad) +{ +} + +std::vector virtual_pad_handler::list_devices() +{ + std::vector list_devices; + for (usz i = 1; i <= MAX_GAMEPADS; i++) // Controllers 1-n in GUI + { + list_devices.emplace_back(fmt::format("Virtual Pad #%d", i), false); + } + return list_devices; +} + +bool virtual_pad_handler::bindPadToDevice(std::shared_ptr pad) +{ + if (!pad || pad->m_player_id >= g_cfg_input.player.size()) + return false; + + const cfg_player* player_config = g_cfg_input.player[pad->m_player_id]; + if (!player_config || player_config->device.to_string() != "Virtual") + return false; + + if (!mOnConnect(pad)) + { + return false; + } + + m_bindings.emplace_back(std::move(pad), nullptr, nullptr); + return true; +} diff --git a/rpcs3/Input/virtual_pad_handler.h b/rpcs3/Input/virtual_pad_handler.h new file mode 100644 index 0000000000..28a86cfdd7 --- /dev/null +++ b/rpcs3/Input/virtual_pad_handler.h @@ -0,0 +1,40 @@ +#pragma once + +#include "Emu/Io/PadHandler.h" + +class virtual_pad_handler final : public PadHandlerBase +{ + using on_connect_cb = std::function &)>; + static on_connect_cb mOnConnect; + +public: + virtual_pad_handler(); + + static void set_on_connect_cb(on_connect_cb cb) + { + mOnConnect = std::move(cb); + } + + bool Init() override + { + return true; + } + + void init_config(cfg_pad* cfg) override + { + if (!cfg) + return; + + cfg->from_default(); + } + + std::vector list_devices() override; + + connection get_next_button_press(const std::string& /*padId*/, const pad_callback& /*callback*/, const pad_fail_callback& /*fail_callback*/, gui_call_type /*call_type*/, const std::vector& /*buttons*/) override + { + return connection::connected; + } + + bool bindPadToDevice(std::shared_ptr pad) override; + void process() override {} +}; diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index 0eeda510e2..377c7577ea 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -1983,6 +1983,7 @@ QString pad_settings_dialog::GetLocalizedPadHandler(const QString& original, pad #ifdef HAVE_LIBEVDEV case pad_handler::evdev: return tr("Evdev"); #endif + case pad_handler::virtual_pad: return tr("Virtual"); } return original; } @@ -2008,6 +2009,7 @@ QString pad_settings_dialog::GetLocalizedPadName(pad_handler handler, const QStr #ifdef HAVE_LIBEVDEV case pad_handler::evdev: break; // Localization not feasible. Names differ for each device. #endif + case pad_handler::virtual_pad: break; } return original; }