mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Add 'Enable Controller Input' checkbox to TAS dialogs
When disabled only inputs from TAS dialog are used. When enabled inputs from TAS dialog are used, except when a change in input is detected from a real controller, in this case the TAS value is replaced with the real controller value.
This commit is contained in:
parent
3d1a7737d8
commit
b94262ec33
@ -63,7 +63,7 @@ add_executable(dolphin-emu
|
|||||||
Config/Mapping/MappingCommon.cpp
|
Config/Mapping/MappingCommon.cpp
|
||||||
Config/Mapping/MappingIndicator.cpp
|
Config/Mapping/MappingIndicator.cpp
|
||||||
Config/Mapping/MappingNumeric.cpp
|
Config/Mapping/MappingNumeric.cpp
|
||||||
Config/Mapping/MappingRadio.cpp
|
Config/Mapping/MappingRadio.cpp
|
||||||
Config/Mapping/MappingWidget.cpp
|
Config/Mapping/MappingWidget.cpp
|
||||||
Config/Mapping/MappingWindow.cpp
|
Config/Mapping/MappingWindow.cpp
|
||||||
Config/Mapping/WiimoteEmuExtension.cpp
|
Config/Mapping/WiimoteEmuExtension.cpp
|
||||||
@ -113,7 +113,7 @@ add_executable(dolphin-emu
|
|||||||
Settings/USBDeviceAddToWhitelistDialog.cpp
|
Settings/USBDeviceAddToWhitelistDialog.cpp
|
||||||
TAS/GCTASInputWindow.cpp
|
TAS/GCTASInputWindow.cpp
|
||||||
TAS/WiiTASInputWindow.cpp
|
TAS/WiiTASInputWindow.cpp
|
||||||
TAS/Shared.cpp
|
TAS/TASInputWindow.cpp
|
||||||
TAS/StickWidget.cpp
|
TAS/StickWidget.cpp
|
||||||
TAS/IRWidget.cpp
|
TAS/IRWidget.cpp
|
||||||
Updater.cpp
|
Updater.cpp
|
||||||
|
@ -110,6 +110,7 @@
|
|||||||
<QtMoc Include="FIFO\FIFOPlayerWindow.h" />
|
<QtMoc Include="FIFO\FIFOPlayerWindow.h" />
|
||||||
<QtMoc Include="TAS\GCTASInputWindow.h" />
|
<QtMoc Include="TAS\GCTASInputWindow.h" />
|
||||||
<QtMoc Include="TAS\WiiTASInputWindow.h" />
|
<QtMoc Include="TAS\WiiTASInputWindow.h" />
|
||||||
|
<QtMoc Include="TAS\TASInputWindow.h" />
|
||||||
<QtMoc Include="TAS\StickWidget.h" />
|
<QtMoc Include="TAS\StickWidget.h" />
|
||||||
<QtMoc Include="TAS\IRWidget.h" />
|
<QtMoc Include="TAS\IRWidget.h" />
|
||||||
<QtMoc Include="Debugger\BreakpointWidget.h" />
|
<QtMoc Include="Debugger\BreakpointWidget.h" />
|
||||||
@ -246,6 +247,7 @@
|
|||||||
<ClCompile Include="$(QtMocOutPrefix)SettingsWindow.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)SettingsWindow.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)SoftwareRendererWidget.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)SoftwareRendererWidget.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)StickWidget.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)StickWidget.cpp" />
|
||||||
|
<ClCompile Include="$(QtMocOutPrefix)TASInputWindow.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)ToolBar.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)ToolBar.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)USBDeviceAddToWhitelistDialog.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)USBDeviceAddToWhitelistDialog.cpp" />
|
||||||
<ClCompile Include="$(QtMocOutPrefix)Updater.cpp" />
|
<ClCompile Include="$(QtMocOutPrefix)Updater.cpp" />
|
||||||
@ -318,9 +320,9 @@
|
|||||||
<ClCompile Include="QtUtils\WinIconHelper.cpp" />
|
<ClCompile Include="QtUtils\WinIconHelper.cpp" />
|
||||||
<ClCompile Include="TAS\GCTASInputWindow.cpp" />
|
<ClCompile Include="TAS\GCTASInputWindow.cpp" />
|
||||||
<ClCompile Include="TAS\WiiTASInputWindow.cpp" />
|
<ClCompile Include="TAS\WiiTASInputWindow.cpp" />
|
||||||
|
<ClCompile Include="TAS\TASInputWindow.cpp" />
|
||||||
<ClCompile Include="TAS\StickWidget.cpp" />
|
<ClCompile Include="TAS\StickWidget.cpp" />
|
||||||
<ClCompile Include="TAS\IRWidget.cpp" />
|
<ClCompile Include="TAS\IRWidget.cpp" />
|
||||||
<ClCompile Include="TAS\Shared.cpp" />
|
|
||||||
<ClCompile Include="Debugger\BreakpointWidget.cpp" />
|
<ClCompile Include="Debugger\BreakpointWidget.cpp" />
|
||||||
<ClCompile Include="Debugger\NewBreakpointDialog.cpp" />
|
<ClCompile Include="Debugger\NewBreakpointDialog.cpp" />
|
||||||
<ClCompile Include="Debugger\RegisterColumn.cpp" />
|
<ClCompile Include="Debugger\RegisterColumn.cpp" />
|
||||||
@ -377,7 +379,6 @@
|
|||||||
<ClInclude Include="QtUtils\RunOnObject.h" />
|
<ClInclude Include="QtUtils\RunOnObject.h" />
|
||||||
<ClInclude Include="QtUtils\WinIconHelper.h" />
|
<ClInclude Include="QtUtils\WinIconHelper.h" />
|
||||||
<ClInclude Include="Resources.h" />
|
<ClInclude Include="Resources.h" />
|
||||||
<ClInclude Include="TAS\Shared.h" />
|
|
||||||
<ClInclude Include="Translation.h" />
|
<ClInclude Include="Translation.h" />
|
||||||
<ClInclude Include="WiiUpdate.h" />
|
<ClInclude Include="WiiUpdate.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -12,35 +12,32 @@
|
|||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
#include "DolphinQt/TAS/Shared.h"
|
|
||||||
|
|
||||||
#include "InputCommon/GCPadStatus.h"
|
#include "InputCommon/GCPadStatus.h"
|
||||||
|
|
||||||
GCTASInputWindow::GCTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
GCTASInputWindow::GCTASInputWindow(QWidget* parent, int num) : TASInputWindow(parent)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("GameCube TAS Input %1").arg(num + 1));
|
setWindowTitle(tr("GameCube TAS Input %1").arg(num + 1));
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
||||||
|
|
||||||
auto* main_stick_box = CreateStickInputs(this, tr("Main Stick"), m_x_main_stick_value,
|
m_main_stick_box = CreateStickInputs(tr("Main Stick"), m_x_main_stick_value, m_y_main_stick_value,
|
||||||
m_y_main_stick_value, 255, 255, Qt::Key_F, Qt::Key_G);
|
255, 255, Qt::Key_F, Qt::Key_G);
|
||||||
auto* c_stick_box = CreateStickInputs(this, tr("C Stick"), m_x_c_stick_value, m_y_c_stick_value,
|
m_c_stick_box = CreateStickInputs(tr("C Stick"), m_x_c_stick_value, m_y_c_stick_value, 255, 255,
|
||||||
255, 255, Qt::Key_H, Qt::Key_J);
|
Qt::Key_H, Qt::Key_J);
|
||||||
|
|
||||||
auto* top_layout = new QHBoxLayout;
|
auto* top_layout = new QHBoxLayout;
|
||||||
top_layout->addWidget(main_stick_box);
|
top_layout->addWidget(m_main_stick_box);
|
||||||
top_layout->addWidget(c_stick_box);
|
top_layout->addWidget(m_c_stick_box);
|
||||||
|
|
||||||
auto* triggers_box = new QGroupBox(tr("Triggers"));
|
m_triggers_box = new QGroupBox(tr("Triggers"));
|
||||||
|
|
||||||
auto* l_trigger_layout = CreateSliderValuePairLayout(this, tr("Left"), m_l_trigger_value, 255,
|
auto* l_trigger_layout =
|
||||||
Qt::Key_N, triggers_box);
|
CreateSliderValuePairLayout(tr("Left"), m_l_trigger_value, 255, Qt::Key_N, m_triggers_box);
|
||||||
auto* r_trigger_layout = CreateSliderValuePairLayout(this, tr("Right"), m_r_trigger_value, 255,
|
auto* r_trigger_layout =
|
||||||
Qt::Key_M, triggers_box);
|
CreateSliderValuePairLayout(tr("Right"), m_r_trigger_value, 255, Qt::Key_M, m_triggers_box);
|
||||||
|
|
||||||
auto* triggers_layout = new QVBoxLayout;
|
auto* triggers_layout = new QVBoxLayout;
|
||||||
triggers_layout->addLayout(l_trigger_layout);
|
triggers_layout->addLayout(l_trigger_layout);
|
||||||
triggers_layout->addLayout(r_trigger_layout);
|
triggers_layout->addLayout(r_trigger_layout);
|
||||||
triggers_box->setLayout(triggers_layout);
|
m_triggers_box->setLayout(triggers_layout);
|
||||||
|
|
||||||
m_a_button = new QCheckBox(QStringLiteral("&A"));
|
m_a_button = new QCheckBox(QStringLiteral("&A"));
|
||||||
m_b_button = new QCheckBox(QStringLiteral("&B"));
|
m_b_button = new QCheckBox(QStringLiteral("&B"));
|
||||||
@ -76,42 +73,35 @@ GCTASInputWindow::GCTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
buttons_layout->addLayout(buttons_layout1);
|
buttons_layout->addLayout(buttons_layout1);
|
||||||
buttons_layout->addLayout(buttons_layout2);
|
buttons_layout->addLayout(buttons_layout2);
|
||||||
|
|
||||||
auto* buttons_box = new QGroupBox(tr("Buttons"));
|
m_buttons_box = new QGroupBox(tr("Buttons"));
|
||||||
buttons_box->setLayout(buttons_layout);
|
m_buttons_box->setLayout(buttons_layout);
|
||||||
|
|
||||||
auto* layout = new QVBoxLayout;
|
auto* layout = new QVBoxLayout;
|
||||||
layout->addLayout(top_layout);
|
layout->addLayout(top_layout);
|
||||||
layout->addWidget(triggers_box);
|
layout->addWidget(m_triggers_box);
|
||||||
layout->addWidget(buttons_box);
|
layout->addWidget(m_buttons_box);
|
||||||
|
layout->addWidget(m_use_controller);
|
||||||
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetButton(QCheckBox* button, GCPadStatus* pad, u16 mask)
|
|
||||||
{
|
|
||||||
if (button->isChecked())
|
|
||||||
pad->button |= mask;
|
|
||||||
else
|
|
||||||
pad->button &= ~mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GCTASInputWindow::GetValues(GCPadStatus* pad)
|
void GCTASInputWindow::GetValues(GCPadStatus* pad)
|
||||||
{
|
{
|
||||||
if (!isVisible())
|
if (!isVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetButton(m_a_button, pad, PAD_BUTTON_A);
|
GetButton<u16>(m_a_button, pad->button, PAD_BUTTON_A);
|
||||||
SetButton(m_b_button, pad, PAD_BUTTON_B);
|
GetButton<u16>(m_b_button, pad->button, PAD_BUTTON_B);
|
||||||
SetButton(m_x_button, pad, PAD_BUTTON_X);
|
GetButton<u16>(m_x_button, pad->button, PAD_BUTTON_X);
|
||||||
SetButton(m_y_button, pad, PAD_BUTTON_Y);
|
GetButton<u16>(m_y_button, pad->button, PAD_BUTTON_Y);
|
||||||
SetButton(m_z_button, pad, PAD_TRIGGER_Z);
|
GetButton<u16>(m_z_button, pad->button, PAD_TRIGGER_Z);
|
||||||
SetButton(m_l_button, pad, PAD_TRIGGER_L);
|
GetButton<u16>(m_l_button, pad->button, PAD_TRIGGER_L);
|
||||||
SetButton(m_r_button, pad, PAD_TRIGGER_R);
|
GetButton<u16>(m_r_button, pad->button, PAD_TRIGGER_R);
|
||||||
SetButton(m_left_button, pad, PAD_BUTTON_LEFT);
|
GetButton<u16>(m_left_button, pad->button, PAD_BUTTON_LEFT);
|
||||||
SetButton(m_up_button, pad, PAD_BUTTON_UP);
|
GetButton<u16>(m_up_button, pad->button, PAD_BUTTON_UP);
|
||||||
SetButton(m_down_button, pad, PAD_BUTTON_DOWN);
|
GetButton<u16>(m_down_button, pad->button, PAD_BUTTON_DOWN);
|
||||||
SetButton(m_right_button, pad, PAD_BUTTON_RIGHT);
|
GetButton<u16>(m_right_button, pad->button, PAD_BUTTON_RIGHT);
|
||||||
SetButton(m_start_button, pad, PAD_BUTTON_START);
|
GetButton<u16>(m_start_button, pad->button, PAD_BUTTON_START);
|
||||||
|
|
||||||
if (m_a_button->isChecked())
|
if (m_a_button->isChecked())
|
||||||
pad->analogA = 0xFF;
|
pad->analogA = 0xFF;
|
||||||
@ -123,11 +113,12 @@ void GCTASInputWindow::GetValues(GCPadStatus* pad)
|
|||||||
else
|
else
|
||||||
pad->analogB = 0x00;
|
pad->analogB = 0x00;
|
||||||
|
|
||||||
pad->triggerLeft = m_l_trigger_value->value();
|
GetSpinBoxU8(m_l_trigger_value, pad->triggerLeft);
|
||||||
pad->triggerRight = m_r_trigger_value->value();
|
GetSpinBoxU8(m_r_trigger_value, pad->triggerRight);
|
||||||
|
|
||||||
pad->stickX = m_x_main_stick_value->value();
|
GetSpinBoxU8(m_x_main_stick_value, pad->stickX);
|
||||||
pad->stickY = m_y_main_stick_value->value();
|
GetSpinBoxU8(m_y_main_stick_value, pad->stickY);
|
||||||
pad->substickX = m_x_c_stick_value->value();
|
|
||||||
pad->substickY = m_y_c_stick_value->value();
|
GetSpinBoxU8(m_x_c_stick_value, pad->substickX);
|
||||||
|
GetSpinBoxU8(m_y_c_stick_value, pad->substickY);
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDialog>
|
#include "DolphinQt/TAS/TASInputWindow.h"
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class QGroupBox;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
struct GCPadStatus;
|
struct GCPadStatus;
|
||||||
|
|
||||||
class GCTASInputWindow : public QDialog
|
class GCTASInputWindow : public TASInputWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -38,4 +37,8 @@ private:
|
|||||||
QSpinBox* m_y_main_stick_value;
|
QSpinBox* m_y_main_stick_value;
|
||||||
QSpinBox* m_x_c_stick_value;
|
QSpinBox* m_x_c_stick_value;
|
||||||
QSpinBox* m_y_c_stick_value;
|
QSpinBox* m_y_c_stick_value;
|
||||||
|
QGroupBox* m_main_stick_box;
|
||||||
|
QGroupBox* m_c_stick_box;
|
||||||
|
QGroupBox* m_triggers_box;
|
||||||
|
QGroupBox* m_buttons_box;
|
||||||
};
|
};
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
// Copyright 2018 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "DolphinQt/TAS/Shared.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <QGroupBox>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QShortcut>
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QSpinBox>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
#include "DolphinQt/QtUtils/AspectRatioWidget.h"
|
|
||||||
#include "DolphinQt/TAS/StickWidget.h"
|
|
||||||
|
|
||||||
#include "InputCommon/GCPadStatus.h"
|
|
||||||
|
|
||||||
QGroupBox* CreateStickInputs(QDialog* window, QString name, QSpinBox*& x_value, QSpinBox*& y_value,
|
|
||||||
u16 max_x, u16 max_y, Qt::Key x_shortcut_key, Qt::Key y_shortcut_key)
|
|
||||||
{
|
|
||||||
const QKeySequence x_shortcut_key_sequence = QKeySequence(Qt::ALT + x_shortcut_key);
|
|
||||||
const QKeySequence y_shortcut_key_sequence = QKeySequence(Qt::ALT + y_shortcut_key);
|
|
||||||
|
|
||||||
auto* box =
|
|
||||||
new QGroupBox(QStringLiteral("%1 (%2/%3)")
|
|
||||||
.arg(name, x_shortcut_key_sequence.toString(QKeySequence::NativeText),
|
|
||||||
y_shortcut_key_sequence.toString(QKeySequence::NativeText)));
|
|
||||||
|
|
||||||
auto* x_layout = new QHBoxLayout;
|
|
||||||
x_value =
|
|
||||||
CreateSliderValuePair(window, x_layout, max_x, x_shortcut_key_sequence, Qt::Horizontal, box);
|
|
||||||
|
|
||||||
auto* y_layout = new QVBoxLayout;
|
|
||||||
y_value =
|
|
||||||
CreateSliderValuePair(window, y_layout, max_y, y_shortcut_key_sequence, Qt::Vertical, box);
|
|
||||||
y_value->setMaximumWidth(60);
|
|
||||||
|
|
||||||
auto* visual = new StickWidget(window, max_x, max_y);
|
|
||||||
window->connect(x_value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), visual,
|
|
||||||
&StickWidget::SetX);
|
|
||||||
window->connect(y_value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), visual,
|
|
||||||
&StickWidget::SetY);
|
|
||||||
window->connect(visual, &StickWidget::ChangedX, x_value, &QSpinBox::setValue);
|
|
||||||
window->connect(visual, &StickWidget::ChangedY, y_value, &QSpinBox::setValue);
|
|
||||||
|
|
||||||
x_value->setValue(static_cast<int>(std::round(max_x / 2.)));
|
|
||||||
y_value->setValue(static_cast<int>(std::round(max_y / 2.)));
|
|
||||||
|
|
||||||
auto* visual_ar = new AspectRatioWidget(visual, max_x, max_y);
|
|
||||||
|
|
||||||
auto* visual_layout = new QHBoxLayout;
|
|
||||||
visual_layout->addWidget(visual_ar);
|
|
||||||
visual_layout->addLayout(y_layout);
|
|
||||||
|
|
||||||
auto* layout = new QVBoxLayout;
|
|
||||||
layout->addLayout(x_layout);
|
|
||||||
layout->addLayout(visual_layout);
|
|
||||||
box->setLayout(layout);
|
|
||||||
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
QBoxLayout* CreateSliderValuePairLayout(QDialog* window, QString name, QSpinBox*& value, u16 max,
|
|
||||||
Qt::Key shortcut_key, QWidget* shortcut_widget, bool invert)
|
|
||||||
{
|
|
||||||
const QKeySequence shortcut_key_sequence = QKeySequence(Qt::ALT + shortcut_key);
|
|
||||||
|
|
||||||
auto* label = new QLabel(QStringLiteral("%1 (%2)").arg(
|
|
||||||
name, shortcut_key_sequence.toString(QKeySequence::NativeText)));
|
|
||||||
|
|
||||||
QBoxLayout* layout = new QHBoxLayout;
|
|
||||||
layout->addWidget(label);
|
|
||||||
|
|
||||||
value = CreateSliderValuePair(window, layout, max, shortcut_key_sequence, Qt::Horizontal,
|
|
||||||
shortcut_widget, invert);
|
|
||||||
|
|
||||||
return layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The shortcut_widget argument needs to specify the container widget that will be hidden/shown.
|
|
||||||
// This is done to avoid ambigous shortcuts
|
|
||||||
QSpinBox* CreateSliderValuePair(QDialog* window, QBoxLayout* layout, u16 max,
|
|
||||||
QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
|
|
||||||
QWidget* shortcut_widget, bool invert)
|
|
||||||
{
|
|
||||||
auto* value = new QSpinBox();
|
|
||||||
value->setRange(0, 99999);
|
|
||||||
window->connect(value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
|
|
||||||
[value, max](int i) {
|
|
||||||
if (i > max)
|
|
||||||
value->setValue(max);
|
|
||||||
});
|
|
||||||
auto* slider = new QSlider(orientation);
|
|
||||||
slider->setRange(0, max);
|
|
||||||
slider->setFocusPolicy(Qt::ClickFocus);
|
|
||||||
slider->setInvertedAppearance(invert);
|
|
||||||
|
|
||||||
window->connect(slider, &QSlider::valueChanged, value, &QSpinBox::setValue);
|
|
||||||
window->connect(value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), slider,
|
|
||||||
&QSlider::setValue);
|
|
||||||
|
|
||||||
auto* shortcut = new QShortcut(shortcut_key_sequence, shortcut_widget);
|
|
||||||
window->connect(shortcut, &QShortcut::activated, [value] {
|
|
||||||
value->setFocus();
|
|
||||||
value->selectAll();
|
|
||||||
});
|
|
||||||
|
|
||||||
layout->addWidget(slider);
|
|
||||||
layout->addWidget(value);
|
|
||||||
if (orientation == Qt::Vertical)
|
|
||||||
layout->setAlignment(slider, Qt::AlignRight);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
// Copyright 2018 Dolphin Emulator Project
|
|
||||||
// Licensed under GPLv2+
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
struct GCPadStatus;
|
|
||||||
class QDialog;
|
|
||||||
class QString;
|
|
||||||
class QSpinBox;
|
|
||||||
class QCheckBox;
|
|
||||||
class QBoxLayout;
|
|
||||||
class QGroupBox;
|
|
||||||
|
|
||||||
QGroupBox* CreateStickInputs(QDialog* window, QString name, QSpinBox*& x_value, QSpinBox*& y_value,
|
|
||||||
u16 max_x, u16 max_y, Qt::Key x_shortcut_key, Qt::Key y_shortcut_key);
|
|
||||||
QBoxLayout* CreateSliderValuePairLayout(QDialog* window, QString name, QSpinBox*& value, u16 max,
|
|
||||||
Qt::Key shortcut_key, QWidget* shortcut_widget,
|
|
||||||
bool invert = false);
|
|
||||||
QSpinBox* CreateSliderValuePair(QDialog* window, QBoxLayout* layout, u16 max,
|
|
||||||
QKeySequence shortcut_key_sequence, Qt::Orientation orientation,
|
|
||||||
QWidget* shortcut_widget, bool invert = false);
|
|
192
Source/Core/DolphinQt/TAS/TASInputWindow.cpp
Normal file
192
Source/Core/DolphinQt/TAS/TASInputWindow.cpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
// Copyright 2018 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QShortcut>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
#include "DolphinQt/QtUtils/AspectRatioWidget.h"
|
||||||
|
#include "DolphinQt/QtUtils/QueueOnObject.h"
|
||||||
|
#include "DolphinQt/TAS/StickWidget.h"
|
||||||
|
#include "DolphinQt/TAS/TASInputWindow.h"
|
||||||
|
|
||||||
|
#include "InputCommon/GCPadStatus.h"
|
||||||
|
|
||||||
|
TASInputWindow::TASInputWindow(QWidget* parent) : QDialog(parent)
|
||||||
|
{
|
||||||
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
|
m_use_controller = new QCheckBox(QStringLiteral("Enable Controller Inpu&t"));
|
||||||
|
m_use_controller->setToolTip(tr("Warning: Analog inputs may reset to controller values at "
|
||||||
|
"random. In some cases this can be fixed by adding a deadzone."));
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox* TASInputWindow::CreateStickInputs(QString name, QSpinBox*& x_value, QSpinBox*& y_value,
|
||||||
|
u16 max_x, u16 max_y, Qt::Key x_shortcut_key,
|
||||||
|
Qt::Key y_shortcut_key)
|
||||||
|
{
|
||||||
|
const QKeySequence x_shortcut_key_sequence = QKeySequence(Qt::ALT + x_shortcut_key);
|
||||||
|
const QKeySequence y_shortcut_key_sequence = QKeySequence(Qt::ALT + y_shortcut_key);
|
||||||
|
|
||||||
|
auto* box =
|
||||||
|
new QGroupBox(QStringLiteral("%1 (%2/%3)")
|
||||||
|
.arg(name, x_shortcut_key_sequence.toString(QKeySequence::NativeText),
|
||||||
|
y_shortcut_key_sequence.toString(QKeySequence::NativeText)));
|
||||||
|
|
||||||
|
auto* x_layout = new QHBoxLayout;
|
||||||
|
x_value = CreateSliderValuePair(x_layout, max_x, x_shortcut_key_sequence, Qt::Horizontal, box);
|
||||||
|
|
||||||
|
auto* y_layout = new QVBoxLayout;
|
||||||
|
y_value = CreateSliderValuePair(y_layout, max_y, y_shortcut_key_sequence, Qt::Vertical, box);
|
||||||
|
y_value->setMaximumWidth(60);
|
||||||
|
|
||||||
|
auto* visual = new StickWidget(this, max_x, max_y);
|
||||||
|
connect(x_value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), visual,
|
||||||
|
&StickWidget::SetX);
|
||||||
|
connect(y_value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), visual,
|
||||||
|
&StickWidget::SetY);
|
||||||
|
connect(visual, &StickWidget::ChangedX, x_value, &QSpinBox::setValue);
|
||||||
|
connect(visual, &StickWidget::ChangedY, y_value, &QSpinBox::setValue);
|
||||||
|
|
||||||
|
x_value->setValue(static_cast<int>(std::round(max_x / 2.)));
|
||||||
|
y_value->setValue(static_cast<int>(std::round(max_y / 2.)));
|
||||||
|
|
||||||
|
auto* visual_ar = new AspectRatioWidget(visual, max_x, max_y);
|
||||||
|
|
||||||
|
auto* visual_layout = new QHBoxLayout;
|
||||||
|
visual_layout->addWidget(visual_ar);
|
||||||
|
visual_layout->addLayout(y_layout);
|
||||||
|
|
||||||
|
auto* layout = new QVBoxLayout;
|
||||||
|
layout->addLayout(x_layout);
|
||||||
|
layout->addLayout(visual_layout);
|
||||||
|
box->setLayout(layout);
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
QBoxLayout* TASInputWindow::CreateSliderValuePairLayout(QString name, QSpinBox*& value, u16 max,
|
||||||
|
Qt::Key shortcut_key,
|
||||||
|
QWidget* shortcut_widget, bool invert)
|
||||||
|
{
|
||||||
|
const QKeySequence shortcut_key_sequence = QKeySequence(Qt::ALT + shortcut_key);
|
||||||
|
|
||||||
|
auto* label = new QLabel(QStringLiteral("%1 (%2)").arg(
|
||||||
|
name, shortcut_key_sequence.toString(QKeySequence::NativeText)));
|
||||||
|
|
||||||
|
QBoxLayout* layout = new QHBoxLayout;
|
||||||
|
layout->addWidget(label);
|
||||||
|
|
||||||
|
value = CreateSliderValuePair(layout, max, shortcut_key_sequence, Qt::Horizontal, shortcut_widget,
|
||||||
|
invert);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The shortcut_widget argument needs to specify the container widget that will be hidden/shown.
|
||||||
|
// This is done to avoid ambigous shortcuts
|
||||||
|
QSpinBox* TASInputWindow::CreateSliderValuePair(QBoxLayout* layout, u16 max,
|
||||||
|
QKeySequence shortcut_key_sequence,
|
||||||
|
Qt::Orientation orientation,
|
||||||
|
QWidget* shortcut_widget, bool invert)
|
||||||
|
{
|
||||||
|
auto* value = new QSpinBox();
|
||||||
|
value->setRange(0, 99999);
|
||||||
|
connect(value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
|
||||||
|
[value, max](int i) {
|
||||||
|
if (i > max)
|
||||||
|
value->setValue(max);
|
||||||
|
});
|
||||||
|
auto* slider = new QSlider(orientation);
|
||||||
|
slider->setRange(0, max);
|
||||||
|
slider->setFocusPolicy(Qt::ClickFocus);
|
||||||
|
slider->setInvertedAppearance(invert);
|
||||||
|
|
||||||
|
connect(slider, &QSlider::valueChanged, value, &QSpinBox::setValue);
|
||||||
|
connect(value, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), slider,
|
||||||
|
&QSlider::setValue);
|
||||||
|
|
||||||
|
auto* shortcut = new QShortcut(shortcut_key_sequence, shortcut_widget);
|
||||||
|
connect(shortcut, &QShortcut::activated, [value] {
|
||||||
|
value->setFocus();
|
||||||
|
value->selectAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
layout->addWidget(slider);
|
||||||
|
layout->addWidget(value);
|
||||||
|
if (orientation == Qt::Vertical)
|
||||||
|
layout->setAlignment(slider, Qt::AlignRight);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename UX>
|
||||||
|
void TASInputWindow::GetButton(QCheckBox* checkbox, UX& buttons, UX mask)
|
||||||
|
{
|
||||||
|
const bool pressed = (buttons & mask) != 0;
|
||||||
|
if (m_use_controller->isChecked())
|
||||||
|
{
|
||||||
|
if (pressed)
|
||||||
|
{
|
||||||
|
m_checkbox_set_by_controller[checkbox] = true;
|
||||||
|
QueueOnObject(checkbox, [checkbox] { checkbox->setChecked(true); });
|
||||||
|
}
|
||||||
|
else if (m_checkbox_set_by_controller.count(checkbox) && m_checkbox_set_by_controller[checkbox])
|
||||||
|
{
|
||||||
|
m_checkbox_set_by_controller[checkbox] = false;
|
||||||
|
QueueOnObject(checkbox, [checkbox] { checkbox->setChecked(false); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkbox->isChecked())
|
||||||
|
buttons |= mask;
|
||||||
|
else
|
||||||
|
buttons &= ~mask;
|
||||||
|
}
|
||||||
|
template void TASInputWindow::GetButton<u8>(QCheckBox* button, u8& pad, u8 mask);
|
||||||
|
template void TASInputWindow::GetButton<u16>(QCheckBox* button, u16& pad, u16 mask);
|
||||||
|
|
||||||
|
void TASInputWindow::GetSpinBoxU8(QSpinBox* spin, u8& controller_value)
|
||||||
|
{
|
||||||
|
if (m_use_controller->isChecked())
|
||||||
|
{
|
||||||
|
if (!m_spinbox_most_recent_values_u8.count(spin) ||
|
||||||
|
m_spinbox_most_recent_values_u8[spin] != controller_value)
|
||||||
|
QueueOnObject(spin, [spin, controller_value] { spin->setValue(controller_value); });
|
||||||
|
|
||||||
|
m_spinbox_most_recent_values_u8[spin] = controller_value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spinbox_most_recent_values_u8.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
controller_value = spin->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TASInputWindow::GetSpinBoxU16(QSpinBox* spin, u16& controller_value)
|
||||||
|
{
|
||||||
|
if (m_use_controller->isChecked())
|
||||||
|
{
|
||||||
|
if (!m_spinbox_most_recent_values_u16.count(spin) ||
|
||||||
|
m_spinbox_most_recent_values_u16[spin] != controller_value)
|
||||||
|
QueueOnObject(spin, [spin, controller_value] { spin->setValue(controller_value); });
|
||||||
|
|
||||||
|
m_spinbox_most_recent_values_u16[spin] = controller_value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_spinbox_most_recent_values_u16.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
controller_value = spin->value();
|
||||||
|
}
|
44
Source/Core/DolphinQt/TAS/TASInputWindow.h
Normal file
44
Source/Core/DolphinQt/TAS/TASInputWindow.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2018 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
struct GCPadStatus;
|
||||||
|
class QBoxLayout;
|
||||||
|
class QCheckBox;
|
||||||
|
class QDialog;
|
||||||
|
class QGroupBox;
|
||||||
|
class QSpinBox;
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
class TASInputWindow : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TASInputWindow(QWidget* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QGroupBox* CreateStickInputs(QString name, QSpinBox*& x_value, QSpinBox*& y_value, u16 max_x,
|
||||||
|
u16 max_y, Qt::Key x_shortcut_key, Qt::Key y_shortcut_key);
|
||||||
|
QBoxLayout* CreateSliderValuePairLayout(QString name, QSpinBox*& value, u16 max,
|
||||||
|
Qt::Key shortcut_key, QWidget* shortcut_widget,
|
||||||
|
bool invert = false);
|
||||||
|
QSpinBox* CreateSliderValuePair(QBoxLayout* layout, u16 max, QKeySequence shortcut_key_sequence,
|
||||||
|
Qt::Orientation orientation, QWidget* shortcut_widget,
|
||||||
|
bool invert = false);
|
||||||
|
template <typename UX>
|
||||||
|
void GetButton(QCheckBox* button, UX& pad, UX mask);
|
||||||
|
void GetSpinBoxU8(QSpinBox* spin, u8& controller_value);
|
||||||
|
void GetSpinBoxU16(QSpinBox* spin, u16& controller_value);
|
||||||
|
QCheckBox* m_use_controller;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<QCheckBox*, bool> m_checkbox_set_by_controller;
|
||||||
|
std::map<QSpinBox*, u8> m_spinbox_most_recent_values_u8;
|
||||||
|
std::map<QSpinBox*, u8> m_spinbox_most_recent_values_u16;
|
||||||
|
};
|
@ -2,8 +2,6 @@
|
|||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "DolphinQt/TAS/WiiTASInputWindow.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
@ -23,15 +21,14 @@
|
|||||||
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
||||||
|
|
||||||
#include "DolphinQt/QtUtils/AspectRatioWidget.h"
|
#include "DolphinQt/QtUtils/AspectRatioWidget.h"
|
||||||
|
#include "DolphinQt/QtUtils/QueueOnObject.h"
|
||||||
#include "DolphinQt/TAS/IRWidget.h"
|
#include "DolphinQt/TAS/IRWidget.h"
|
||||||
#include "DolphinQt/TAS/Shared.h"
|
#include "DolphinQt/TAS/WiiTASInputWindow.h"
|
||||||
|
|
||||||
#include "InputCommon/InputConfig.h"
|
#include "InputCommon/InputConfig.h"
|
||||||
|
|
||||||
WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent), m_num(num)
|
WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : TASInputWindow(parent), m_num(num)
|
||||||
{
|
{
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
||||||
|
|
||||||
const QKeySequence ir_x_shortcut_key_sequence = QKeySequence(Qt::ALT + Qt::Key_F);
|
const QKeySequence ir_x_shortcut_key_sequence = QKeySequence(Qt::ALT + Qt::Key_F);
|
||||||
const QKeySequence ir_y_shortcut_key_sequence = QKeySequence(Qt::ALT + Qt::Key_G);
|
const QKeySequence ir_y_shortcut_key_sequence = QKeySequence(Qt::ALT + Qt::Key_G);
|
||||||
|
|
||||||
@ -41,12 +38,12 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
ir_y_shortcut_key_sequence.toString(QKeySequence::NativeText)));
|
ir_y_shortcut_key_sequence.toString(QKeySequence::NativeText)));
|
||||||
|
|
||||||
auto* x_layout = new QHBoxLayout;
|
auto* x_layout = new QHBoxLayout;
|
||||||
m_ir_x_value = CreateSliderValuePair(this, x_layout, ir_max_x, ir_x_shortcut_key_sequence,
|
m_ir_x_value = CreateSliderValuePair(x_layout, ir_max_x, ir_x_shortcut_key_sequence,
|
||||||
Qt::Horizontal, m_ir_box, true);
|
Qt::Horizontal, m_ir_box, true);
|
||||||
|
|
||||||
auto* y_layout = new QVBoxLayout;
|
auto* y_layout = new QVBoxLayout;
|
||||||
m_ir_y_value = CreateSliderValuePair(this, y_layout, ir_max_y, ir_y_shortcut_key_sequence,
|
m_ir_y_value = CreateSliderValuePair(y_layout, ir_max_y, ir_y_shortcut_key_sequence, Qt::Vertical,
|
||||||
Qt::Vertical, m_ir_box, true);
|
m_ir_box, true);
|
||||||
m_ir_y_value->setMaximumWidth(60);
|
m_ir_y_value->setMaximumWidth(60);
|
||||||
|
|
||||||
auto* visual = new IRWidget(this);
|
auto* visual = new IRWidget(this);
|
||||||
@ -71,15 +68,15 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
ir_layout->addLayout(visual_layout);
|
ir_layout->addLayout(visual_layout);
|
||||||
m_ir_box->setLayout(ir_layout);
|
m_ir_box->setLayout(ir_layout);
|
||||||
|
|
||||||
m_nunchuk_stick_box = CreateStickInputs(this, tr("Nunchuk Stick"), m_nunchuk_stick_x_value,
|
m_nunchuk_stick_box = CreateStickInputs(tr("Nunchuk Stick"), m_nunchuk_stick_x_value,
|
||||||
m_nunchuk_stick_y_value, 255, 255, Qt::Key_X, Qt::Key_Y);
|
m_nunchuk_stick_y_value, 255, 255, Qt::Key_X, Qt::Key_Y);
|
||||||
|
|
||||||
m_classic_left_stick_box =
|
m_classic_left_stick_box =
|
||||||
CreateStickInputs(this, tr("Left Stick"), m_classic_left_stick_x_value,
|
CreateStickInputs(tr("Left Stick"), m_classic_left_stick_x_value,
|
||||||
m_classic_left_stick_y_value, 63, 63, Qt::Key_F, Qt::Key_G);
|
m_classic_left_stick_y_value, 63, 63, Qt::Key_F, Qt::Key_G);
|
||||||
|
|
||||||
m_classic_right_stick_box =
|
m_classic_right_stick_box =
|
||||||
CreateStickInputs(this, tr("Right Stick"), m_classic_right_stick_x_value,
|
CreateStickInputs(tr("Right Stick"), m_classic_right_stick_x_value,
|
||||||
m_classic_right_stick_y_value, 31, 31, Qt::Key_Q, Qt::Key_W);
|
m_classic_right_stick_y_value, 31, 31, Qt::Key_Q, Qt::Key_W);
|
||||||
|
|
||||||
// Need to enforce the same minimum width because otherwise the different lengths in the labels
|
// Need to enforce the same minimum width because otherwise the different lengths in the labels
|
||||||
@ -97,17 +94,21 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
|
|
||||||
auto* remote_orientation_x_layout =
|
auto* remote_orientation_x_layout =
|
||||||
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
||||||
CreateSliderValuePairLayout(this, tr("X"), m_remote_orientation_x_value, 1023, Qt::Key_Q,
|
CreateSliderValuePairLayout(tr("X"), m_remote_orientation_x_value, 1023, Qt::Key_Q,
|
||||||
m_remote_orientation_box);
|
m_remote_orientation_box);
|
||||||
auto* remote_orientation_y_layout =
|
auto* remote_orientation_y_layout =
|
||||||
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
||||||
CreateSliderValuePairLayout(this, tr("Y"), m_remote_orientation_y_value, 1023, Qt::Key_W,
|
CreateSliderValuePairLayout(tr("Y"), m_remote_orientation_y_value, 1023, Qt::Key_W,
|
||||||
m_remote_orientation_box);
|
m_remote_orientation_box);
|
||||||
auto* remote_orientation_z_layout =
|
auto* remote_orientation_z_layout =
|
||||||
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
||||||
CreateSliderValuePairLayout(this, tr("Z"), m_remote_orientation_z_value, 1023, Qt::Key_E,
|
CreateSliderValuePairLayout(tr("Z"), m_remote_orientation_z_value, 1023, Qt::Key_E,
|
||||||
m_remote_orientation_box);
|
m_remote_orientation_box);
|
||||||
|
|
||||||
|
m_remote_orientation_x_value->setValue(512);
|
||||||
|
m_remote_orientation_y_value->setValue(512);
|
||||||
|
m_remote_orientation_z_value->setValue(616);
|
||||||
|
|
||||||
auto* remote_orientation_layout = new QVBoxLayout;
|
auto* remote_orientation_layout = new QVBoxLayout;
|
||||||
remote_orientation_layout->addLayout(remote_orientation_x_layout);
|
remote_orientation_layout->addLayout(remote_orientation_x_layout);
|
||||||
remote_orientation_layout->addLayout(remote_orientation_y_layout);
|
remote_orientation_layout->addLayout(remote_orientation_y_layout);
|
||||||
@ -118,17 +119,21 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
|
|
||||||
auto* nunchuk_orientation_x_layout =
|
auto* nunchuk_orientation_x_layout =
|
||||||
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
||||||
CreateSliderValuePairLayout(this, tr("X"), m_nunchuk_orientation_x_value, 1023, Qt::Key_I,
|
CreateSliderValuePairLayout(tr("X"), m_nunchuk_orientation_x_value, 1023, Qt::Key_I,
|
||||||
m_nunchuk_orientation_box);
|
m_nunchuk_orientation_box);
|
||||||
auto* nunchuk_orientation_y_layout =
|
auto* nunchuk_orientation_y_layout =
|
||||||
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
||||||
CreateSliderValuePairLayout(this, tr("Y"), m_nunchuk_orientation_y_value, 1023, Qt::Key_O,
|
CreateSliderValuePairLayout(tr("Y"), m_nunchuk_orientation_y_value, 1023, Qt::Key_O,
|
||||||
m_nunchuk_orientation_box);
|
m_nunchuk_orientation_box);
|
||||||
auto* nunchuk_orientation_z_layout =
|
auto* nunchuk_orientation_z_layout =
|
||||||
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
// i18n: Refers to a 3D axis (used when mapping motion controls)
|
||||||
CreateSliderValuePairLayout(this, tr("Z"), m_nunchuk_orientation_z_value, 1023, Qt::Key_P,
|
CreateSliderValuePairLayout(tr("Z"), m_nunchuk_orientation_z_value, 1023, Qt::Key_P,
|
||||||
m_nunchuk_orientation_box);
|
m_nunchuk_orientation_box);
|
||||||
|
|
||||||
|
m_nunchuk_orientation_x_value->setValue(512);
|
||||||
|
m_nunchuk_orientation_y_value->setValue(512);
|
||||||
|
m_nunchuk_orientation_z_value->setValue(512);
|
||||||
|
|
||||||
auto* nunchuk_orientation_layout = new QVBoxLayout;
|
auto* nunchuk_orientation_layout = new QVBoxLayout;
|
||||||
nunchuk_orientation_layout->addLayout(nunchuk_orientation_x_layout);
|
nunchuk_orientation_layout->addLayout(nunchuk_orientation_x_layout);
|
||||||
nunchuk_orientation_layout->addLayout(nunchuk_orientation_y_layout);
|
nunchuk_orientation_layout->addLayout(nunchuk_orientation_y_layout);
|
||||||
@ -136,9 +141,9 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
m_nunchuk_orientation_box->setLayout(nunchuk_orientation_layout);
|
m_nunchuk_orientation_box->setLayout(nunchuk_orientation_layout);
|
||||||
|
|
||||||
m_triggers_box = new QGroupBox(tr("Triggers"));
|
m_triggers_box = new QGroupBox(tr("Triggers"));
|
||||||
auto* l_trigger_layout = CreateSliderValuePairLayout(this, tr("Left"), m_left_trigger_value, 31,
|
auto* l_trigger_layout =
|
||||||
Qt::Key_N, m_triggers_box);
|
CreateSliderValuePairLayout(tr("Left"), m_left_trigger_value, 31, Qt::Key_N, m_triggers_box);
|
||||||
auto* r_trigger_layout = CreateSliderValuePairLayout(this, tr("Right"), m_right_trigger_value, 31,
|
auto* r_trigger_layout = CreateSliderValuePairLayout(tr("Right"), m_right_trigger_value, 31,
|
||||||
Qt::Key_M, m_triggers_box);
|
Qt::Key_M, m_triggers_box);
|
||||||
|
|
||||||
auto* triggers_layout = new QVBoxLayout;
|
auto* triggers_layout = new QVBoxLayout;
|
||||||
@ -241,6 +246,7 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : QDialog(parent)
|
|||||||
layout->addWidget(m_remote_buttons_box);
|
layout->addWidget(m_remote_buttons_box);
|
||||||
layout->addWidget(m_nunchuk_buttons_box);
|
layout->addWidget(m_nunchuk_buttons_box);
|
||||||
layout->addWidget(m_classic_buttons_box);
|
layout->addWidget(m_classic_buttons_box);
|
||||||
|
layout->addWidget(m_use_controller);
|
||||||
layout->setAlignment(m_nunchuk_buttons_box, Qt::AlignLeft);
|
layout->setAlignment(m_nunchuk_buttons_box, Qt::AlignLeft);
|
||||||
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
@ -312,15 +318,6 @@ void WiiTASInputWindow::UpdateExt(u8 ext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename UX>
|
|
||||||
static void SetButton(QCheckBox* check_box, UX* buttons, UX mask)
|
|
||||||
{
|
|
||||||
if (check_box->isChecked())
|
|
||||||
*buttons |= mask;
|
|
||||||
else
|
|
||||||
*buttons &= ~mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiiTASInputWindow::GetValues(u8* report_data, WiimoteEmu::ReportFeatures rptf, int ext,
|
void WiiTASInputWindow::GetValues(u8* report_data, WiimoteEmu::ReportFeatures rptf, int ext,
|
||||||
wiimote_key key)
|
wiimote_key key)
|
||||||
{
|
{
|
||||||
@ -336,18 +333,18 @@ void WiiTASInputWindow::GetValues(u8* report_data, WiimoteEmu::ReportFeatures rp
|
|||||||
|
|
||||||
if (m_remote_buttons_box->isVisible() && buttons_data)
|
if (m_remote_buttons_box->isVisible() && buttons_data)
|
||||||
{
|
{
|
||||||
u16* buttons = &(reinterpret_cast<wm_buttons*>(buttons_data))->hex;
|
u16& buttons = (reinterpret_cast<wm_buttons*>(buttons_data))->hex;
|
||||||
SetButton<u16>(m_a_button, buttons, WiimoteEmu::Wiimote::BUTTON_A);
|
GetButton<u16>(m_a_button, buttons, WiimoteEmu::Wiimote::BUTTON_A);
|
||||||
SetButton<u16>(m_b_button, buttons, WiimoteEmu::Wiimote::BUTTON_B);
|
GetButton<u16>(m_b_button, buttons, WiimoteEmu::Wiimote::BUTTON_B);
|
||||||
SetButton<u16>(m_1_button, buttons, WiimoteEmu::Wiimote::BUTTON_ONE);
|
GetButton<u16>(m_1_button, buttons, WiimoteEmu::Wiimote::BUTTON_ONE);
|
||||||
SetButton<u16>(m_2_button, buttons, WiimoteEmu::Wiimote::BUTTON_TWO);
|
GetButton<u16>(m_2_button, buttons, WiimoteEmu::Wiimote::BUTTON_TWO);
|
||||||
SetButton<u16>(m_plus_button, buttons, WiimoteEmu::Wiimote::BUTTON_PLUS);
|
GetButton<u16>(m_plus_button, buttons, WiimoteEmu::Wiimote::BUTTON_PLUS);
|
||||||
SetButton<u16>(m_minus_button, buttons, WiimoteEmu::Wiimote::BUTTON_MINUS);
|
GetButton<u16>(m_minus_button, buttons, WiimoteEmu::Wiimote::BUTTON_MINUS);
|
||||||
SetButton<u16>(m_home_button, buttons, WiimoteEmu::Wiimote::BUTTON_HOME);
|
GetButton<u16>(m_home_button, buttons, WiimoteEmu::Wiimote::BUTTON_HOME);
|
||||||
SetButton<u16>(m_left_button, buttons, WiimoteEmu::Wiimote::PAD_LEFT);
|
GetButton<u16>(m_left_button, buttons, WiimoteEmu::Wiimote::PAD_LEFT);
|
||||||
SetButton<u16>(m_up_button, buttons, WiimoteEmu::Wiimote::PAD_UP);
|
GetButton<u16>(m_up_button, buttons, WiimoteEmu::Wiimote::PAD_UP);
|
||||||
SetButton<u16>(m_down_button, buttons, WiimoteEmu::Wiimote::PAD_DOWN);
|
GetButton<u16>(m_down_button, buttons, WiimoteEmu::Wiimote::PAD_DOWN);
|
||||||
SetButton<u16>(m_right_button, buttons, WiimoteEmu::Wiimote::PAD_RIGHT);
|
GetButton<u16>(m_right_button, buttons, WiimoteEmu::Wiimote::PAD_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_remote_orientation_box->isVisible() && accel_data && buttons_data)
|
if (m_remote_orientation_box->isVisible() && accel_data && buttons_data)
|
||||||
@ -355,16 +352,24 @@ void WiiTASInputWindow::GetValues(u8* report_data, WiimoteEmu::ReportFeatures rp
|
|||||||
wm_accel& accel = *reinterpret_cast<wm_accel*>(accel_data);
|
wm_accel& accel = *reinterpret_cast<wm_accel*>(accel_data);
|
||||||
wm_buttons& buttons = *reinterpret_cast<wm_buttons*>(buttons_data);
|
wm_buttons& buttons = *reinterpret_cast<wm_buttons*>(buttons_data);
|
||||||
|
|
||||||
accel.x = m_remote_orientation_x_value->value() >> 2;
|
u16 accel_x = (accel.x << 2) & (buttons.acc_x_lsb & 0b11);
|
||||||
accel.y = m_remote_orientation_y_value->value() >> 2;
|
u16 accel_y = (accel.y << 2) & ((buttons.acc_y_lsb & 0b1) << 1);
|
||||||
accel.z = m_remote_orientation_z_value->value() >> 2;
|
u16 accel_z = (accel.z << 2) & ((buttons.acc_z_lsb & 0b1) << 1);
|
||||||
|
|
||||||
buttons.acc_x_lsb = m_remote_orientation_x_value->value() & 0x3;
|
GetSpinBoxU16(m_remote_orientation_x_value, accel_x);
|
||||||
buttons.acc_y_lsb = m_remote_orientation_y_value->value() >> 1 & 0x1;
|
GetSpinBoxU16(m_remote_orientation_y_value, accel_y);
|
||||||
buttons.acc_z_lsb = m_remote_orientation_z_value->value() >> 1 & 0x1;
|
GetSpinBoxU16(m_remote_orientation_z_value, accel_z);
|
||||||
|
|
||||||
|
accel.x = accel_x >> 2;
|
||||||
|
accel.y = accel_y >> 2;
|
||||||
|
accel.z = accel_z >> 2;
|
||||||
|
|
||||||
|
buttons.acc_x_lsb = accel_x & 0b11;
|
||||||
|
buttons.acc_y_lsb = (accel_y >> 1) & 0b1;
|
||||||
|
buttons.acc_z_lsb = (accel_z >> 1) & 0b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ir_box->isVisible() && ir_data)
|
if (m_ir_box->isVisible() && ir_data && !m_use_controller->isChecked())
|
||||||
{
|
{
|
||||||
u16 y = m_ir_y_value->value();
|
u16 y = m_ir_y_value->value();
|
||||||
std::array<u16, 4> x;
|
std::array<u16, 4> x;
|
||||||
@ -429,19 +434,30 @@ void WiiTASInputWindow::GetValues(u8* report_data, WiimoteEmu::ReportFeatures rp
|
|||||||
if (ext_data && m_nunchuk_stick_box->isVisible())
|
if (ext_data && m_nunchuk_stick_box->isVisible())
|
||||||
{
|
{
|
||||||
wm_nc& nunchuk = *reinterpret_cast<wm_nc*>(ext_data);
|
wm_nc& nunchuk = *reinterpret_cast<wm_nc*>(ext_data);
|
||||||
nunchuk.jx = m_nunchuk_stick_x_value->value();
|
|
||||||
nunchuk.jy = m_nunchuk_stick_y_value->value();
|
|
||||||
|
|
||||||
nunchuk.ax = m_nunchuk_orientation_x_value->value() >> 2;
|
GetSpinBoxU8(m_nunchuk_stick_x_value, nunchuk.jx);
|
||||||
nunchuk.bt.acc_x_lsb = m_nunchuk_orientation_x_value->value() & 0x3;
|
GetSpinBoxU8(m_nunchuk_stick_y_value, nunchuk.jy);
|
||||||
nunchuk.ay = m_nunchuk_orientation_y_value->value() >> 2;
|
|
||||||
nunchuk.bt.acc_y_lsb = m_nunchuk_orientation_y_value->value() & 0x3;
|
|
||||||
nunchuk.az = m_nunchuk_orientation_z_value->value() >> 2;
|
|
||||||
nunchuk.bt.acc_z_lsb = m_nunchuk_orientation_z_value->value() & 0x3;
|
|
||||||
|
|
||||||
SetButton<u8>(m_c_button, &nunchuk.bt.hex, WiimoteEmu::Nunchuk::BUTTON_C);
|
u16 accel_x = nunchuk.ax << 2 & (nunchuk.bt.acc_x_lsb & 0b11);
|
||||||
SetButton<u8>(m_z_button, &nunchuk.bt.hex, WiimoteEmu::Nunchuk::BUTTON_Z);
|
u16 accel_y = nunchuk.ay << 2 & (nunchuk.bt.acc_y_lsb & 0b11);
|
||||||
nunchuk.bt.hex ^= 0x3;
|
u16 accel_z = nunchuk.az << 2 & (nunchuk.bt.acc_z_lsb & 0b11);
|
||||||
|
|
||||||
|
GetSpinBoxU16(m_nunchuk_orientation_x_value, accel_x);
|
||||||
|
GetSpinBoxU16(m_nunchuk_orientation_y_value, accel_y);
|
||||||
|
GetSpinBoxU16(m_nunchuk_orientation_z_value, accel_z);
|
||||||
|
|
||||||
|
nunchuk.ax = accel_x >> 2;
|
||||||
|
nunchuk.ay = accel_y >> 2;
|
||||||
|
nunchuk.az = accel_z >> 2;
|
||||||
|
|
||||||
|
nunchuk.bt.acc_x_lsb = accel_x & 0b11;
|
||||||
|
nunchuk.bt.acc_y_lsb = accel_y & 0b11;
|
||||||
|
nunchuk.bt.acc_z_lsb = accel_z & 0b11;
|
||||||
|
|
||||||
|
nunchuk.bt.hex ^= 0b11;
|
||||||
|
GetButton<u8>(m_c_button, nunchuk.bt.hex, WiimoteEmu::Nunchuk::BUTTON_C);
|
||||||
|
GetButton<u8>(m_z_button, nunchuk.bt.hex, WiimoteEmu::Nunchuk::BUTTON_Z);
|
||||||
|
nunchuk.bt.hex ^= 0b11;
|
||||||
|
|
||||||
WiimoteEncrypt(&key, reinterpret_cast<u8*>(&nunchuk), 0, sizeof(wm_nc));
|
WiimoteEncrypt(&key, reinterpret_cast<u8*>(&nunchuk), 0, sizeof(wm_nc));
|
||||||
}
|
}
|
||||||
@ -450,36 +466,51 @@ void WiiTASInputWindow::GetValues(u8* report_data, WiimoteEmu::ReportFeatures rp
|
|||||||
{
|
{
|
||||||
wm_classic_extension& cc = *reinterpret_cast<wm_classic_extension*>(ext_data);
|
wm_classic_extension& cc = *reinterpret_cast<wm_classic_extension*>(ext_data);
|
||||||
WiimoteDecrypt(&key, reinterpret_cast<u8*>(&cc), 0, sizeof(wm_classic_extension));
|
WiimoteDecrypt(&key, reinterpret_cast<u8*>(&cc), 0, sizeof(wm_classic_extension));
|
||||||
cc.bt.hex = 0;
|
|
||||||
|
|
||||||
SetButton<u16>(m_classic_a_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_A);
|
cc.bt.hex ^= 0xFFFF;
|
||||||
SetButton<u16>(m_classic_b_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_B);
|
GetButton<u16>(m_classic_a_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_A);
|
||||||
SetButton<u16>(m_classic_x_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_X);
|
GetButton<u16>(m_classic_b_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_B);
|
||||||
SetButton<u16>(m_classic_y_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_Y);
|
GetButton<u16>(m_classic_x_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_X);
|
||||||
SetButton<u16>(m_classic_plus_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_PLUS);
|
GetButton<u16>(m_classic_y_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_Y);
|
||||||
SetButton<u16>(m_classic_minus_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_MINUS);
|
GetButton<u16>(m_classic_plus_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_PLUS);
|
||||||
SetButton<u16>(m_classic_l_button, &cc.bt.hex, WiimoteEmu::Classic::TRIGGER_L);
|
GetButton<u16>(m_classic_minus_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_MINUS);
|
||||||
SetButton<u16>(m_classic_r_button, &cc.bt.hex, WiimoteEmu::Classic::TRIGGER_R);
|
GetButton<u16>(m_classic_l_button, cc.bt.hex, WiimoteEmu::Classic::TRIGGER_L);
|
||||||
SetButton<u16>(m_classic_zl_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_ZL);
|
GetButton<u16>(m_classic_r_button, cc.bt.hex, WiimoteEmu::Classic::TRIGGER_R);
|
||||||
SetButton<u16>(m_classic_zr_button, &cc.bt.hex, WiimoteEmu::Classic::BUTTON_ZR);
|
GetButton<u16>(m_classic_zl_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_ZL);
|
||||||
SetButton<u16>(m_classic_left_button, &cc.bt.hex, WiimoteEmu::Classic::PAD_LEFT);
|
GetButton<u16>(m_classic_zr_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_ZR);
|
||||||
SetButton<u16>(m_classic_up_button, &cc.bt.hex, WiimoteEmu::Classic::PAD_UP);
|
GetButton<u16>(m_classic_home_button, cc.bt.hex, WiimoteEmu::Classic::BUTTON_HOME);
|
||||||
SetButton<u16>(m_classic_down_button, &cc.bt.hex, WiimoteEmu::Classic::PAD_DOWN);
|
GetButton<u16>(m_classic_left_button, cc.bt.hex, WiimoteEmu::Classic::PAD_LEFT);
|
||||||
SetButton<u16>(m_classic_right_button, &cc.bt.hex, WiimoteEmu::Classic::PAD_RIGHT);
|
GetButton<u16>(m_classic_up_button, cc.bt.hex, WiimoteEmu::Classic::PAD_UP);
|
||||||
|
GetButton<u16>(m_classic_down_button, cc.bt.hex, WiimoteEmu::Classic::PAD_DOWN);
|
||||||
|
GetButton<u16>(m_classic_right_button, cc.bt.hex, WiimoteEmu::Classic::PAD_RIGHT);
|
||||||
cc.bt.hex ^= 0xFFFF;
|
cc.bt.hex ^= 0xFFFF;
|
||||||
|
|
||||||
u16 rx = m_classic_right_stick_x_value->value();
|
u8 rx = (cc.rx1 & 0b1) & ((cc.rx2 & 0b11) << 1) & ((cc.rx3 & 0b11) << 3);
|
||||||
cc.rx1 = rx & 0x1;
|
GetSpinBoxU8(m_classic_right_stick_x_value, rx);
|
||||||
cc.rx2 = (rx >> 1) & 0x3;
|
cc.rx1 = rx & 0b1;
|
||||||
cc.rx3 = (rx >> 3) & 0x3;
|
cc.rx2 = (rx >> 1) & 0b11;
|
||||||
cc.ry = m_classic_right_stick_y_value->value();
|
cc.rx3 = (rx >> 3) & 0b11;
|
||||||
|
|
||||||
cc.regular_data.lx = m_classic_left_stick_x_value->value();
|
u8 ry = cc.ry;
|
||||||
cc.regular_data.ly = m_classic_left_stick_y_value->value();
|
GetSpinBoxU8(m_classic_right_stick_y_value, ry);
|
||||||
|
cc.ry = ry;
|
||||||
|
|
||||||
cc.rt = m_right_trigger_value->value();
|
u8 lx = cc.regular_data.lx;
|
||||||
cc.lt1 = m_left_trigger_value->value() & 0x7;
|
GetSpinBoxU8(m_classic_left_stick_x_value, lx);
|
||||||
cc.lt2 = (m_left_trigger_value->value() >> 3) & 0x3;
|
cc.regular_data.lx = lx;
|
||||||
|
|
||||||
|
u8 ly = cc.regular_data.ly;
|
||||||
|
GetSpinBoxU8(m_classic_left_stick_y_value, ly);
|
||||||
|
cc.regular_data.ly = ly;
|
||||||
|
|
||||||
|
u8 rt = cc.rt;
|
||||||
|
GetSpinBoxU8(m_right_trigger_value, rt);
|
||||||
|
cc.rt = rt;
|
||||||
|
|
||||||
|
u8 lt = (cc.lt1 & 0b111) & (cc.lt2 >> 3);
|
||||||
|
GetSpinBoxU8(m_left_trigger_value, lt);
|
||||||
|
cc.lt1 = lt & 0b111;
|
||||||
|
cc.lt2 = (lt >> 3) & 0b11;
|
||||||
|
|
||||||
WiimoteEncrypt(&key, reinterpret_cast<u8*>(&cc), 0, sizeof(wm_classic_extension));
|
WiimoteEncrypt(&key, reinterpret_cast<u8*>(&cc), 0, sizeof(wm_classic_extension));
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDialog>
|
#include "DolphinQt/TAS/TASInputWindow.h"
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
|
||||||
|
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
@ -17,7 +15,7 @@ class QGroupBox;
|
|||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
struct wiimote_key;
|
struct wiimote_key;
|
||||||
|
|
||||||
class WiiTASInputWindow : public QDialog
|
class WiiTASInputWindow : public TASInputWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user