diff options
| author | 2021-01-02 22:04:50 -0600 | |
|---|---|---|
| committer | 2021-01-15 09:05:17 -0600 | |
| commit | 8495e1bd8373fed993975e40c360c87409455e9e (patch) | |
| tree | fffff1304673212280dc0e927b69efa3ca4fc8b3 /src/core/hle | |
| parent | Allow to return up to 16 touch inputs per engine (diff) | |
| download | yuzu-8495e1bd8373fed993975e40c360c87409455e9e.tar.gz yuzu-8495e1bd8373fed993975e40c360c87409455e9e.tar.xz yuzu-8495e1bd8373fed993975e40c360c87409455e9e.zip | |
Add mutitouch support for touch screens
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.h | 14 |
2 files changed, 25 insertions, 19 deletions
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index dc0d2c712..cd318f25b 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -18,7 +18,7 @@ Controller_Touchscreen::Controller_Touchscreen(Core::System& system) : Controlle | |||
| 18 | Controller_Touchscreen::~Controller_Touchscreen() = default; | 18 | Controller_Touchscreen::~Controller_Touchscreen() = default; |
| 19 | 19 | ||
| 20 | void Controller_Touchscreen::OnInit() { | 20 | void Controller_Touchscreen::OnInit() { |
| 21 | for (size_t id = 0; id < MAX_FINGERS; id++) { | 21 | for (std::size_t id = 0; id < MAX_FINGERS; ++id) { |
| 22 | mouse_finger_id[id] = MAX_FINGERS; | 22 | mouse_finger_id[id] = MAX_FINGERS; |
| 23 | keyboard_finger_id[id] = MAX_FINGERS; | 23 | keyboard_finger_id[id] = MAX_FINGERS; |
| 24 | udp_finger_id[id] = MAX_FINGERS; | 24 | udp_finger_id[id] = MAX_FINGERS; |
| @@ -48,23 +48,29 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 48 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 48 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 49 | 49 | ||
| 50 | const Input::TouchStatus& mouse_status = touch_mouse_device->GetStatus(); | 50 | const Input::TouchStatus& mouse_status = touch_mouse_device->GetStatus(); |
| 51 | const Input::TouchStatus& keyboard_status = touch_btn_device->GetStatus(); | ||
| 52 | const Input::TouchStatus& udp_status = touch_udp_device->GetStatus(); | 51 | const Input::TouchStatus& udp_status = touch_udp_device->GetStatus(); |
| 53 | for (size_t id = 0; id < mouse_status.size(); id++) { | 52 | for (std::size_t id = 0; id < mouse_status.size(); ++id) { |
| 54 | mouse_finger_id[id] = UpdateTouchInputEvent(mouse_status[id], mouse_finger_id[id]); | 53 | mouse_finger_id[id] = UpdateTouchInputEvent(mouse_status[id], mouse_finger_id[id]); |
| 55 | keyboard_finger_id[id] = UpdateTouchInputEvent(keyboard_status[id], keyboard_finger_id[id]); | ||
| 56 | udp_finger_id[id] = UpdateTouchInputEvent(udp_status[id], udp_finger_id[id]); | 54 | udp_finger_id[id] = UpdateTouchInputEvent(udp_status[id], udp_finger_id[id]); |
| 57 | } | 55 | } |
| 58 | 56 | ||
| 57 | if (Settings::values.use_touch_from_button) { | ||
| 58 | const Input::TouchStatus& keyboard_status = touch_btn_device->GetStatus(); | ||
| 59 | for (std::size_t id = 0; id < mouse_status.size(); ++id) { | ||
| 60 | keyboard_finger_id[id] = | ||
| 61 | UpdateTouchInputEvent(keyboard_status[id], keyboard_finger_id[id]); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 59 | std::array<Finger, 16> active_fingers; | 65 | std::array<Finger, 16> active_fingers; |
| 60 | const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), | 66 | const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), |
| 61 | [](const auto& finger) { return finger.pressed; }); | 67 | [](const auto& finger) { return finger.pressed; }); |
| 62 | const auto active_fingers_count = | 68 | const auto active_fingers_count = |
| 63 | static_cast<size_t>(std::distance(active_fingers.begin(), end_iter)); | 69 | static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); |
| 64 | 70 | ||
| 65 | const u64 tick = core_timing.GetCPUTicks(); | 71 | const u64 tick = core_timing.GetCPUTicks(); |
| 66 | cur_entry.entry_count = static_cast<s32_le>(active_fingers_count); | 72 | cur_entry.entry_count = static_cast<s32_le>(active_fingers_count); |
| 67 | for (size_t id = 0; id < MAX_FINGERS; id++) { | 73 | for (std::size_t id = 0; id < MAX_FINGERS; ++id) { |
| 68 | auto& touch_entry = cur_entry.states[id]; | 74 | auto& touch_entry = cur_entry.states[id]; |
| 69 | if (id < active_fingers_count) { | 75 | if (id < active_fingers_count) { |
| 70 | touch_entry.x = static_cast<u16>(active_fingers[id].x * Layout::ScreenUndocked::Width); | 76 | touch_entry.x = static_cast<u16>(active_fingers[id].x * Layout::ScreenUndocked::Width); |
| @@ -73,7 +79,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 73 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; | 79 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; |
| 74 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; | 80 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; |
| 75 | touch_entry.delta_time = tick - active_fingers[id].last_touch; | 81 | touch_entry.delta_time = tick - active_fingers[id].last_touch; |
| 76 | active_fingers[id].last_touch = tick; | 82 | fingers[active_fingers[id].id].last_touch = tick; |
| 77 | touch_entry.finger = active_fingers[id].id; | 83 | touch_entry.finger = active_fingers[id].id; |
| 78 | touch_entry.attribute.raw = active_fingers[id].attribute.raw; | 84 | touch_entry.attribute.raw = active_fingers[id].attribute.raw; |
| 79 | } else { | 85 | } else { |
| @@ -101,8 +107,8 @@ void Controller_Touchscreen::OnLoadInputDevices() { | |||
| 101 | } | 107 | } |
| 102 | } | 108 | } |
| 103 | 109 | ||
| 104 | std::optional<size_t> Controller_Touchscreen::GetUnusedFingerID() const { | 110 | std::optional<std::size_t> Controller_Touchscreen::GetUnusedFingerID() const { |
| 105 | size_t first_free_id = 0; | 111 | std::size_t first_free_id = 0; |
| 106 | while (first_free_id < MAX_FINGERS) { | 112 | while (first_free_id < MAX_FINGERS) { |
| 107 | if (!fingers[first_free_id].pressed) { | 113 | if (!fingers[first_free_id].pressed) { |
| 108 | return first_free_id; | 114 | return first_free_id; |
| @@ -113,11 +119,11 @@ std::optional<size_t> Controller_Touchscreen::GetUnusedFingerID() const { | |||
| 113 | return std::nullopt; | 119 | return std::nullopt; |
| 114 | } | 120 | } |
| 115 | 121 | ||
| 116 | size_t Controller_Touchscreen::UpdateTouchInputEvent( | 122 | std::size_t Controller_Touchscreen::UpdateTouchInputEvent( |
| 117 | const std::tuple<float, float, bool>& touch_input, size_t finger_id) { | 123 | const std::tuple<float, float, bool>& touch_input, std::size_t finger_id) { |
| 118 | const auto& [x, y, pressed] = touch_input; | 124 | const auto& [x, y, pressed] = touch_input; |
| 119 | if (pressed) { | 125 | if (pressed) { |
| 120 | Attributes attribute = {}; | 126 | Attributes attribute{}; |
| 121 | if (finger_id == MAX_FINGERS) { | 127 | if (finger_id == MAX_FINGERS) { |
| 122 | const auto first_free_id = GetUnusedFingerID(); | 128 | const auto first_free_id = GetUnusedFingerID(); |
| 123 | if (!first_free_id) { | 129 | if (!first_free_id) { |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index e39ab89ee..784124e25 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h | |||
| @@ -30,17 +30,17 @@ public: | |||
| 30 | void OnLoadInputDevices() override; | 30 | void OnLoadInputDevices() override; |
| 31 | 31 | ||
| 32 | private: | 32 | private: |
| 33 | static constexpr size_t MAX_FINGERS = 16; | 33 | static constexpr std::size_t MAX_FINGERS = 16; |
| 34 | 34 | ||
| 35 | // Returns an unused finger id, if there is no fingers available std::nullopt will be returned | 35 | // Returns an unused finger id, if there is no fingers available std::nullopt will be returned |
| 36 | std::optional<size_t> GetUnusedFingerID() const; | 36 | std::optional<std::size_t> GetUnusedFingerID() const; |
| 37 | 37 | ||
| 38 | // If the touch is new it tries to assing a new finger id, if there is no fingers avaliable no | 38 | // If the touch is new it tries to assing a new finger id, if there is no fingers avaliable no |
| 39 | // changes will be made. Updates the coordinates if the finger id it's already set. If the touch | 39 | // changes will be made. Updates the coordinates if the finger id it's already set. If the touch |
| 40 | // ends delays the output by one frame to set the end_touch flag before finally freeing the | 40 | // ends delays the output by one frame to set the end_touch flag before finally freeing the |
| 41 | // finger id | 41 | // finger id |
| 42 | size_t UpdateTouchInputEvent(const std::tuple<float, float, bool>& touch_input, | 42 | std::size_t UpdateTouchInputEvent(const std::tuple<float, float, bool>& touch_input, |
| 43 | size_t finger_id); | 43 | std::size_t finger_id); |
| 44 | 44 | ||
| 45 | struct Attributes { | 45 | struct Attributes { |
| 46 | union { | 46 | union { |
| @@ -92,9 +92,9 @@ private: | |||
| 92 | std::unique_ptr<Input::TouchDevice> touch_mouse_device; | 92 | std::unique_ptr<Input::TouchDevice> touch_mouse_device; |
| 93 | std::unique_ptr<Input::TouchDevice> touch_udp_device; | 93 | std::unique_ptr<Input::TouchDevice> touch_udp_device; |
| 94 | std::unique_ptr<Input::TouchDevice> touch_btn_device; | 94 | std::unique_ptr<Input::TouchDevice> touch_btn_device; |
| 95 | std::array<size_t, MAX_FINGERS> mouse_finger_id; | 95 | std::array<std::size_t, MAX_FINGERS> mouse_finger_id; |
| 96 | std::array<size_t, MAX_FINGERS> keyboard_finger_id; | 96 | std::array<std::size_t, MAX_FINGERS> keyboard_finger_id; |
| 97 | std::array<size_t, MAX_FINGERS> udp_finger_id; | 97 | std::array<std::size_t, MAX_FINGERS> udp_finger_id; |
| 98 | std::array<Finger, MAX_FINGERS> fingers; | 98 | std::array<Finger, MAX_FINGERS> fingers; |
| 99 | }; | 99 | }; |
| 100 | } // namespace Service::HID | 100 | } // namespace Service::HID |