diff options
Diffstat (limited to '')
26 files changed, 353 insertions, 225 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index 5b0b285cd..b0f6f0c34 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -111,7 +111,14 @@ void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) { sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); - core_timing.ScheduleEvent(GetBufferReleaseNS(*active_buffer) - ns_late, release_event, {}); + const auto buffer_release_ns = GetBufferReleaseNS(*active_buffer); + + // If ns_late is higher than the update rate ignore the delay + if (ns_late > buffer_release_ns) { + ns_late = {}; + } + + core_timing.ScheduleEvent(buffer_release_ns - ns_late, release_event, {}); } void Stream::ReleaseActiveBuffer(std::chrono::nanoseconds ns_late) { diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index bfd11e76d..263c457cd 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -206,6 +206,8 @@ if (MSVC) else() target_compile_options(common PRIVATE -Werror + + $<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation> ) endif() diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 4cba2aaa4..7b614ad89 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -141,27 +141,13 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st } std::string UTF16ToUTF8(const std::u16string& input) { -#ifdef _MSC_VER - // Workaround for missing char16_t/char32_t instantiations in MSVC2017 - std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert; - std::basic_string<__int16> tmp_buffer(input.cbegin(), input.cend()); - return convert.to_bytes(tmp_buffer); -#else std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; return convert.to_bytes(input); -#endif } std::u16string UTF8ToUTF16(const std::string& input) { -#ifdef _MSC_VER - // Workaround for missing char16_t/char32_t instantiations in MSVC2017 - std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert; - auto tmp_buffer = convert.from_bytes(input); - return std::u16string(tmp_buffer.cbegin(), tmp_buffer.cend()); -#else std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; return convert.from_bytes(input); -#endif } #ifdef _WIN32 diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 386d7bddf..987076956 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -653,6 +653,8 @@ else() $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> + $<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation> + -Wno-sign-conversion ) endif() diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 3022438b1..79b209c6b 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -121,6 +121,10 @@ void SoftwareKeyboard::ExecuteInteractive() { std::memcpy(&request, data.data(), sizeof(Request)); switch (request) { + case Request::Finalize: + complete = true; + broker.SignalStateChanged(); + break; case Request::Calc: { broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{1})); broker.SignalStateChanged(); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 51a010a55..1e2677320 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -110,6 +110,7 @@ void IAppletResource::DeactivateController(HidController controller) { IAppletResource ::~IAppletResource() { system.CoreTiming().UnscheduleEvent(pad_update_event, 0); + system.CoreTiming().UnscheduleEvent(motion_update_event, 0); } void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp index 4440135ed..e2ac71fa1 100644 --- a/src/core/hle/service/olsc/olsc.cpp +++ b/src/core/hle/service/olsc/olsc.cpp @@ -17,7 +17,7 @@ public: static const FunctionInfo functions[] = { {0, &OLSC::Initialize, "Initialize"}, {10, nullptr, "VerifySaveDataBackupLicenseAsync"}, - {13, nullptr, "GetSaveDataBackupSetting"}, + {13, &OLSC::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"}, {14, &OLSC::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"}, {15, nullptr, "SetCustomData"}, {16, nullptr, "DeleteSaveDataBackupSetting"}, @@ -52,6 +52,17 @@ private: rb.Push(RESULT_SUCCESS); } + void GetSaveDataBackupSetting(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_OLSC, "(STUBBED) called"); + + // backup_setting is set to 0 since real value is unknown + constexpr u64 backup_setting = 0; + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push(backup_setting); + } + void SetSaveDataBackupSettingEnabled(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_OLSC, "(STUBBED) called"); diff --git a/src/core/settings.h b/src/core/settings.h index a324530bd..d849dded3 100644 --- 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; + float mouse_panning_sensitivity; bool mouse_enabled; 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/mouse/mouse_input.cpp b/src/input_common/mouse/mouse_input.cpp index 10786a541..67a584d53 100644 --- 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 { @@ -36,6 +37,9 @@ void Mouse::UpdateThread() { if (configuring) { UpdateYuzuSettings(); } + if (mouse_panning_timout++ > 8) { + StopPanning(); + } std::this_thread::sleep_for(std::chrono::milliseconds(update_time)); } } @@ -65,8 +69,34 @@ 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::StopPanning() { + for (MouseInfo& info : mouse_info) { + if (Settings::values.mouse_panning) { + info.data.axis = {}; + info.tilt_speed = 0; + info.last_mouse_change = {}; + } + } +} + +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); + mouse_panning_timout = 0; + + if (mouse_change.y == 0 && mouse_change.x == 0) { + continue; + } + + info.last_mouse_change = (info.last_mouse_change * 0.8f) + (mouse_change * 0.2f); + info.data.axis = {static_cast<int>(16 * info.last_mouse_change.x), + static_cast<int>(16 * -info.last_mouse_change.y)}; + info.tilt_direction = info.last_mouse_change; + 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..46aa676c1 100644 --- 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. @@ -74,11 +76,13 @@ public: private: void UpdateThread(); void UpdateYuzuSettings(); + void StopPanning(); struct MouseInfo { InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; Common::Vec2<int> mouse_origin; Common::Vec2<int> last_mouse_position; + Common::Vec2<float> last_mouse_change; bool is_tilting = false; float sensitivity{0.120f}; @@ -94,5 +98,6 @@ private: Common::SPSCQueue<MouseStatus> mouse_queue; bool configuring{false}; bool update_thread_running{true}; + int mouse_panning_timout{}; }; } // namespace MouseInput diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp index 3d799b293..bb56787ee 100644 --- a/src/input_common/mouse/mouse_poller.cpp +++ b/src/input_common/mouse/mouse_poller.cpp @@ -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 { diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index e7e50d789..c4afa4174 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp @@ -144,6 +144,10 @@ Client::~Client() { Reset(); } +Client::ClientData::ClientData() = default; + +Client::ClientData::~ClientData() = default; + std::vector<Common::ParamPackage> Client::GetInputDevices() const { std::vector<Common::ParamPackage> devices; for (std::size_t client = 0; client < clients.size(); client++) { diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h index 822f9c550..a523f6124 100644 --- a/src/input_common/udp/client.h +++ b/src/input_common/udp/client.h @@ -98,6 +98,9 @@ public: private: struct ClientData { + ClientData(); + ~ClientData(); + std::string host{"127.0.0.1"}; u16 port{26760}; std::size_t pad_index{}; diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp index b630281a0..9829da6f0 100644 --- a/src/input_common/udp/udp.cpp +++ b/src/input_common/udp/udp.cpp @@ -84,8 +84,8 @@ public: private: const std::string ip; - const u16 port; - const u16 pad; + [[maybe_unused]] const u16 port; + [[maybe_unused]] const u16 pad; CemuhookUDP::Client* client; mutable std::mutex mutex; }; diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 2cf95937e..dd4c29ed3 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -271,14 +271,13 @@ create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PRIVATE glad xbyak) -if (MSVC) - target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR}) - target_link_libraries(video_core PUBLIC ${FFMPEG_LIBRARY_DIR}/swscale.lib ${FFMPEG_LIBRARY_DIR}/avcodec.lib ${FFMPEG_LIBRARY_DIR}/avutil.lib) -else() - target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR}) - target_link_libraries(video_core PRIVATE ${FFMPEG_LIBRARIES}) +if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32) + add_dependencies(video_core ffmpeg-build) endif() +target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_DIR}) +target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARIES}) + add_dependencies(video_core host_shaders) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8aa63d329..ea4ca9a82 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -67,9 +67,6 @@ constexpr size_t TOTAL_CONST_BUFFER_BYTES = constexpr size_t NUM_SUPPORTED_VERTEX_ATTRIBUTES = 16; constexpr size_t NUM_SUPPORTED_VERTEX_BINDINGS = 16; -constexpr size_t MAX_TEXTURES = 192; -constexpr size_t MAX_IMAGES = 48; - struct TextureHandle { constexpr TextureHandle(u32 data, bool via_header_index) { const Tegra::Texture::TextureHandle handle{data}; diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index bb2cdef81..a0bc1f7b6 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -169,40 +169,6 @@ template <u32 GOB_EXTENT> return Common::DivCeil(AdjustMipSize(size, level), block_size); } -[[nodiscard]] constexpr u32 LayerSize(const TICEntry& config, PixelFormat format) { - return config.Width() * config.Height() * BytesPerBlock(format); -} - -[[nodiscard]] constexpr bool HasTwoDimsPerLayer(TextureType type) { - switch (type) { - case TextureType::Texture2D: - case TextureType::Texture2DArray: - case TextureType::Texture2DNoMipmap: - case TextureType::Texture3D: - case TextureType::TextureCubeArray: - case TextureType::TextureCubemap: - return true; - case TextureType::Texture1D: - case TextureType::Texture1DArray: - case TextureType::Texture1DBuffer: - return false; - } - return false; -} - -[[nodiscard]] constexpr bool HasTwoDimsPerLayer(ImageType type) { - switch (type) { - case ImageType::e2D: - case ImageType::e3D: - case ImageType::Linear: - return true; - case ImageType::e1D: - case ImageType::Buffer: - return false; - } - UNREACHABLE_MSG("Invalid image type={}", static_cast<int>(type)); -} - [[nodiscard]] constexpr std::pair<int, int> Samples(int num_samples) { switch (num_samples) { case 1: diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index ffdf34a4a..d9a3035cb 100644 --- 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(); } @@ -714,6 +719,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; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 8d85a1986..8f7458119 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -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}}, @@ -235,6 +235,7 @@ const std::array<UISettings::Shortcut, 16> Config::default_hotkeys{{ {QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}}, {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, + {QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}}, }}; @@ -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"), 1).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, 1.0f); qt_config->endGroup(); } diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 8a600e19d..949c4eb13 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -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); diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 4e557bc6f..a1a0eb676 100644 --- 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<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(); diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index f207e5d3b..173130d8d 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2546,27 +2546,65 @@ </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="toolTip"> + <string>Mouse sensitivity</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="decimals"> + <number>2</number> + </property> + <property name="minimum"> + <double>0.100000000000000</double> + </property> + <property name="maximum"> + <double>16.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.010000000000000</double> + </property> + <property name="value"> + <double>1.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 +2620,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 +2647,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> diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index e3e8bde48..0e8a964d2 100644 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp @@ -37,7 +37,8 @@ void PlayerControlPreview::SetPlayerInput(std::size_t index, const ButtonParam& Input::CreateDevice<Input::AnalogDevice>); UpdateColors(); } -void PlayerControlPreview::SetPlayerInputRaw(std::size_t index, const Settings::ButtonsRaw buttons_, +void PlayerControlPreview::SetPlayerInputRaw(std::size_t index, + const Settings::ButtonsRaw& buttons_, Settings::AnalogsRaw analogs_) { player_index = index; std::transform(buttons_.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, @@ -517,14 +518,15 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF 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, center + QPointF(-180, 90), axis_values[LStick].raw_value, - axis_values[LStick].properties); - DrawRawJoystick(p, center + QPointF(180, 90), axis_values[RStick].raw_value, - axis_values[RStick].properties); + const auto& l_stick = axis_values[LStick]; + const auto l_button = button_values[Settings::NativeButton::LStick]; + const auto& r_stick = axis_values[RStick]; + const auto r_button = button_values[Settings::NativeButton::RStick]; + + DrawJoystick(p, center + QPointF(-65, -65) + (l_stick.value * 7), 1.62f, l_button); + DrawJoystick(p, center + QPointF(65, 12) + (r_stick.value * 7), 1.62f, r_button); + DrawRawJoystick(p, center + QPointF(-180, 90), l_stick.raw_value, l_stick.properties); + DrawRawJoystick(p, center + QPointF(180, 90), r_stick.raw_value, r_stick.properties); } using namespace Settings::NativeButton; @@ -603,14 +605,15 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen { // Draw joysticks using namespace Settings::NativeAnalog; - DrawJoystick(p, center + QPointF(-171, -41) + (axis_values[LStick].value * 4), 1.0f, - button_values[Settings::NativeButton::LStick]); - DrawJoystick(p, center + QPointF(171, 8) + (axis_values[RStick].value * 4), 1.0f, - button_values[Settings::NativeButton::RStick]); - DrawRawJoystick(p, center + QPointF(-50, 0), axis_values[LStick].raw_value, - axis_values[LStick].properties); - DrawRawJoystick(p, center + QPointF(50, 0), axis_values[RStick].raw_value, - axis_values[RStick].properties); + const auto& l_stick = axis_values[LStick]; + const auto l_button = button_values[Settings::NativeButton::LStick]; + const auto& r_stick = axis_values[RStick]; + const auto r_button = button_values[Settings::NativeButton::RStick]; + + DrawJoystick(p, center + QPointF(-171, -41) + (l_stick.value * 4), 1.0f, l_button); + DrawJoystick(p, center + QPointF(171, 8) + (r_stick.value * 4), 1.0f, r_button); + DrawRawJoystick(p, center + QPointF(-50, 0), l_stick.raw_value, l_stick.properties); + DrawRawJoystick(p, center + QPointF(50, 0), r_stick.raw_value, r_stick.properties); } using namespace Settings::NativeButton; @@ -699,9 +702,9 @@ void PlayerControlPreview::DrawProController(QPainter& p, const QPointF center) { // Draw joysticks using namespace Settings::NativeAnalog; - DrawProJoystick(p, center + QPointF(-111, -55) + (axis_values[LStick].value * 11), + DrawProJoystick(p, center + QPointF(-111, -55), axis_values[LStick].value, 11, button_values[Settings::NativeButton::LStick]); - DrawProJoystick(p, center + QPointF(51, 0) + (axis_values[RStick].value * 11), + DrawProJoystick(p, center + QPointF(51, 0), axis_values[RStick].value, 11, button_values[Settings::NativeButton::RStick]); DrawRawJoystick(p, center + QPointF(-50, 105), axis_values[LStick].raw_value, axis_values[LStick].properties); @@ -1002,12 +1005,6 @@ constexpr std::array<float, 3 * 2> up_arrow_symbol = { 0.0f, -3.0f, -3.0f, 2.0f, 3.0f, 2.0f, }; -constexpr std::array<float, 13 * 2> up_arrow = { - 9.4f, -9.8f, 9.4f, -10.2f, 8.9f, -29.8f, 8.5f, -30.0f, 8.1f, - -30.1f, 7.7f, -30.1f, -8.6f, -30.0f, -9.0f, -29.8f, -9.3f, -29.5f, - -9.5f, -29.1f, -9.5f, -28.7f, -9.1f, -9.1f, -8.8f, -8.8f, -}; - constexpr std::array<float, 64 * 2> trigger_button = { 5.5f, -12.6f, 5.8f, -12.6f, 6.7f, -12.5f, 8.1f, -12.3f, 8.6f, -12.2f, 9.2f, -12.0f, 9.5f, -11.9f, 9.9f, -11.8f, 10.6f, -11.5f, 11.0f, -11.3f, 11.2f, -11.2f, 11.4f, -11.1f, @@ -1457,15 +1454,18 @@ void PlayerControlPreview::DrawProBody(QPainter& p, const QPointF center) { constexpr int radius1 = 32; for (std::size_t point = 0; point < pro_left_handle.size() / 2; ++point) { - qleft_handle[point] = - center + QPointF(pro_left_handle[point * 2], pro_left_handle[point * 2 + 1]); - qright_handle[point] = - center + QPointF(-pro_left_handle[point * 2], pro_left_handle[point * 2 + 1]); + const float left_x = pro_left_handle[point * 2 + 0]; + const float left_y = pro_left_handle[point * 2 + 1]; + + qleft_handle[point] = center + QPointF(left_x, left_y); + qright_handle[point] = center + QPointF(-left_x, left_y); } for (std::size_t point = 0; point < pro_body.size() / 2; ++point) { - qbody[point] = center + QPointF(pro_body[point * 2], pro_body[point * 2 + 1]); - qbody[pro_body.size() - 1 - point] = - center + QPointF(-pro_body[point * 2], pro_body[point * 2 + 1]); + const float body_x = pro_body[point * 2 + 0]; + const float body_y = pro_body[point * 2 + 1]; + + qbody[point] = center + QPointF(body_x, body_y); + qbody[pro_body.size() - 1 - point] = center + QPointF(-body_x, body_y); } // Draw left handle body @@ -1496,21 +1496,25 @@ void PlayerControlPreview::DrawGCBody(QPainter& p, const QPointF center) { constexpr float angle = 2 * 3.1415f / 8; for (std::size_t point = 0; point < gc_left_body.size() / 2; ++point) { - qleft_handle[point] = - center + QPointF(gc_left_body[point * 2], gc_left_body[point * 2 + 1]); - qright_handle[point] = - center + QPointF(-gc_left_body[point * 2], gc_left_body[point * 2 + 1]); + const float body_x = gc_left_body[point * 2 + 0]; + const float body_y = gc_left_body[point * 2 + 1]; + + qleft_handle[point] = center + QPointF(body_x, body_y); + qright_handle[point] = center + QPointF(-body_x, body_y); } for (std::size_t point = 0; point < gc_body.size() / 2; ++point) { - qbody[point] = center + QPointF(gc_body[point * 2], gc_body[point * 2 + 1]); - qbody[gc_body.size() - 1 - point] = - center + QPointF(-gc_body[point * 2], gc_body[point * 2 + 1]); + const float body_x = gc_body[point * 2 + 0]; + const float body_y = gc_body[point * 2 + 1]; + + qbody[point] = center + QPointF(body_x, body_y); + qbody[gc_body.size() - 1 - point] = center + QPointF(-body_x, body_y); } for (std::size_t point = 0; point < 8; ++point) { - left_hex[point] = - center + QPointF(34 * std::cos(point * angle) - 111, 34 * std::sin(point * angle) - 44); - right_hex[point] = - center + QPointF(26 * std::cos(point * angle) + 61, 26 * std::sin(point * angle) + 37); + const float point_cos = std::cos(point * angle); + const float point_sin = std::sin(point * angle); + + left_hex[point] = center + QPointF(34 * point_cos - 111, 34 * point_sin - 44); + right_hex[point] = center + QPointF(26 * point_cos + 61, 26 * point_sin + 37); } // Draw body @@ -1631,32 +1635,36 @@ void PlayerControlPreview::DrawDualBody(QPainter& p, const QPointF center) { 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, - left_joycon_body[point * 2 + 1] * size - 1); - right_joycon[point] = center + QPointF(-left_joycon_body[point * 2] * size - offset, - left_joycon_body[point * 2 + 1] * size - 1); + const float body_x = left_joycon_body[point * 2 + 0]; + const float body_y = left_joycon_body[point * 2 + 1]; + + left_joycon[point] = center + QPointF(body_x * size + offset, body_y * size - 1); + right_joycon[point] = center + QPointF(-body_x * size - offset, body_y * size - 1); } 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]); + const float slider_x = left_joycon_slider[point * 2 + 0]; + const float slider_y = left_joycon_slider[point * 2 + 1]; + + qleft_joycon_slider[point] = center + QPointF(slider_x, slider_y); + qright_joycon_slider[point] = center + QPointF(-slider_x, slider_y); } for (std::size_t point = 0; point < left_joycon_topview.size() / 2; ++point) { + const float top_view_x = left_joycon_topview[point * 2 + 0]; + const float top_view_y = left_joycon_topview[point * 2 + 1]; + qleft_joycon_topview[point] = - center + QPointF(left_joycon_topview[point * 2] * size2 - 52, - left_joycon_topview[point * 2 + 1] * size2 - 52); + center + QPointF(top_view_x * size2 - 52, top_view_y * size2 - 52); qright_joycon_topview[point] = - center + QPointF(-left_joycon_topview[point * 2] * size2 + 52, - left_joycon_topview[point * 2 + 1] * size2 - 52); + center + QPointF(-top_view_x * size2 + 52, top_view_y * size2 - 52); } for (std::size_t point = 0; point < left_joycon_slider_topview.size() / 2; ++point) { + const float top_view_x = left_joycon_slider_topview[point * 2 + 0]; + const float top_view_y = left_joycon_slider_topview[point * 2 + 1]; + qleft_joycon_slider_topview[point] = - center + QPointF(left_joycon_slider_topview[point * 2] * size2 - 52, - left_joycon_slider_topview[point * 2 + 1] * size2 - 52); + center + QPointF(top_view_x * size2 - 52, top_view_y * 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); + center + QPointF(-top_view_x * size2 + 52, top_view_y * size2 - 52); } // right joycon body @@ -1905,18 +1913,19 @@ void PlayerControlPreview::DrawProTriggers(QPainter& p, const QPointF center, bo std::array<QPointF, pro_body_top.size()> qbody_top; for (std::size_t point = 0; point < pro_left_trigger.size() / 2; ++point) { - qleft_trigger[point] = - center + QPointF(pro_left_trigger[point * 2], - pro_left_trigger[point * 2 + 1] + (left_pressed ? 2 : 0)); - qright_trigger[point] = - center + QPointF(-pro_left_trigger[point * 2], - pro_left_trigger[point * 2 + 1] + (right_pressed ? 2 : 0)); + const float trigger_x = pro_left_trigger[point * 2 + 0]; + const float trigger_y = pro_left_trigger[point * 2 + 1]; + + qleft_trigger[point] = center + QPointF(trigger_x, trigger_y + (left_pressed ? 2 : 0)); + qright_trigger[point] = center + QPointF(-trigger_x, trigger_y + (right_pressed ? 2 : 0)); } for (std::size_t point = 0; point < pro_body_top.size() / 2; ++point) { - qbody_top[pro_body_top.size() - 1 - point] = - center + QPointF(-pro_body_top[point * 2], pro_body_top[point * 2 + 1]); - qbody_top[point] = center + QPointF(pro_body_top[point * 2], pro_body_top[point * 2 + 1]); + const float top_x = pro_body_top[point * 2 + 0]; + const float top_y = pro_body_top[point * 2 + 1]; + + qbody_top[pro_body_top.size() - 1 - point] = center + QPointF(-top_x, top_y); + qbody_top[point] = center + QPointF(top_x, top_y); } // Pro body detail @@ -1939,12 +1948,11 @@ void PlayerControlPreview::DrawGCTriggers(QPainter& p, const QPointF center, boo std::array<QPointF, left_gc_trigger.size() / 2> qright_trigger; for (std::size_t point = 0; point < left_gc_trigger.size() / 2; ++point) { - qleft_trigger[point] = - center + QPointF(left_gc_trigger[point * 2], - left_gc_trigger[point * 2 + 1] + (left_pressed ? 10 : 0)); - qright_trigger[point] = - center + QPointF(-left_gc_trigger[point * 2], - left_gc_trigger[point * 2 + 1] + (right_pressed ? 10 : 0)); + const float trigger_x = left_gc_trigger[point * 2 + 0]; + const float trigger_y = left_gc_trigger[point * 2 + 1]; + + qleft_trigger[point] = center + QPointF(trigger_x, trigger_y + (left_pressed ? 10 : 0)); + qright_trigger[point] = center + QPointF(-trigger_x, trigger_y + (right_pressed ? 10 : 0)); } // Left trigger @@ -1973,12 +1981,13 @@ void PlayerControlPreview::DrawHandheldTriggers(QPainter& p, const QPointF cente std::array<QPointF, left_joycon_trigger.size() / 2> qright_trigger; for (std::size_t point = 0; point < left_joycon_trigger.size() / 2; ++point) { + const float left_trigger_x = left_joycon_trigger[point * 2 + 0]; + const float left_trigger_y = left_joycon_trigger[point * 2 + 1]; + qleft_trigger[point] = - center + QPointF(left_joycon_trigger[point * 2], - left_joycon_trigger[point * 2 + 1] + (left_pressed ? 0.5f : 0)); + center + QPointF(left_trigger_x, left_trigger_y + (left_pressed ? 0.5f : 0)); qright_trigger[point] = - center + QPointF(-left_joycon_trigger[point * 2], - left_joycon_trigger[point * 2 + 1] + (right_pressed ? 0.5f : 0)); + center + QPointF(-left_trigger_x, left_trigger_y + (right_pressed ? 0.5f : 0)); } // Left trigger @@ -1998,12 +2007,14 @@ void PlayerControlPreview::DrawDualTriggers(QPainter& p, const QPointF center, b constexpr float size = 1.62f; constexpr float offset = 210.6f; for (std::size_t point = 0; point < left_joycon_trigger.size() / 2; ++point) { - qleft_trigger[point] = - center + QPointF(left_joycon_trigger[point * 2] * size + offset, - left_joycon_trigger[point * 2 + 1] * size + (left_pressed ? 0.5f : 0)); - qright_trigger[point] = center + QPointF(-left_joycon_trigger[point * 2] * size - offset, - left_joycon_trigger[point * 2 + 1] * size + - (right_pressed ? 0.5f : 0)); + const float left_trigger_x = left_joycon_trigger[point * 2 + 0]; + const float left_trigger_y = left_joycon_trigger[point * 2 + 1]; + + qleft_trigger[point] = center + QPointF(left_trigger_x * size + offset, + left_trigger_y * size + (left_pressed ? 0.5f : 0)); + qright_trigger[point] = + center + QPointF(-left_trigger_x * size - offset, + left_trigger_y * size + (right_pressed ? 0.5f : 0)); } // Left trigger @@ -2023,13 +2034,16 @@ void PlayerControlPreview::DrawDualTriggersTopView(QPainter& p, const QPointF ce constexpr float size = 0.9f; 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); + const float top_view_x = left_joystick_L_topview[point * 2 + 0]; + const float top_view_y = left_joystick_L_topview[point * 2 + 1]; + + qleft_trigger[point] = center + QPointF(top_view_x * size - 50, top_view_y * 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); + const float top_view_x = left_joystick_L_topview[point * 2 + 0]; + const float top_view_y = left_joystick_L_topview[point * 2 + 1]; + + qright_trigger[point] = center + QPointF(-top_view_x * size + 50, top_view_y * size - 52); } p.setPen(colors.outline); @@ -2273,15 +2287,39 @@ void PlayerControlPreview::DrawJoystickSideview(QPainter& p, const QPointF cente p.drawLine(p2.at(32), p2.at(71)); } -void PlayerControlPreview::DrawProJoystick(QPainter& p, const QPointF center, bool pressed) { +void PlayerControlPreview::DrawProJoystick(QPainter& p, const QPointF center, const QPointF offset, + float offset_scalar, bool pressed) { + const float radius1 = 24.0f; + const float radius2 = 17.0f; + + const QPointF offset_center = center + offset * offset_scalar; + + const auto amplitude = static_cast<float>( + 1.0 - std::sqrt((offset.x() * offset.x()) + (offset.y() * offset.y())) * 0.1f); + + const float rotation = + ((offset.x() == 0) ? atan(1) * 2 : atan(offset.y() / offset.x())) * (180 / (atan(1) * 4)); + + p.save(); + p.translate(offset_center); + p.rotate(rotation); + // Outer circle p.setPen(colors.outline); p.setBrush(pressed ? colors.highlight : colors.button); - DrawCircle(p, center, 24.0f); + p.drawEllipse(QPointF(0, 0), radius1 * amplitude, radius1); // Inner circle p.setBrush(pressed ? colors.highlight2 : colors.button2); - DrawCircle(p, center, 17.0f); + + const float inner_offset = + (radius1 - radius2) * 0.4f * ((offset.x() == 0 && offset.y() < 0) ? -1.0f : 1.0f); + const float offset_factor = (1.0f - amplitude) / 0.1f; + + p.drawEllipse(QPointF((offset.x() < 0) ? -inner_offset : inner_offset, 0) * offset_factor, + radius2 * amplitude, radius2); + + p.restore(); } void PlayerControlPreview::DrawGCJoystick(QPainter& p, const QPointF center, bool pressed) { @@ -2299,7 +2337,7 @@ void PlayerControlPreview::DrawGCJoystick(QPainter& p, const QPointF center, boo } void PlayerControlPreview::DrawRawJoystick(QPainter& p, const QPointF center, const QPointF value, - const Input::AnalogProperties properties) { + const Input::AnalogProperties& properties) { constexpr float size = 45.0f; const float range = size * properties.range; const float deadzone = size * properties.deadzone; @@ -2422,17 +2460,16 @@ void PlayerControlPreview::DrawArrowButtonOutline(QPainter& p, const QPointF cen std::array<QPointF, (arrow_points - 1) * 4> arrow_button_outline; for (std::size_t point = 0; point < arrow_points - 1; ++point) { - arrow_button_outline[point] = center + QPointF(up_arrow_button[point * 2] * size, - up_arrow_button[point * 2 + 1] * size); + const float up_arrow_x = up_arrow_button[point * 2 + 0]; + const float up_arrow_y = up_arrow_button[point * 2 + 1]; + + arrow_button_outline[point] = center + QPointF(up_arrow_x * size, up_arrow_y * size); arrow_button_outline[(arrow_points - 1) * 2 - point - 1] = - center + - QPointF(up_arrow_button[point * 2 + 1] * size, up_arrow_button[point * 2] * size); + center + QPointF(up_arrow_y * size, up_arrow_x * size); arrow_button_outline[(arrow_points - 1) * 2 + point] = - center + - QPointF(-up_arrow_button[point * 2] * size, -up_arrow_button[point * 2 + 1] * size); + center + QPointF(-up_arrow_x * size, -up_arrow_y * size); arrow_button_outline[(arrow_points - 1) * 4 - point - 1] = - center + - QPointF(-up_arrow_button[point * 2 + 1] * size, -up_arrow_button[point * 2] * size); + center + QPointF(-up_arrow_y * size, -up_arrow_x * size); } // Draw arrow button outline p.setPen(colors.outline); @@ -2446,22 +2483,21 @@ void PlayerControlPreview::DrawArrowButton(QPainter& p, const QPointF center, QPoint offset; for (std::size_t point = 0; point < up_arrow_button.size() / 2; ++point) { + const float up_arrow_x = up_arrow_button[point * 2 + 0]; + const float up_arrow_y = up_arrow_button[point * 2 + 1]; + switch (direction) { case Direction::Up: - arrow_button[point] = center + QPointF(up_arrow_button[point * 2] * size, - up_arrow_button[point * 2 + 1] * size); + arrow_button[point] = center + QPointF(up_arrow_x * size, up_arrow_y * size); break; case Direction::Left: - arrow_button[point] = center + QPointF(up_arrow_button[point * 2 + 1] * size, - up_arrow_button[point * 2] * size); + arrow_button[point] = center + QPointF(up_arrow_y * size, up_arrow_x * size); break; case Direction::Right: - arrow_button[point] = center + QPointF(-up_arrow_button[point * 2 + 1] * size, - up_arrow_button[point * 2] * size); + arrow_button[point] = center + QPointF(-up_arrow_y * size, up_arrow_x * size); break; case Direction::Down: - arrow_button[point] = center + QPointF(up_arrow_button[point * 2] * size, - -up_arrow_button[point * 2 + 1] * size); + arrow_button[point] = center + QPointF(up_arrow_x * size, -up_arrow_y * size); break; case Direction::None: break; @@ -2500,17 +2536,17 @@ void PlayerControlPreview::DrawArrowButton(QPainter& p, const QPointF center, void PlayerControlPreview::DrawTriggerButton(QPainter& p, const QPointF center, const Direction direction, bool pressed) { std::array<QPointF, trigger_button.size() / 2> qtrigger_button; - QPoint offset; for (std::size_t point = 0; point < trigger_button.size() / 2; ++point) { + const float trigger_button_x = trigger_button[point * 2 + 0]; + const float trigger_button_y = trigger_button[point * 2 + 1]; + switch (direction) { case Direction::Left: - qtrigger_button[point] = - center + QPointF(-trigger_button[point * 2], trigger_button[point * 2 + 1]); + qtrigger_button[point] = center + QPointF(-trigger_button_x, trigger_button_y); break; case Direction::Right: - qtrigger_button[point] = - center + QPointF(trigger_button[point * 2], trigger_button[point * 2 + 1]); + qtrigger_button[point] = center + QPointF(trigger_button_x, trigger_button_y); break; case Direction::Up: case Direction::Down: @@ -2633,22 +2669,21 @@ void PlayerControlPreview::DrawArrow(QPainter& p, const QPointF center, const Di std::array<QPointF, up_arrow_symbol.size() / 2> arrow_symbol; for (std::size_t point = 0; point < up_arrow_symbol.size() / 2; ++point) { + const float up_arrow_x = up_arrow_symbol[point * 2 + 0]; + const float up_arrow_y = up_arrow_symbol[point * 2 + 1]; + switch (direction) { case Direction::Up: - arrow_symbol[point] = center + QPointF(up_arrow_symbol[point * 2] * size, - up_arrow_symbol[point * 2 + 1] * size); + arrow_symbol[point] = center + QPointF(up_arrow_x * size, up_arrow_y * size); break; case Direction::Left: - arrow_symbol[point] = center + QPointF(up_arrow_symbol[point * 2 + 1] * size, - up_arrow_symbol[point * 2] * size); + arrow_symbol[point] = center + QPointF(up_arrow_y * size, up_arrow_x * size); break; case Direction::Right: - arrow_symbol[point] = center + QPointF(-up_arrow_symbol[point * 2 + 1] * size, - up_arrow_symbol[point * 2] * size); + arrow_symbol[point] = center + QPointF(-up_arrow_y * size, up_arrow_x * size); break; case Direction::Down: - arrow_symbol[point] = center + QPointF(up_arrow_symbol[point * 2] * size, - -up_arrow_symbol[point * 2 + 1] * size); + arrow_symbol[point] = center + QPointF(up_arrow_x * size, -up_arrow_y * size); break; case Direction::None: break; diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h index 39565f795..91c3343f1 100644 --- a/src/yuzu/configuration/configure_input_player_widget.h +++ b/src/yuzu/configuration/configure_input_player_widget.h @@ -25,7 +25,7 @@ public: void SetPlayerInput(std::size_t index, const ButtonParam& buttons_param, const AnalogParam& analogs_param); - void SetPlayerInputRaw(std::size_t index, const Settings::ButtonsRaw buttons_, + void SetPlayerInputRaw(std::size_t index, const Settings::ButtonsRaw& buttons_, Settings::AnalogsRaw analogs_); void SetConnectedStatus(bool checked); void SetControllerType(Settings::ControllerType type); @@ -138,9 +138,9 @@ private: // Draw joystick functions void DrawJoystick(QPainter& p, QPointF center, float size, bool pressed); void DrawJoystickSideview(QPainter& p, QPointF center, float angle, float size, bool pressed); - void DrawRawJoystick(QPainter& p, QPointF center, const QPointF value, - const Input::AnalogProperties properties); - void DrawProJoystick(QPainter& p, QPointF center, bool pressed); + void DrawRawJoystick(QPainter& p, QPointF center, QPointF value, + const Input::AnalogProperties& properties); + void DrawProJoystick(QPainter& p, QPointF center, QPointF offset, float scalar, bool pressed); void DrawGCJoystick(QPainter& p, QPointF center, bool pressed); // Draw button functions diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index ef92c25bc..52218eb70 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -850,6 +850,16 @@ 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; + 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); + } + }); } void GMainWindow::SetDefaultUIGeometry() { @@ -1197,7 +1207,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); @@ -2359,7 +2369,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(); @@ -2600,7 +2610,8 @@ void GMainWindow::UpdateUISettings() { } void GMainWindow::HideMouseCursor() { - if (emu_thread == nullptr || UISettings::values.hide_mouse == false) { + if (emu_thread == nullptr || + (!UISettings::values.hide_mouse && !Settings::values.mouse_panning)) { mouse_hide_timer.stop(); ShowMouseCursor(); return; @@ -2610,13 +2621,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 100644 --- 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) { |