diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index f3251c1170..f0f5fd2416 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -22,6 +22,28 @@ LOG_CHANNEL(cellGem); +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](gem_btn value) + { + switch (value) + { + case gem_btn::start: return "Start"; + case gem_btn::select: return "Select"; + case gem_btn::triangle: return "Triangle"; + case gem_btn::circle: return "Circle"; + case gem_btn::cross: return "Cross"; + case gem_btn::square: return "Square"; + case gem_btn::move: return "Move"; + case gem_btn::t: return "T"; + case gem_btn::count: return "Count"; + } + + return unknown; + }); +} + template <> void fmt_class_string::format(std::string& out, u64 arg) { diff --git a/rpcs3/Emu/Io/Buzz.cpp b/rpcs3/Emu/Io/Buzz.cpp index ee917e427d..e038031956 100644 --- a/rpcs3/Emu/Io/Buzz.cpp +++ b/rpcs3/Emu/Io/Buzz.cpp @@ -8,6 +8,25 @@ LOG_CHANNEL(buzz_log, "BUZZ"); +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](buzz_btn value) + { + switch (value) + { + case buzz_btn::red: return "Red"; + case buzz_btn::yellow: return "Yellow"; + case buzz_btn::green: return "Green"; + case buzz_btn::orange: return "Orange"; + case buzz_btn::blue: return "Blue"; + case buzz_btn::count: return "Count"; + } + + return unknown; + }); +} + usb_device_buzz::usb_device_buzz(u32 first_controller, u32 last_controller, const std::array& location) : usb_device_emulated(location) , m_first_controller(first_controller) diff --git a/rpcs3/Emu/Io/GHLtar.cpp b/rpcs3/Emu/Io/GHLtar.cpp index 14d6d74dd4..b3bc2761ae 100644 --- a/rpcs3/Emu/Io/GHLtar.cpp +++ b/rpcs3/Emu/Io/GHLtar.cpp @@ -8,6 +8,33 @@ LOG_CHANNEL(ghltar_log, "GHLTAR"); +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](ghltar_btn value) + { + switch (value) + { + case ghltar_btn::w1: return "W1"; + case ghltar_btn::w2: return "W2"; + case ghltar_btn::w3: return "W3"; + case ghltar_btn::b1: return "B1"; + case ghltar_btn::b2: return "B2"; + case ghltar_btn::b3: return "B3"; + case ghltar_btn::start: return "Start"; + case ghltar_btn::hero_power: return "Hero Power"; + case ghltar_btn::ghtv: return "GHTV"; + case ghltar_btn::strum_down: return "Strum Down"; + case ghltar_btn::strum_up: return "Strum Up"; + case ghltar_btn::dpad_left: return "D-Pad Left"; + case ghltar_btn::dpad_right: return "D-Pad Right"; + case ghltar_btn::count: return "Count"; + } + + return unknown; + }); +} + usb_device_ghltar::usb_device_ghltar(u32 controller_index, const std::array& location) : usb_device_emulated(location), m_controller_index(controller_index) { diff --git a/rpcs3/Emu/Io/Turntable.cpp b/rpcs3/Emu/Io/Turntable.cpp index 62bde59af4..52d88e4ed6 100644 --- a/rpcs3/Emu/Io/Turntable.cpp +++ b/rpcs3/Emu/Io/Turntable.cpp @@ -8,6 +8,33 @@ LOG_CHANNEL(turntable_log, "TURN"); +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](turntable_btn value) + { + switch (value) + { + case turntable_btn::blue: return "Blue"; + case turntable_btn::green: return "Green"; + case turntable_btn::red: return "Red"; + case turntable_btn::dpad_up: return "D-Pad Up"; + case turntable_btn::dpad_down: return "D-Pad Down"; + case turntable_btn::dpad_left: return "D-Pad Left"; + case turntable_btn::dpad_right: return "D-Pad Right"; + case turntable_btn::start: return "Start"; + case turntable_btn::select: return "Select"; + case turntable_btn::square: return "Square"; + case turntable_btn::circle: return "Circle"; + case turntable_btn::cross: return "Cross"; + case turntable_btn::triangle: return "Triangle"; + case turntable_btn::count: return "Count"; + } + + return unknown; + }); +} + usb_device_turntable::usb_device_turntable(u32 controller_index, const std::array& location) : usb_device_emulated(location), m_controller_index(controller_index) { diff --git a/rpcs3/Emu/Io/emulated_pad_config.h b/rpcs3/Emu/Io/emulated_pad_config.h index a3e66981e4..f8d206c603 100644 --- a/rpcs3/Emu/Io/emulated_pad_config.h +++ b/rpcs3/Emu/Io/emulated_pad_config.h @@ -6,6 +6,7 @@ #include #include #include +#include LOG_CHANNEL(cfg_log, "CFG"); @@ -32,6 +33,7 @@ struct emulated_pad_config : cfg::node { using cfg::node::node; + std::vector*> buttons; std::map*>> button_map; std::optional*> find_button(u32 offset, u32 keycode) const @@ -47,12 +49,44 @@ struct emulated_pad_config : cfg::node return std::nullopt; } + cfg_pad_btn* get_button(T id) + { + for (cfg_pad_btn* item : buttons) + { + if (item && item->btn_id() == id) + { + return item; + } + } + + return nullptr; + } + + pad_button get_pad_button(T id) + { + if (cfg_pad_btn* item = get_button(id)) + { + return item->get(); + } + + return pad_button::pad_button_max_enum; + } + + void set_button(T id, pad_button btn_id) + { + if (cfg_pad_btn* item = get_button(id)) + { + item->set(btn_id); + } + } + void init_button(cfg_pad_btn* pbtn) { if (!pbtn) return; const u32 offset = pad_button_offset(pbtn->get()); const u32 keycode = pad_button_keycode(pbtn->get()); button_map[(offset >> 8) & 0xFF][keycode & 0xFF] = std::as_const(pbtn); + buttons.push_back(pbtn); } void init_buttons() diff --git a/rpcs3/Emu/Io/usio.cpp b/rpcs3/Emu/Io/usio.cpp index 42acff76cf..4bb51da8fa 100644 --- a/rpcs3/Emu/Io/usio.cpp +++ b/rpcs3/Emu/Io/usio.cpp @@ -9,6 +9,34 @@ LOG_CHANNEL(usio_log, "USIO"); +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](usio_btn value) + { + switch (value) + { + case usio_btn::test: return "Test"; + case usio_btn::coin: return "Coin"; + case usio_btn::enter: return "Enter"; + case usio_btn::up: return "Up"; + case usio_btn::down: return "Down"; + case usio_btn::service: return "Service"; + case usio_btn::strong_hit_side_left: return "Strong Hit Side Left"; + case usio_btn::strong_hit_side_right: return "Strong Hit Side Right"; + case usio_btn::strong_hit_center_left: return "Strong Hit Center Left"; + case usio_btn::strong_hit_center_right: return "Strong Hit Center Right"; + case usio_btn::small_hit_side_left: return "Small Hit Side Left"; + case usio_btn::small_hit_side_right: return "Small Hit Side Right"; + case usio_btn::small_hit_center_left: return "Small Hit Center Left"; + case usio_btn::small_hit_center_right: return "Small Hit Center Right"; + case usio_btn::count: return "Count"; + } + + return unknown; + }); +} + struct usio_memory { std::vector backup_memory; diff --git a/rpcs3/Emu/Io/usio.h b/rpcs3/Emu/Io/usio.h index 310c00d692..d0a1fb2588 100644 --- a/rpcs3/Emu/Io/usio.h +++ b/rpcs3/Emu/Io/usio.h @@ -5,7 +5,6 @@ class usb_device_usio : public usb_device_emulated { - public: usb_device_usio(const std::array& location); ~usb_device_usio(); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 3d915b1eaa..dd6818ca48 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -228,6 +228,9 @@ true + + true + true @@ -486,6 +489,9 @@ true + + true + true @@ -707,6 +713,7 @@ + @@ -721,6 +728,7 @@ + @@ -1195,6 +1203,16 @@ .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DMINIUPNP_STATICLIB -DHAVE_SDL2 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\libsdl-org\SDL\include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DMINIUPNP_STATICLIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\rtmidi\rtmidi" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DMINIUPNP_STATICLIB -DHAVE_SDL2 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\rtmidi\rtmidi" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\libsdl-org\SDL\include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + Moc%27ing %(Identity)... diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 11aebfff59..76d205b086 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -1026,6 +1026,18 @@ Gui\settings + + Gui\settings + + + Generated Files\Debug + + + Generated Files\Release + + + Gui\settings + @@ -1504,6 +1516,9 @@ Gui\dev tools + + Gui\settings + @@ -1540,4 +1555,4 @@ StyleSheets - + \ No newline at end of file diff --git a/rpcs3/rpcs3qt/CMakeLists.txt b/rpcs3/rpcs3qt/CMakeLists.txt index c25f35d642..a505c92d6c 100644 --- a/rpcs3/rpcs3qt/CMakeLists.txt +++ b/rpcs3/rpcs3qt/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRC_FILES _discord_utils.cpp emu_settings.cpp elf_memory_dumping_dialog.cpp + emulated_pad_settings_dialog.cpp fatal_error_dialog.cpp find_dialog.cpp flow_layout.cpp @@ -44,7 +45,7 @@ set(SRC_FILES ipc_settings_dialog.cpp kernel_explorer.cpp localized.cpp - localized_emu.h + localized_emu.cpp log_frame.cpp log_viewer.cpp main_window.cpp diff --git a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp new file mode 100644 index 0000000000..dd86315d41 --- /dev/null +++ b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp @@ -0,0 +1,268 @@ +#include "stdafx.h" +#include "emulated_pad_settings_dialog.h" +#include "localized_emu.h" +#include "Emu/Io/buzz_config.h" +#include "Emu/Io/gem_config.h" +#include "Emu/Io/ghltar_config.h" +#include "Emu/Io/turntable_config.h" +#include "Emu/Io/usio_config.h" +#include "util/asm.hpp" + +#include +#include +#include +#include +#include +#include + +emulated_pad_settings_dialog::emulated_pad_settings_dialog(pad_type type, QWidget* parent) + : QDialog(parent), m_type(type) +{ + setObjectName("emulated_pad_settings_dialog"); + setAttribute(Qt::WA_DeleteOnClose); + setAttribute(Qt::WA_StyledBackground); + + QVBoxLayout* v_layout = new QVBoxLayout(this); + + QTabWidget* tabs = new QTabWidget(); + tabs->setUsesScrollButtons(false); + + QDialogButtonBox* buttons =new QDialogButtonBox(this); + buttons->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::Save | QDialogButtonBox::RestoreDefaults); + + connect(buttons, &QDialogButtonBox::clicked, this, [this, buttons](QAbstractButton* button) + { + if (button == buttons->button(QDialogButtonBox::Apply)) + { + save_config(); + } + else if (button == buttons->button(QDialogButtonBox::Save)) + { + save_config(); + accept(); + } + else if (button == buttons->button(QDialogButtonBox::RestoreDefaults)) + { + if (QMessageBox::question(this, tr("Confirm Reset"), tr("Reset all buttons of all players?")) != QMessageBox::Yes) + return; + reset_config(); + } + else if (button == buttons->button(QDialogButtonBox::Cancel)) + { + reject(); + } + }); + + load_config(); + + switch (m_type) + { + case emulated_pad_settings_dialog::pad_type::buzz: + setWindowTitle(tr("Configure Emulated Buzz")); + add_tabs(tabs); + break; + case emulated_pad_settings_dialog::pad_type::turntable: + setWindowTitle(tr("Configure Emulated Turntable")); + add_tabs(tabs); + break; + case emulated_pad_settings_dialog::pad_type::ghltar: + setWindowTitle(tr("Configure Emulated GHLtar")); + add_tabs(tabs); + break; + case emulated_pad_settings_dialog::pad_type::usio: + setWindowTitle(tr("Configure Emulated USIO")); + add_tabs(tabs); + break; + case emulated_pad_settings_dialog::pad_type::ds3gem: + setWindowTitle(tr("Configure Emulated PS Move (DS3)")); + add_tabs(tabs); + break; + } + + v_layout->addWidget(tabs); + v_layout->addWidget(buttons); + setLayout(v_layout); +} + +template +void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) +{ + ensure(!!tabs); + + constexpr u32 max_items_per_column = 6; + int rows = static_cast(T::count); + + for (u32 cols = 1; utils::aligned_div(static_cast(T::count), cols) > max_items_per_column;) + { + rows = utils::aligned_div(static_cast(T::count), ++cols); + } + + for (int player = 0; player < 7; player++) + { + QWidget* widget = new QWidget(this); + QGridLayout* grid_layout = new QGridLayout(this); + + for (int i = 0, row = 0, col = 0; i < static_cast(T::count); i++, row++) + { + const T id = static_cast(i); + const QString name = QString::fromStdString(fmt::format("%s", id)); + + QHBoxLayout* h_layout = new QHBoxLayout(this); + QGroupBox* gb = new QGroupBox(name, this); + QComboBox* combo = new QComboBox; + + for (int p = 0; p < static_cast(pad_button::pad_button_max_enum); p++) + { + const QString translated = localized_emu::translated_pad_button(static_cast(p)); + combo->addItem(translated, p); + } + + pad_button saved_btn_id = pad_button::pad_button_max_enum; + switch (m_type) + { + case pad_type::buzz: + saved_btn_id = ::at32(g_cfg_buzz.players, player)->get_pad_button(static_cast(id)); + break; + case pad_type::turntable: + saved_btn_id = ::at32(g_cfg_turntable.players, player)->get_pad_button(static_cast(id)); + break; + case pad_type::ghltar: + saved_btn_id = ::at32(g_cfg_ghltar.players, player)->get_pad_button(static_cast(id)); + break; + case pad_type::usio: + saved_btn_id = ::at32(g_cfg_usio.players, player)->get_pad_button(static_cast(id)); + break; + case pad_type::ds3gem: + saved_btn_id = ::at32(g_cfg_gem.players, player)->get_pad_button(static_cast(id)); + break; + } + + combo->setCurrentIndex(combo->findData(static_cast(saved_btn_id))); + + connect(combo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, player, id, combo](int index) + { + if (index < 0 || !combo) + return; + + const QVariant data = combo->itemData(index); + if (!data.isValid() || !data.canConvert()) + return; + + const pad_button btn_id = static_cast(combo->itemData(index).toInt()); + + switch (m_type) + { + case pad_type::buzz: + ::at32(g_cfg_buzz.players, player)->set_button(static_cast(id), btn_id); + break; + case pad_type::turntable: + ::at32(g_cfg_turntable.players, player)->set_button(static_cast(id), btn_id); + break; + case pad_type::ghltar: + ::at32(g_cfg_ghltar.players, player)->set_button(static_cast(id), btn_id); + break; + case pad_type::usio: + ::at32(g_cfg_usio.players, player)->set_button(static_cast(id), btn_id); + break; + case pad_type::ds3gem: + ::at32(g_cfg_gem.players, player)->set_button(static_cast(id), btn_id); + break; + } + }); + + if (row >= rows) + { + row = 0; + col++; + } + + h_layout->addWidget(combo); + gb->setLayout(h_layout); + grid_layout->addWidget(gb, row, col); + } + + widget->setLayout(grid_layout); + tabs->addTab(widget, tr("Player %0").arg(player + 1)); + } +} + +void emulated_pad_settings_dialog::load_config() +{ + switch (m_type) + { + case emulated_pad_settings_dialog::pad_type::buzz: + if (!g_cfg_buzz.load()) + { + cfg_log.notice("Could not load buzz config. Using defaults."); + } + break; + case emulated_pad_settings_dialog::pad_type::turntable: + if (!g_cfg_turntable.load()) + { + cfg_log.notice("Could not load turntable config. Using defaults."); + } + break; + case emulated_pad_settings_dialog::pad_type::ghltar: + if (!g_cfg_ghltar.load()) + { + cfg_log.notice("Could not load ghltar config. Using defaults."); + } + break; + case emulated_pad_settings_dialog::pad_type::usio: + if (!g_cfg_usio.load()) + { + cfg_log.notice("Could not load usio config. Using defaults."); + } + break; + case emulated_pad_settings_dialog::pad_type::ds3gem: + if (!g_cfg_gem.load()) + { + cfg_log.notice("Could not load gem config. Using defaults."); + } + break; + } +} + +void emulated_pad_settings_dialog::save_config() +{ + switch (m_type) + { + case emulated_pad_settings_dialog::pad_type::buzz: + g_cfg_buzz.save(); + break; + case emulated_pad_settings_dialog::pad_type::turntable: + g_cfg_turntable.save(); + break; + case emulated_pad_settings_dialog::pad_type::ghltar: + g_cfg_ghltar.save(); + break; + case emulated_pad_settings_dialog::pad_type::usio: + g_cfg_usio.save(); + break; + case emulated_pad_settings_dialog::pad_type::ds3gem: + g_cfg_gem.save(); + break; + } +} + +void emulated_pad_settings_dialog::reset_config() +{ + switch (m_type) + { + case emulated_pad_settings_dialog::pad_type::buzz: + g_cfg_buzz.from_default(); + break; + case emulated_pad_settings_dialog::pad_type::turntable: + g_cfg_turntable.from_default(); + break; + case emulated_pad_settings_dialog::pad_type::ghltar: + g_cfg_ghltar.from_default(); + break; + case emulated_pad_settings_dialog::pad_type::usio: + g_cfg_usio.from_default(); + break; + case emulated_pad_settings_dialog::pad_type::ds3gem: + g_cfg_gem.from_default(); + break; + } +} diff --git a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h new file mode 100644 index 0000000000..bb4646741c --- /dev/null +++ b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Emu/Io/pad_types.h" + +#include +#include + +class emulated_pad_settings_dialog : public QDialog +{ + Q_OBJECT + +public: + enum class pad_type + { + buzz, + turntable, + ghltar, + usio, + ds3gem + }; + + emulated_pad_settings_dialog(pad_type type, QWidget* parent = nullptr); + +private: + template + void add_tabs(QTabWidget* tabs); + + void load_config(); + void save_config(); + void reset_config(); + + pad_type m_type; +}; diff --git a/rpcs3/rpcs3qt/localized_emu.cpp b/rpcs3/rpcs3qt/localized_emu.cpp new file mode 100644 index 0000000000..8b5111bf22 --- /dev/null +++ b/rpcs3/rpcs3qt/localized_emu.cpp @@ -0,0 +1,36 @@ +#include "stdafx.h" +#include "localized_emu.h" + +QString localized_emu::translated_pad_button(pad_button btn) +{ + switch (btn) + { + case pad_button::dpad_up: return tr("D-Pad Up"); + case pad_button::dpad_down: return tr("D-Pad Down"); + case pad_button::dpad_left: return tr("D-Pad Left"); + case pad_button::dpad_right: return tr("D-Pad Right"); + case pad_button::select: return tr("Select"); + case pad_button::start: return tr("Start"); + case pad_button::ps: return tr("PS"); + case pad_button::triangle: return tr("Triangle"); + case pad_button::circle: return tr("Circle"); + case pad_button::square: return tr("Square"); + case pad_button::cross: return tr("Cross"); + case pad_button::L1: return tr("L1"); + case pad_button::R1: return tr("R1"); + case pad_button::L2: return tr("L2"); + case pad_button::R2: return tr("R2"); + case pad_button::L3: return tr("L3"); + case pad_button::R3: return tr("R3"); + case pad_button::ls_up: return tr("Left Stick Up"); + case pad_button::ls_down: return tr("Left Stick Down"); + case pad_button::ls_left: return tr("Left Stick Left"); + case pad_button::ls_right: return tr("Left Stick Right"); + case pad_button::rs_up: return tr("Right Stick Up"); + case pad_button::rs_down: return tr("Right Stick Down"); + case pad_button::rs_left: return tr("Right Stick Left"); + case pad_button::rs_right: return tr("Right Stick Right"); + case pad_button::pad_button_max_enum: return ""; + } + return ""; +} diff --git a/rpcs3/rpcs3qt/localized_emu.h b/rpcs3/rpcs3qt/localized_emu.h index 1f80e530ff..9553c6fefd 100644 --- a/rpcs3/rpcs3qt/localized_emu.h +++ b/rpcs3/rpcs3qt/localized_emu.h @@ -4,6 +4,7 @@ #include #include "Emu/localized_string_id.h" +#include "Emu/Io/pad_types.h" /** * Localized emucore string collection class @@ -16,6 +17,8 @@ class localized_emu : public QObject public: localized_emu() = default; + static QString translated_pad_button(pad_button btn); + template static std::string get_string(localized_string_id id, Args&&... args) { diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 15bc6ffe98..3d52b88a67 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -34,6 +34,7 @@ #include "config_checker.h" #include "shortcut_dialog.h" #include "system_cmd_dialog.h" +#include "emulated_pad_settings_dialog.h" #include #include @@ -2364,6 +2365,36 @@ void main_window::CreateConnects() connect(ui->confPadsAct, &QAction::triggered, this, open_pad_settings); + connect(ui->confBuzzAct, &QAction::triggered, this, [this] + { + emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::buzz, this); + dlg->show(); + }); + + connect(ui->confGHLtarAct, &QAction::triggered, this, [this] + { + emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::ghltar, this); + dlg->show(); + }); + + connect(ui->confTurntableAct, &QAction::triggered, this, [this] + { + emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::turntable, this); + dlg->show(); + }); + + connect(ui->confUSIOAct, &QAction::triggered, this, [this] + { + emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::usio, this); + dlg->show(); + }); + + connect(ui->confPSMoveDS3Act, &QAction::triggered, this, [this] + { + emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::ds3gem, this); + dlg->show(); + }); + connect(ui->confCamerasAct, &QAction::triggered, this, [this]() { camera_settings_dialog dlg(this); diff --git a/rpcs3/rpcs3qt/main_window.ui b/rpcs3/rpcs3qt/main_window.ui index c09affdcdc..b8ea4c6e6e 100644 --- a/rpcs3/rpcs3qt/main_window.ui +++ b/rpcs3/rpcs3qt/main_window.ui @@ -230,10 +230,21 @@ Configuration + + + Emulated Pads + + + + + + + + @@ -1251,6 +1262,31 @@ System Commands + + + Buzz + + + + + GHLtar + + + + + Turntable + + + + + USIO + + + + + PS Move (DS3) + +