From 965781ea9dd13b9d3f1739d489cc842e6ae25597 Mon Sep 17 00:00:00 2001 From: rlnilsen <47765059+rlnilsen@users.noreply.github.com> Date: Mon, 4 Nov 2019 04:19:33 +0100 Subject: [PATCH] Motion Input: Add nunchuk support. --- .../Core/HW/WiimoteEmu/Extension/Nunchuk.cpp | 13 ++- .../Core/HW/WiimoteEmu/Extension/Nunchuk.h | 4 +- Source/Core/DolphinQt/CMakeLists.txt | 4 + .../Config/Mapping/MappingWindow.cpp | 28 ++++++- .../DolphinQt/Config/Mapping/MappingWindow.h | 7 +- .../Config/Mapping/WiimoteEmuExtension.cpp | 11 +-- .../WiimoteEmuExtensionMotionInput.cpp | 80 +++++++++++++++++++ .../Mapping/WiimoteEmuExtensionMotionInput.h | 32 ++++++++ .../WiimoteEmuExtensionMotionSimulation.cpp | 65 +++++++++++++++ .../WiimoteEmuExtensionMotionSimulation.h | 32 ++++++++ .../Config/Mapping/WiimoteEmuGeneral.cpp | 2 + Source/Core/DolphinQt/DolphinQt.vcxproj | 6 ++ 12 files changed, 268 insertions(+), 16 deletions(-) create mode 100644 Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp create mode 100644 Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.h create mode 100644 Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp create mode 100644 Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.h diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp index 971a038d89..76d1f29f5e 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp @@ -21,6 +21,7 @@ #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/Force.h" +#include "InputCommon/ControllerEmu/ControlGroup/IMUAccelerometer.h" #include "InputCommon/ControllerEmu/ControlGroup/Tilt.h" namespace WiimoteEmu @@ -54,6 +55,10 @@ Nunchuk::Nunchuk() : Extension1stParty(_trans("Nunchuk")) // Inverse the default intensity so shake is opposite that of wiimote. // This is needed by DKCR for proper shake action detection. groups.emplace_back(m_shake = new ControllerEmu::Shake(_trans("Shake"), -1)); + + // accelerometer + groups.emplace_back(m_imu_accelerometer = new ControllerEmu::IMUAccelerometer( + "IMUAccelerometer", _trans("Accelerometer"))); } void Nunchuk::Update() @@ -94,8 +99,10 @@ void Nunchuk::Update() const auto transformation = GetRotationalMatrix(-m_tilt_state.angle - m_swing_state.angle); - Common::Vec3 accel = transformation * (m_swing_state.acceleration + - Common::Vec3(0, 0, float(GRAVITY_ACCELERATION))); + Common::Vec3 accel = + transformation * + (m_swing_state.acceleration + + m_imu_accelerometer->GetState().value_or(Common::Vec3(0, 0, float(GRAVITY_ACCELERATION)))); // shake accel += m_shake_state.acceleration; @@ -173,6 +180,8 @@ ControllerEmu::ControlGroup* Nunchuk::GetGroup(NunchukGroup group) return m_swing; case NunchukGroup::Shake: return m_shake; + case NunchukGroup::IMUAccelerometer: + return m_imu_accelerometer; default: assert(false); return nullptr; diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h index 42afa582a2..702d504b47 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.h @@ -27,7 +27,8 @@ enum class NunchukGroup Stick, Tilt, Swing, - Shake + Shake, + IMUAccelerometer, }; class Nunchuk : public Extension1stParty @@ -96,6 +97,7 @@ private: ControllerEmu::Shake* m_shake; ControllerEmu::Buttons* m_buttons; ControllerEmu::AnalogStick* m_stick; + ControllerEmu::IMUAccelerometer* m_imu_accelerometer; // Dynamics: MotionState m_swing_state; diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 8c6936d10d..8ce9e2ddd1 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -140,6 +140,10 @@ add_executable(dolphin-emu Config/Mapping/MappingWindow.h Config/Mapping/WiimoteEmuExtension.cpp Config/Mapping/WiimoteEmuExtension.h + Config/Mapping/WiimoteEmuExtensionMotionInput.cpp + Config/Mapping/WiimoteEmuExtensionMotionInput.h + Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp + Config/Mapping/WiimoteEmuExtensionMotionSimulation.h Config/Mapping/WiimoteEmuGeneral.cpp Config/Mapping/WiimoteEmuGeneral.h Config/Mapping/WiimoteEmuMotionControl.cpp diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index cdddc07fe2..a30e15fa06 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -33,6 +33,8 @@ #include "DolphinQt/Config/Mapping/HotkeyTAS.h" #include "DolphinQt/Config/Mapping/HotkeyWii.h" #include "DolphinQt/Config/Mapping/WiimoteEmuExtension.h" +#include "DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.h" +#include "DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.h" #include "DolphinQt/Config/Mapping/WiimoteEmuGeneral.h" #include "DolphinQt/Config/Mapping/WiimoteEmuMotionControl.h" #include "DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.h" @@ -346,12 +348,18 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) case Type::MAPPING_WIIMOTE_EMU: { auto* extension = new WiimoteEmuExtension(this); + auto* extension_motion_input = new WiimoteEmuExtensionMotionInput(this); + auto* extension_motion_simulation = new WiimoteEmuExtensionMotionSimulation(this); widget = new WiimoteEmuGeneral(this, extension); setWindowTitle(tr("Wii Remote %1").arg(GetPort() + 1)); AddWidget(tr("General and Options"), widget); AddWidget(tr("Motion Simulation"), new WiimoteEmuMotionControl(this)); AddWidget(tr("Motion Input"), new WiimoteEmuMotionControlIMU(this)); AddWidget(tr("Extension"), extension); + m_extension_motion_simulation_tab = + AddWidget(EXTENSION_MOTION_SIMULATION_TAB_NAME, extension_motion_simulation); + m_extension_motion_input_tab = + AddWidget(EXTENSION_MOTION_INPUT_TAB_NAME, extension_motion_input); break; } case Type::MAPPING_HOTKEYS: @@ -395,9 +403,11 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) m_profiles_combo->setCurrentIndex(-1); } -void MappingWindow::AddWidget(const QString& name, QWidget* widget) +QWidget* MappingWindow::AddWidget(const QString& name, QWidget* widget) { - m_tab_widget->addTab(GetWrappedWidget(widget, this, 150, 210), name); + QWidget* wrapper = GetWrappedWidget(widget, this, 150, 210); + m_tab_widget->addTab(wrapper, name); + return wrapper; } int MappingWindow::GetPort() const @@ -432,3 +442,17 @@ void MappingWindow::OnClearFieldsPressed() emit ConfigChanged(); emit Save(); } + +void MappingWindow::ShowExtensionMotionTabs(bool show) +{ + if (show) + { + m_tab_widget->addTab(m_extension_motion_simulation_tab, EXTENSION_MOTION_SIMULATION_TAB_NAME); + m_tab_widget->addTab(m_extension_motion_input_tab, EXTENSION_MOTION_INPUT_TAB_NAME); + } + else + { + m_tab_widget->removeTab(5); + m_tab_widget->removeTab(4); + } +} diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h index d0549b3d99..220a19d570 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.h @@ -50,6 +50,7 @@ public: int GetPort() const; ControllerEmu::EmulatedController* GetController() const; bool IsMappingAllDevices() const; + void ShowExtensionMotionTabs(bool show); signals: // Emitted when config has changed so widgets can update to reflect the change. @@ -66,7 +67,7 @@ private: void CreateMainLayout(); void ConnectWidgets(); - void AddWidget(const QString& name, QWidget* widget); + QWidget* AddWidget(const QString& name, QWidget* widget); void RefreshDevices(); @@ -108,6 +109,10 @@ private: QPushButton* m_reset_clear; QTabWidget* m_tab_widget; + QWidget* m_extension_motion_input_tab; + QWidget* m_extension_motion_simulation_tab; + const QString EXTENSION_MOTION_INPUT_TAB_NAME = tr("Extension Motion Input"); + const QString EXTENSION_MOTION_SIMULATION_TAB_NAME = tr("Extension Motion Simulation"); Type m_mapping_type; const int m_port; diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp index cafbb5d22d..20d0fd81f1 100644 --- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp @@ -108,16 +108,7 @@ void WiimoteEmuExtension::CreateNunchukLayout() layout->addWidget( CreateGroupBox(tr("Buttons"), Wiimote::GetNunchukGroup(GetPort(), WiimoteEmu::NunchukGroup::Buttons)), - 1, 0); - layout->addWidget(CreateGroupBox(tr("Shake"), Wiimote::GetNunchukGroup( - GetPort(), WiimoteEmu::NunchukGroup::Shake)), - 0, 1, -1, 1); - layout->addWidget(CreateGroupBox(tr("Tilt"), Wiimote::GetNunchukGroup( - GetPort(), WiimoteEmu::NunchukGroup::Tilt)), - 0, 2, -1, 1); - layout->addWidget(CreateGroupBox(tr("Swing"), Wiimote::GetNunchukGroup( - GetPort(), WiimoteEmu::NunchukGroup::Swing)), - 0, 3, -1, 1); + 0, 1); m_nunchuk_box->setLayout(layout); } diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp new file mode 100644 index 0000000000..a5430ae404 --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp @@ -0,0 +1,80 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.h" + +#include +#include +#include +#include +#include + +#include "Core/HW/Wiimote.h" +#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" +#include "Core/HW/WiimoteEmu/WiimoteEmu.h" + +#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" + +#include "InputCommon/InputConfig.h" + +WiimoteEmuExtensionMotionInput::WiimoteEmuExtensionMotionInput(MappingWindow* window) + : MappingWidget(window) +{ + CreateNunchukLayout(); + CreateMainLayout(); +} + +void WiimoteEmuExtensionMotionInput::CreateNunchukLayout() +{ + auto* layout = new QGridLayout(); + m_nunchuk_box = new QGroupBox(tr("Nunchuk"), this); + + auto* warning_layout = new QHBoxLayout(); + auto* warning_label = new QLabel( + tr("WARNING: These controls are designed to interface directly with motion " + "sensor hardware. They are not intended for mapping traditional buttons, triggers or " + "axes. You might need to configure alternate input sources before using these controls.")); + warning_label->setWordWrap(true); + auto* warning_input_sources_button = new QPushButton(tr("Alternate Input Sources")); + warning_layout->addWidget(warning_label, 1); + warning_layout->addWidget(warning_input_sources_button, 0, Qt::AlignRight); + connect(warning_input_sources_button, &QPushButton::clicked, this, [this] { + ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this); + window->setAttribute(Qt::WA_DeleteOnClose, true); + window->setWindowModality(Qt::WindowModality::WindowModal); + window->show(); + }); + layout->addLayout(warning_layout, 0, 0, 1, -1); + + layout->addWidget(CreateGroupBox(tr("Accelerometer"), + Wiimote::GetNunchukGroup( + GetPort(), WiimoteEmu::NunchukGroup::IMUAccelerometer)), + 1, 0); + + m_nunchuk_box->setLayout(layout); +} + +void WiimoteEmuExtensionMotionInput::CreateMainLayout() +{ + m_main_layout = new QHBoxLayout(); + + m_main_layout->addWidget(m_nunchuk_box); + + setLayout(m_main_layout); +} + +void WiimoteEmuExtensionMotionInput::LoadSettings() +{ + Wiimote::LoadConfig(); +} + +void WiimoteEmuExtensionMotionInput::SaveSettings() +{ + Wiimote::GetConfig()->SaveConfig(); +} + +InputConfig* WiimoteEmuExtensionMotionInput::GetConfig() +{ + return Wiimote::GetConfig(); +} diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.h b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.h new file mode 100644 index 0000000000..05d7aff1f3 --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.h @@ -0,0 +1,32 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt/Config/Mapping/MappingWidget.h" + +#include "Core/HW/WiimoteEmu/ExtensionPort.h" + +class QGroupBox; +class QHBoxLayout; + +class WiimoteEmuExtensionMotionInput final : public MappingWidget +{ + Q_OBJECT +public: + explicit WiimoteEmuExtensionMotionInput(MappingWindow* window); + + InputConfig* GetConfig() override; + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateNunchukLayout(); + void CreateMainLayout(); + + // Main + QHBoxLayout* m_main_layout; + QGroupBox* m_nunchuk_box; +}; diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp new file mode 100644 index 0000000000..fa00de37f5 --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp @@ -0,0 +1,65 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.h" + +#include +#include +#include +#include + +#include "Core/HW/Wiimote.h" +#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" +#include "Core/HW/WiimoteEmu/WiimoteEmu.h" + +#include "InputCommon/InputConfig.h" + +WiimoteEmuExtensionMotionSimulation::WiimoteEmuExtensionMotionSimulation(MappingWindow* window) + : MappingWidget(window) +{ + CreateNunchukLayout(); + CreateMainLayout(); +} + +void WiimoteEmuExtensionMotionSimulation::CreateNunchukLayout() +{ + auto* layout = new QGridLayout(); + m_nunchuk_box = new QGroupBox(tr("Nunchuk"), this); + + layout->addWidget(CreateGroupBox(tr("Shake"), Wiimote::GetNunchukGroup( + GetPort(), WiimoteEmu::NunchukGroup::Shake)), + 0, 0); + layout->addWidget(CreateGroupBox(tr("Tilt"), Wiimote::GetNunchukGroup( + GetPort(), WiimoteEmu::NunchukGroup::Tilt)), + 0, 1); + layout->addWidget(CreateGroupBox(tr("Swing"), Wiimote::GetNunchukGroup( + GetPort(), WiimoteEmu::NunchukGroup::Swing)), + 0, 2); + + m_nunchuk_box->setLayout(layout); +} + +void WiimoteEmuExtensionMotionSimulation::CreateMainLayout() +{ + m_main_layout = new QHBoxLayout(); + + m_main_layout->addWidget(m_nunchuk_box); + + setLayout(m_main_layout); +} + +void WiimoteEmuExtensionMotionSimulation::LoadSettings() +{ + Wiimote::LoadConfig(); +} + +void WiimoteEmuExtensionMotionSimulation::SaveSettings() +{ + Wiimote::GetConfig()->SaveConfig(); +} + +InputConfig* WiimoteEmuExtensionMotionSimulation::GetConfig() +{ + return Wiimote::GetConfig(); +} diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.h b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.h new file mode 100644 index 0000000000..3ba97868b3 --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.h @@ -0,0 +1,32 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt/Config/Mapping/MappingWidget.h" + +#include "Core/HW/WiimoteEmu/ExtensionPort.h" + +class QGroupBox; +class QHBoxLayout; + +class WiimoteEmuExtensionMotionSimulation final : public MappingWidget +{ + Q_OBJECT +public: + explicit WiimoteEmuExtensionMotionSimulation(MappingWindow* window); + + InputConfig* GetConfig() override; + +private: + void LoadSettings() override; + void SaveSettings() override; + + void CreateNunchukLayout(); + void CreateMainLayout(); + + // Main + QHBoxLayout* m_main_layout; + QGroupBox* m_nunchuk_box; +}; diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp index b68999f16e..633245a324 100644 --- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuGeneral.cpp @@ -76,6 +76,8 @@ void WiimoteEmuGeneral::Connect(MappingWindow* window) void WiimoteEmuGeneral::OnAttachmentChanged(int extension) { + GetParent()->ShowExtensionMotionTabs(extension == WiimoteEmu::ExtensionNumber::NUNCHUK); + m_extension_widget->ChangeExtensionType(extension); auto* ce_extension = static_cast( diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index d89cf632ff..aa1095b2f6 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -93,6 +93,8 @@ + + @@ -292,6 +294,8 @@ + + @@ -344,6 +348,8 @@ + +