diff options
| author | spycrab <spycrab@users.noreply.github.com> | 2018-07-07 00:40:15 +0200 |
|---|---|---|
| committer | spycrab <spycrab@users.noreply.github.com> | 2018-07-07 00:48:38 +0200 |
| commit | 13ba24c5a6795532c8893eccf2a21ae95682e1b7 (patch) | |
| tree | 747e394036c189c46add1b3e1451e50f48230e11 /Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp | |
| parent | 059880bb1640d5a3b0e1fbbf66e1a356df4b9f41 (diff) | |
Move DolphinQt2 to DolphinQt
Diffstat (limited to 'Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp')
| -rw-r--r-- | Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp new file mode 100644 index 0000000000..5416b4fd2f --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -0,0 +1,292 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Config/Mapping/MappingIndicator.h" + +#include <array> +#include <cmath> + +#include <QPainter> +#include <QTimer> + +#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 "DolphinQt/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); + p.setRenderHint(QPainter::Antialiasing, true); + p.setRenderHint(QPainter::SmoothPixmapTransform, true); + + 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 (std::abs(curx) < deadzone && std::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); + p.setRenderHint(QPainter::Antialiasing, true); + p.setRenderHint(QPainter::SmoothPixmapTransform, true); + + // 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); + p.setRenderHint(QPainter::Antialiasing, true); + p.setRenderHint(QPainter::TextAntialiasing, true); + p.setRenderHint(QPainter::SmoothPixmapTransform, true); + + // 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, 20, tr("L-Analog")); + p.drawText(width() * 0.8 + 16, 20, tr("L")); + p.drawText(width() * 0.225, 52, tr("R-Analog")); + p.drawText(width() * 0.8 + 16, 52, 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; + } +} |
