diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2026-02-13 02:36:31 -0600 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2026-02-15 20:14:15 -0600 |
| commit | f00b1c590e5513e6248b32102a20a22a5d7d0849 (patch) | |
| tree | cc22f9136c3017cdea5d63ed8f0b7b363250ad2c | |
| parent | 0fc8f463f2dacb66afc54ebac9ebc05de1a39191 (diff) | |
DolphinQt: Add Triforce tab to main settings window.
16 files changed, 155 insertions, 88 deletions
diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 0899ef5307..c61edc244b 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -376,8 +376,8 @@ add_executable(dolphin-emu Settings/OnScreenDisplayPane.h Settings/PathPane.cpp Settings/PathPane.h - Settings/TriforceBaseboardSettingsDialog.cpp - Settings/TriforceBaseboardSettingsDialog.h + Settings/TriforcePane.cpp + Settings/TriforcePane.h Settings/USBDevicePicker.cpp Settings/USBDevicePicker.h Settings/WiiPane.cpp diff --git a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp index f995a67a1a..33c54edbd6 100644 --- a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp +++ b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp @@ -133,7 +133,6 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index) case SerialInterface::SIDEVICE_NONE: case SerialInterface::SIDEVICE_GC_GBA: return; - case SerialInterface::SIDEVICE_AM_BASEBOARD: case SerialInterface::SIDEVICE_GC_CONTROLLER: type = MappingWindow::Type::MAPPING_GCPAD; break; @@ -158,6 +157,9 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index) case SerialInterface::SIDEVICE_GC_KEYBOARD: type = MappingWindow::Type::MAPPING_GC_KEYBOARD; break; + case SerialInterface::SIDEVICE_AM_BASEBOARD: + type = MappingWindow::Type::MAPPING_AM_BASEBOARD; + break; default: return; } diff --git a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp index 7ae4a68083..a8af073792 100644 --- a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp @@ -8,19 +8,15 @@ #include "Core/HW/GCPad.h" #include "Core/HW/GCPadEmu.h" -#include "Core/HW/SI/SI.h" -#include "Core/HW/SI/SI_DeviceAMBaseboard.h" - -#include "Core/Config/MainSettings.h" #include "InputCommon/InputConfig.h" -GCPadEmu::GCPadEmu(MappingWindow* window) : MappingWidget(window) +GCPadEmu::GCPadEmu(MappingWindow* window, SubType sub_type) : MappingWidget(window) { - CreateMainLayout(); + CreateMainLayout(sub_type); } -void GCPadEmu::CreateMainLayout() +void GCPadEmu::CreateMainLayout(SubType sub_type) { auto* layout = new QGridLayout; @@ -28,8 +24,7 @@ void GCPadEmu::CreateMainLayout() 0); layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0); - if (Config::Get(Config::GetInfoForSIDevice(0)) == - SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD) + if (sub_type == SubType::AMBaseboard) { layout->addWidget(CreateGroupBox(tr("Triforce"), Pad::GetGroup(GetPort(), PadGroup::Triforce)), 2, 0); diff --git a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.h b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.h index dad55b4c76..6b315b2a2c 100644 --- a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.h +++ b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.h @@ -9,12 +9,28 @@ class GCPadEmu final : public MappingWidget { Q_OBJECT public: - explicit GCPadEmu(MappingWindow* window); + enum class SubType + { + StandardController, + AMBaseboard, + }; + + GCPadEmu(MappingWindow* window, SubType sub_type); InputConfig* GetConfig() override; private: void LoadSettings() override; void SaveSettings() override; - void CreateMainLayout(); + void CreateMainLayout(SubType sub_type); }; + +[[nodiscard]] inline auto CreateStandardControllerMappingWidget(MappingWindow* parent) +{ + return new GCPadEmu{parent, GCPadEmu::SubType::StandardController}; +} + +[[nodiscard]] inline auto CreateAMBaseboardMappingWidget(MappingWindow* parent) +{ + return new GCPadEmu{parent, GCPadEmu::SubType::AMBaseboard}; +} diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index d2151a0f06..d52e950a27 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -460,18 +460,9 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) case Type::MAPPING_GC_STEERINGWHEEL: case Type::MAPPING_GC_DANCEMAT: case Type::MAPPING_GCPAD: - widget = new GCPadEmu(this); - if (Config::Get(Config::GetInfoForSIDevice(GetPort())) == - SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD) - { - setWindowTitle(tr("Triforce Baseboard at Port %1").arg(GetPort() + 1)); - AddWidget(tr("Triforce Baseboard"), widget); - } - else - { - setWindowTitle(tr("GameCube Controller at Port %1").arg(GetPort() + 1)); - AddWidget(tr("GameCube Controller"), widget); - } + widget = CreateStandardControllerMappingWidget(this); + setWindowTitle(tr("GameCube Controller at Port %1").arg(GetPort() + 1)); + AddWidget(tr("GameCube Controller"), widget); break; case Type::MAPPING_GC_MICROPHONE: widget = new GCMicrophone(this); @@ -528,6 +519,11 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) setWindowTitle(tr("Free Look Controller %1").arg(GetPort() + 1)); } break; + case Type::MAPPING_AM_BASEBOARD: + widget = CreateAMBaseboardMappingWidget(this); + setWindowTitle(tr("Triforce Baseboard at Port %1").arg(GetPort() + 1)); + AddWidget(tr("Triforce Baseboard"), widget); + break; default: return; } diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h index 222d3e3a58..40789b8469 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h @@ -45,6 +45,8 @@ public: MAPPING_HOTKEYS, // Freelook MAPPING_FREELOOK, + // Triforce + MAPPING_AM_BASEBOARD, }; explicit MappingWindow(QWidget* parent, Type type, int port_num); diff --git a/Source/Core/DolphinQt/Config/SettingsWindow.cpp b/Source/Core/DolphinQt/Config/SettingsWindow.cpp index 2898b4cd8a..e80b1fa7ff 100644 --- a/Source/Core/DolphinQt/Config/SettingsWindow.cpp +++ b/Source/Core/DolphinQt/Config/SettingsWindow.cpp @@ -29,6 +29,7 @@ #include "DolphinQt/Settings/InterfacePane.h" #include "DolphinQt/Settings/OnScreenDisplayPane.h" #include "DolphinQt/Settings/PathPane.h" +#include "DolphinQt/Settings/TriforcePane.h" #include "DolphinQt/Settings/WiiPane.h" StackedSettingsWindow::StackedSettingsWindow(QWidget* parent) : QDialog{parent} @@ -197,8 +198,9 @@ SettingsWindow::SettingsWindow(MainWindow* parent) : StackedSettingsWindow{paren AddWrappedPane(new OnScreenDisplayPane, tr("On-Screen Display")); AddWrappedPane(new AudioPane, tr("Audio")); AddWrappedPane(new PathPane, tr("Paths")); - AddWrappedPane(new GameCubePane, tr("GameCube")); + AddWrappedPane(new GameCubePane{parent}, tr("GameCube")); AddWrappedPane(new WiiPane, tr("Wii")); + AddWrappedPane(new TriforcePane, tr("Triforce")); AddWrappedPane(new AdvancedPane, tr("Advanced")); OnDoneCreatingPanes(); diff --git a/Source/Core/DolphinQt/Config/SettingsWindow.h b/Source/Core/DolphinQt/Config/SettingsWindow.h index 9048e83385..3874c75ae0 100644 --- a/Source/Core/DolphinQt/Config/SettingsWindow.h +++ b/Source/Core/DolphinQt/Config/SettingsWindow.h @@ -49,6 +49,7 @@ enum class SettingsWindowPaneIndex : int Paths, GameCube, Wii, + Triforce, Advanced, }; diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 33741cb09c..9df5caf413 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -223,7 +223,7 @@ <ClCompile Include="Settings\GeneralPane.cpp" /> <ClCompile Include="Settings\InterfacePane.cpp" /> <ClCompile Include="Settings\OnScreenDisplayPane.cpp" /> - <ClCompile Include="Settings\TriforceBaseboardSettingsDialog.cpp" /> + <ClCompile Include="Settings\TriforcePane.cpp" /> <ClCompile Include="Settings\PathPane.cpp" /> <ClCompile Include="Settings\USBDevicePicker.cpp" /> <ClCompile Include="Settings\WiiPane.cpp" /> @@ -440,7 +440,7 @@ <QtMoc Include="Settings\GeneralPane.h" /> <QtMoc Include="Settings\InterfacePane.h" /> <QtMoc Include="Settings\PathPane.h" /> - <QtMoc Include="Settings\TriforceBaseboardSettingsDialog.h" /> + <QtMoc Include="Settings\TriforcePane.h" /> <QtMoc Include="Settings\USBDevicePicker.h" /> <QtMoc Include="Settings\WiiPane.h" /> <QtMoc Include="SkylanderPortal\SkylanderPortalWindow.h" /> diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index e29539ae2d..962f75e96c 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1315,6 +1315,12 @@ void MainWindow::ShowControllersWindow() m_settings_window->SelectPane(SettingsWindowPaneIndex::Controllers); } +void MainWindow::ShowTriforceWindow() +{ + ShowSettingsWindow(); + m_settings_window->SelectPane(SettingsWindowPaneIndex::Triforce); +} + void MainWindow::ShowFreeLookWindow() { if (!m_freelook_window) diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index bb7307c98c..c0d5bd110e 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -92,6 +92,8 @@ public: bool eventFilter(QObject* object, QEvent* event) override; QMenu* createPopupMenu() override; + void ShowTriforceWindow(); + signals: void ReadOnlyModeChanged(bool read_only); void RecordingStatusChanged(bool recording); diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 692258edb5..b4ee1f25ad 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -31,6 +31,7 @@ #include "Core/Core.h" #include "Core/HW/EXI/EXI.h" #include "Core/HW/GCMemcard/GCMemcard.h" +#include "DolphinQt/Config/SettingsWindow.h" #ifdef HAS_LIBMGBA #include "Core/NetPlayServer.h" #endif @@ -50,16 +51,18 @@ #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Settings/BroadbandAdapterSettingsDialog.h" -#include "DolphinQt/Settings/TriforceBaseboardSettingsDialog.h" +#include "DolphinQt/Settings/TriforcePane.h" constexpr std::initializer_list<ExpansionInterface::Slot> GUI_SLOTS = { ExpansionInterface::Slot::A, ExpansionInterface::Slot::B, ExpansionInterface::Slot::SP1}; -GameCubePane::GameCubePane() +GameCubePane::GameCubePane(MainWindow* main_window) { CreateWidgets(); LoadSettings(); ConnectWidgets(); + + connect(this, &GameCubePane::ShowTriforceWindow, main_window, &MainWindow::ShowTriforceWindow); } void GameCubePane::CreateWidgets() @@ -423,8 +426,7 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot) } case ExpansionInterface::EXIDeviceType::Baseboard: { - TriforceBaseboardSettingsDialog dialog(this); - dialog.exec(); + ShowTriforceWindow(); return; } default: diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.h b/Source/Core/DolphinQt/Settings/GameCubePane.h index bf7c7c2e6d..a97e82af3f 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.h +++ b/Source/Core/DolphinQt/Settings/GameCubePane.h @@ -11,6 +11,7 @@ #include "Common/EnumMap.h" #include "Core/HW/EXI/EXI.h" +#include "DolphinQt/MainWindow.h" class ConfigBool; class ConfigChoice; @@ -28,10 +29,13 @@ class GameCubePane : public QWidget { Q_OBJECT public: - explicit GameCubePane(); + explicit GameCubePane(MainWindow* main_window); static std::string GetOpenGBARom(std::string_view title); +signals: + void ShowTriforceWindow(); + private: void CreateWidgets(); void ConnectWidgets(); diff --git a/Source/Core/DolphinQt/Settings/TriforceBaseboardSettingsDialog.h b/Source/Core/DolphinQt/Settings/TriforceBaseboardSettingsDialog.h deleted file mode 100644 index f57d562da1..0000000000 --- a/Source/Core/DolphinQt/Settings/TriforceBaseboardSettingsDialog.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2026 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <QDialog> - -class QLineEdit; -class QTableWidget; - -class TriforceBaseboardSettingsDialog final : public QDialog -{ - Q_OBJECT - -public: - explicit TriforceBaseboardSettingsDialog(QWidget* parent); - -private: - void LoadConfig(); - void SaveConfig(); - - void LoadDefault(); - void OnClear(); - - QTableWidget* m_ip_overrides_table; -}; diff --git a/Source/Core/DolphinQt/Settings/TriforceBaseboardSettingsDialog.cpp b/Source/Core/DolphinQt/Settings/TriforcePane.cpp index 5ae697c148..6efb9b94b2 100644 --- a/Source/Core/DolphinQt/Settings/TriforceBaseboardSettingsDialog.cpp +++ b/Source/Core/DolphinQt/Settings/TriforcePane.cpp @@ -1,12 +1,11 @@ // Copyright 2026 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "DolphinQt/Settings/TriforceBaseboardSettingsDialog.h" +#include "DolphinQt/Settings/TriforcePane.h" #include <QDialogButtonBox> #include <QGroupBox> #include <QHeaderView> -#include <QLineEdit> #include <QPushButton> #include <QTableWidget> #include <QVBoxLayout> @@ -19,25 +18,84 @@ #include "Core/Config/MainSettings.h" #include "Core/HW/DVD/AMMediaboard.h" +#include "DolphinQt/Config/Mapping/MappingWindow.h" +#include "DolphinQt/QtUtils/NonDefaultQPushButton.h" #include "DolphinQt/QtUtils/QtUtils.h" -static constexpr int COLUMN_EMULATED = 0; -static constexpr int COLUMN_REAL = 1; -static constexpr int COLUMN_DESCRIPTION = 2; +namespace +{ + +constexpr int COLUMN_EMULATED = 0; +constexpr int COLUMN_REAL = 1; +constexpr int COLUMN_DESCRIPTION = 2; + +class IPAddressOverridesDialog final : public QDialog +{ +public: + explicit IPAddressOverridesDialog(QWidget* parent); + +private: + void LoadConfig(); + void SaveConfig() const; + + void LoadDefault(); + void OnClear(); + + QTableWidget* m_ip_overrides_table; +}; + +} // namespace -TriforceBaseboardSettingsDialog::TriforceBaseboardSettingsDialog(QWidget* parent) : QDialog{parent} +TriforcePane::TriforcePane() { - setWindowTitle(tr("Triforce Baseboard")); + auto* const main_layout = new QVBoxLayout{this}; - auto* const dialog_layout = new QVBoxLayout{this}; + auto* const controllers_group = new QGroupBox{tr("Controllers")}; + main_layout->addWidget(controllers_group); + + auto* const controllers_layout = new QVBoxLayout{controllers_group}; + + auto* const configure_controllers_button = new NonDefaultQPushButton{tr("Configure")}; + controllers_layout->addWidget(configure_controllers_button); + + connect(configure_controllers_button, &QPushButton::clicked, this, [this] { + auto* const window = new MappingWindow(this, MappingWindow::Type::MAPPING_AM_BASEBOARD, 0); + window->setAttribute(Qt::WA_DeleteOnClose, true); + window->setWindowModality(Qt::WindowModality::WindowModal); + window->show(); + }); auto* const ip_override_group = new QGroupBox{tr("IP Address Overrides")}; - dialog_layout->addWidget(ip_override_group); + main_layout->addWidget(ip_override_group); auto* const ip_override_layout = new QVBoxLayout{ip_override_group}; + auto* const configure_ip_overrides_button = new NonDefaultQPushButton{tr("Configure")}; + ip_override_layout->addWidget(configure_ip_overrides_button); + + connect(configure_ip_overrides_button, &QPushButton::clicked, this, [this] { + auto* const ip_overrides = new IPAddressOverridesDialog{this}; + ip_overrides->setAttribute(Qt::WA_DeleteOnClose); + ip_overrides->open(); + }); + + main_layout->addStretch(1); +} + +IPAddressOverridesDialog::IPAddressOverridesDialog(QWidget* parent) : QDialog{parent} +{ + setWindowTitle(tr("IP Address Overrides")); + + auto* const main_layout = new QVBoxLayout{this}; + + auto* const load_default_button = new QPushButton(tr("Default")); + connect(load_default_button, &QPushButton::clicked, this, &IPAddressOverridesDialog::LoadDefault); + + auto* const clear_button = new QPushButton(tr("Clear")); + connect(clear_button, &QPushButton::clicked, this, &IPAddressOverridesDialog::OnClear); + m_ip_overrides_table = new QTableWidget; - ip_override_layout->addWidget(m_ip_overrides_table); + main_layout->addWidget(m_ip_overrides_table); m_ip_overrides_table->setColumnCount(3); m_ip_overrides_table->setHorizontalHeaderLabels({tr("Emulated"), tr("Real"), tr("Description")}); @@ -48,23 +106,15 @@ TriforceBaseboardSettingsDialog::TriforceBaseboardSettingsDialog(QWidget* parent QAbstractItemView::EditKeyPressed); auto* const button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - dialog_layout->addWidget(button_box); - - auto* const load_default_button = new QPushButton(tr("Default")); - connect(load_default_button, &QPushButton::clicked, this, - &TriforceBaseboardSettingsDialog::LoadDefault); - - auto* const clear_button = new QPushButton(tr("Clear")); - connect(clear_button, &QPushButton::clicked, this, &TriforceBaseboardSettingsDialog::OnClear); + main_layout->addWidget(button_box); button_box->addButton(load_default_button, QDialogButtonBox::ActionRole); button_box->addButton(clear_button, QDialogButtonBox::ActionRole); - connect(button_box, &QDialogButtonBox::accepted, this, &TriforceBaseboardSettingsDialog::accept); - connect(button_box, &QDialogButtonBox::rejected, this, &TriforceBaseboardSettingsDialog::reject); + connect(button_box, &QDialogButtonBox::accepted, this, &IPAddressOverridesDialog::accept); + connect(button_box, &QDialogButtonBox::rejected, this, &IPAddressOverridesDialog::reject); - connect(this, &TriforceBaseboardSettingsDialog::accepted, this, - &TriforceBaseboardSettingsDialog::SaveConfig); + connect(this, &IPAddressOverridesDialog::accepted, this, &IPAddressOverridesDialog::SaveConfig); connect(m_ip_overrides_table, &QTableWidget::itemChanged, this, [this](QTableWidgetItem* item) { const int row_count = m_ip_overrides_table->rowCount(); @@ -87,7 +137,7 @@ TriforceBaseboardSettingsDialog::TriforceBaseboardSettingsDialog(QWidget* parent QtUtils::AdjustSizeWithinScreen(this); } -void TriforceBaseboardSettingsDialog::LoadConfig() +void IPAddressOverridesDialog::LoadConfig() { m_ip_overrides_table->setRowCount(0); @@ -120,7 +170,7 @@ void TriforceBaseboardSettingsDialog::LoadConfig() } } -void TriforceBaseboardSettingsDialog::SaveConfig() +void IPAddressOverridesDialog::SaveConfig() const { // Ignore our empty row. const int row_count = m_ip_overrides_table->rowCount() - 1; @@ -152,7 +202,7 @@ void TriforceBaseboardSettingsDialog::SaveConfig() fmt::format("{}", fmt::join(replacements, ","))); } -void TriforceBaseboardSettingsDialog::LoadDefault() +void IPAddressOverridesDialog::LoadDefault() { // This alters the config before "OK" is pressed. Bad UX.. @@ -161,8 +211,9 @@ void TriforceBaseboardSettingsDialog::LoadDefault() LoadConfig(); } -void TriforceBaseboardSettingsDialog::OnClear() +void IPAddressOverridesDialog::OnClear() { - Config::SetBaseOrCurrent(Config::MAIN_TRIFORCE_IP_OVERRIDES, ""); - LoadConfig(); + m_ip_overrides_table->setRowCount(0); + // Add the final empty row. + m_ip_overrides_table->insertRow(0); } diff --git a/Source/Core/DolphinQt/Settings/TriforcePane.h b/Source/Core/DolphinQt/Settings/TriforcePane.h new file mode 100644 index 0000000000..49038b3c5c --- /dev/null +++ b/Source/Core/DolphinQt/Settings/TriforcePane.h @@ -0,0 +1,14 @@ +// Copyright 2026 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <QWidget> + +class TriforcePane final : public QWidget +{ + Q_OBJECT + +public: + TriforcePane(); +}; |
