diff options
| author | Anthony <Helios747@users.noreply.github.com> | 2017-05-09 10:22:02 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-09 10:22:02 -0700 |
| commit | d21f1b24f8c83f0541109b2604609b04b1053048 (patch) | |
| tree | 3fda0576b03e3676c3eae09a42cc81982bae9a75 /Source/Core/DolphinQt2/Config/ControllersWindow.cpp | |
| parent | a11775396fe41b53f3d7a687924138af226461d4 (diff) | |
| parent | c8d0b647ac7bd0c2acb34429b50805d719edeb21 (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.cpp | 487 |
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(); +} |
