early-access version 1409
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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, | ||||
| }; | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -135,19 +135,15 @@ struct KernelCore::Impl { | ||||
|         system_resource_limit = std::make_shared<KResourceLimit>(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(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -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<VAddr> 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; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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<KThread> thread; | ||||
|     { | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -139,6 +139,10 @@ public: | ||||
|                                static_cast<float>(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: | ||||
|   | ||||
| @@ -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<float>(); | ||||
|                 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; | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| #include <utility> | ||||
|  | ||||
| #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<float>(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<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const { | ||||
| @@ -106,6 +107,16 @@ public: | ||||
|         return {0.0f, 0.0f}; | ||||
|     } | ||||
|  | ||||
|     std::tuple<float, float> 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; | ||||
|   | ||||
| @@ -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<QMouseEvent*>(event); | ||||
|             mouseMoveEvent(hover_event); | ||||
|             return false; | ||||
|         } | ||||
|         emit MouseActivity(); | ||||
|     } | ||||
|     return false; | ||||
|   | ||||
| @@ -220,7 +220,7 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> 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<UISettings::Shortcut, 16> Config::default_hotkeys{{ | ||||
| const std::array<UISettings::Shortcut, 17> 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<UISettings::Shortcut, 16> 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(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -42,7 +42,7 @@ public: | ||||
|         default_mouse_buttons; | ||||
|     static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys; | ||||
|     static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods; | ||||
|     static const std::array<UISettings::Shortcut, 16> default_hotkeys; | ||||
|     static const std::array<UISettings::Shortcut, 17> default_hotkeys; | ||||
|  | ||||
| private: | ||||
|     void Initialize(const std::string& config_name); | ||||
|   | ||||
| @@ -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<float>(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(); | ||||
|   | ||||
| @@ -2546,27 +2546,62 @@ | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="1" column="0"> | ||||
|                  <widget class="QCheckBox" name="emulate_analog_keyboard"> | ||||
|                    <property name="minimumSize"> | ||||
|                      <size> | ||||
|                        <width>0</width> | ||||
|                        <height>23</height> | ||||
|                      </size> | ||||
|                    </property> | ||||
|                    <property name="text"> | ||||
|                      <string>Emulate Analog with Keyboard Input</string> | ||||
|                    </property> | ||||
|                  </widget> | ||||
|                </item> | ||||
|                <item row="5" column="2"> | ||||
|                 <item row="1" column="0"> | ||||
|                   <widget class="QCheckBox" name="emulate_analog_keyboard"> | ||||
|                     <property name="minimumSize"> | ||||
|                       <size> | ||||
|                         <width>0</width> | ||||
|                         <height>23</height> | ||||
|                       </size> | ||||
|                     </property> | ||||
|                     <property name="text"> | ||||
|                       <string>Emulate Analog with Keyboard Input</string> | ||||
|                     </property> | ||||
|                   </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="0"> | ||||
|                   <widget class="QCheckBox" name="mouse_panning"> | ||||
|                     <property name="minimumSize"> | ||||
|                       <size> | ||||
|                         <width>0</width> | ||||
|                         <height>23</height> | ||||
|                       </size> | ||||
|                     </property> | ||||
|                     <property name="text"> | ||||
|                       <string>Enable mouse panning</string> | ||||
|                     </property> | ||||
|                   </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="2"> | ||||
|                     <widget class="QDoubleSpinBox" name="mouse_panning_sensitivity"> | ||||
|                       <property name="alignment"> | ||||
|                         <set>Qt::AlignCenter</set> | ||||
|                       </property> | ||||
|                       <property name="decimals"> | ||||
|                         <number>1</number> | ||||
|                       </property> | ||||
|                       <property name="minimum"> | ||||
|                         <double>0.100000000000000</double> | ||||
|                       </property> | ||||
|                       <property name="maximum"> | ||||
|                         <double>32.000000000000000</double> | ||||
|                       </property> | ||||
|                       <property name="singleStep"> | ||||
|                         <double>0.100000000000000</double> | ||||
|                       </property> | ||||
|                       <property name="value"> | ||||
|                         <double>16.000000000000000</double> | ||||
|                       </property> | ||||
|                     </widget> | ||||
|                 </item> | ||||
|                <item row="6" column="2"> | ||||
|                 <widget class="QPushButton" name="touchscreen_advanced"> | ||||
|                  <property name="text"> | ||||
|                   <string>Advanced</string> | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="2" column="1"> | ||||
|                <item row="3" column="1"> | ||||
|                 <spacer name="horizontalSpacer_8"> | ||||
|                  <property name="orientation"> | ||||
|                   <enum>Qt::Horizontal</enum> | ||||
| @@ -2582,21 +2617,21 @@ | ||||
|                  </property> | ||||
|                 </spacer> | ||||
|                </item> | ||||
|                <item row="2" column="2"> | ||||
|                <item row="3" column="2"> | ||||
|                 <widget class="QPushButton" name="mouse_advanced"> | ||||
|                  <property name="text"> | ||||
|                   <string>Advanced</string> | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="5" column="0"> | ||||
|                <item row="6" column="0"> | ||||
|                 <widget class="QCheckBox" name="touchscreen_enabled"> | ||||
|                  <property name="text"> | ||||
|                   <string>Touchscreen</string> | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="2" column="0"> | ||||
|                <item row="3" column="0"> | ||||
|                 <widget class="QCheckBox" name="mouse_enabled"> | ||||
|                  <property name="minimumSize"> | ||||
|                   <size> | ||||
| @@ -2609,28 +2644,28 @@ | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="7" column="0"> | ||||
|                <item row="8" column="0"> | ||||
|                 <widget class="QLabel" name="motion_touch"> | ||||
|                  <property name="text"> | ||||
|                   <string>Motion / Touch</string> | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="7" column="2"> | ||||
|                <item row="8" column="2"> | ||||
|                 <widget class="QPushButton" name="buttonMotionTouch"> | ||||
|                  <property name="text"> | ||||
|                   <string>Configure</string> | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="6" column="0"> | ||||
|                <item row="7" column="0"> | ||||
|                 <widget class="QCheckBox" name="debug_enabled"> | ||||
|                  <property name="text"> | ||||
|                   <string>Debug Controller</string> | ||||
|                  </property> | ||||
|                 </widget> | ||||
|                </item> | ||||
|                <item row="6" column="2"> | ||||
|                <item row="7" column="2"> | ||||
|                 <widget class="QPushButton" name="debug_configure"> | ||||
|                  <property name="text"> | ||||
|                   <string>Configure</string> | ||||
|   | ||||
| @@ -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<int>(stick_x_rf * 45) != | ||||
|                 static_cast<int>(axis_values[index].raw_value.x() * 45) || | ||||
|             static_cast<int>(-stick_y_rf * 45) != | ||||
|                 static_cast<int>(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<float, 18 * 2> 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<float, 110 * 2> symbol_zr = { | ||||
| constexpr std::array<float, 57 * 2> 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<float, 109 * 2> 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<float, 110 * 2> 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<float, 148 * 2> 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<float, 12 * 2> house = { | ||||
| @@ -1093,15 +1154,16 @@ constexpr std::array<float, 40 * 2> left_joycon_body_trigger = { | ||||
| }; | ||||
|  | ||||
| constexpr std::array<float, 49 * 2> 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<float, 41 * 2> 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<QPointF, left_joycon_body.size() / 2> left_joycon; | ||||
|     std::array<QPointF, left_joycon_body.size() / 2> right_joycon; | ||||
|     std::array<QPointF, left_joycon_sideview.size() / 2> qleft_joycon_sideview; | ||||
|     std::array<QPointF, left_joycon_sideview.size() / 2> qright_joycon_sideview; | ||||
|     std::array<QPointF, left_joycon_body_trigger.size() / 2> qleft_joycon_trigger; | ||||
|     std::array<QPointF, left_joycon_body_trigger.size() / 2> qright_joycon_trigger; | ||||
|     std::array<QPointF, left_joycon_slider.size() / 2> qleft_joycon_slider; | ||||
|     std::array<QPointF, left_joycon_slider.size() / 2> qright_joycon_slider; | ||||
|     std::array<QPointF, left_joycon_slider_topview.size() / 2> qleft_joycon_slider_topview; | ||||
|     std::array<QPointF, left_joycon_slider_topview.size() / 2> qright_joycon_slider_topview; | ||||
|     std::array<QPointF, left_joycon_topview.size() / 2> qleft_joycon_topview; | ||||
|     std::array<QPointF, left_joycon_topview.size() / 2> 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<QPointF, left_joycon_sideview_zl.size() / 2> qleft_trigger; | ||||
|     std::array<QPointF, left_joycon_sideview_zl.size() / 2> qright_trigger; | ||||
| void PlayerControlPreview::DrawDualTriggersTopView(QPainter& p, const QPointF center, | ||||
|                                                    bool left_pressed, bool right_pressed) { | ||||
|     std::array<QPointF, left_joystick_L_topview.size() / 2> qleft_trigger; | ||||
|     std::array<QPointF, left_joystick_L_topview.size() / 2> 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<QPointF, left_joystick_ZL_topview.size() / 2> qleft_trigger; | ||||
|     std::array<QPointF, left_joystick_ZL_topview.size() / 2> 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<QPointF> joystick; | ||||
|     joystick.reserve(left_joystick_sideview.size() / 2); | ||||
|     joystick.reserve(static_cast<int>(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<QPointF, symbol_x.size() / 2> x_icon; | ||||
|     std::array<QPointF, symbol_y.size() / 2> y_icon; | ||||
|     std::array<QPointF, symbol_zl.size() / 2> zl_icon; | ||||
|     std::array<QPointF, symbol_sl.size() / 2> sl_icon; | ||||
|     std::array<QPointF, symbol_zr.size() / 2> zr_icon; | ||||
|     std::array<QPointF, symbol_sr.size() / 2> 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<int>(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<int>(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<int>(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<int>(sr_icon.size())); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user