diff options
Diffstat (limited to 'Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp')
| -rw-r--r-- | Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp new file mode 100644 index 0000000000..205cbdaf03 --- /dev/null +++ b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp @@ -0,0 +1,198 @@ +// Copyright 2021 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Config/GamecubeControllersWidget.h" + +#include <QComboBox> +#include <QGridLayout> +#include <QGroupBox> +#include <QLabel> +#include <QPushButton> +#include <QVBoxLayout> + +#include <map> +#include <optional> + +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "Core/HW/SI/SI.h" +#include "Core/HW/SI/SI_Device.h" + +#include "DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.h" +#include "DolphinQt/Config/Mapping/MappingWindow.h" +#include "DolphinQt/Settings.h" + +#include "InputCommon/GCAdapter.h" + +static const std::map<SerialInterface::SIDevices, int> s_gc_types = { + {SerialInterface::SIDEVICE_NONE, 0}, {SerialInterface::SIDEVICE_GC_CONTROLLER, 1}, + {SerialInterface::SIDEVICE_WIIU_ADAPTER, 2}, {SerialInterface::SIDEVICE_GC_STEERING, 3}, + {SerialInterface::SIDEVICE_DANCEMAT, 4}, {SerialInterface::SIDEVICE_GC_TARUKONGA, 5}, + {SerialInterface::SIDEVICE_GC_GBA, 6}, {SerialInterface::SIDEVICE_GC_KEYBOARD, 7}}; + +static std::optional<int> ToGCMenuIndex(const SerialInterface::SIDevices sidevice) +{ + auto it = s_gc_types.find(sidevice); + return it != s_gc_types.end() ? it->second : std::optional<int>(); +} + +static std::optional<SerialInterface::SIDevices> FromGCMenuIndex(const int menudevice) +{ + auto it = std::find_if(s_gc_types.begin(), s_gc_types.end(), + [=](auto pair) { return pair.second == menudevice; }); + return it != s_gc_types.end() ? it->first : std::optional<SerialInterface::SIDevices>(); +} + +GamecubeControllersWidget::GamecubeControllersWidget(QWidget* parent) : QWidget(parent) +{ + CreateLayout(); + LoadSettings(); + ConnectWidgets(); +} + +void GamecubeControllersWidget::CreateLayout() +{ + m_gc_box = new QGroupBox(tr("GameCube Controllers")); + m_gc_layout = new QGridLayout(); + m_gc_layout->setVerticalSpacing(7); + m_gc_layout->setColumnStretch(1, 1); + + for (size_t i = 0; i < m_gc_groups.size(); i++) + { + auto* gc_label = new QLabel(tr("Port %1").arg(i + 1)); + auto* gc_box = m_gc_controller_boxes[i] = new QComboBox(); + auto* gc_button = m_gc_buttons[i] = new QPushButton(tr("Configure")); + + for (const auto& item : + {tr("None"), tr("Standard Controller"), tr("GameCube Adapter for Wii U"), + tr("Steering Wheel"), tr("Dance Mat"), tr("DK Bongos"), tr("GBA"), tr("Keyboard")}) + { + gc_box->addItem(item); + } + + int controller_row = m_gc_layout->rowCount(); + m_gc_layout->addWidget(gc_label, controller_row, 0); + m_gc_layout->addWidget(gc_box, controller_row, 1); + m_gc_layout->addWidget(gc_button, controller_row, 2); + } + m_gc_box->setLayout(m_gc_layout); + + auto* layout = new QVBoxLayout; + layout->setMargin(0); + layout->setAlignment(Qt::AlignTop); + layout->addWidget(m_gc_box); + setLayout(layout); +} + +void GamecubeControllersWidget::ConnectWidgets() +{ + for (size_t i = 0; i < m_gc_controller_boxes.size(); i++) + { + connect(m_gc_controller_boxes[i], qOverload<int>(&QComboBox::currentIndexChanged), this, + &GamecubeControllersWidget::SaveSettings); + connect(m_gc_controller_boxes[i], qOverload<int>(&QComboBox::currentIndexChanged), this, + &GamecubeControllersWidget::OnGCTypeChanged); + connect(m_gc_buttons[i], &QPushButton::clicked, this, + &GamecubeControllersWidget::OnGCPadConfigure); + } +} + +void GamecubeControllersWidget::OnGCTypeChanged(int type) +{ + const auto* box = static_cast<QComboBox*>(QObject::sender()); + + for (size_t i = 0; i < m_gc_groups.size(); i++) + { + if (m_gc_controller_boxes[i] == box) + { + const int index = box->currentIndex(); + m_gc_buttons[i]->setEnabled(index != 0 && index != 6); + return; + } + } + + SaveSettings(); +} + +void GamecubeControllersWidget::OnGCPadConfigure() +{ + size_t index; + for (index = 0; index < m_gc_groups.size(); index++) + { + if (m_gc_buttons[index] == QObject::sender()) + break; + } + + MappingWindow::Type type; + + switch (m_gc_controller_boxes[index]->currentIndex()) + { + case 0: // None + case 6: // GBA + return; + case 1: // Standard Controller + type = MappingWindow::Type::MAPPING_GCPAD; + break; + case 2: // GameCube Adapter for Wii U + GCPadWiiUConfigDialog(static_cast<int>(index), this).exec(); + return; + case 3: // Steering Wheel + type = MappingWindow::Type::MAPPING_GC_STEERINGWHEEL; + break; + case 4: // Dance Mat + type = MappingWindow::Type::MAPPING_GC_DANCEMAT; + break; + case 5: // DK Bongos + type = MappingWindow::Type::MAPPING_GC_BONGOS; + break; + case 7: // Keyboard + type = MappingWindow::Type::MAPPING_GC_KEYBOARD; + break; + default: + return; + } + + MappingWindow* window = new MappingWindow(this, type, static_cast<int>(index)); + window->setAttribute(Qt::WA_DeleteOnClose, true); + window->setWindowModality(Qt::WindowModality::WindowModal); + window->show(); +} + +void GamecubeControllersWidget::LoadSettings() +{ + for (size_t i = 0; i < m_gc_groups.size(); i++) + { + const std::optional<int> gc_index = ToGCMenuIndex(SConfig::GetInstance().m_SIDevice[i]); + if (gc_index) + { + m_gc_controller_boxes[i]->setCurrentIndex(*gc_index); + m_gc_buttons[i]->setEnabled(*gc_index != 0 && *gc_index != 6); + } + } +} + +void GamecubeControllersWidget::SaveSettings() +{ + for (size_t i = 0; i < m_gc_groups.size(); i++) + { + const int index = m_gc_controller_boxes[i]->currentIndex(); + const std::optional<SerialInterface::SIDevices> si_device = FromGCMenuIndex(index); + if (si_device) + { + SConfig::GetInstance().m_SIDevice[i] = *si_device; + + if (Core::IsRunning()) + SerialInterface::ChangeDevice(*si_device, static_cast<s32>(i)); + } + + m_gc_buttons[i]->setEnabled(index != 0 && index != 6); + } + + if (GCAdapter::UseAdapter()) + GCAdapter::StartScanThread(); + else + GCAdapter::StopScanThread(); + + SConfig::GetInstance().SaveSettings(); +} |
