Qt/Mapping: Implement indicators
This commit is contained in:
parent
220e4bcd99
commit
ec54b421a4
|
@ -292,9 +292,6 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1
|
|||
m_extension->attachments.emplace_back(new WiimoteEmu::Drums(m_reg_ext));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::Turntable(m_reg_ext));
|
||||
|
||||
m_extension->boolean_settings.emplace_back(
|
||||
m_motion_plus_setting = new ControllerEmu::BooleanSetting(_trans("Motion Plus"), false));
|
||||
|
||||
// rumble
|
||||
groups.emplace_back(m_rumble = new ControllerEmu::ControlGroup(_trans("Rumble")));
|
||||
m_rumble->controls.emplace_back(m_motor = new ControllerEmu::Output(_trans("Motor")));
|
||||
|
|
|
@ -65,6 +65,7 @@ set(SRCS
|
|||
Config/Mapping/MappingBool.cpp
|
||||
Config/Mapping/MappingButton.cpp
|
||||
Config/Mapping/MappingCommon.cpp
|
||||
Config/Mapping/MappingIndicator.cpp
|
||||
Config/Mapping/MappingNumeric.cpp
|
||||
Config/Mapping/MappingWidget.cpp
|
||||
Config/Mapping/MappingWindow.cpp
|
||||
|
|
|
@ -35,6 +35,8 @@ MappingButton::MappingButton(MappingWidget* widget, ControlReference* ref, bool
|
|||
m_reference(ref)
|
||||
{
|
||||
Connect();
|
||||
setToolTip(
|
||||
tr("Left-click to detect input.\nMiddle-click to clear.\nRight-click for more options."));
|
||||
if (!m_reference->IsInput() || !indicator)
|
||||
return;
|
||||
|
||||
|
@ -116,6 +118,7 @@ void MappingButton::Clear()
|
|||
{
|
||||
m_reference->SetExpression("");
|
||||
m_parent->SaveSettings();
|
||||
Update();
|
||||
}
|
||||
|
||||
void MappingButton::Update()
|
||||
|
@ -136,7 +139,7 @@ void MappingButton::mouseReleaseEvent(QMouseEvent* event)
|
|||
else
|
||||
emit AdvancedPressed();
|
||||
return;
|
||||
case Qt::MouseButton::MiddleButton:
|
||||
case Qt::MouseButton::MidButton:
|
||||
Clear();
|
||||
return;
|
||||
case Qt::MouseButton::RightButton:
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt2/Config/Mapping/MappingIndicator.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "InputCommon/ControlReference/ControlReference.h"
|
||||
#include "InputCommon/ControllerEmu/Control/Control.h"
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
|
||||
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
|
||||
#include "InputCommon/ControllerInterface/Device.h"
|
||||
|
||||
#include "DolphinQt2/Settings.h"
|
||||
|
||||
MappingIndicator::MappingIndicator(ControllerEmu::ControlGroup* group) : m_group(group)
|
||||
{
|
||||
setMinimumHeight(128);
|
||||
|
||||
switch (m_group->type)
|
||||
{
|
||||
case ControllerEmu::GroupType::Cursor:
|
||||
BindCursorControls(false);
|
||||
break;
|
||||
case ControllerEmu::GroupType::Stick:
|
||||
BindStickControls();
|
||||
break;
|
||||
case ControllerEmu::GroupType::Tilt:
|
||||
BindCursorControls(true);
|
||||
break;
|
||||
case ControllerEmu::GroupType::MixedTriggers:
|
||||
BindMixedTriggersControls();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_timer = new QTimer(this);
|
||||
connect(m_timer, &QTimer::timeout, this, [this] { repaint(); });
|
||||
m_timer->start(1000 / 30);
|
||||
}
|
||||
|
||||
void MappingIndicator::BindCursorControls(bool tilt)
|
||||
{
|
||||
m_cursor_up = m_group->controls[0]->control_ref.get();
|
||||
m_cursor_down = m_group->controls[1]->control_ref.get();
|
||||
m_cursor_left = m_group->controls[2]->control_ref.get();
|
||||
m_cursor_right = m_group->controls[3]->control_ref.get();
|
||||
|
||||
if (!tilt)
|
||||
{
|
||||
m_cursor_forward = m_group->controls[4]->control_ref.get();
|
||||
m_cursor_backward = m_group->controls[5]->control_ref.get();
|
||||
|
||||
m_cursor_center = m_group->numeric_settings[0].get();
|
||||
m_cursor_width = m_group->numeric_settings[1].get();
|
||||
m_cursor_height = m_group->numeric_settings[2].get();
|
||||
m_cursor_deadzone = m_group->numeric_settings[3].get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursor_deadzone = m_group->numeric_settings[0].get();
|
||||
}
|
||||
}
|
||||
|
||||
void MappingIndicator::BindStickControls()
|
||||
{
|
||||
m_stick_up = m_group->controls[0]->control_ref.get();
|
||||
m_stick_down = m_group->controls[1]->control_ref.get();
|
||||
m_stick_left = m_group->controls[2]->control_ref.get();
|
||||
m_stick_right = m_group->controls[3]->control_ref.get();
|
||||
m_stick_modifier = m_group->controls[4]->control_ref.get();
|
||||
|
||||
m_stick_radius = m_group->numeric_settings[0].get();
|
||||
m_stick_deadzone = m_group->numeric_settings[1].get();
|
||||
}
|
||||
|
||||
void MappingIndicator::BindMixedTriggersControls()
|
||||
{
|
||||
m_mixed_triggers_l_button = m_group->controls[0]->control_ref.get();
|
||||
m_mixed_triggers_r_button = m_group->controls[1]->control_ref.get();
|
||||
m_mixed_triggers_l_analog = m_group->controls[2]->control_ref.get();
|
||||
m_mixed_triggers_r_analog = m_group->controls[3]->control_ref.get();
|
||||
|
||||
m_mixed_triggers_threshold = m_group->numeric_settings[0].get();
|
||||
}
|
||||
|
||||
static ControlState PollControlState(ControlReference* ref)
|
||||
{
|
||||
Settings::Instance().SetControllerStateNeeded(true);
|
||||
|
||||
auto state = ref->State();
|
||||
|
||||
Settings::Instance().SetControllerStateNeeded(false);
|
||||
|
||||
if (state != 0)
|
||||
return state;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MappingIndicator::DrawCursor(bool tilt)
|
||||
{
|
||||
float centerx = width() / 2., centery = height() / 2.;
|
||||
|
||||
QPainter p(this);
|
||||
|
||||
float width = 64, height = 64;
|
||||
float deadzone = m_cursor_deadzone->GetValue() * 48;
|
||||
|
||||
if (!tilt)
|
||||
{
|
||||
float depth = centery - PollControlState(m_cursor_forward) * this->height() / 2.5 +
|
||||
PollControlState(m_cursor_backward) * this->height() / 2.5;
|
||||
|
||||
p.fillRect(0, depth, this->width(), 4, Qt::gray);
|
||||
|
||||
width *= m_cursor_width->GetValue();
|
||||
height *= m_cursor_height->GetValue();
|
||||
}
|
||||
|
||||
float curx = centerx - 4 - std::min(PollControlState(m_cursor_left), 0.5) * width +
|
||||
std::min(PollControlState(m_cursor_right), 0.5) * width,
|
||||
cury = centery - 4 - std::min(PollControlState(m_cursor_up), 0.5) * height +
|
||||
std::min(PollControlState(m_cursor_down), 0.5) * height;
|
||||
|
||||
// Draw background
|
||||
p.setBrush(Qt::white);
|
||||
p.setPen(Qt::black);
|
||||
p.drawRect(centerx - (width / 2), centery - (height / 2), width, height);
|
||||
|
||||
// Draw deadzone
|
||||
p.setBrush(Qt::lightGray);
|
||||
p.drawEllipse(centerx - (deadzone / 2), centery - (deadzone / 2), deadzone, deadzone);
|
||||
|
||||
// Draw cursor
|
||||
p.fillRect(curx, cury, 8, 8, Qt::red);
|
||||
}
|
||||
|
||||
void MappingIndicator::DrawStick()
|
||||
{
|
||||
float centerx = width() / 2., centery = height() / 2.;
|
||||
|
||||
bool c_stick = m_group->name == "C-Stick";
|
||||
bool classic_controller = m_group->name == "Left Stick" || m_group->name == "Right Stick";
|
||||
|
||||
float ratio = 1;
|
||||
|
||||
if (c_stick)
|
||||
ratio = 1.;
|
||||
else if (classic_controller)
|
||||
ratio = 0.9f;
|
||||
|
||||
// Polled values
|
||||
float mod = PollControlState(m_stick_modifier) ? 0.5 : 1;
|
||||
float radius = m_stick_radius->GetValue();
|
||||
float curx = -PollControlState(m_stick_left) + PollControlState(m_stick_right),
|
||||
cury = -PollControlState(m_stick_up) + PollControlState(m_stick_down);
|
||||
// The maximum deadzone value covers 50% of the stick area
|
||||
float deadzone = m_stick_deadzone->GetValue() / 2.;
|
||||
|
||||
// Size parameters
|
||||
float max_size = (height() / 2.5) / ratio;
|
||||
float stick_size = (height() / 3.) / ratio;
|
||||
|
||||
// Emulated cursor position
|
||||
float virt_curx, virt_cury;
|
||||
|
||||
if (abs(curx) < deadzone && abs(cury) < deadzone)
|
||||
{
|
||||
virt_curx = virt_cury = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
virt_curx = curx * mod;
|
||||
virt_cury = cury * mod;
|
||||
}
|
||||
|
||||
// Coordinates for an octagon
|
||||
std::array<QPointF, 8> radius_octagon = {
|
||||
QPointF(centerx, centery + stick_size), // Bottom
|
||||
QPointF(centerx + stick_size / sqrt(2), centery + stick_size / sqrt(2)), // Bottom Right
|
||||
QPointF(centerx + stick_size, centery), // Right
|
||||
QPointF(centerx + stick_size / sqrt(2), centery - stick_size / sqrt(2)), // Top Right
|
||||
QPointF(centerx, centery - stick_size), // Top
|
||||
QPointF(centerx - stick_size / sqrt(2), centery - stick_size / sqrt(2)), // Top Left
|
||||
QPointF(centerx - stick_size, centery), // Left
|
||||
QPointF(centerx - stick_size / sqrt(2), centery + stick_size / sqrt(2)) // Bottom Left
|
||||
};
|
||||
|
||||
QPainter p(this);
|
||||
|
||||
// Draw maximum values
|
||||
p.setBrush(Qt::white);
|
||||
p.setPen(Qt::black);
|
||||
p.drawRect(centerx - max_size, centery - max_size, max_size * 2, max_size * 2);
|
||||
|
||||
// Draw radius
|
||||
p.setBrush(c_stick ? Qt::yellow : Qt::darkGray);
|
||||
p.drawPolygon(radius_octagon.data(), static_cast<int>(radius_octagon.size()));
|
||||
|
||||
// Draw deadzone
|
||||
p.setBrush(c_stick ? Qt::darkYellow : Qt::lightGray);
|
||||
p.drawEllipse(centerx - deadzone * stick_size, centery - deadzone * stick_size,
|
||||
deadzone * stick_size * 2, deadzone * stick_size * 2);
|
||||
|
||||
// Draw stick
|
||||
p.setBrush(Qt::black);
|
||||
p.drawEllipse(centerx - 4 + curx * max_size, centery - 4 + cury * max_size, 8, 8);
|
||||
|
||||
// Draw virtual stick
|
||||
p.setBrush(Qt::red);
|
||||
p.drawEllipse(centerx - 4 + virt_curx * max_size * radius,
|
||||
centery - 4 + virt_cury * max_size * radius, 8, 8);
|
||||
}
|
||||
|
||||
void MappingIndicator::DrawMixedTriggers()
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
// Polled values
|
||||
double r_analog = PollControlState(m_mixed_triggers_r_analog);
|
||||
double r_button = PollControlState(m_mixed_triggers_r_button);
|
||||
double l_analog = PollControlState(m_mixed_triggers_l_analog);
|
||||
double l_button = PollControlState(m_mixed_triggers_l_button);
|
||||
double threshold = m_mixed_triggers_threshold->GetValue();
|
||||
|
||||
double r_bar_percent = r_analog;
|
||||
double l_bar_percent = l_analog;
|
||||
|
||||
if (r_button && (r_button != r_analog) || (r_button == r_analog) && (r_analog > threshold))
|
||||
r_bar_percent = 1;
|
||||
else
|
||||
r_bar_percent *= 0.8;
|
||||
|
||||
if (l_button && (l_button != l_analog) || (l_button == l_analog) && (l_analog > threshold))
|
||||
l_bar_percent = 1;
|
||||
else
|
||||
l_bar_percent *= 0.8;
|
||||
|
||||
p.fillRect(0, 0, width(), 64, Qt::black);
|
||||
|
||||
p.fillRect(0, 0, l_bar_percent * width(), 32, Qt::red);
|
||||
p.fillRect(0, 32, r_bar_percent * width(), 32, Qt::red);
|
||||
|
||||
p.setPen(Qt::white);
|
||||
p.drawLine(width() * 0.8, 0, width() * 0.8, 63);
|
||||
p.drawLine(0, 32, width(), 32);
|
||||
|
||||
p.setPen(Qt::green);
|
||||
p.drawLine(width() * 0.8 * threshold, 0, width() * 0.8 * threshold, 63);
|
||||
|
||||
p.setBrush(Qt::black);
|
||||
p.setPen(Qt::white);
|
||||
p.drawText(width() * 0.225, 16, tr("L-Analog"));
|
||||
p.drawText(width() * 0.8 + 16, 16, tr("L"));
|
||||
p.drawText(width() * 0.225, 48, tr("R-Analog"));
|
||||
p.drawText(width() * 0.8 + 16, 48, tr("R"));
|
||||
}
|
||||
|
||||
void MappingIndicator::paintEvent(QPaintEvent*)
|
||||
{
|
||||
switch (m_group->type)
|
||||
{
|
||||
case ControllerEmu::GroupType::Cursor:
|
||||
DrawCursor(false);
|
||||
break;
|
||||
case ControllerEmu::GroupType::Tilt:
|
||||
DrawCursor(true);
|
||||
break;
|
||||
case ControllerEmu::GroupType::Stick:
|
||||
DrawStick();
|
||||
break;
|
||||
case ControllerEmu::GroupType::MixedTriggers:
|
||||
DrawMixedTriggers();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace ControllerEmu
|
||||
{
|
||||
class Control;
|
||||
class ControlGroup;
|
||||
class NumericSetting;
|
||||
}
|
||||
|
||||
class QPaintEvent;
|
||||
class QTimer;
|
||||
|
||||
class ControlReference;
|
||||
|
||||
class MappingIndicator : public QWidget
|
||||
{
|
||||
public:
|
||||
explicit MappingIndicator(ControllerEmu::ControlGroup* group);
|
||||
|
||||
private:
|
||||
void BindCursorControls(bool tilt);
|
||||
void BindStickControls();
|
||||
void BindMixedTriggersControls();
|
||||
|
||||
void DrawCursor(bool tilt);
|
||||
void DrawStick();
|
||||
void DrawMixedTriggers();
|
||||
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
ControllerEmu::ControlGroup* m_group;
|
||||
|
||||
// Stick settings
|
||||
ControlReference* m_stick_up;
|
||||
ControlReference* m_stick_down;
|
||||
ControlReference* m_stick_left;
|
||||
ControlReference* m_stick_right;
|
||||
ControlReference* m_stick_modifier;
|
||||
|
||||
ControllerEmu::NumericSetting* m_stick_radius;
|
||||
ControllerEmu::NumericSetting* m_stick_deadzone;
|
||||
|
||||
// Cursor settings
|
||||
ControlReference* m_cursor_up;
|
||||
ControlReference* m_cursor_down;
|
||||
ControlReference* m_cursor_left;
|
||||
ControlReference* m_cursor_right;
|
||||
ControlReference* m_cursor_forward;
|
||||
ControlReference* m_cursor_backward;
|
||||
|
||||
ControllerEmu::NumericSetting* m_cursor_center;
|
||||
ControllerEmu::NumericSetting* m_cursor_width;
|
||||
ControllerEmu::NumericSetting* m_cursor_height;
|
||||
ControllerEmu::NumericSetting* m_cursor_deadzone;
|
||||
|
||||
// Triggers settings
|
||||
ControlReference* m_mixed_triggers_r_analog;
|
||||
ControlReference* m_mixed_triggers_r_button;
|
||||
ControlReference* m_mixed_triggers_l_analog;
|
||||
ControlReference* m_mixed_triggers_l_button;
|
||||
|
||||
ControllerEmu::NumericSetting* m_mixed_triggers_threshold;
|
||||
|
||||
QTimer* m_timer;
|
||||
};
|
|
@ -11,6 +11,7 @@
|
|||
#include "DolphinQt2/Config/Mapping/IOWindow.h"
|
||||
#include "DolphinQt2/Config/Mapping/MappingBool.h"
|
||||
#include "DolphinQt2/Config/Mapping/MappingButton.h"
|
||||
#include "DolphinQt2/Config/Mapping/MappingIndicator.h"
|
||||
#include "DolphinQt2/Config/Mapping/MappingNumeric.h"
|
||||
#include "DolphinQt2/Config/Mapping/MappingWindow.h"
|
||||
#include "InputCommon/ControlReference/ControlReference.h"
|
||||
|
@ -49,7 +50,8 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con
|
|||
|
||||
bool need_indicator = group->type == ControllerEmu::GroupType::Cursor ||
|
||||
group->type == ControllerEmu::GroupType::Stick ||
|
||||
group->type == ControllerEmu::GroupType::Tilt;
|
||||
group->type == ControllerEmu::GroupType::Tilt ||
|
||||
group->type == ControllerEmu::GroupType::MixedTriggers;
|
||||
|
||||
for (auto& control : group->controls)
|
||||
{
|
||||
|
|
|
@ -205,6 +205,7 @@
|
|||
<ClCompile Include="Config\Mapping\MappingBool.cpp" />
|
||||
<ClCompile Include="Config\Mapping\MappingButton.cpp" />
|
||||
<ClCompile Include="Config\Mapping\MappingCommon.cpp" />
|
||||
<ClCompile Include="Config\Mapping\MappingIndicator.cpp" />
|
||||
<ClCompile Include="Config\Mapping\MappingNumeric.cpp" />
|
||||
<ClCompile Include="Config\Mapping\MappingWidget.cpp" />
|
||||
<ClCompile Include="Config\Mapping\MappingWindow.cpp" />
|
||||
|
@ -272,6 +273,7 @@
|
|||
<ClInclude Include="Config\Mapping\HotkeyWii.h" />
|
||||
<ClInclude Include="Config\Mapping\MappingBool.h" />
|
||||
<ClInclude Include="Config\Mapping\MappingCommon.h" />
|
||||
<ClInclude Include="Config\Mapping\MappingIndicator.h" />
|
||||
<ClInclude Include="Config\Mapping\MappingNumeric.h" />
|
||||
<ClInclude Include="Config\Mapping\WiimoteEmuExtension.h" />
|
||||
<ClInclude Include="Config\Mapping\WiimoteEmuGeneral.h" />
|
||||
|
|
Loading…
Reference in New Issue