summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt2/Config/ControllersWindow.cpp
diff options
context:
space:
mode:
authorAnthony <Helios747@users.noreply.github.com>2017-05-09 10:22:02 -0700
committerGitHub <noreply@github.com>2017-05-09 10:22:02 -0700
commitd21f1b24f8c83f0541109b2604609b04b1053048 (patch)
tree3fda0576b03e3676c3eae09a42cc81982bae9a75 /Source/Core/DolphinQt2/Config/ControllersWindow.cpp
parenta11775396fe41b53f3d7a687924138af226461d4 (diff)
parentc8d0b647ac7bd0c2acb34429b50805d719edeb21 (diff)
Merge pull request #5377 from spycrab/qt_controller
Qt: Add controller (overview) window
Diffstat (limited to 'Source/Core/DolphinQt2/Config/ControllersWindow.cpp')
-rw-r--r--Source/Core/DolphinQt2/Config/ControllersWindow.cpp487
1 files changed, 487 insertions, 0 deletions
diff --git a/Source/Core/DolphinQt2/Config/ControllersWindow.cpp b/Source/Core/DolphinQt2/Config/ControllersWindow.cpp
new file mode 100644
index 0000000000..1b6e1b5265
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/ControllersWindow.cpp
@@ -0,0 +1,487 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <QBoxLayout>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QFormLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QPixmap>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QSpacerItem>
+#include <QVBoxLayout>
+
+#include <unordered_map>
+
+#include "Core/ConfigManager.h"
+#include "Core/HW/SI/SI.h"
+#include "Core/HW/Wiimote.h"
+#include "Core/HW/WiimoteReal/WiimoteReal.h"
+#include "Core/IOS/IOS.h"
+#include "Core/IOS/USB/Bluetooth/BTReal.h"
+#include "Core/NetPlayProto.h"
+#include "DolphinQt2/Settings.h"
+#include "UICommon/UICommon.h"
+
+#include "DolphinQt2/Config/ControllersWindow.h"
+
+static const std::unordered_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 const std::unordered_map<int, int> s_wiimote_types = {
+ {WIIMOTE_SRC_NONE, 0}, {WIIMOTE_SRC_EMU, 1}, {WIIMOTE_SRC_REAL, 2}, {WIIMOTE_SRC_HYBRID, 3}};
+
+static int ToGCMenuIndex(const SerialInterface::SIDevices sidevice)
+{
+ return s_gc_types.at(sidevice);
+}
+
+static 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->first;
+}
+
+static int ToWiimoteMenuIndex(const int device)
+{
+ return s_wiimote_types.at(device);
+}
+
+static int FromWiimoteMenuIndex(const int menudevice)
+{
+ auto it = std::find_if(s_wiimote_types.begin(), s_wiimote_types.end(),
+ [=](auto pair) { return pair.second == menudevice; });
+ return it->first;
+}
+
+ControllersWindow::ControllersWindow(QWidget* parent)
+ : QDialog(parent),
+ m_configure_icon(Settings().GetThemeDir().append(QStringLiteral("config.png"))),
+ m_gamecube_icon(Settings().GetResourcesDir().append(QStringLiteral("Platform_Gamecube.png"))),
+ m_wii_icon(Settings().GetResourcesDir().append(QStringLiteral("Platform_Wii.png")))
+{
+ setWindowTitle(tr("Controller Settings"));
+
+ CreateGamecubeLayout();
+ CreateWiimoteLayout();
+ CreateAdvancedLayout();
+ CreateMainLayout();
+ LoadSettings();
+ ConnectWidgets();
+}
+
+void ControllersWindow::CreateGamecubeLayout()
+{
+ m_gc_box = new QGroupBox(m_gc_label);
+ m_gc_layout = new QFormLayout();
+ m_gc_label = new QLabel();
+ m_gc_label->setPixmap(QPixmap(m_gamecube_icon));
+ m_gc_label->setAlignment(Qt::AlignCenter);
+ m_gc_layout->addRow(m_gc_label);
+
+ for (size_t i = 0; i < m_gc_groups.size(); i++)
+ {
+ auto* gc_box = m_gc_controller_boxes[i] = new QComboBox();
+ auto* gc_button = m_gc_buttons[i] = new QPushButton(QIcon(m_configure_icon), QString());
+ auto* gc_group = m_gc_groups[i] = new QHBoxLayout();
+
+ gc_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ gc_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ 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);
+ }
+
+ gc_group->addItem(new QSpacerItem(42, 1));
+ gc_group->addWidget(gc_box);
+ gc_group->addWidget(gc_button);
+
+ m_gc_layout->addRow(tr("Controller %1").arg(i + 1), gc_group);
+ }
+ m_gc_box->setLayout(m_gc_layout);
+}
+
+static QHBoxLayout* CreateSubItem(QLabel* label, QWidget* widget)
+{
+ QHBoxLayout* hbox = new QHBoxLayout();
+ hbox->addItem(new QSpacerItem(25, 1));
+
+ if (label != nullptr)
+ hbox->addWidget(label);
+
+ hbox->addWidget(widget);
+
+ return hbox;
+}
+
+static QHBoxLayout* CreateSubItem(const QString& text, QWidget* widget)
+{
+ QLabel* label = text.isEmpty() ? nullptr : new QLabel(text);
+ return CreateSubItem(label, widget);
+}
+
+void ControllersWindow::CreateWiimoteLayout()
+{
+ m_wiimote_box = new QGroupBox();
+ m_wiimote_layout = new QFormLayout();
+ m_wiimote_passthrough = new QRadioButton(tr("Use Bluetooth Passthrough"));
+ m_wiimote_sync = new QPushButton(tr("Sync"));
+ m_wiimote_reset = new QPushButton(tr("Reset"));
+ m_wiimote_pt_labels[0] = new QLabel(tr("Sync real Wii Remotes and pair them"));
+ m_wiimote_pt_labels[1] = new QLabel(tr("Reset all saved Wii Remote pairings"));
+ m_wiimote_emu = new QRadioButton(tr("Emulate the Wii Bluetooth Adapter"));
+ m_wiimote_continuous_scanning = new QCheckBox(tr("Continuous Scanning"));
+ m_wiimote_real_balance_board = new QCheckBox(tr("Real Balance Board"));
+ m_wiimote_speaker_data = new QCheckBox(tr("Enable Speaker Data"));
+
+ m_wiimote_layout->setLabelAlignment(Qt::AlignLeft);
+
+ m_wii_label = new QLabel();
+ m_wii_label->setPixmap(QPixmap(m_wii_icon));
+ m_wii_label->setAlignment(Qt::AlignCenter);
+ m_wiimote_layout->addRow(m_wii_label);
+
+ // Passthrough BT
+
+ m_wiimote_layout->addRow(m_wiimote_passthrough);
+
+ m_wiimote_sync->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ m_wiimote_reset->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ m_wiimote_layout->addRow(CreateSubItem(m_wiimote_pt_labels[0], m_wiimote_sync));
+ m_wiimote_layout->addRow(CreateSubItem(m_wiimote_pt_labels[1], m_wiimote_reset));
+
+ // Emulated BT
+ m_wiimote_layout->addRow(m_wiimote_emu);
+
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ {
+ auto* wm_label = m_wiimote_labels[i] = new QLabel(tr("Wii Remote %1").arg(i + 1));
+ auto* wm_box = m_wiimote_boxes[i] = new QComboBox();
+ auto* wm_button = m_wiimote_buttons[i] = new QPushButton(QIcon(m_configure_icon), QString());
+ auto* wm_group = m_wiimote_groups[i] = new QHBoxLayout();
+
+ for (const auto& item :
+ {tr("None"), tr("Emulated Wii Remote"), tr("Real Wii Remote"), tr("Hybrid Wii Remote")})
+ {
+ wm_box->addItem(item);
+ }
+
+ wm_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ wm_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ wm_group->addItem(new QSpacerItem(25, 1));
+ wm_group->addWidget(wm_label);
+ wm_group->addItem(new QSpacerItem(10, 1));
+ wm_group->addWidget(wm_box);
+ wm_group->addWidget(wm_button);
+
+ m_wiimote_layout->addRow(wm_group);
+ }
+
+ m_wiimote_layout->addRow(CreateSubItem(QStringLiteral(""), m_wiimote_continuous_scanning));
+ m_wiimote_layout->addRow(CreateSubItem(QStringLiteral(""), m_wiimote_real_balance_board));
+ m_wiimote_layout->addRow(CreateSubItem(QStringLiteral(""), m_wiimote_speaker_data));
+
+ m_wiimote_box->setLayout(m_wiimote_layout);
+}
+
+void ControllersWindow::CreateAdvancedLayout()
+{
+ m_advanced_box = new QGroupBox(tr("Advanced"));
+ m_advanced_layout = new QHBoxLayout();
+ m_advanced_bg_input = new QCheckBox(tr("Background Input"));
+
+ m_advanced_layout->addWidget(m_advanced_bg_input);
+
+ m_advanced_box->setLayout(m_advanced_layout);
+}
+
+void ControllersWindow::CreateMainLayout()
+{
+ m_main_layout = new QVBoxLayout();
+ m_button_box = new QDialogButtonBox(QDialogButtonBox::Ok);
+
+ m_main_layout->addWidget(m_gc_box);
+ m_main_layout->addWidget(m_wiimote_box);
+ m_main_layout->addWidget(m_advanced_box);
+ m_main_layout->addWidget(m_button_box);
+
+ setLayout(m_main_layout);
+}
+
+void ControllersWindow::ConnectWidgets()
+{
+ connect(m_wiimote_passthrough, &QRadioButton::toggled, this,
+ &ControllersWindow::OnWiimoteModeChanged);
+
+ connect(m_advanced_bg_input, &QCheckBox::toggled, this, &ControllersWindow::SaveSettings);
+ connect(m_wiimote_continuous_scanning, &QCheckBox::toggled, this,
+ &ControllersWindow::SaveSettings);
+ connect(m_wiimote_real_balance_board, &QCheckBox::toggled, this,
+ &ControllersWindow::SaveSettings);
+ connect(m_wiimote_speaker_data, &QCheckBox::toggled, this, &ControllersWindow::SaveSettings);
+ connect(m_wiimote_sync, &QPushButton::clicked, this,
+ &ControllersWindow::OnBluetoothPassthroughSyncPressed);
+ connect(m_wiimote_reset, &QPushButton::clicked, this,
+ &ControllersWindow::OnBluetoothPassthroughResetPressed);
+ connect(m_button_box, &QDialogButtonBox::accepted, this, &ControllersWindow::accept);
+
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ {
+ connect(m_wiimote_boxes[i],
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &ControllersWindow::SaveSettings);
+ connect(m_wiimote_boxes[i],
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &ControllersWindow::OnWiimoteTypeChanged);
+ connect(m_wiimote_buttons[i], &QPushButton::clicked, this,
+ &ControllersWindow::OnWiimoteConfigure);
+
+ connect(m_gc_controller_boxes[i],
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &ControllersWindow::SaveSettings);
+ connect(m_gc_controller_boxes[i],
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ &ControllersWindow::OnGCTypeChanged);
+ connect(m_gc_buttons[i], &QPushButton::clicked, this, &ControllersWindow::OnGCPadConfigure);
+ }
+}
+
+void ControllersWindow::OnWiimoteModeChanged(bool passthrough)
+{
+ SaveSettings();
+
+ m_wiimote_sync->setEnabled(passthrough);
+ m_wiimote_reset->setEnabled(passthrough);
+
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ {
+ const int index = m_wiimote_boxes[i]->currentIndex();
+
+ if (i < 2)
+ m_wiimote_pt_labels[i]->setEnabled(passthrough);
+
+ m_wiimote_labels[i]->setEnabled(!passthrough);
+ m_wiimote_boxes[i]->setEnabled(!passthrough);
+ m_wiimote_buttons[i]->setEnabled(!passthrough && index != 0 && index != 2);
+ }
+
+ m_wiimote_real_balance_board->setEnabled(!passthrough);
+ m_wiimote_speaker_data->setEnabled(!passthrough);
+ m_wiimote_continuous_scanning->setEnabled(!passthrough);
+}
+
+void ControllersWindow::OnWiimoteTypeChanged(int type)
+{
+ const auto* box = static_cast<QComboBox*>(QObject::sender());
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ {
+ if (m_wiimote_boxes[i] == box)
+ {
+ const int index = box->currentIndex();
+ m_wiimote_buttons[i]->setEnabled(index != 0 && index != 2);
+ return;
+ }
+ }
+}
+
+void ControllersWindow::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;
+ }
+ }
+}
+
+void ControllersWindow::OnBluetoothPassthroughResetPressed()
+{
+ const auto ios = IOS::HLE::GetIOS();
+
+ if (!ios)
+ {
+ QMessageBox error(this);
+ error.setIcon(QMessageBox::Warning);
+ error.setText(tr("Saved Wii Remote pairings can only be reset when a Wii game is running."));
+ error.exec();
+ return;
+ }
+
+ auto device = ios->GetDeviceByName("/dev/usb/oh1/57e/305");
+ if (device != nullptr)
+ {
+ std::static_pointer_cast<IOS::HLE::Device::BluetoothBase>(device)->TriggerSyncButtonHeldEvent();
+ }
+}
+
+void ControllersWindow::OnBluetoothPassthroughSyncPressed()
+{
+ const auto ios = IOS::HLE::GetIOS();
+
+ if (!ios)
+ {
+ QMessageBox error(this);
+ error.setIcon(QMessageBox::Warning);
+ error.setText(tr("A sync can only be triggered when a Wii game is running"));
+ error.exec();
+ return;
+ }
+
+ auto device = ios->GetDeviceByName("/dev/usb/oh1/57e/305");
+
+ if (device != nullptr)
+ {
+ std::static_pointer_cast<IOS::HLE::Device::BluetoothBase>(device)
+ ->TriggerSyncButtonPressedEvent();
+ }
+}
+
+void ControllersWindow::OnEmulationStateChanged(bool running)
+{
+ if (!Settings().IsWiiGameRunning() || NetPlay::IsNetPlayRunning())
+ {
+ m_wiimote_sync->setEnabled(!running);
+ m_wiimote_reset->setEnabled(!running);
+
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ m_wiimote_boxes[i]->setEnabled(!running);
+ }
+
+ m_wiimote_emu->setEnabled(!running);
+ m_wiimote_passthrough->setEnabled(!running);
+
+ if (!Settings().IsWiiGameRunning())
+ {
+ m_wiimote_real_balance_board->setEnabled(!running);
+ m_wiimote_continuous_scanning->setEnabled(!running);
+ m_wiimote_speaker_data->setEnabled(!running);
+ }
+}
+
+void ControllersWindow::OnGCPadConfigure()
+{
+ size_t index;
+ for (index = 0; index < m_gc_groups.size(); index++)
+ {
+ if (m_gc_buttons[index] == QObject::sender())
+ break;
+ }
+
+ switch (m_gc_controller_boxes[index]->currentIndex())
+ {
+ case 0: // None
+ case 6: // GBA
+ return;
+ case 1: // Standard Controller
+ case 2: // GameCube Adapter for Wii U
+ case 3: // Steering Wheel
+ case 4: // Dance Mat
+ case 5: // DK Bongos
+ case 7: // Keyboard
+ UnimplementedButton();
+ return;
+ }
+}
+
+void ControllersWindow::OnWiimoteConfigure()
+{
+ size_t index;
+ for (index = 0; index < m_wiimote_groups.size(); index++)
+ {
+ if (m_wiimote_buttons[index] == QObject::sender())
+ break;
+ }
+
+ switch (m_wiimote_boxes[index]->currentIndex())
+ {
+ case 0: // None
+ case 2: // Real Wii Remote
+ return;
+ case 1: // Emulated Wii Remote
+ case 3: // Hybrid Wii Remote
+ UnimplementedButton();
+ return;
+ }
+}
+
+void ControllersWindow::UnimplementedButton()
+{
+ QMessageBox error_dialog(this);
+
+ error_dialog.setIcon(QMessageBox::Warning);
+ error_dialog.setText(tr("Not implemented yet."));
+ error_dialog.exec();
+}
+
+void ControllersWindow::LoadSettings()
+{
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ {
+ m_gc_controller_boxes[i]->setCurrentIndex(ToGCMenuIndex(Settings().GetSIDevice(i)));
+ m_wiimote_boxes[i]->setCurrentIndex(ToWiimoteMenuIndex(g_wiimote_sources[i]));
+ }
+ m_wiimote_real_balance_board->setChecked(g_wiimote_sources[WIIMOTE_BALANCE_BOARD] ==
+ WIIMOTE_SRC_REAL);
+ m_wiimote_speaker_data->setChecked(Settings().IsWiimoteSpeakerEnabled());
+ m_wiimote_continuous_scanning->setChecked(Settings().IsContinuousScanningEnabled());
+
+ m_advanced_bg_input->setChecked(Settings().IsBackgroundInputEnabled());
+
+ if (Settings().IsBluetoothPassthroughEnabled())
+ m_wiimote_passthrough->setChecked(true);
+ else
+ m_wiimote_emu->setChecked(true);
+
+ OnWiimoteModeChanged(Settings().IsBluetoothPassthroughEnabled());
+}
+
+void ControllersWindow::SaveSettings()
+{
+ Settings().SetWiimoteSpeakerEnabled(m_wiimote_speaker_data->isChecked());
+ Settings().SetContinuousScanningEnabled(m_wiimote_continuous_scanning->isChecked());
+
+ Settings().SetBluetoothPassthroughEnabled(m_wiimote_passthrough->isChecked());
+ Settings().SetBackgroundInputEnabled(m_advanced_bg_input->isChecked());
+
+ WiimoteReal::ChangeWiimoteSource(WIIMOTE_BALANCE_BOARD,
+ m_wiimote_real_balance_board->isChecked() ? WIIMOTE_SRC_REAL :
+ WIIMOTE_SRC_NONE);
+
+ for (size_t i = 0; i < m_wiimote_groups.size(); i++)
+ {
+ const int index = m_wiimote_boxes[i]->currentIndex();
+ g_wiimote_sources[i] = FromWiimoteMenuIndex(index);
+ m_wiimote_buttons[i]->setEnabled(index != 0 && index != 2);
+ }
+
+ UICommon::SaveWiimoteSources();
+
+ for (size_t i = 0; i < m_gc_groups.size(); i++)
+ {
+ const int index = m_gc_controller_boxes[i]->currentIndex();
+ Settings().SetSIDevice(i, FromGCMenuIndex(index));
+ m_gc_buttons[i]->setEnabled(index != 0 && index != 6);
+ }
+ Settings().Save();
+}