From baa567a60d5cd321c48f372e87d1001f3ba97773 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Wed, 3 Feb 2021 23:00:31 +0100 Subject: [PATCH] early-access version 1409 --- README.md | 2 +- src/core/hle/kernel/k_resource_limit.h | 10 +- src/core/hle/kernel/k_thread.cpp | 2 +- src/core/hle/kernel/kernel.cpp | 16 +- src/core/hle/kernel/memory/page_table.cpp | 11 +- src/core/hle/kernel/process.cpp | 18 +- src/core/hle/kernel/svc.cpp | 8 +- src/core/settings.h | 5 +- src/input_common/analog_from_button.cpp | 4 + src/input_common/mouse/mouse_input.cpp | 16 +- src/input_common/mouse/mouse_input.h | 4 +- src/input_common/mouse/mouse_poller.cpp | 13 +- src/yuzu/bootmanager.cpp | 14 +- src/yuzu/configuration/config.cpp | 10 +- src/yuzu/configuration/config.h | 2 +- .../configure_input_advanced.cpp | 5 + .../configuration/configure_input_advanced.ui | 79 ++- .../configure_input_player_widget.cpp | 459 ++++++++++-------- .../configure_input_player_widget.h | 8 +- src/yuzu/main.cpp | 15 +- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 3 +- 21 files changed, 435 insertions(+), 269 deletions(-) diff --git a/README.md b/README.md index 0cd66893d..5b7708e13 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1408. +This is the source code for early-access 1409. ## Legal Notice diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 6b3437ea6..58ae456f1 100755 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h @@ -22,11 +22,11 @@ class System; namespace Kernel { class KernelCore; enum class LimitableResource : u32 { - PhysicalMemoryMax = 0, - ThreadCountMax = 1, - EventCountMax = 2, - TransferMemoryCountMax = 3, - SessionCountMax = 4, + PhysicalMemory = 0, + Threads = 1, + Events = 2, + TransferMemory = 3, + Sessions = 4, Count, }; diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 38fd8e500..b59259c4f 100755 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -247,7 +247,7 @@ void KThread::Finalize() { // Decrement the parent process's thread count. if (parent != nullptr) { parent->DecrementThreadCount(); - parent->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1); + parent->GetResourceLimit()->Release(LimitableResource::Threads, 1); } } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index c66a993c2..b20c2d13a 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -135,19 +135,15 @@ struct KernelCore::Impl { system_resource_limit = std::make_shared(kernel, system); // If setting the default system values fails, then something seriously wrong has occurred. - ASSERT( - system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, 0x100000000) - .IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800) + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) .IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700) - .IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200) - .IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 900) + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) .IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 900).IsSuccess()); - if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, 0x60000)) { + if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 0x60000)) { UNREACHABLE(); } } diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index d8c7d980a..7de91c768 100755 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -413,8 +413,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { const std::size_t remaining_size{size - mapped_size}; const std::size_t remaining_pages{remaining_size / PageSize}; - if (process->GetResourceLimit() && !process->GetResourceLimit()->Reserve( - LimitableResource::PhysicalMemoryMax, remaining_size)) { + if (process->GetResourceLimit() && + !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, remaining_size)) { return ERR_RESOURCE_LIMIT_EXCEEDED; } @@ -422,8 +422,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { { auto block_guard = detail::ScopeExit([&] { system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); - process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, - remaining_size); + process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, remaining_size); }); CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, @@ -475,7 +474,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { CASCADE_CODE(UnmapMemory(addr, size)); auto process{system.Kernel().CurrentProcess()}; - process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, mapped_size); + process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size); physical_memory_usage -= mapped_size; return RESULT_SUCCESS; @@ -784,7 +783,7 @@ ResultVal PageTable::SetHeapSize(std::size_t size) { auto process{system.Kernel().CurrentProcess()}; if (process->GetResourceLimit() && delta != 0 && - !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, delta)) { + !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, delta)) { return ERR_RESOURCE_LIMIT_EXCEEDED; } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 9efcb95f3..afdb27c54 100755 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -154,7 +154,7 @@ void Process::DecrementThreadCount() { } u64 Process::GetTotalPhysicalMemoryAvailable() const { - const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemoryMax) + + const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + main_thread_stack_size}; @@ -308,13 +308,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, // Set initial resource limits resource_limit->SetLimitValue( - LimitableResource::PhysicalMemoryMax, + LimitableResource::PhysicalMemory, kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); - resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 608); - resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700); - resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 128); - resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 894); - ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, code_size)); + resource_limit->SetLimitValue(LimitableResource::Threads, 608); + resource_limit->SetLimitValue(LimitableResource::Events, 700); + resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); + resource_limit->SetLimitValue(LimitableResource::Sessions, 894); + ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemory, code_size)); // Create TLS region tls_region_address = CreateTLSRegion(); @@ -331,8 +331,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { ChangeStatus(ProcessStatus::Running); SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); - resource_limit->Reserve(LimitableResource::ThreadCountMax, 1); - resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, main_thread_stack_size); + resource_limit->Reserve(LimitableResource::Threads, 1); + resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); } void Process::PrepareForTermination() { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index d89873104..74eb90100 100755 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -312,8 +312,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, return ERR_NOT_FOUND; } - ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::SessionCountMax, - 1)); + ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::Sessions, 1)); auto client_port = it->second; @@ -1451,9 +1450,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e Svc::ResultInvalidPriority); R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); - ASSERT(process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1, - system.CoreTiming().GetGlobalTimeNs().count() + - 100000000)); + ASSERT(process.GetResourceLimit()->Reserve( + LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000)); std::shared_ptr thread; { diff --git a/src/core/settings.h b/src/core/settings.h index a324530bd..2fbdc6ec7 100755 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -181,12 +181,13 @@ struct Values { std::string motion_device; std::string udp_input_servers; - bool emulate_analog_keyboard; - + bool mouse_panning; bool mouse_enabled; + float mouse_panning_sensitivity; std::string mouse_device; MouseButtonsRaw mouse_buttons; + bool emulate_analog_keyboard; bool keyboard_enabled; KeyboardKeysRaw keyboard_keys; KeyboardModsRaw keyboard_mods; diff --git a/src/input_common/analog_from_button.cpp b/src/input_common/analog_from_button.cpp index 07a0fa4a1..770893687 100755 --- a/src/input_common/analog_from_button.cpp +++ b/src/input_common/analog_from_button.cpp @@ -139,6 +139,10 @@ public: static_cast(y) * coef * (x == 0 ? 1.0f : SQRT_HALF)); } + Input::AnalogProperties GetAnalogProperties() const override { + return {modifier_scale, 1.0f, 0.5f}; + } + bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override { switch (direction) { case Input::AnalogDirection::RIGHT: diff --git a/src/input_common/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp index 10786a541..3cdf7b7f1 100755 --- a/src/input_common/mouse/mouse_input.cpp +++ b/src/input_common/mouse/mouse_input.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include "core/settings.h" #include "input_common/mouse/mouse_input.h" namespace MouseInput { @@ -65,8 +66,21 @@ void Mouse::PressButton(int x, int y, int button_) { mouse_info[button_index].data.pressed = true; } -void Mouse::MouseMove(int x, int y) { +void Mouse::MouseMove(int x, int y, int center_x, int center_y) { for (MouseInfo& info : mouse_info) { + if (Settings::values.mouse_panning) { + const auto mouse_change = Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y); + info.data.axis = {mouse_change.x, -mouse_change.y}; + + if (mouse_change.x == 0 && mouse_change.y == 0) { + info.tilt_speed = 0; + } else { + info.tilt_direction = mouse_change.Cast(); + info.tilt_speed = info.tilt_direction.Normalize() * info.sensitivity; + } + continue; + } + if (info.data.pressed) { const auto mouse_move = Common::MakeVec(x, y) - info.mouse_origin; const auto mouse_change = Common::MakeVec(x, y) - info.last_mouse_position; diff --git a/src/input_common/mouse/mouse_input.h b/src/input_common/mouse/mouse_input.h index 58803c1bf..ad852f27a 100755 --- a/src/input_common/mouse/mouse_input.h +++ b/src/input_common/mouse/mouse_input.h @@ -57,8 +57,10 @@ public: * Signals that mouse has moved. * @param x the x-coordinate of the cursor * @param y the y-coordinate of the cursor + * @param center_x the x-coordinate of the middle of the screen + * @param center_y the y-coordinate of the middle of the screen */ - void MouseMove(int x, int y); + void MouseMove(int x, int y, int center_x, int center_y); /** * Signals that a motion sensor tilt has ended. diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp index 508eb0c7d..bb56787ee 100755 --- a/src/input_common/mouse/mouse_poller.cpp +++ b/src/input_common/mouse/mouse_poller.cpp @@ -6,6 +6,7 @@ #include #include "common/threadsafe_queue.h" +#include "core/settings.h" #include "input_common/mouse/mouse_input.h" #include "input_common/mouse/mouse_poller.h" @@ -71,7 +72,7 @@ public: std::lock_guard lock{mutex}; const auto axis_value = static_cast(mouse_input->GetMouseState(button).axis.at(axis)); - return axis_value / (100.0f * range); + return axis_value * Settings::values.mouse_panning_sensitivity / (100.0f * range); } std::pair GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { @@ -106,6 +107,16 @@ public: return {0.0f, 0.0f}; } + std::tuple GetRawStatus() const override { + const float x = GetAxis(axis_x); + const float y = GetAxis(axis_y); + return {x, y}; + } + + Input::AnalogProperties GetAnalogProperties() const override { + return {deadzone, range, 0.5f}; + } + private: const u32 button; const u32 axis_x; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 5bb55bc45..e1085c0dd 100755 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -405,12 +405,17 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { if (event->source() == Qt::MouseEventSynthesizedBySystem) { return; } - auto pos = event->pos(); const auto [x, y] = ScaleTouch(pos); - input_subsystem->GetMouse()->MouseMove(x, y); + const int center_x = width() / 2; + const int center_y = height() / 2; + input_subsystem->GetMouse()->MouseMove(x, y, center_x, center_y); this->TouchMoved(x, y, 0); + if (Settings::values.mouse_panning) { + QCursor::setPos(mapToGlobal({center_x, center_y})); + } + emit MouseActivity(); } @@ -727,6 +732,11 @@ void GRenderWindow::showEvent(QShowEvent* event) { bool GRenderWindow::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::HoverMove) { + if (Settings::values.mouse_panning) { + auto* hover_event = static_cast(event); + mouseMoveEvent(hover_event); + return false; + } emit MouseActivity(); } return false; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index e8f4afcd9..82409c7d2 100755 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -220,7 +220,7 @@ const std::array Config::default // This must be in alphabetical order according to action name as it must have the same order as // UISetting::values.shortcuts, which is alphabetically ordered. // clang-format off -const std::array Config::default_hotkeys{{ +const std::array Config::default_hotkeys{{ {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::WidgetWithChildrenShortcut}}, {QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}}, {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}}, @@ -237,6 +237,7 @@ const std::array Config::default_hotkeys{{ {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}}, + {QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::ApplicationShortcut}}, }}; // clang-format on @@ -507,6 +508,9 @@ void Config::ReadControlValues() { Settings::values.emulate_analog_keyboard = ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool(); + Settings::values.mouse_panning = ReadSetting(QStringLiteral("mouse_panning"), false).toBool(); + Settings::values.mouse_panning_sensitivity = + ReadSetting(QStringLiteral("mouse_panning_sensitivity"), 16).toFloat(); ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), true); ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"), @@ -1184,7 +1188,9 @@ void Config::SaveControlValues() { WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false); WriteSetting(QStringLiteral("emulate_analog_keyboard"), Settings::values.emulate_analog_keyboard, false); - + WriteSetting(QStringLiteral("mouse_panning"), Settings::values.mouse_panning, false); + WriteSetting(QStringLiteral("mouse_panning_sensitivity"), + Settings::values.mouse_panning_sensitivity, 16.0f); qt_config->endGroup(); } diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 8a600e19d..949c4eb13 100755 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -42,7 +42,7 @@ public: default_mouse_buttons; static const std::array default_keyboard_keys; static const std::array default_keyboard_mods; - static const std::array default_hotkeys; + static const std::array default_hotkeys; private: void Initialize(const std::string& config_name); diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 4e557bc6f..a1a0eb676 100755 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -122,6 +122,9 @@ void ConfigureInputAdvanced::ApplyConfiguration() { Settings::values.mouse_enabled = ui->mouse_enabled->isChecked(); Settings::values.keyboard_enabled = ui->keyboard_enabled->isChecked(); Settings::values.emulate_analog_keyboard = ui->emulate_analog_keyboard->isChecked(); + Settings::values.mouse_panning = ui->mouse_panning->isChecked(); + Settings::values.mouse_panning_sensitivity = + static_cast(ui->mouse_panning_sensitivity->value()); Settings::values.touchscreen.enabled = ui->touchscreen_enabled->isChecked(); } @@ -149,6 +152,8 @@ void ConfigureInputAdvanced::LoadConfiguration() { ui->mouse_enabled->setChecked(Settings::values.mouse_enabled); ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled); ui->emulate_analog_keyboard->setChecked(Settings::values.emulate_analog_keyboard); + ui->mouse_panning->setChecked(Settings::values.mouse_panning); + ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity); ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled); UpdateUIEnabled(); diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index f207e5d3b..25b6df26c 100755 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2546,27 +2546,62 @@ - - - - - 0 - 23 - - - - Emulate Analog with Keyboard Input - - - - + + + + + 0 + 23 + + + + Emulate Analog with Keyboard Input + + + + + + + + 0 + 23 + + + + Enable mouse panning + + + + + + + Qt::AlignCenter + + + 1 + + + 0.100000000000000 + + + 32.000000000000000 + + + 0.100000000000000 + + + 16.000000000000000 + + + + Advanced - + Qt::Horizontal @@ -2582,21 +2617,21 @@ - + Advanced - + Touchscreen - + @@ -2609,28 +2644,28 @@ - + Motion / Touch - + Configure - + Debug Controller - + Configure diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index 77d7569fe..1e3251547 100755 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp @@ -11,10 +11,10 @@ PlayerControlPreview::PlayerControlPreview(QWidget* parent) : QFrame(parent) { UpdateColors(); QTimer* timer = new QTimer(this); - connect(timer, &QTimer::timeout, this, QOverload<>::of(&PlayerControlPreview::update)); + connect(timer, &QTimer::timeout, this, QOverload<>::of(&PlayerControlPreview::UpdateInput)); - // refresh at 40hz - timer->start(25); + // refresh at 60hz + timer->start(16); } PlayerControlPreview::~PlayerControlPreview() = default; @@ -155,12 +155,8 @@ void PlayerControlPreview::UpdateColors() { // colors.right = QColor(Settings::values.players.GetValue()[player_index].body_color_right); } -void PlayerControlPreview::paintEvent(QPaintEvent* event) { - QFrame::paintEvent(event); - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - const QPointF center = rect().center(); - +void PlayerControlPreview::UpdateInput() { + bool input_changed = false; const auto& button_state = buttons; for (std::size_t index = 0; index < button_values.size(); ++index) { bool value = false; @@ -169,7 +165,10 @@ void PlayerControlPreview::paintEvent(QPaintEvent* event) { } bool blink = mapping_active && index == button_mapping_index; if (analog_mapping_index == Settings::NativeAnalog::NUM_STICKS_HID) { - blink &= blink_counter > 12; + blink &= blink_counter > 25; + } + if (button_values[index] != value || blink) { + input_changed = true; } button_values[index] = value || blink; } @@ -178,17 +177,42 @@ void PlayerControlPreview::paintEvent(QPaintEvent* event) { for (std::size_t index = 0; index < axis_values.size(); ++index) { const auto [stick_x_f, stick_y_f] = analog_state[index]->GetStatus(); const auto [stick_x_rf, stick_y_rf] = analog_state[index]->GetRawStatus(); + + if (static_cast(stick_x_rf * 45) != + static_cast(axis_values[index].raw_value.x() * 45) || + static_cast(-stick_y_rf * 45) != + static_cast(axis_values[index].raw_value.y() * 45)) { + input_changed = true; + } + axis_values[index].properties = analog_state[index]->GetAnalogProperties(); axis_values[index].value = QPointF(stick_x_f, -stick_y_f); axis_values[index].raw_value = QPointF(stick_x_rf, -stick_y_rf); const bool blink_analog = mapping_active && index == analog_mapping_index; if (blink_analog) { + input_changed = true; axis_values[index].value = - QPointF(blink_counter < 12 ? -blink_counter / 12.0f : 0, - blink_counter > 12 ? -(blink_counter - 12) / 12.0f : 0); + QPointF(blink_counter < 25 ? -blink_counter / 25.0f : 0, + blink_counter > 25 ? -(blink_counter - 25) / 25.0f : 0); } } + + if (input_changed) { + update(); + } + + if (mapping_active) { + blink_counter = (blink_counter + 1) % 50; + } +} + +void PlayerControlPreview::paintEvent(QPaintEvent* event) { + QFrame::paintEvent(event); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + const QPointF center = rect().center(); + switch (controller_type) { case Settings::ControllerType::Handheld: DrawHandheldController(p, center); @@ -207,9 +231,6 @@ void PlayerControlPreview::paintEvent(QPaintEvent* event) { DrawProController(p, center); break; } - if (mapping_active) { - blink_counter = (blink_counter + 1) % 24; - } } void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center) { @@ -272,7 +293,7 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center) using namespace Settings::NativeAnalog; DrawJoystick(p, center + QPointF(9, -69) + (axis_values[LStick].value * 8), 1.8f, button_values[Settings::NativeButton::LStick]); - DrawRawJoystick(p, center + QPointF(-140, 100), axis_values[LStick].raw_value, + DrawRawJoystick(p, center + QPointF(-140, 90), axis_values[LStick].raw_value, axis_values[LStick].properties); } @@ -307,12 +328,10 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center) DrawRoundButton(p, center + QPoint(155, -69), button_values[SL], 5.2f, 12, Direction::None, 4); // SR and SL text - SetTextFont(p, 5.7f); - p.setPen(colors.outline); - p.rotate(90); - p.drawText(QPointF(center.y() - 5, -center.x() + 3) + QPointF(52, -155), tr("SR")); - p.drawText(QPointF(center.y() - 5, -center.x() + 3) + QPointF(-69, -155), tr("SL")); - p.rotate(-90); + p.setPen(colors.transparent); + p.setBrush(colors.font2); + DrawSymbol(p, center + QPointF(155, 52), Symbol::SR, 1.0f); + DrawSymbol(p, center + QPointF(155, -69), Symbol::SL, 1.0f); // Minus button button_color = colors.button; @@ -388,7 +407,7 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center using namespace Settings::NativeAnalog; DrawJoystick(p, center + QPointF(-9, 11) + (axis_values[RStick].value * 8), 1.8f, button_values[Settings::NativeButton::RStick]); - DrawRawJoystick(p, center + QPointF(140, 100), axis_values[RStick].raw_value, + DrawRawJoystick(p, center + QPointF(140, 90), axis_values[RStick].raw_value, axis_values[RStick].properties); } @@ -423,12 +442,12 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center DrawRoundButton(p, center + QPoint(-155, -69), button_values[SR], 5, 12, Direction::None, 4.0f); // SR and SL text - SetTextFont(p, 5.7f); - p.setPen(colors.outline); - p.rotate(-90); - p.drawText(QPointF(-center.y() - 5, center.x() + 3) + QPointF(-52, -155), tr("SL")); - p.drawText(QPointF(-center.y() - 5, center.x() + 3) + QPointF(69, -155), tr("SR")); - p.rotate(90); + p.setPen(colors.transparent); + p.setBrush(colors.font2); + p.rotate(-180); + DrawSymbol(p, QPointF(-center.x(), -center.y()) + QPointF(155, 69), Symbol::SR, 1.0f); + DrawSymbol(p, QPointF(-center.x(), -center.y()) + QPointF(155, -52), Symbol::SL, 1.0f); + p.rotate(180); // Plus Button DrawPlusButton(p, center + QPoint(-40, -118), button_values[Plus], 16); @@ -448,64 +467,60 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center) { using namespace Settings::NativeButton; - // Sideview joystick - DrawJoystickSideview(p, center + QPoint(-174, -65), - -axis_values[Settings::NativeAnalog::LStick].value.y(), 1.0f, - button_values[LStick]); - DrawJoystickSideview(p, center + QPoint(174, 12), - axis_values[Settings::NativeAnalog::RStick].value.y() + 10.0f, 1.0f, - button_values[RStick]); - // Left/Right trigger DrawDualTriggers(p, center, button_values[L], button_values[R]); - DrawDualZTriggers(p, center, button_values[ZL], button_values[ZR]); - // sideview Left and Right trigger + // Topview face buttons p.setPen(colors.outline); button_color = colors.button; - DrawRoundButton(p, center + QPoint(-166, -131), button_values[L], 7, 4, Direction::Down); - DrawRoundButton(p, center + QPoint(166, -131), button_values[R], 7, 4, Direction::Down); + DrawRoundButton(p, center + QPoint(200, -71), button_values[A], 10, 5, Direction::Up); + DrawRoundButton(p, center + QPoint(160, -71), button_values[Y], 10, 5, Direction::Up); - // Sideview face buttons - DrawRoundButton(p, center + QPoint(180, -65), button_values[A], 5, 10, Direction::Left); - DrawRoundButton(p, center + QPoint(180, -45), button_values[B], 5, 10, Direction::Left); - DrawRoundButton(p, center + QPoint(180, -85), button_values[X], 5, 10, Direction::Left); - DrawRoundButton(p, center + QPoint(180, -65), button_values[Y], 5, 10, Direction::Left); + // Topview right joystick + DrawJoystickSideview(p, center + QPointF(180, -78), + -axis_values[Settings::NativeAnalog::RStick].value.x() + 15.0f, 1, + button_values[RStick]); - // Sideview D-pad buttons - DrawRoundButton(p, center + QPoint(-180, 12), button_values[DLeft], 5, 10, - Direction::Right); - DrawRoundButton(p, center + QPoint(-180, 33), button_values[DDown], 5, 10, - Direction::Right); - DrawRoundButton(p, center + QPoint(-180, -8), button_values[DUp], 5, 10, Direction::Right); - DrawRoundButton(p, center + QPoint(-180, 12), button_values[DRight], 5, 10, - Direction::Right); - - // Sideview home and plus button - DrawRoundButton(p, center + QPoint(180, 60), button_values[Home], 3, 11, Direction::Left); - DrawRoundButton(p, center + QPoint(180, -106), button_values[Plus], 4, 7, Direction::Left, + // Topview plus button + p.setPen(colors.outline); + button_color = colors.button; + DrawRoundButton(p, center + QPoint(154, -72), button_values[Plus], 7, 4, Direction::Up, 1); + DrawRoundButton(p, center + QPoint(154, -72), button_values[Plus], 2.33f, 4, Direction::Up, 1); - DrawRoundButton(p, center + QPoint(180, -106), button_values[Plus], 4, 2.33f, - Direction::Left, 1); - // Sideview screenshot and minus button - DrawRoundButton(p, center + QPoint(-180, 63), button_values[Screenshot], 3, 8, - Direction::Right, 1); - DrawRoundButton(p, center + QPoint(-180, -106), button_values[Minus], 4, 2.66f, - Direction::Right, 1); + // Topview D-pad buttons + p.setPen(colors.outline); + button_color = colors.button; + DrawRoundButton(p, center + QPoint(-200, -71), button_values[DLeft], 10, 5, Direction::Up); + DrawRoundButton(p, center + QPoint(-160, -71), button_values[DRight], 10, 5, Direction::Up); + + // Topview left joystick + DrawJoystickSideview(p, center + QPointF(-180.5f, -78), + -axis_values[Settings::NativeAnalog::LStick].value.x() + 15.0f, 1, + button_values[LStick]); + + // Topview minus button + p.setPen(colors.outline); + button_color = colors.button; + DrawRoundButton(p, center + QPoint(-154, -72), button_values[Minus], 7, 4, Direction::Up, + 1); + + DrawDualBody(p, center); + + // Right trigger top view + DrawDualTriggersTopView(p, center, button_values[L], button_values[R]); + DrawDualZTriggersTopView(p, center, button_values[ZL], button_values[ZR]); } - DrawDualBody(p, center); - { // Draw joysticks using namespace Settings::NativeAnalog; DrawJoystick(p, center + QPointF(-65, -65) + (axis_values[LStick].value * 7), 1.62f, button_values[Settings::NativeButton::LStick]); DrawJoystick(p, center + QPointF(65, 12) + (axis_values[RStick].value * 7), 1.62f, button_values[Settings::NativeButton::RStick]); - DrawRawJoystick(p, rect().bottomLeft() + QPointF(45, -45), axis_values[LStick].raw_value, + DrawRawJoystick(p, center + QPointF(-180, 90), axis_values[LStick].raw_value, axis_values[LStick].properties); - DrawRawJoystick(p, rect().bottomRight() + QPointF(-45, -45), axis_values[RStick].raw_value, + DrawRawJoystick(p, center + QPointF(180, 90), axis_values[RStick].raw_value, axis_values[RStick].properties); } @@ -598,7 +613,7 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen // Face buttons constants const QPointF face_center = center + QPoint(171, -41); - constexpr float face_distance = 12.8; + constexpr float face_distance = 12.8f; constexpr float face_radius = 6.4f; constexpr float text_size = 0.6f; @@ -620,7 +635,7 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen // D-pad constants const QPointF dpad_center = center + QPoint(-171, 8); - constexpr float dpad_distance = 12.8; + constexpr float dpad_distance = 12.8f; constexpr float dpad_radius = 6.4f; constexpr float dpad_arrow_size = 0.68f; @@ -810,7 +825,21 @@ constexpr std::array symbol_zl = { 5.43f, 2.1f, 5.43f, 3.22f, 0.98f, 3.22f, 0.98f, -3.23f, 2.4f, -3.23f, -6.0f, 2.12f, }; -constexpr std::array symbol_zr = { +constexpr std::array symbol_sl = { + -3.0f, -3.65f, -2.76f, -4.26f, -2.33f, -4.76f, -1.76f, -5.09f, -1.13f, -5.26f, -0.94f, + -4.77f, -0.87f, -4.11f, -1.46f, -3.88f, -1.91f, -3.41f, -2.05f, -2.78f, -1.98f, -2.13f, + -1.59f, -1.61f, -0.96f, -1.53f, -0.56f, -2.04f, -0.38f, -2.67f, -0.22f, -3.31f, 0.0f, + -3.93f, 0.34f, -4.49f, 0.86f, -4.89f, 1.49f, -5.05f, 2.14f, -4.95f, 2.69f, -4.6f, + 3.07f, -4.07f, 3.25f, -3.44f, 3.31f, -2.78f, 3.25f, -2.12f, 3.07f, -1.49f, 2.7f, + -0.95f, 2.16f, -0.58f, 1.52f, -0.43f, 1.41f, -0.99f, 1.38f, -1.65f, 1.97f, -1.91f, + 2.25f, -2.49f, 2.25f, -3.15f, 1.99f, -3.74f, 1.38f, -3.78f, 1.06f, -3.22f, 0.88f, + -2.58f, 0.71f, -1.94f, 0.49f, -1.32f, 0.13f, -0.77f, -0.4f, -0.4f, -1.04f, -0.25f, + -1.69f, -0.32f, -2.28f, -0.61f, -2.73f, -1.09f, -2.98f, -1.69f, -3.09f, -2.34f, + + 3.23f, 2.4f, -2.1f, 2.4f, -2.1f, 5.43f, -3.22f, 5.43f, -3.22f, 0.98f, 3.23f, + 0.98f, 3.23f, 2.4f, -3.09f, -2.34f, +}; +constexpr std::array symbol_zr = { -2.6f, -2.13f, -5.6f, -2.13f, -5.6f, -3.23f, -0.8f, -3.23f, -0.8f, -2.13f, -4.4f, 2.12f, -0.7f, 2.12f, -0.7f, 3.22f, -6.0f, 3.22f, -6.0f, 2.12f, @@ -828,10 +857,42 @@ constexpr std::array symbol_zr = { 0.7f, 3.3f, 0.6f, 2.9f, 0.5f, 2.3f, 0.6f, 2.3f, 0.7f, 2.2f, 3.3f, 1.0f, 3.2f, 1.0f, 3.1f, 1.0f, 0.0f, - 4.2f, -0.5f, 4.2f, -0.5f, 4.4f, -0.6f, 4.7f, -0.7f, 4.8f, -0.8f, 4.9f, -1.0f, 5.0f, - -1.1f, 5.0f, -1.2f, 4.9f, -1.7f, 4.9f, -1.8f, 4.8f, -1.9f, 4.8f, -2.0f, 4.6f, -2.1f, - 4.3f, -2.2f, 2.3f, -2.1f, 2.3f, -2.0f, 2.4f, -0.5f, 4.2f, -0.5f, 1.0f, 0.0f, -6.0f, - 2.12f, + 4.2f, -0.5f, 4.4f, -0.6f, 4.7f, -0.7f, 4.8f, -0.8f, 4.9f, -1.0f, 5.0f, -1.1f, 5.0f, + -1.2f, 4.9f, -1.7f, 4.9f, -1.8f, 4.8f, -1.9f, 4.8f, -2.0f, 4.6f, -2.1f, 4.3f, -2.2f, + 2.3f, -2.1f, 2.3f, -2.0f, 2.4f, -0.5f, 4.2f, -0.5f, 1.0f, 0.0f, -6.0f, 2.12f, +}; + +constexpr std::array symbol_sr = { + -3.0f, -3.65f, -2.76f, -4.26f, -2.33f, -4.76f, -1.76f, -5.09f, -1.13f, -5.26f, -0.94f, -4.77f, + -0.87f, -4.11f, -1.46f, -3.88f, -1.91f, -3.41f, -2.05f, -2.78f, -1.98f, -2.13f, -1.59f, -1.61f, + -0.96f, -1.53f, -0.56f, -2.04f, -0.38f, -2.67f, -0.22f, -3.31f, 0.0f, -3.93f, 0.34f, -4.49f, + 0.86f, -4.89f, 1.49f, -5.05f, 2.14f, -4.95f, 2.69f, -4.6f, 3.07f, -4.07f, 3.25f, -3.44f, + 3.31f, -2.78f, 3.25f, -2.12f, 3.07f, -1.49f, 2.7f, -0.95f, 2.16f, -0.58f, 1.52f, -0.43f, + 1.41f, -0.99f, 1.38f, -1.65f, 1.97f, -1.91f, 2.25f, -2.49f, 2.25f, -3.15f, 1.99f, -3.74f, + 1.38f, -3.78f, 1.06f, -3.22f, 0.88f, -2.58f, 0.71f, -1.94f, 0.49f, -1.32f, 0.13f, -0.77f, + -0.4f, -0.4f, -1.04f, -0.25f, -1.69f, -0.32f, -2.28f, -0.61f, -2.73f, -1.09f, -2.98f, -1.69f, + -3.09f, -2.34f, + + -1.0f, 0.0f, 0.1f, 1.0f, 3.3f, 1.1f, 3.2f, 4.3f, 3.1f, 5.1f, 3.0f, 5.4f, + 2.9f, 5.6f, 2.8f, 5.7f, 2.7f, 5.9f, 2.6f, 5.9f, 2.5f, 6.0f, 2.3f, 6.1f, + 2.2f, 6.2f, 2.1f, 6.2f, 2.0f, 6.3f, 1.9f, 6.3f, 0.8f, 6.2f, 0.7f, 6.2f, + 0.6f, 6.1f, 0.5f, 6.1f, 0.4f, 6.0f, 0.3f, 6.0f, 0.2f, 5.9f, 0.1f, 5.7f, + 0.0f, 5.7f, -0.1f, 5.6f, -0.2f, 5.4f, -0.3f, 5.1f, -0.4f, 4.7f, -0.5f, 4.7f, + -0.6f, 4.9f, -0.7f, 5.0f, -0.8f, 5.2f, -0.9f, 5.2f, -1.0f, 5.3f, -1.1f, 5.5f, + -1.2f, 5.5f, -1.3f, 5.6f, -1.5f, 5.7f, -1.6f, 5.8f, -1.8f, 5.9f, -1.9f, 6.0f, + -2.1f, 6.1f, -2.2f, 6.2f, -2.3f, 6.2f, -2.4f, 6.3f, -2.6f, 6.4f, -2.7f, 6.5f, + -2.9f, 6.6f, -3.0f, 6.7f, -3.1f, 6.7f, -3.2f, 6.8f, -3.3f, 6.8f, -3.2f, 5.3f, + -3.1f, 5.2f, -3.0f, 5.2f, -2.9f, 5.1f, -2.7f, 5.0f, -2.6f, 4.9f, -2.4f, 4.8f, + -2.3f, 4.7f, -2.1f, 4.6f, -2.0f, 4.5f, -1.8f, 4.4f, -1.7f, 4.3f, -1.4f, 4.1f, + -1.3f, 4.0f, -1.1f, 3.9f, -1.0f, 3.8f, -0.9f, 3.6f, -0.8f, 3.6f, -0.7f, 3.5f, + -0.6f, 3.3f, -0.5f, 2.9f, -0.6f, 2.3f, -0.7f, 2.3f, -3.3f, 2.2f, -3.2f, 1.0f, + -3.1f, 1.0f, 0.0f, 1.0f, + + 0.5f, 4.2f, 0.6f, 4.4f, 0.7f, 4.7f, 0.8f, 4.8f, 1.0f, 4.9f, 1.1f, 5.0f, + 1.2f, 5.0f, 1.7f, 4.9f, 1.8f, 4.9f, 1.9f, 4.8f, 2.0f, 4.8f, 2.1f, 4.6f, + 2.2f, 4.3f, 2.1f, 2.3f, 2.0f, 2.3f, 0.5f, 2.4f, 0.5f, 4.2f, -0.0f, 1.0f, + -3.09f, -2.34f, + }; constexpr std::array house = { @@ -1093,15 +1154,16 @@ constexpr std::array left_joycon_body_trigger = { }; constexpr std::array left_joycon_topview = { - -184.8, -20.8, -185.6, -21.1, -186.4, -21.5, -187.1, -22.1, -187.8, -22.6, -188.4, - -23.2, -189.6, -24.5, -190.2, -25.2, -190.7, -25.9, -191.1, -26.7, -191.4, -27.5, - -191.6, -28.4, -191.7, -29.2, -191.7, -30.1, -191.5, -47.7, -191.2, -48.5, -191, - -49.4, -190.7, -50.2, -190.3, -51, -190, -51.8, -189.6, -52.6, -189.1, -53.4, - -188.6, -54.1, -187.5, -55.4, -186.9, -56.1, -186.2, -56.7, -185.5, -57.2, -184, - -58.1, -183.3, -58.5, -182.5, -58.9, -181.6, -59.2, -180.8, -59.5, -179.9, -59.7, - -179.1, -59.9, -178.2, -60, -174.7, -60.1, -168.5, -60.2, -162.4, -60.3, -156.2, - -60.4, -149.2, -60.5, -143, -60.6, -136.9, -60.7, -130.7, -60.8, -123.7, -60.9, - -117.5, -61, -110.5, -61.1, -94.4, -60.4, -94.4, -59.5, -94.4, -20.6, + -184.8f, -20.8f, -185.6f, -21.1f, -186.4f, -21.5f, -187.1f, -22.1f, -187.8f, -22.6f, + -188.4f, -23.2f, -189.6f, -24.5f, -190.2f, -25.2f, -190.7f, -25.9f, -191.1f, -26.7f, + -191.4f, -27.5f, -191.6f, -28.4f, -191.7f, -29.2f, -191.7f, -30.1f, -191.5f, -47.7f, + -191.2f, -48.5f, -191.0f, -49.4f, -190.7f, -50.2f, -190.3f, -51.0f, -190.0f, -51.8f, + -189.6f, -52.6f, -189.1f, -53.4f, -188.6f, -54.1f, -187.5f, -55.4f, -186.9f, -56.1f, + -186.2f, -56.7f, -185.5f, -57.2f, -184.0f, -58.1f, -183.3f, -58.5f, -182.5f, -58.9f, + -181.6f, -59.2f, -180.8f, -59.5f, -179.9f, -59.7f, -179.1f, -59.9f, -178.2f, -60.0f, + -174.7f, -60.1f, -168.5f, -60.2f, -162.4f, -60.3f, -156.2f, -60.4f, -149.2f, -60.5f, + -143.0f, -60.6f, -136.9f, -60.7f, -130.7f, -60.8f, -123.7f, -60.9f, -117.5f, -61.0f, + -110.5f, -61.1f, -94.4f, -60.4f, -94.4f, -59.5f, -94.4f, -20.6f, }; constexpr std::array left_joycon_slider_topview = { @@ -1288,14 +1350,15 @@ void PlayerControlPreview::DrawHandheldBody(QPainter& p, const QPointF center) { void PlayerControlPreview::DrawDualBody(QPainter& p, const QPointF center) { std::array left_joycon; std::array right_joycon; - std::array qleft_joycon_sideview; - std::array qright_joycon_sideview; - std::array qleft_joycon_trigger; - std::array qright_joycon_trigger; std::array qleft_joycon_slider; std::array qright_joycon_slider; + std::array qleft_joycon_slider_topview; + std::array qright_joycon_slider_topview; + std::array qleft_joycon_topview; + std::array qright_joycon_topview; constexpr float size = 1.61f; - constexpr float offset = 209.3; + constexpr float size2 = 0.9f; + constexpr float offset = 209.3f; for (std::size_t point = 0; point < left_joycon_body.size() / 2; ++point) { left_joycon[point] = center + QPointF(left_joycon_body[point * 2] * size + offset, @@ -1303,45 +1366,56 @@ void PlayerControlPreview::DrawDualBody(QPainter& p, const QPointF center) { right_joycon[point] = center + QPointF(-left_joycon_body[point * 2] * size - offset, left_joycon_body[point * 2 + 1] * size - 1); } - for (std::size_t point = 0; point < left_joycon_sideview.size() / 2; ++point) { - qleft_joycon_sideview[point] = center + QPointF(left_joycon_sideview[point * 2], - left_joycon_sideview[point * 2 + 1] + 2); - qright_joycon_sideview[point] = center + QPointF(-left_joycon_sideview[point * 2], - left_joycon_sideview[point * 2 + 1] + 2); - } for (std::size_t point = 0; point < left_joycon_slider.size() / 2; ++point) { qleft_joycon_slider[point] = center + QPointF(left_joycon_slider[point * 2], left_joycon_slider[point * 2 + 1]); qright_joycon_slider[point] = center + QPointF(-left_joycon_slider[point * 2], left_joycon_slider[point * 2 + 1]); } - for (std::size_t point = 0; point < left_joycon_body_trigger.size() / 2; ++point) { - qleft_joycon_trigger[point] = center + QPointF(left_joycon_body_trigger[point * 2], - left_joycon_body_trigger[point * 2 + 1] + 2); - qright_joycon_trigger[point] = - center + QPointF(-left_joycon_body_trigger[point * 2], - left_joycon_body_trigger[point * 2 + 1] + 2); + for (std::size_t point = 0; point < left_joycon_topview.size() / 2; ++point) { + qleft_joycon_topview[point] = + center + QPointF(left_joycon_topview[point * 2] * size2 - 52, + left_joycon_topview[point * 2 + 1] * size2 - 52); + qright_joycon_topview[point] = + center + QPointF(-left_joycon_topview[point * 2] * size2 + 52, + left_joycon_topview[point * 2 + 1] * size2 - 52); + } + for (std::size_t point = 0; point < left_joycon_slider_topview.size() / 2; ++point) { + qleft_joycon_slider_topview[point] = + center + QPointF(left_joycon_slider_topview[point * 2] * size2 - 52, + left_joycon_slider_topview[point * 2 + 1] * size2 - 52); + qright_joycon_slider_topview[point] = + center + QPointF(-left_joycon_slider_topview[point * 2] * size2 + 52, + left_joycon_slider_topview[point * 2 + 1] * size2 - 52); } // right joycon body p.setPen(colors.outline); p.setBrush(colors.right); DrawPolygon(p, right_joycon); - DrawPolygon(p, qright_joycon_trigger); // Left joycon body p.setPen(colors.outline); p.setBrush(colors.left); DrawPolygon(p, left_joycon); - DrawPolygon(p, qleft_joycon_trigger); - // Right Slider release button + // Slider release button top view p.setBrush(colors.button); - DrawRoundRectangle(p, center + QPoint(145, -100), 12, 12, 2); + DrawRoundRectangle(p, center + QPoint(-149, -108), 12, 11, 2); + DrawRoundRectangle(p, center + QPoint(149, -108), 12, 11, 2); - // Left Slider release button - p.setBrush(colors.button); - DrawRoundRectangle(p, center + QPoint(-145, -100), 12, 12, 2); + // Joycon slider top view + p.setBrush(colors.slider); + DrawPolygon(p, qleft_joycon_slider_topview); + p.drawLine(center + QPointF(-133.8f, -99.0f), center + QPointF(-133.8f, -78.5f)); + DrawPolygon(p, qright_joycon_slider_topview); + p.drawLine(center + QPointF(133.8f, -99.0f), center + QPointF(133.8f, -78.5f)); + + // Joycon body top view + p.setBrush(colors.left); + DrawPolygon(p, qleft_joycon_topview); + p.setBrush(colors.right); + DrawPolygon(p, qright_joycon_topview); // Right SR and SL sideview buttons p.setPen(colors.outline); @@ -1354,81 +1428,12 @@ void PlayerControlPreview::DrawDualBody(QPainter& p, const QPointF center) { DrawRoundRectangle(p, center + QPoint(-19, -62), 7, 22, 1); // Right Sideview body - p.setBrush(colors.right); - DrawPolygon(p, qright_joycon_sideview); p.setBrush(colors.slider); DrawPolygon(p, qright_joycon_slider); // Left Sideview body - p.setBrush(colors.left); - DrawPolygon(p, qleft_joycon_sideview); p.setBrush(colors.slider); DrawPolygon(p, qleft_joycon_slider); - - const QPointF right_sideview_center = QPointF(162.5f, 0) + center; - const QPointF left_sideview_center = QPointF(-162.5f, 0) + center; - - // right sideview slider body - p.setBrush(colors.slider); - DrawRoundRectangle(p, right_sideview_center + QPointF(0, -6), 26, 227, 3); - p.setBrush(colors.button2); - DrawRoundRectangle(p, right_sideview_center + QPointF(0, 85), 20.2f, 40.2f, 3); - - // left sideview slider body - p.setBrush(colors.slider); - DrawRoundRectangle(p, left_sideview_center + QPointF(0, -6), 26, 227, 3); - p.setBrush(colors.button2); - DrawRoundRectangle(p, left_sideview_center + QPointF(0, 85), 20.2f, 40.2f, 3); - - // Right Slider decorations - p.setPen(colors.outline); - p.setBrush(colors.slider_arrow); - DrawArrow(p, right_sideview_center + QPoint(0, 73), Direction::Down, 2.1f); - DrawArrow(p, right_sideview_center + QPoint(0, 85), Direction::Down, 2.1f); - DrawArrow(p, right_sideview_center + QPoint(0, 97), Direction::Down, 2.1f); - DrawCircle(p, right_sideview_center + QPointF(0, 17), 3.8f); - - // Left Slider decorations - DrawArrow(p, left_sideview_center + QPoint(0, 73), Direction::Down, 2.1f); - DrawArrow(p, left_sideview_center + QPoint(0, 85), Direction::Down, 2.1f); - DrawArrow(p, left_sideview_center + QPoint(0, 97), Direction::Down, 2.1f); - DrawCircle(p, left_sideview_center + QPointF(0, 17), 3.8f); - - // Right SR and SL buttons - p.setPen(colors.outline); - p.setBrush(colors.slider_button); - DrawRoundRectangle(p, right_sideview_center + QPoint(0, 47), 10, 22, 3.6f); - DrawRoundRectangle(p, right_sideview_center + QPoint(0, -62), 10, 22, 3.6f); - - // Left SR and SL buttons - DrawRoundRectangle(p, left_sideview_center + QPoint(0, 47), 10, 22, 3.6f); - DrawRoundRectangle(p, left_sideview_center + QPoint(0, -62), 10, 22, 3.6f); - - // Right SR and SL text - SetTextFont(p, 5.5f); - p.setPen(colors.outline); - p.rotate(-90); - p.drawText(QPointF(-center.y() - 5, center.x() + 3) + QPointF(-47, 162.5f), tr("SL")); - p.drawText(QPointF(-center.y() - 5, center.x() + 3) + QPointF(62, 162.5f), tr("SR")); - p.rotate(90); - - // Left SR and SL text - p.rotate(90); - p.drawText(QPointF(center.y() - 5, -center.x() + 3) + QPointF(47, 162.5f), tr("SR")); - p.drawText(QPointF(center.y() - 5, -center.x() + 3) + QPointF(-62, 162.5f), tr("SL")); - p.rotate(-90); - - // LED indicators - const float led_size = 5.0f; - const QPointF left_led_position = left_sideview_center + QPointF(0, -33); - const QPointF right_led_position = right_sideview_center + QPointF(0, -33); - int led_count = 0; - for (const auto color : led_color) { - p.setBrush(color); - DrawRectangle(p, left_led_position + QPointF(0, 11 * led_count), led_size, led_size); - DrawRectangle(p, right_led_position + QPointF(0, 11 * led_count), led_size, led_size); - led_count++; - } } void PlayerControlPreview::DrawLeftBody(QPainter& p, const QPointF center) { @@ -1707,18 +1712,20 @@ void PlayerControlPreview::DrawDualTriggers(QPainter& p, const QPointF center, b DrawPolygon(p, qright_trigger); } -void PlayerControlPreview::DrawDualZTriggers(QPainter& p, const QPointF center, bool left_pressed, - bool right_pressed) { - std::array qleft_trigger; - std::array qright_trigger; +void PlayerControlPreview::DrawDualTriggersTopView(QPainter& p, const QPointF center, + bool left_pressed, bool right_pressed) { + std::array qleft_trigger; + std::array qright_trigger; + constexpr float size = 0.9f; - for (std::size_t point = 0; point < left_joycon_sideview_zl.size() / 2; ++point) { - qleft_trigger[point] = - center + QPointF(left_joycon_sideview_zl[point * 2], - left_joycon_sideview_zl[point * 2 + 1] + (left_pressed ? 2.5f : 2.0f)); - qright_trigger[point] = center + QPointF(-left_joycon_sideview_zl[point * 2], - left_joycon_sideview_zl[point * 2 + 1] + - (right_pressed ? 2.5f : 2.0f)); + for (std::size_t point = 0; point < left_joystick_L_topview.size() / 2; ++point) { + qleft_trigger[point] = center + QPointF(left_joystick_L_topview[point * 2] * size - 50, + left_joystick_L_topview[point * 2 + 1] * size - 52); + } + for (std::size_t point = 0; point < left_joystick_L_topview.size() / 2; ++point) { + qright_trigger[point] = + center + QPointF(-left_joystick_L_topview[point * 2] * size + 50, + left_joystick_L_topview[point * 2 + 1] * size - 52); } p.setPen(colors.outline); @@ -1726,10 +1733,58 @@ void PlayerControlPreview::DrawDualZTriggers(QPainter& p, const QPointF center, DrawPolygon(p, qleft_trigger); p.setBrush(right_pressed ? colors.highlight : colors.button); DrawPolygon(p, qright_trigger); - p.drawArc(center.x() - 159, center.y() - 183 + (left_pressed ? 0.5f : 0), 70, 70, 225 * 16, - 44 * 16); - p.drawArc(center.x() + 90, center.y() - 183 + (right_pressed ? 0.5f : 0), 70, 70, 271 * 16, - 44 * 16); + + // Draw ZL text + p.setPen(colors.transparent); + p.setBrush(colors.font2); + DrawSymbol(p, center + QPointF(-183, -84), Symbol::ZL, 1.0f); + + // Delete Z character + p.setBrush(left_pressed ? colors.highlight : colors.button); + DrawRectangle(p, center + QPointF(-186, -84), 6, 10); + + // Draw ZR text + p.setPen(colors.transparent); + p.setBrush(colors.font2); + DrawSymbol(p, center + QPointF(177, -84), Symbol::ZR, 1.0f); + + // Delete Z character + p.setBrush(right_pressed ? colors.highlight : colors.button); + DrawRectangle(p, center + QPointF(174, -84), 6, 10); +} + +void PlayerControlPreview::DrawDualZTriggersTopView(QPainter& p, const QPointF center, + bool left_pressed, bool right_pressed) { + std::array qleft_trigger; + std::array qright_trigger; + constexpr float size = 0.9f; + + for (std::size_t point = 0; point < left_joystick_ZL_topview.size() / 2; ++point) { + qleft_trigger[point] = + center + QPointF(left_joystick_ZL_topview[point * 2] * size - 52, + left_joystick_ZL_topview[point * 2 + 1] * size - 52); + } + for (std::size_t point = 0; point < left_joystick_ZL_topview.size() / 2; ++point) { + qright_trigger[point] = + center + QPointF(-left_joystick_ZL_topview[point * 2] * size + 52, + left_joystick_ZL_topview[point * 2 + 1] * size - 52); + } + + p.setPen(colors.outline); + p.setBrush(left_pressed ? colors.highlight : colors.button); + DrawPolygon(p, qleft_trigger); + p.setBrush(right_pressed ? colors.highlight : colors.button); + DrawPolygon(p, qright_trigger); + + // Draw ZL text + p.setPen(colors.transparent); + p.setBrush(colors.font2); + DrawSymbol(p, center + QPointF(-180, -113), Symbol::ZL, 1.0f); + + // Draw ZR text + p.setPen(colors.transparent); + p.setBrush(colors.font2); + DrawSymbol(p, center + QPointF(180, -113), Symbol::ZR, 1.0f); } void PlayerControlPreview::DrawLeftTriggers(QPainter& p, const QPointF center, bool left_pressed) { @@ -1909,7 +1964,7 @@ void PlayerControlPreview::DrawJoystick(QPainter& p, const QPointF center, float void PlayerControlPreview::DrawJoystickSideview(QPainter& p, const QPointF center, float angle, float size, bool pressed) { QVector joystick; - joystick.reserve(left_joystick_sideview.size() / 2); + joystick.reserve(static_cast(left_joystick_sideview.size() / 2)); for (std::size_t point = 0; point < left_joystick_sideview.size() / 2; ++point) { joystick.append(QPointF(left_joystick_sideview[point * 2] * size + (pressed ? 1 : 0), @@ -2136,7 +2191,9 @@ void PlayerControlPreview::DrawSymbol(QPainter& p, const QPointF center, Symbol std::array x_icon; std::array y_icon; std::array zl_icon; + std::array sl_icon; std::array zr_icon; + std::array sr_icon; switch (symbol) { case Symbol::House: for (std::size_t point = 0; point < house.size() / 2; ++point) { @@ -2180,6 +2237,13 @@ void PlayerControlPreview::DrawSymbol(QPainter& p, const QPointF center, Symbol } p.drawPolygon(zl_icon.data(), static_cast(zl_icon.size())); break; + case Symbol::SL: + for (std::size_t point = 0; point < symbol_sl.size() / 2; ++point) { + sl_icon[point] = center + QPointF(symbol_sl[point * 2] * icon_size, + symbol_sl[point * 2 + 1] * icon_size); + } + p.drawPolygon(sl_icon.data(), static_cast(sl_icon.size())); + break; case Symbol::ZR: for (std::size_t point = 0; point < symbol_zr.size() / 2; ++point) { zr_icon[point] = center + QPointF(symbol_zr[point * 2] * icon_size, @@ -2187,6 +2251,13 @@ void PlayerControlPreview::DrawSymbol(QPainter& p, const QPointF center, Symbol } p.drawPolygon(zr_icon.data(), static_cast(zr_icon.size())); break; + case Symbol::SR: + for (std::size_t point = 0; point < symbol_sr.size() / 2; ++point) { + sr_icon[point] = center + QPointF(symbol_sr[point * 2] * icon_size, + symbol_sr[point * 2 + 1] * icon_size); + } + p.drawPolygon(sr_icon.data(), static_cast(sr_icon.size())); + break; } } diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h index ba5e49da3..33a5482ba 100755 --- a/src/yuzu/configuration/configure_input_player_widget.h +++ b/src/yuzu/configuration/configure_input_player_widget.h @@ -32,6 +32,7 @@ public: void BeginMappingButton(std::size_t button_id); void BeginMappingAnalog(std::size_t button_id); void EndMapping(); + void UpdateInput(); protected: void paintEvent(QPaintEvent* event) override; @@ -51,8 +52,10 @@ private: B, X, Y, + SL, ZL, ZR, + SR, }; struct AxisValue { @@ -113,7 +116,10 @@ private: void DrawProTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed); void DrawHandheldTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed); void DrawDualTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed); - void DrawDualZTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed); + void DrawDualTriggersTopView(QPainter& p, QPointF center, bool left_pressed, + bool right_pressed); + void DrawDualZTriggersTopView(QPainter& p, QPointF center, bool left_pressed, + bool right_pressed); void DrawLeftTriggers(QPainter& p, QPointF center, bool left_pressed); void DrawLeftZTriggers(QPainter& p, QPointF center, bool left_pressed); void DrawLeftTriggersTopView(QPainter& p, QPointF center, bool left_pressed); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f6f902fab..dd58d99fc 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -850,6 +850,10 @@ void GMainWindow::InitializeHotkeys() { connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this), &QShortcut::activated, this, [] { Settings::values.audio_muted = !Settings::values.audio_muted; }); + + connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this), + &QShortcut::activated, this, + [] { Settings::values.mouse_panning = !Settings::values.mouse_panning; }); } void GMainWindow::SetDefaultUIGeometry() { @@ -1197,7 +1201,7 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index) { multicore_status_button->setDisabled(true); renderer_status_button->setDisabled(true); - if (UISettings::values.hide_mouse) { + if (UISettings::values.hide_mouse || Settings::values.mouse_panning) { mouse_hide_timer.start(); render_window->installEventFilter(render_window); render_window->setAttribute(Qt::WA_Hover, true); @@ -2358,7 +2362,7 @@ void GMainWindow::OnConfigure() { config->Save(); - if (UISettings::values.hide_mouse && emulation_running) { + if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) { render_window->installEventFilter(render_window); render_window->setAttribute(Qt::WA_Hover, true); mouse_hide_timer.start(); @@ -2609,13 +2613,16 @@ void GMainWindow::HideMouseCursor() { void GMainWindow::ShowMouseCursor() { render_window->unsetCursor(); - if (emu_thread != nullptr && UISettings::values.hide_mouse) { + if (emu_thread != nullptr && + (UISettings::values.hide_mouse || Settings::values.mouse_panning)) { mouse_hide_timer.start(); } } void GMainWindow::OnMouseActivity() { - ShowMouseCursor(); + if (!Settings::values.mouse_panning) { + ShowMouseCursor(); + } } void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) { diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 7843d5167..39841aa28 100755 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -30,7 +30,8 @@ EmuWindow_SDL2::~EmuWindow_SDL2() { void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0), 0); - input_subsystem->GetMouse()->MouseMove(x, y); + + input_subsystem->GetMouse()->MouseMove(x, y, 0, 0); } void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {