diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/frontend/emu_window.cpp | 42 | ||||
| -rw-r--r-- | src/core/frontend/emu_window.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.h | 14 |
4 files changed, 56 insertions, 42 deletions
diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 589842917..af6c1633a 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp | |||
| @@ -21,21 +21,17 @@ public: | |||
| 21 | 21 | ||
| 22 | std::mutex mutex; | 22 | std::mutex mutex; |
| 23 | 23 | ||
| 24 | bool touch_pressed = false; ///< True if touchpad area is currently pressed, otherwise false | 24 | Input::TouchStatus status; |
| 25 | |||
| 26 | float touch_x = 0.0f; ///< Touchpad X-position | ||
| 27 | float touch_y = 0.0f; ///< Touchpad Y-position | ||
| 28 | 25 | ||
| 29 | private: | 26 | private: |
| 30 | class Device : public Input::TouchDevice { | 27 | class Device : public Input::TouchDevice { |
| 31 | public: | 28 | public: |
| 32 | explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {} | 29 | explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {} |
| 33 | Input::TouchStatus GetStatus() const override { | 30 | Input::TouchStatus GetStatus() const override { |
| 34 | Input::TouchStatus touch_status = {}; | 31 | Input::TouchStatus touch_status{}; |
| 35 | if (auto state = touch_state.lock()) { | 32 | if (auto state = touch_state.lock()) { |
| 36 | std::lock_guard guard{state->mutex}; | 33 | std::lock_guard guard{state->mutex}; |
| 37 | touch_status[0] = | 34 | touch_status = state->status; |
| 38 | std::make_tuple(state->touch_x, state->touch_y, state->touch_pressed); | ||
| 39 | } | 35 | } |
| 40 | return touch_status; | 36 | return touch_status; |
| 41 | } | 37 | } |
| @@ -81,36 +77,44 @@ std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsi | |||
| 81 | return std::make_tuple(new_x, new_y); | 77 | return std::make_tuple(new_x, new_y); |
| 82 | } | 78 | } |
| 83 | 79 | ||
| 84 | void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | 80 | void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id) { |
| 85 | if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) | 81 | if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) { |
| 86 | return; | 82 | return; |
| 83 | } | ||
| 84 | if (id >= touch_state->status.size()) { | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | 87 | ||
| 88 | std::lock_guard guard{touch_state->mutex}; | 88 | std::lock_guard guard{touch_state->mutex}; |
| 89 | touch_state->touch_x = | 89 | const float x = |
| 90 | static_cast<float>(framebuffer_x - framebuffer_layout.screen.left) / | 90 | static_cast<float>(framebuffer_x - framebuffer_layout.screen.left) / |
| 91 | static_cast<float>(framebuffer_layout.screen.right - framebuffer_layout.screen.left); | 91 | static_cast<float>(framebuffer_layout.screen.right - framebuffer_layout.screen.left); |
| 92 | touch_state->touch_y = | 92 | const float y = |
| 93 | static_cast<float>(framebuffer_y - framebuffer_layout.screen.top) / | 93 | static_cast<float>(framebuffer_y - framebuffer_layout.screen.top) / |
| 94 | static_cast<float>(framebuffer_layout.screen.bottom - framebuffer_layout.screen.top); | 94 | static_cast<float>(framebuffer_layout.screen.bottom - framebuffer_layout.screen.top); |
| 95 | 95 | ||
| 96 | touch_state->touch_pressed = true; | 96 | touch_state->status[id] = std::make_tuple(x, y, true); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | void EmuWindow::TouchReleased() { | 99 | void EmuWindow::TouchReleased(std::size_t id) { |
| 100 | if (id >= touch_state->status.size()) { | ||
| 101 | return; | ||
| 102 | } | ||
| 100 | std::lock_guard guard{touch_state->mutex}; | 103 | std::lock_guard guard{touch_state->mutex}; |
| 101 | touch_state->touch_pressed = false; | 104 | touch_state->status[id] = std::make_tuple(0.0f, 0.0f, false); |
| 102 | touch_state->touch_x = 0; | ||
| 103 | touch_state->touch_y = 0; | ||
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { | 107 | void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id) { |
| 107 | if (!touch_state->touch_pressed) | 108 | if (id >= touch_state->status.size()) { |
| 109 | return; | ||
| 110 | } | ||
| 111 | if (!std::get<2>(touch_state->status[id])) | ||
| 108 | return; | 112 | return; |
| 109 | 113 | ||
| 110 | if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) | 114 | if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) |
| 111 | std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y); | 115 | std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y); |
| 112 | 116 | ||
| 113 | TouchPressed(framebuffer_x, framebuffer_y); | 117 | TouchPressed(framebuffer_x, framebuffer_y, id); |
| 114 | } | 118 | } |
| 115 | 119 | ||
| 116 | void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) { | 120 | void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) { |
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 276d2b906..f8db42ab4 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h | |||
| @@ -117,18 +117,22 @@ public: | |||
| 117 | * Signal that a touch pressed event has occurred (e.g. mouse click pressed) | 117 | * Signal that a touch pressed event has occurred (e.g. mouse click pressed) |
| 118 | * @param framebuffer_x Framebuffer x-coordinate that was pressed | 118 | * @param framebuffer_x Framebuffer x-coordinate that was pressed |
| 119 | * @param framebuffer_y Framebuffer y-coordinate that was pressed | 119 | * @param framebuffer_y Framebuffer y-coordinate that was pressed |
| 120 | * @param id Touch event id | ||
| 120 | */ | 121 | */ |
| 121 | void TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y); | 122 | void TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id); |
| 122 | 123 | ||
| 123 | /// Signal that a touch released event has occurred (e.g. mouse click released) | 124 | /** Signal that a touch released event has occurred (e.g. mouse click released) |
| 124 | void TouchReleased(); | 125 | *@param id Touch event id |
| 126 | */ | ||
| 127 | void TouchReleased(std::size_t id); | ||
| 125 | 128 | ||
| 126 | /** | 129 | /** |
| 127 | * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window) | 130 | * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window) |
| 128 | * @param framebuffer_x Framebuffer x-coordinate | 131 | * @param framebuffer_x Framebuffer x-coordinate |
| 129 | * @param framebuffer_y Framebuffer y-coordinate | 132 | * @param framebuffer_y Framebuffer y-coordinate |
| 133 | * @param id Touch event id | ||
| 130 | */ | 134 | */ |
| 131 | void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y); | 135 | void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id); |
| 132 | 136 | ||
| 133 | /** | 137 | /** |
| 134 | * Returns currently active configuration. | 138 | * Returns currently active configuration. |
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 |