Skip to content
Permalink
Browse files
Merge pull request #8451 from rlnilsen/motion-input-nunchuk
Add motion input support to nunchuk
  • Loading branch information
JMC47 committed Jan 13, 2020
2 parents 966e1b3 + 965781e commit 48fd27c
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 16 deletions.
@@ -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;
@@ -27,7 +27,8 @@ enum class NunchukGroup
Stick,
Tilt,
Swing,
Shake
Shake,
IMUAccelerometer,
};

class Nunchuk : public Extension1stParty
@@ -96,6 +97,7 @@ class Nunchuk : public Extension1stParty
ControllerEmu::Shake* m_shake;
ControllerEmu::Buttons* m_buttons;
ControllerEmu::AnalogStick* m_stick;
ControllerEmu::IMUAccelerometer* m_imu_accelerometer;

// Dynamics:
MotionState m_swing_state;
@@ -144,6 +144,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
@@ -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);
}
}
@@ -50,6 +50,7 @@ class MappingWindow final : public QDialog
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 @@ class MappingWindow final : public QDialog
void CreateMainLayout();
void ConnectWidgets();

void AddWidget(const QString& name, QWidget* widget);
QWidget* AddWidget(const QString& name, QWidget* widget);

void RefreshDevices();

@@ -108,6 +109,10 @@ class MappingWindow final : public QDialog
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;
@@ -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);
}
@@ -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 <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>

#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();
}
@@ -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;
};
@@ -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 <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>

#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();
}
@@ -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;
};
@@ -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<ControllerEmu::Attachments*>(

0 comments on commit 48fd27c

Please sign in to comment.