summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/fs/path_util.cpp4
-rw-r--r--src/common/input.h1
-rw-r--r--src/common/string_util.cpp4
-rw-r--r--src/common/string_util.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_cp15.cpp2
-rw-r--r--src/core/hid/emulated_console.cpp15
-rw-r--r--src/core/hid/emulated_controller.cpp34
-rw-r--r--src/core/hid/input_converter.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp6
-rw-r--r--src/input_common/drivers/sdl_driver.cpp23
-rw-r--r--src/input_common/drivers/sdl_driver.h12
-rw-r--r--src/input_common/drivers/touch_screen.cpp89
-rw-r--r--src/input_common/drivers/touch_screen.h52
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.h2
-rw-r--r--src/shader_recompiler/frontend/maxwell/opcodes.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp18
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp2
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/about_dialog.cpp6
-rw-r--r--src/yuzu/aboutdialog.ui16
-rw-r--r--src/yuzu/applets/qt_software_keyboard.cpp29
-rw-r--r--src/yuzu/bootmanager.cpp58
-rw-r--r--src/yuzu/bootmanager.h6
-rw-r--r--src/yuzu/main.cpp6
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp2
26 files changed, 273 insertions, 128 deletions
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index 62318e70c..1074f2421 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -232,9 +232,7 @@ void SetYuzuPath(YuzuPath yuzu_path, const fs::path& new_path) {
232fs::path GetExeDirectory() { 232fs::path GetExeDirectory() {
233 wchar_t exe_path[MAX_PATH]; 233 wchar_t exe_path[MAX_PATH];
234 234
235 GetModuleFileNameW(nullptr, exe_path, MAX_PATH); 235 if (GetModuleFileNameW(nullptr, exe_path, MAX_PATH) == 0) {
236
237 if (!exe_path) {
238 LOG_ERROR(Common_Filesystem, 236 LOG_ERROR(Common_Filesystem,
239 "Failed to get the path to the executable of the current process"); 237 "Failed to get the path to the executable of the current process");
240 } 238 }
diff --git a/src/common/input.h b/src/common/input.h
index 54fcb24b0..bb42aaacc 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -72,6 +72,7 @@ enum class PollingError {
72enum class VibrationAmplificationType { 72enum class VibrationAmplificationType {
73 Linear, 73 Linear,
74 Exponential, 74 Exponential,
75 Test,
75}; 76};
76 77
77// Analog properties for calibration 78// Analog properties for calibration
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 703aa5db8..7a495bc79 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -178,6 +178,10 @@ std::wstring UTF8ToUTF16W(const std::string& input) {
178 178
179#endif 179#endif
180 180
181std::u16string U16StringFromBuffer(const u16* input, std::size_t length) {
182 return std::u16string(reinterpret_cast<const char16_t*>(input), length);
183}
184
181std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer, std::size_t max_len) { 185std::string StringFromFixedZeroTerminatedBuffer(std::string_view buffer, std::size_t max_len) {
182 std::size_t len = 0; 186 std::size_t len = 0;
183 while (len < buffer.length() && len < max_len && buffer[len] != '\0') { 187 while (len < buffer.length() && len < max_len && buffer[len] != '\0') {
diff --git a/src/common/string_util.h b/src/common/string_util.h
index a33830aec..ce18a33cf 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -44,6 +44,8 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
44 44
45#endif 45#endif
46 46
47[[nodiscard]] std::u16string U16StringFromBuffer(const u16* input, std::size_t length);
48
47/** 49/**
48 * Compares the string defined by the range [`begin`, `end`) to the null-terminated C-string 50 * Compares the string defined by the range [`begin`, `end`) to the null-terminated C-string
49 * `other` for equality. 51 * `other` for equality.
diff --git a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp
index a043e6735..6aae79c48 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_cp15.cpp
@@ -20,7 +20,7 @@ struct fmt::formatter<Dynarmic::A32::CoprocReg> {
20 } 20 }
21 template <typename FormatContext> 21 template <typename FormatContext>
22 auto format(const Dynarmic::A32::CoprocReg& reg, FormatContext& ctx) { 22 auto format(const Dynarmic::A32::CoprocReg& reg, FormatContext& ctx) {
23 return format_to(ctx.out(), "cp{}", static_cast<size_t>(reg)); 23 return fmt::format_to(ctx.out(), "cp{}", static_cast<size_t>(reg));
24 } 24 }
25}; 25};
26 26
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index fd220ccb5..aac45907d 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -27,12 +27,19 @@ void EmulatedConsole::SetTouchParams() {
27 // We can't use mouse as touch if native mouse is enabled 27 // We can't use mouse as touch if native mouse is enabled
28 touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"}; 28 touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
29 } 29 }
30 touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0"}; 30
31 touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1"}; 31 touch_params[index++] =
32 Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0,touch_id:0"};
33 touch_params[index++] =
34 Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1,touch_id:1"};
35 touch_params[index++] =
36 Common::ParamPackage{"engine:touch,axis_x:4,axis_y:5,button:2,touch_id:2"};
37 touch_params[index++] =
38 Common::ParamPackage{"engine:touch,axis_x:6,axis_y:7,button:3,touch_id:3"};
32 touch_params[index++] = 39 touch_params[index++] =
33 Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"}; 40 Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536,touch_id:0"};
34 touch_params[index++] = 41 touch_params[index++] =
35 Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072"}; 42 Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072,touch_id:1"};
36 43
37 const auto button_index = 44 const auto button_index =
38 static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue()); 45 static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index ba1dcd171..bd2384515 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -884,18 +884,42 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
884} 884}
885 885
886bool EmulatedController::TestVibration(std::size_t device_index) { 886bool EmulatedController::TestVibration(std::size_t device_index) {
887 static constexpr VibrationValue test_vibration = { 887 if (device_index >= output_devices.size()) {
888 return false;
889 }
890 if (!output_devices[device_index]) {
891 return false;
892 }
893
894 const auto player_index = NpadIdTypeToIndex(npad_id_type);
895 const auto& player = Settings::values.players.GetValue()[player_index];
896
897 if (!player.vibration_enabled) {
898 return false;
899 }
900
901 const Common::Input::VibrationStatus test_vibration = {
888 .low_amplitude = 0.001f, 902 .low_amplitude = 0.001f,
889 .low_frequency = 160.0f, 903 .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
890 .high_amplitude = 0.001f, 904 .high_amplitude = 0.001f,
891 .high_frequency = 320.0f, 905 .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
906 .type = Common::Input::VibrationAmplificationType::Test,
907 };
908
909 const Common::Input::VibrationStatus zero_vibration = {
910 .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
911 .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
912 .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
913 .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
914 .type = Common::Input::VibrationAmplificationType::Test,
892 }; 915 };
893 916
894 // Send a slight vibration to test for rumble support 917 // Send a slight vibration to test for rumble support
895 SetVibration(device_index, test_vibration); 918 output_devices[device_index]->SetVibration(test_vibration);
896 919
897 // Stop any vibration and return the result 920 // Stop any vibration and return the result
898 return SetVibration(device_index, DEFAULT_VIBRATION_VALUE); 921 return output_devices[device_index]->SetVibration(zero_vibration) ==
922 Common::Input::VibrationError::None;
899} 923}
900 924
901bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { 925bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
index 3c26260f3..18d9f042d 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -1,6 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm>
4#include <random> 5#include <random>
5 6
6#include "common/input.h" 7#include "common/input.h"
@@ -196,6 +197,9 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
196 x = std::clamp(x, 0.0f, 1.0f); 197 x = std::clamp(x, 0.0f, 1.0f);
197 y = std::clamp(y, 0.0f, 1.0f); 198 y = std::clamp(y, 0.0f, 1.0f);
198 199
200 // Limit id to maximum number of fingers
201 status.id = std::clamp(status.id, 0, 16);
202
199 if (status.pressed.inverted) { 203 if (status.pressed.inverted) {
200 status.pressed.value = !status.pressed.value; 204 status.pressed.value = !status.pressed.value;
201 } 205 }
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 108ce5a41..1da8d3eb0 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -44,7 +44,6 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
44 for (std::size_t id = 0; id < MAX_FINGERS; id++) { 44 for (std::size_t id = 0; id < MAX_FINGERS; id++) {
45 const auto& current_touch = touch_status[id]; 45 const auto& current_touch = touch_status[id];
46 auto& finger = fingers[id]; 46 auto& finger = fingers[id];
47 finger.position = current_touch.position;
48 finger.id = current_touch.id; 47 finger.id = current_touch.id;
49 48
50 if (finger.attribute.start_touch) { 49 if (finger.attribute.start_touch) {
@@ -61,13 +60,18 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
61 if (!finger.pressed && current_touch.pressed) { 60 if (!finger.pressed && current_touch.pressed) {
62 finger.attribute.start_touch.Assign(1); 61 finger.attribute.start_touch.Assign(1);
63 finger.pressed = true; 62 finger.pressed = true;
63 finger.position = current_touch.position;
64 continue; 64 continue;
65 } 65 }
66 66
67 if (finger.pressed && !current_touch.pressed) { 67 if (finger.pressed && !current_touch.pressed) {
68 finger.attribute.raw = 0; 68 finger.attribute.raw = 0;
69 finger.attribute.end_touch.Assign(1); 69 finger.attribute.end_touch.Assign(1);
70 continue;
70 } 71 }
72
73 // Only update position if touch is not on a special frame
74 finger.position = current_touch.position;
71 } 75 }
72 76
73 std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers; 77 std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers;
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index a5c63e74a..1a14ef10b 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
434 using namespace std::chrono_literals; 434 using namespace std::chrono_literals;
435 while (initialized) { 435 while (initialized) {
436 SDL_PumpEvents(); 436 SDL_PumpEvents();
437 SendVibrations();
437 std::this_thread::sleep_for(1ms); 438 std::this_thread::sleep_for(1ms);
438 } 439 }
439 }); 440 });
@@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble(
531 .type = Common::Input::VibrationAmplificationType::Exponential, 532 .type = Common::Input::VibrationAmplificationType::Exponential,
532 }; 533 };
533 534
534 if (!joystick->RumblePlay(new_vibration)) { 535 if (vibration.type == Common::Input::VibrationAmplificationType::Test) {
535 return Common::Input::VibrationError::Unknown; 536 if (!joystick->RumblePlay(new_vibration)) {
537 return Common::Input::VibrationError::Unknown;
538 }
539 return Common::Input::VibrationError::None;
536 } 540 }
537 541
542 vibration_queue.Push(VibrationRequest{
543 .identifier = identifier,
544 .vibration = new_vibration,
545 });
546
538 return Common::Input::VibrationError::None; 547 return Common::Input::VibrationError::None;
539} 548}
540 549
550void SDLDriver::SendVibrations() {
551 while (!vibration_queue.Empty()) {
552 VibrationRequest request;
553 vibration_queue.Pop(request);
554 const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(),
555 static_cast<int>(request.identifier.port));
556 joystick->RumblePlay(request.vibration);
557 }
558}
559
541Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, 560Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,
542 s32 axis, float value) const { 561 s32 axis, float value) const {
543 Common::ParamPackage params{}; 562 Common::ParamPackage params{};
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h
index dcd0d1e64..c82632506 100644
--- a/src/input_common/drivers/sdl_driver.h
+++ b/src/input_common/drivers/sdl_driver.h
@@ -12,6 +12,7 @@
12#include <SDL.h> 12#include <SDL.h>
13 13
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/threadsafe_queue.h"
15#include "input_common/input_engine.h" 16#include "input_common/input_engine.h"
16 17
17union SDL_Event; 18union SDL_Event;
@@ -64,12 +65,20 @@ public:
64 const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; 65 const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
65 66
66private: 67private:
68 struct VibrationRequest {
69 PadIdentifier identifier;
70 Common::Input::VibrationStatus vibration;
71 };
72
67 void InitJoystick(int joystick_index); 73 void InitJoystick(int joystick_index);
68 void CloseJoystick(SDL_Joystick* sdl_joystick); 74 void CloseJoystick(SDL_Joystick* sdl_joystick);
69 75
70 /// Needs to be called before SDL_QuitSubSystem. 76 /// Needs to be called before SDL_QuitSubSystem.
71 void CloseJoysticks(); 77 void CloseJoysticks();
72 78
79 /// Takes all vibrations from the queue and sends the command to the controller
80 void SendVibrations();
81
73 Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, 82 Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,
74 float value = 0.1f) const; 83 float value = 0.1f) const;
75 Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, 84 Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid,
@@ -107,6 +116,9 @@ private:
107 /// Returns true if the button is on the left joycon 116 /// Returns true if the button is on the left joycon
108 bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; 117 bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const;
109 118
119 /// Queue of vibration request to controllers
120 Common::SPSCQueue<VibrationRequest> vibration_queue;
121
110 /// Map of GUID of a list of corresponding virtual Joysticks 122 /// Map of GUID of a list of corresponding virtual Joysticks
111 std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; 123 std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
112 std::mutex joystick_map_mutex; 124 std::mutex joystick_map_mutex;
diff --git a/src/input_common/drivers/touch_screen.cpp b/src/input_common/drivers/touch_screen.cpp
index 8acbe4584..1753e0893 100644
--- a/src/input_common/drivers/touch_screen.cpp
+++ b/src/input_common/drivers/touch_screen.cpp
@@ -14,38 +14,93 @@ constexpr PadIdentifier identifier = {
14 14
15TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) { 15TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
16 PreSetController(identifier); 16 PreSetController(identifier);
17 ReleaseAllTouch();
17} 18}
18 19
19void TouchScreen::TouchMoved(float x, float y, std::size_t finger) { 20void TouchScreen::TouchMoved(float x, float y, std::size_t finger_id) {
20 if (finger >= 16) { 21 const auto index = GetIndexFromFingerId(finger_id);
22 if (!index) {
23 // Touch doesn't exist handle it as a new one
24 TouchPressed(x, y, finger_id);
21 return; 25 return;
22 } 26 }
23 TouchPressed(x, y, finger); 27 const auto i = index.value();
28 fingers[i].is_active = true;
29 SetButton(identifier, static_cast<int>(i), true);
30 SetAxis(identifier, static_cast<int>(i * 2), x);
31 SetAxis(identifier, static_cast<int>(i * 2 + 1), y);
24} 32}
25 33
26void TouchScreen::TouchPressed(float x, float y, std::size_t finger) { 34void TouchScreen::TouchPressed(float x, float y, std::size_t finger_id) {
27 if (finger >= 16) { 35 if (GetIndexFromFingerId(finger_id)) {
36 // Touch already exist. Just update the data
37 TouchMoved(x, y, finger_id);
28 return; 38 return;
29 } 39 }
30 SetButton(identifier, static_cast<int>(finger), true); 40 const auto index = GetNextFreeIndex();
31 SetAxis(identifier, static_cast<int>(finger * 2), x); 41 if (!index) {
32 SetAxis(identifier, static_cast<int>(finger * 2 + 1), y); 42 // No free entries. Ignore input
43 return;
44 }
45 const auto i = index.value();
46 fingers[i].is_enabled = true;
47 fingers[i].finger_id = finger_id;
48 TouchMoved(x, y, finger_id);
33} 49}
34 50
35void TouchScreen::TouchReleased(std::size_t finger) { 51void TouchScreen::TouchReleased(std::size_t finger_id) {
36 if (finger >= 16) { 52 const auto index = GetIndexFromFingerId(finger_id);
53 if (!index) {
37 return; 54 return;
38 } 55 }
39 SetButton(identifier, static_cast<int>(finger), false); 56 const auto i = index.value();
40 SetAxis(identifier, static_cast<int>(finger * 2), 0.0f); 57 fingers[i].is_enabled = false;
41 SetAxis(identifier, static_cast<int>(finger * 2 + 1), 0.0f); 58 SetButton(identifier, static_cast<int>(i), false);
59 SetAxis(identifier, static_cast<int>(i * 2), 0.0f);
60 SetAxis(identifier, static_cast<int>(i * 2 + 1), 0.0f);
61}
62
63std::optional<std::size_t> TouchScreen::GetIndexFromFingerId(std::size_t finger_id) const {
64 for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) {
65 const auto& finger = fingers[index];
66 if (!finger.is_enabled) {
67 continue;
68 }
69 if (finger.finger_id == finger_id) {
70 return index;
71 }
72 }
73 return std::nullopt;
74}
75
76std::optional<std::size_t> TouchScreen::GetNextFreeIndex() const {
77 for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) {
78 if (!fingers[index].is_enabled) {
79 return index;
80 }
81 }
82 return std::nullopt;
83}
84
85void TouchScreen::ClearActiveFlag() {
86 for (auto& finger : fingers) {
87 finger.is_active = false;
88 }
89}
90
91void TouchScreen::ReleaseInactiveTouch() {
92 for (const auto& finger : fingers) {
93 if (!finger.is_active) {
94 TouchReleased(finger.finger_id);
95 }
96 }
42} 97}
43 98
44void TouchScreen::ReleaseAllTouch() { 99void TouchScreen::ReleaseAllTouch() {
45 for (int index = 0; index < 16; ++index) { 100 for (const auto& finger : fingers) {
46 SetButton(identifier, index, false); 101 if (finger.is_enabled) {
47 SetAxis(identifier, index * 2, 0.0f); 102 TouchReleased(finger.finger_id);
48 SetAxis(identifier, index * 2 + 1, 0.0f); 103 }
49 } 104 }
50} 105}
51 106
diff --git a/src/input_common/drivers/touch_screen.h b/src/input_common/drivers/touch_screen.h
index 193478ead..f46036ffd 100644
--- a/src/input_common/drivers/touch_screen.h
+++ b/src/input_common/drivers/touch_screen.h
@@ -3,41 +3,65 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <optional>
7
6#include "input_common/input_engine.h" 8#include "input_common/input_engine.h"
7 9
8namespace InputCommon { 10namespace InputCommon {
9 11
10/** 12/**
11 * A button device factory representing a keyboard. It receives keyboard events and forward them 13 * A touch device factory representing a touch screen. It receives touch events and forward them
12 * to all button devices it created. 14 * to all touch devices it created.
13 */ 15 */
14class TouchScreen final : public InputEngine { 16class TouchScreen final : public InputEngine {
15public: 17public:
16 explicit TouchScreen(std::string input_engine_); 18 explicit TouchScreen(std::string input_engine_);
17 19
18 /** 20 /**
19 * Signals that mouse has moved. 21 * Signals that touch has moved and marks this touch point as active
20 * @param x the x-coordinate of the cursor 22 * @param x new horizontal position
21 * @param y the y-coordinate of the cursor 23 * @param y new vertical position
22 * @param center_x the x-coordinate of the middle of the screen 24 * @param finger_id of the touch point to be updated
23 * @param center_y the y-coordinate of the middle of the screen
24 */ 25 */
25 void TouchMoved(float x, float y, std::size_t finger); 26 void TouchMoved(float x, float y, std::size_t finger_id);
26 27
27 /** 28 /**
28 * Sets the status of all buttons bound with the key to pressed 29 * Signals and creates a new touch point with this finger id
29 * @param key_code the code of the key to press 30 * @param x starting horizontal position
31 * @param y starting vertical position
32 * @param finger_id to be assigned to the new touch point
30 */ 33 */
31 void TouchPressed(float x, float y, std::size_t finger); 34 void TouchPressed(float x, float y, std::size_t finger_id);
32 35
33 /** 36 /**
34 * Sets the status of all buttons bound with the key to released 37 * Signals and resets the touch point related to the this finger id
35 * @param key_code the code of the key to release 38 * @param finger_id to be released
36 */ 39 */
37 void TouchReleased(std::size_t finger); 40 void TouchReleased(std::size_t finger_id);
41
42 /// Resets the active flag for each touch point
43 void ClearActiveFlag();
44
45 /// Releases all touch that haven't been marked as active
46 void ReleaseInactiveTouch();
38 47
39 /// Resets all inputs to their initial value 48 /// Resets all inputs to their initial value
40 void ReleaseAllTouch(); 49 void ReleaseAllTouch();
50
51private:
52 static constexpr std::size_t MAX_FINGER_COUNT = 16;
53
54 struct TouchStatus {
55 std::size_t finger_id{};
56 bool is_enabled{};
57 bool is_active{};
58 };
59
60 std::optional<std::size_t> GetIndexFromFingerId(std::size_t finger_id) const;
61
62 std::optional<std::size_t> GetNextFreeIndex() const;
63
64 std::array<TouchStatus, MAX_FINGER_COUNT> fingers{};
41}; 65};
42 66
43} // namespace InputCommon 67} // namespace InputCommon
diff --git a/src/shader_recompiler/frontend/ir/opcodes.h b/src/shader_recompiler/frontend/ir/opcodes.h
index d17dc0376..752879a18 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.h
+++ b/src/shader_recompiler/frontend/ir/opcodes.h
@@ -103,6 +103,6 @@ struct fmt::formatter<Shader::IR::Opcode> {
103 } 103 }
104 template <typename FormatContext> 104 template <typename FormatContext>
105 auto format(const Shader::IR::Opcode& op, FormatContext& ctx) { 105 auto format(const Shader::IR::Opcode& op, FormatContext& ctx) {
106 return format_to(ctx.out(), "{}", Shader::IR::NameOf(op)); 106 return fmt::format_to(ctx.out(), "{}", Shader::IR::NameOf(op));
107 } 107 }
108}; 108};
diff --git a/src/shader_recompiler/frontend/maxwell/opcodes.h b/src/shader_recompiler/frontend/maxwell/opcodes.h
index 83093fca0..72dd143c2 100644
--- a/src/shader_recompiler/frontend/maxwell/opcodes.h
+++ b/src/shader_recompiler/frontend/maxwell/opcodes.h
@@ -24,6 +24,6 @@ struct fmt::formatter<Shader::Maxwell::Opcode> {
24 } 24 }
25 template <typename FormatContext> 25 template <typename FormatContext>
26 auto format(const Shader::Maxwell::Opcode& opcode, FormatContext& ctx) { 26 auto format(const Shader::Maxwell::Opcode& opcode, FormatContext& ctx) {
27 return format_to(ctx.out(), "{}", NameOf(opcode)); 27 return fmt::format_to(ctx.out(), "{}", NameOf(opcode));
28 } 28 }
29}; 29};
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index fd27581ce..ce6c853c1 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -784,8 +784,8 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs)
784 }); 784 });
785 } else { 785 } else {
786 // Front face defines both faces 786 // Front face defines both faces
787 scheduler.Record([ref = regs.stencil_back_func_ref, write_mask = regs.stencil_back_mask, 787 scheduler.Record([ref = regs.stencil_front_func_ref, write_mask = regs.stencil_front_mask,
788 test_mask = regs.stencil_back_func_mask](vk::CommandBuffer cmdbuf) { 788 test_mask = regs.stencil_front_func_mask](vk::CommandBuffer cmdbuf) {
789 cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref); 789 cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref);
790 cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask); 790 cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask);
791 cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask); 791 cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask);
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 7b2ca8046..b3a77e07f 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -566,7 +566,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
566 } 566 }
567 567
568 VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR workgroup_layout; 568 VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR workgroup_layout;
569 if (khr_workgroup_memory_explicit_layout) { 569 if (khr_workgroup_memory_explicit_layout && is_shader_int16_supported) {
570 workgroup_layout = { 570 workgroup_layout = {
571 .sType = 571 .sType =
572 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, 572 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR,
@@ -577,6 +577,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
577 .workgroupMemoryExplicitLayout16BitAccess = VK_TRUE, 577 .workgroupMemoryExplicitLayout16BitAccess = VK_TRUE,
578 }; 578 };
579 SetNext(next, workgroup_layout); 579 SetNext(next, workgroup_layout);
580 } else if (khr_workgroup_memory_explicit_layout) {
581 // TODO(lat9nq): Find a proper fix for this
582 LOG_WARNING(Render_Vulkan, "Disabling VK_KHR_workgroup_memory_explicit_layout due to a "
583 "yuzu bug when host driver does not support 16-bit integers");
584 khr_workgroup_memory_explicit_layout = false;
580 } 585 }
581 586
582 VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR executable_properties; 587 VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR executable_properties;
@@ -664,6 +669,17 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
664 const bool is_amd = 669 const bool is_amd =
665 driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; 670 driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE;
666 if (is_amd) { 671 if (is_amd) {
672 // TODO(lat9nq): Add an upper bound when AMD fixes their VK_KHR_push_descriptor
673 const bool has_broken_push_descriptor = VK_VERSION_MAJOR(properties.driverVersion) == 2 &&
674 VK_VERSION_MINOR(properties.driverVersion) == 0 &&
675 VK_VERSION_PATCH(properties.driverVersion) >= 226;
676 if (khr_push_descriptor && has_broken_push_descriptor) {
677 LOG_WARNING(
678 Render_Vulkan,
679 "Disabling AMD driver 2.0.226 and later from broken VK_KHR_push_descriptor");
680 khr_push_descriptor = false;
681 }
682
667 // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2. 683 // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2.
668 sets_per_pool = 96; 684 sets_per_pool = 96;
669 // Disable VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT on AMD GCN4 and lower as it is broken. 685 // Disable VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT on AMD GCN4 and lower as it is broken.
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index b1ea6075a..2ad98dcfe 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -325,6 +325,8 @@ const char* ToString(VkResult result) noexcept {
325 return "VK_PIPELINE_COMPILE_REQUIRED_EXT"; 325 return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
326 case VkResult::VK_RESULT_MAX_ENUM: 326 case VkResult::VK_RESULT_MAX_ENUM:
327 return "VK_RESULT_MAX_ENUM"; 327 return "VK_RESULT_MAX_ENUM";
328 case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT:
329 return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
328 } 330 }
329 return "Unknown"; 331 return "Unknown";
330} 332}
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 2ee21f751..404acdd05 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -240,7 +240,7 @@ elseif(WIN32)
240 if(MSVC) 240 if(MSVC)
241 set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") 241 set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
242 elseif(MINGW) 242 elseif(MINGW)
243 set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-mwindows") 243 set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-Wl,--subsystem,windows")
244 endif() 244 endif()
245endif() 245endif()
246 246
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index cbcef7b45..eeff54359 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -19,7 +19,11 @@ AboutDialog::AboutDialog(QWidget* parent)
19 const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build; 19 const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build;
20 20
21 ui->setupUi(this); 21 ui->setupUi(this);
22 ui->labelLogo->setPixmap(QIcon::fromTheme(QStringLiteral("yuzu")).pixmap(200)); 22 // Try and request the icon from Qt theme (Linux?)
23 const QIcon yuzu_logo = QIcon::fromTheme(QStringLiteral("org.yuzu_emu.yuzu"));
24 if (!yuzu_logo.isNull()) {
25 ui->labelLogo->setPixmap(yuzu_logo.pixmap(200));
26 }
23 ui->labelBuildInfo->setText( 27 ui->labelBuildInfo->setText(
24 ui->labelBuildInfo->text().arg(QString::fromStdString(yuzu_build_version), 28 ui->labelBuildInfo->text().arg(QString::fromStdString(yuzu_build_version),
25 QString::fromUtf8(Common::g_build_date).left(10))); 29 QString::fromUtf8(Common::g_build_date).left(10)));
diff --git a/src/yuzu/aboutdialog.ui b/src/yuzu/aboutdialog.ui
index 2f7ddc7f3..1dd7b74bf 100644
--- a/src/yuzu/aboutdialog.ui
+++ b/src/yuzu/aboutdialog.ui
@@ -26,8 +26,20 @@
26 <verstretch>0</verstretch> 26 <verstretch>0</verstretch>
27 </sizepolicy> 27 </sizepolicy>
28 </property> 28 </property>
29 <property name="maximumSize">
30 <size>
31 <width>200</width>
32 <height>200</height>
33 </size>
34 </property>
29 <property name="text"> 35 <property name="text">
30 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/icons/yuzu.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> 36 <string/>
37 </property>
38 <property name="pixmap">
39 <pixmap resource="../../dist/qt_themes/default/default.qrc">:/icons/default/256x256/yuzu.png</pixmap>
40 </property>
41 <property name="scaledContents">
42 <bool>true</bool>
31 </property> 43 </property>
32 </widget> 44 </widget>
33 </item> 45 </item>
@@ -152,7 +164,7 @@ p, li { white-space: pre-wrap; }
152 </layout> 164 </layout>
153 </widget> 165 </widget>
154 <resources> 166 <resources>
155 <include location="../../dist/icons/icons.qrc"/> 167 <include location="../../dist/qt_themes_default/default/default.qrc"/>
156 </resources> 168 </resources>
157 <connections> 169 <connections>
158 <connection> 170 <connection>
diff --git a/src/yuzu/applets/qt_software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp
index d3cf0b43b..e8b217d90 100644
--- a/src/yuzu/applets/qt_software_keyboard.cpp
+++ b/src/yuzu/applets/qt_software_keyboard.cpp
@@ -411,11 +411,11 @@ void QtSoftwareKeyboardDialog::ShowTextCheckDialog(
411 break; 411 break;
412 } 412 }
413 413
414 auto text = ui->topOSK->currentIndex() == 1 414 const auto text = ui->topOSK->currentIndex() == 1 ? ui->text_edit_osk->toPlainText()
415 ? ui->text_edit_osk->toPlainText().toStdU16String() 415 : ui->line_edit_osk->text();
416 : ui->line_edit_osk->text().toStdU16String(); 416 auto text_str = Common::U16StringFromBuffer(text.utf16(), text.size());
417 417
418 emit SubmitNormalText(SwkbdResult::Ok, std::move(text), true); 418 emit SubmitNormalText(SwkbdResult::Ok, std::move(text_str), true);
419 break; 419 break;
420 } 420 }
421 } 421 }
@@ -562,7 +562,7 @@ void QtSoftwareKeyboardDialog::keyPressEvent(QKeyEvent* event) {
562 return; 562 return;
563 } 563 }
564 564
565 InlineTextInsertString(entered_text.toStdU16String()); 565 InlineTextInsertString(Common::U16StringFromBuffer(entered_text.utf16(), entered_text.size()));
566} 566}
567 567
568void QtSoftwareKeyboardDialog::MoveAndResizeWindow(QPoint pos, QSize size) { 568void QtSoftwareKeyboardDialog::MoveAndResizeWindow(QPoint pos, QSize size) {
@@ -1119,11 +1119,11 @@ void QtSoftwareKeyboardDialog::NormalKeyboardButtonClicked(QPushButton* button)
1119 } 1119 }
1120 1120
1121 if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) { 1121 if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) {
1122 auto text = ui->topOSK->currentIndex() == 1 1122 const auto text = ui->topOSK->currentIndex() == 1 ? ui->text_edit_osk->toPlainText()
1123 ? ui->text_edit_osk->toPlainText().toStdU16String() 1123 : ui->line_edit_osk->text();
1124 : ui->line_edit_osk->text().toStdU16String(); 1124 auto text_str = Common::U16StringFromBuffer(text.utf16(), text.size());
1125 1125
1126 emit SubmitNormalText(SwkbdResult::Ok, std::move(text)); 1126 emit SubmitNormalText(SwkbdResult::Ok, std::move(text_str));
1127 return; 1127 return;
1128 } 1128 }
1129 1129
@@ -1189,7 +1189,8 @@ void QtSoftwareKeyboardDialog::InlineKeyboardButtonClicked(QPushButton* button)
1189 return; 1189 return;
1190 } 1190 }
1191 1191
1192 InlineTextInsertString(button->text().toStdU16String()); 1192 const auto button_text = button->text();
1193 InlineTextInsertString(Common::U16StringFromBuffer(button_text.utf16(), button_text.size()));
1193 1194
1194 // Revert the keyboard to lowercase if the shift key is active. 1195 // Revert the keyboard to lowercase if the shift key is active.
1195 if (bottom_osk_index == BottomOSKIndex::UpperCase && !caps_lock_enabled) { 1196 if (bottom_osk_index == BottomOSKIndex::UpperCase && !caps_lock_enabled) {
@@ -1282,11 +1283,11 @@ void QtSoftwareKeyboardDialog::TranslateButtonPress(Core::HID::NpadButton button
1282 if (is_inline) { 1283 if (is_inline) {
1283 emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position); 1284 emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position);
1284 } else { 1285 } else {
1285 auto text = ui->topOSK->currentIndex() == 1 1286 const auto text = ui->topOSK->currentIndex() == 1 ? ui->text_edit_osk->toPlainText()
1286 ? ui->text_edit_osk->toPlainText().toStdU16String() 1287 : ui->line_edit_osk->text();
1287 : ui->line_edit_osk->text().toStdU16String(); 1288 auto text_str = Common::U16StringFromBuffer(text.utf16(), text.size());
1288 1289
1289 emit SubmitNormalText(SwkbdResult::Cancel, std::move(text)); 1290 emit SubmitNormalText(SwkbdResult::Cancel, std::move(text_str));
1290 } 1291 }
1291 break; 1292 break;
1292 case Core::HID::NpadButton::Y: 1293 case Core::HID::NpadButton::Y:
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index a1b819ae0..8f0a6bbb8 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -772,65 +772,25 @@ void GRenderWindow::wheelEvent(QWheelEvent* event) {
772void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { 772void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
773 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); 773 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
774 for (const auto& touch_point : touch_points) { 774 for (const auto& touch_point : touch_points) {
775 if (!TouchUpdate(touch_point)) { 775 const auto [x, y] = ScaleTouch(touch_point.pos());
776 TouchStart(touch_point); 776 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
777 } 777 input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, touch_point.id());
778 } 778 }
779} 779}
780 780
781void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) { 781void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) {
782 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); 782 QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
783 input_subsystem->GetTouchScreen()->ClearActiveFlag();
783 for (const auto& touch_point : touch_points) { 784 for (const auto& touch_point : touch_points) {
784 if (!TouchUpdate(touch_point)) { 785 const auto [x, y] = ScaleTouch(touch_point.pos());
785 TouchStart(touch_point); 786 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
786 } 787 input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, touch_point.id());
787 }
788 // Release all inactive points
789 for (std::size_t id = 0; id < touch_ids.size(); ++id) {
790 if (!TouchExist(touch_ids[id], touch_points)) {
791 touch_ids[id] = 0;
792 input_subsystem->GetTouchScreen()->TouchReleased(id);
793 }
794 } 788 }
789 input_subsystem->GetTouchScreen()->ReleaseInactiveTouch();
795} 790}
796 791
797void GRenderWindow::TouchEndEvent() { 792void GRenderWindow::TouchEndEvent() {
798 for (std::size_t id = 0; id < touch_ids.size(); ++id) { 793 input_subsystem->GetTouchScreen()->ReleaseAllTouch();
799 if (touch_ids[id] != 0) {
800 touch_ids[id] = 0;
801 input_subsystem->GetTouchScreen()->TouchReleased(id);
802 }
803 }
804}
805
806void GRenderWindow::TouchStart(const QTouchEvent::TouchPoint& touch_point) {
807 for (std::size_t id = 0; id < touch_ids.size(); ++id) {
808 if (touch_ids[id] == 0) {
809 touch_ids[id] = touch_point.id() + 1;
810 const auto [x, y] = ScaleTouch(touch_point.pos());
811 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
812 input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id);
813 }
814 }
815}
816
817bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) {
818 for (std::size_t id = 0; id < touch_ids.size(); ++id) {
819 if (touch_ids[id] == static_cast<std::size_t>(touch_point.id() + 1)) {
820 const auto [x, y] = ScaleTouch(touch_point.pos());
821 const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
822 input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id);
823 return true;
824 }
825 }
826 return false;
827}
828
829bool GRenderWindow::TouchExist(std::size_t id,
830 const QList<QTouchEvent::TouchPoint>& touch_points) const {
831 return std::any_of(touch_points.begin(), touch_points.end(), [id](const auto& point) {
832 return id == static_cast<std::size_t>(point.id() + 1);
833 });
834} 794}
835 795
836bool GRenderWindow::event(QEvent* event) { 796bool GRenderWindow::event(QEvent* event) {
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 4b0ce0293..841816564 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -217,10 +217,6 @@ private:
217 void TouchUpdateEvent(const QTouchEvent* event); 217 void TouchUpdateEvent(const QTouchEvent* event);
218 void TouchEndEvent(); 218 void TouchEndEvent();
219 219
220 void TouchStart(const QTouchEvent::TouchPoint& touch_point);
221 bool TouchUpdate(const QTouchEvent::TouchPoint& touch_point);
222 bool TouchExist(std::size_t id, const QList<QTouchEvent::TouchPoint>& touch_points) const;
223
224 void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; 220 void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
225 221
226 bool InitializeOpenGL(); 222 bool InitializeOpenGL();
@@ -246,8 +242,6 @@ private:
246 bool first_frame = false; 242 bool first_frame = false;
247 InputCommon::TasInput::TasState last_tas_state; 243 InputCommon::TasInput::TasState last_tas_state;
248 244
249 std::array<std::size_t, 16> touch_ids{};
250
251 Core::System& system; 245 Core::System& system;
252 246
253protected: 247protected:
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f607f464a..f4a9a7171 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1401,7 +1401,8 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1401 if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success && 1401 if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
1402 type == StartGameType::Normal) { 1402 type == StartGameType::Normal) {
1403 // Load per game settings 1403 // Load per game settings
1404 const auto file_path = std::filesystem::path{filename.toStdU16String()}; 1404 const auto file_path =
1405 std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())};
1405 const auto config_file_name = title_id == 0 1406 const auto config_file_name = title_id == 0
1406 ? Common::FS::PathToUTF8String(file_path.filename()) 1407 ? Common::FS::PathToUTF8String(file_path.filename())
1407 : fmt::format("{:016X}", title_id); 1408 : fmt::format("{:016X}", title_id);
@@ -1482,7 +1483,8 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1482 } 1483 }
1483 if (res != Loader::ResultStatus::Success || title_name.empty()) { 1484 if (res != Loader::ResultStatus::Success || title_name.empty()) {
1484 title_name = Common::FS::PathToUTF8String( 1485 title_name = Common::FS::PathToUTF8String(
1485 std::filesystem::path{filename.toStdU16String()}.filename()); 1486 std::filesystem::path{Common::U16StringFromBuffer(filename.utf16(), filename.size())}
1487 .filename());
1486 } 1488 }
1487 const bool is_64bit = system->Kernel().CurrentProcess()->Is64BitProcess(); 1489 const bool is_64bit = system->Kernel().CurrentProcess()->Is64BitProcess();
1488 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)"); 1490 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index ae2e62dc5..71c413e64 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -93,7 +93,7 @@ void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) {
93} 93}
94 94
95void EmuWindow_SDL2::OnFingerUp() { 95void EmuWindow_SDL2::OnFingerUp() {
96 input_subsystem->GetTouchScreen()->TouchReleased(0); 96 input_subsystem->GetTouchScreen()->ReleaseAllTouch();
97} 97}
98 98
99void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { 99void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {