diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.cpp | 97 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/touchscreen.h | 19 |
2 files changed, 93 insertions, 23 deletions
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 0df395e85..de8315ce4 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -40,29 +40,43 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 40 | cur_entry.sampling_number = last_entry.sampling_number + 1; | 40 | cur_entry.sampling_number = last_entry.sampling_number + 1; |
| 41 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 41 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 42 | 42 | ||
| 43 | bool pressed = false; | 43 | updateTouchInputEvent(touch_device->GetStatus(), mouse_finger_id); |
| 44 | float x, y; | 44 | updateTouchInputEvent(touch_btn_device->GetStatus(), keyboar_finger_id); |
| 45 | std::tie(x, y, pressed) = touch_device->GetStatus(); | 45 | |
| 46 | auto& touch_entry = cur_entry.states[0]; | 46 | std::array<Finger, 16> sorted_fingers; |
| 47 | touch_entry.attribute.raw = 0; | 47 | s32_le active_fingers = 0; |
| 48 | if (!pressed && touch_btn_device) { | 48 | for (Finger finger : fingers) { |
| 49 | std::tie(x, y, pressed) = touch_btn_device->GetStatus(); | 49 | if (finger.pressed) { |
| 50 | } | 50 | sorted_fingers[active_fingers++] = finger; |
| 51 | if (pressed && Settings::values.touchscreen.enabled) { | 51 | } |
| 52 | touch_entry.x = static_cast<u16>(x * Layout::ScreenUndocked::Width); | ||
| 53 | touch_entry.y = static_cast<u16>(y * Layout::ScreenUndocked::Height); | ||
| 54 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; | ||
| 55 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; | ||
| 56 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; | ||
| 57 | const u64 tick = core_timing.GetCPUTicks(); | ||
| 58 | touch_entry.delta_time = tick - last_touch; | ||
| 59 | last_touch = tick; | ||
| 60 | touch_entry.finger = Settings::values.touchscreen.finger; | ||
| 61 | cur_entry.entry_count = 1; | ||
| 62 | } else { | ||
| 63 | cur_entry.entry_count = 0; | ||
| 64 | } | 52 | } |
| 65 | 53 | ||
| 54 | const u64 tick = core_timing.GetCPUTicks(); | ||
| 55 | cur_entry.entry_count = active_fingers; | ||
| 56 | for (size_t id = 0; id < MAX_FINGERS; id++) { | ||
| 57 | auto& touch_entry = cur_entry.states[id]; | ||
| 58 | if (id < active_fingers) { | ||
| 59 | touch_entry.x = static_cast<u16>(sorted_fingers[id].x * Layout::ScreenUndocked::Width); | ||
| 60 | touch_entry.y = static_cast<u16>(sorted_fingers[id].y * Layout::ScreenUndocked::Height); | ||
| 61 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; | ||
| 62 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; | ||
| 63 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; | ||
| 64 | touch_entry.delta_time = tick - sorted_fingers[id].last_touch; | ||
| 65 | sorted_fingers[id].last_touch = tick; | ||
| 66 | touch_entry.finger = sorted_fingers[id].id; | ||
| 67 | touch_entry.attribute.raw = sorted_fingers[id].attribute.raw; | ||
| 68 | } else { | ||
| 69 | // Clear touch entry | ||
| 70 | touch_entry.attribute.raw = 0; | ||
| 71 | touch_entry.x = 0; | ||
| 72 | touch_entry.y = 0; | ||
| 73 | touch_entry.diameter_x = 0; | ||
| 74 | touch_entry.diameter_y = 0; | ||
| 75 | touch_entry.rotation_angle = 0; | ||
| 76 | touch_entry.delta_time = 0; | ||
| 77 | touch_entry.finger = 0; | ||
| 78 | } | ||
| 79 | } | ||
| 66 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(TouchScreenSharedMemory)); | 80 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(TouchScreenSharedMemory)); |
| 67 | } | 81 | } |
| 68 | 82 | ||
| @@ -74,4 +88,45 @@ void Controller_Touchscreen::OnLoadInputDevices() { | |||
| 74 | touch_btn_device.reset(); | 88 | touch_btn_device.reset(); |
| 75 | } | 89 | } |
| 76 | } | 90 | } |
| 91 | |||
| 92 | void Controller_Touchscreen::updateTouchInputEvent( | ||
| 93 | const std::tuple<float, float, bool>& touch_input, int& finger_id) { | ||
| 94 | bool pressed = false; | ||
| 95 | float x, y; | ||
| 96 | std::tie(x, y, pressed) = touch_input; | ||
| 97 | if (pressed) { | ||
| 98 | if (finger_id == -1) { | ||
| 99 | int first_free_id = 0; | ||
| 100 | int found = false; | ||
| 101 | while (!found && first_free_id < MAX_FINGERS) { | ||
| 102 | if (!fingers[first_free_id].pressed) { | ||
| 103 | found = true; | ||
| 104 | } else { | ||
| 105 | first_free_id++; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | if (found) { | ||
| 109 | finger_id = first_free_id; | ||
| 110 | fingers[finger_id].x = x; | ||
| 111 | fingers[finger_id].y = y; | ||
| 112 | fingers[finger_id].pressed = true; | ||
| 113 | fingers[finger_id].id = finger_id; | ||
| 114 | fingers[finger_id].attribute.start_touch.Assign(1); | ||
| 115 | } | ||
| 116 | } else { | ||
| 117 | fingers[finger_id].x = x; | ||
| 118 | fingers[finger_id].y = y; | ||
| 119 | fingers[finger_id].attribute.raw = 0; | ||
| 120 | } | ||
| 121 | } else if (finger_id != -1) { | ||
| 122 | if (!fingers[finger_id].attribute.end_touch) { | ||
| 123 | fingers[finger_id].attribute.end_touch.Assign(1); | ||
| 124 | fingers[finger_id].attribute.start_touch.Assign(0); | ||
| 125 | } else { | ||
| 126 | fingers[finger_id].pressed = false; | ||
| 127 | finger_id = -1; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 77 | } // namespace Service::HID | 132 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 4d9042adc..6c7620420 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h | |||
| @@ -30,6 +30,9 @@ public: | |||
| 30 | void OnLoadInputDevices() override; | 30 | void OnLoadInputDevices() override; |
| 31 | 31 | ||
| 32 | private: | 32 | private: |
| 33 | void updateTouchInputEvent(const std::tuple<float, float, bool>& touch_input, int& finger_id); | ||
| 34 | static const size_t MAX_FINGERS = 16; | ||
| 35 | |||
| 33 | struct Attributes { | 36 | struct Attributes { |
| 34 | union { | 37 | union { |
| 35 | u32 raw{}; | 38 | u32 raw{}; |
| @@ -55,7 +58,7 @@ private: | |||
| 55 | s64_le sampling_number; | 58 | s64_le sampling_number; |
| 56 | s64_le sampling_number2; | 59 | s64_le sampling_number2; |
| 57 | s32_le entry_count; | 60 | s32_le entry_count; |
| 58 | std::array<TouchState, 16> states; | 61 | std::array<TouchState, MAX_FINGERS> states; |
| 59 | }; | 62 | }; |
| 60 | static_assert(sizeof(TouchScreenEntry) == 0x298, "TouchScreenEntry is an invalid size"); | 63 | static_assert(sizeof(TouchScreenEntry) == 0x298, "TouchScreenEntry is an invalid size"); |
| 61 | 64 | ||
| @@ -66,9 +69,21 @@ private: | |||
| 66 | }; | 69 | }; |
| 67 | static_assert(sizeof(TouchScreenSharedMemory) == 0x3000, | 70 | static_assert(sizeof(TouchScreenSharedMemory) == 0x3000, |
| 68 | "TouchScreenSharedMemory is an invalid size"); | 71 | "TouchScreenSharedMemory is an invalid size"); |
| 72 | |||
| 73 | struct Finger { | ||
| 74 | u64_le last_touch{}; | ||
| 75 | float x{}; | ||
| 76 | float y{}; | ||
| 77 | u32_le id{}; | ||
| 78 | bool pressed{}; | ||
| 79 | Attributes attribute; | ||
| 80 | }; | ||
| 81 | |||
| 69 | TouchScreenSharedMemory shared_memory{}; | 82 | TouchScreenSharedMemory shared_memory{}; |
| 70 | std::unique_ptr<Input::TouchDevice> touch_device; | 83 | std::unique_ptr<Input::TouchDevice> touch_device; |
| 71 | std::unique_ptr<Input::TouchDevice> touch_btn_device; | 84 | std::unique_ptr<Input::TouchDevice> touch_btn_device; |
| 72 | s64_le last_touch{}; | 85 | int mouse_finger_id{-1}; |
| 86 | int keyboar_finger_id{-1}; | ||
| 87 | std::array<Finger, MAX_FINGERS> fingers; | ||
| 73 | }; | 88 | }; |
| 74 | } // namespace Service::HID | 89 | } // namespace Service::HID |