touchscreen.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include "common/bit_field.h"
  6. #include "common/common_funcs.h"
  7. #include "common/common_types.h"
  8. #include "common/point.h"
  9. #include "common/swap.h"
  10. #include "core/frontend/input.h"
  11. #include "core/hle/service/hid/controllers/controller_base.h"
  12. namespace Service::HID {
  13. class Controller_Touchscreen final : public ControllerBase {
  14. public:
  15. enum class TouchScreenModeForNx : u8 {
  16. UseSystemSetting,
  17. Finger,
  18. Heat2,
  19. };
  20. struct TouchScreenConfigurationForNx {
  21. TouchScreenModeForNx mode;
  22. INSERT_PADDING_BYTES_NOINIT(0x7);
  23. INSERT_PADDING_BYTES_NOINIT(0xF); // Reserved
  24. };
  25. static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17,
  26. "TouchScreenConfigurationForNx is an invalid size");
  27. explicit Controller_Touchscreen(Core::System& system_);
  28. ~Controller_Touchscreen() override;
  29. // Called when the controller is initialized
  30. void OnInit() override;
  31. // When the controller is released
  32. void OnRelease() override;
  33. // When the controller is requesting an update for the shared memory
  34. void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
  35. // Called when input devices should be loaded
  36. void OnLoadInputDevices() override;
  37. private:
  38. static constexpr std::size_t MAX_FINGERS = 16;
  39. // Returns an unused finger id, if there is no fingers available std::nullopt will be returned
  40. std::optional<std::size_t> GetUnusedFingerID() const;
  41. // If the touch is new it tries to assing a new finger id, if there is no fingers avaliable no
  42. // changes will be made. Updates the coordinates if the finger id it's already set. If the touch
  43. // ends delays the output by one frame to set the end_touch flag before finally freeing the
  44. // finger id
  45. std::size_t UpdateTouchInputEvent(const std::tuple<float, float, bool>& touch_input,
  46. std::size_t finger_id);
  47. struct Attributes {
  48. union {
  49. u32 raw{};
  50. BitField<0, 1, u32> start_touch;
  51. BitField<1, 1, u32> end_touch;
  52. };
  53. };
  54. static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
  55. struct TouchState {
  56. u64_le delta_time;
  57. Attributes attribute;
  58. u32_le finger;
  59. Common::Point<u32_le> position;
  60. u32_le diameter_x;
  61. u32_le diameter_y;
  62. u32_le rotation_angle;
  63. };
  64. static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
  65. struct TouchScreenEntry {
  66. s64_le sampling_number;
  67. s64_le sampling_number2;
  68. s32_le entry_count;
  69. std::array<TouchState, MAX_FINGERS> states;
  70. };
  71. static_assert(sizeof(TouchScreenEntry) == 0x298, "TouchScreenEntry is an invalid size");
  72. struct TouchScreenSharedMemory {
  73. CommonHeader header;
  74. std::array<TouchScreenEntry, 17> shared_memory_entries{};
  75. INSERT_PADDING_BYTES(0x3c8);
  76. };
  77. static_assert(sizeof(TouchScreenSharedMemory) == 0x3000,
  78. "TouchScreenSharedMemory is an invalid size");
  79. struct Finger {
  80. u64_le last_touch{};
  81. Common::Point<float> position;
  82. u32_le id{};
  83. bool pressed{};
  84. Attributes attribute;
  85. };
  86. TouchScreenSharedMemory shared_memory{};
  87. std::unique_ptr<Input::TouchDevice> touch_mouse_device;
  88. std::unique_ptr<Input::TouchDevice> touch_udp_device;
  89. std::unique_ptr<Input::TouchDevice> touch_btn_device;
  90. std::array<std::size_t, MAX_FINGERS> mouse_finger_id;
  91. std::array<std::size_t, MAX_FINGERS> keyboard_finger_id;
  92. std::array<std::size_t, MAX_FINGERS> udp_finger_id;
  93. std::array<Finger, MAX_FINGERS> fingers;
  94. };
  95. } // namespace Service::HID