npad.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <atomic>
  6. #include <mutex>
  7. #include <span>
  8. #include "common/common_types.h"
  9. #include "hid_core/hid_types.h"
  10. #include "hid_core/resources/controller_base.h"
  11. #include "hid_core/resources/npad/npad_resource.h"
  12. #include "hid_core/resources/npad/npad_types.h"
  13. namespace Core::HID {
  14. class EmulatedController;
  15. enum class ControllerTriggerType;
  16. } // namespace Core::HID
  17. namespace Kernel {
  18. class KEvent;
  19. class KReadableEvent;
  20. } // namespace Kernel
  21. namespace Service::KernelHelpers {
  22. class ServiceContext;
  23. } // namespace Service::KernelHelpers
  24. union Result;
  25. namespace Service::HID {
  26. class AppletResource;
  27. struct NpadInternalState;
  28. struct NpadSixAxisSensorLifo;
  29. struct NpadSharedMemoryFormat;
  30. class NPad final {
  31. public:
  32. explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
  33. ~NPad();
  34. Result Activate();
  35. Result Activate(u64 aruid);
  36. Result ActivateNpadResource();
  37. Result ActivateNpadResource(u64 aruid);
  38. // When the controller is requesting an update for the shared memory
  39. void OnUpdate(const Core::Timing::CoreTiming& core_timing);
  40. Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set);
  41. Result GetSupportedNpadStyleSet(u64 aruid,
  42. Core::HID::NpadStyleSet& out_supported_style_set) const;
  43. Result GetMaskedSupportedNpadStyleSet(u64 aruid,
  44. Core::HID::NpadStyleSet& out_supported_style_set) const;
  45. Result SetSupportedNpadIdType(u64 aruid,
  46. std::span<const Core::HID::NpadIdType> supported_npad_list);
  47. Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type);
  48. Result GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const;
  49. Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode);
  50. Result GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const;
  51. bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
  52. NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
  53. bool VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
  54. std::size_t device_index,
  55. const Core::HID::VibrationValue& vibration_value);
  56. void VibrateController(u64 aruid,
  57. const Core::HID::VibrationDeviceHandle& vibration_device_handle,
  58. const Core::HID::VibrationValue& vibration_value);
  59. void VibrateControllers(
  60. u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
  61. std::span<const Core::HID::VibrationValue> vibration_values);
  62. Core::HID::VibrationValue GetLastVibration(
  63. u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
  64. void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
  65. void InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
  66. std::size_t device_index);
  67. void SetPermitVibrationSession(bool permit_vibration_session);
  68. bool IsVibrationDeviceMounted(
  69. u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
  70. Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
  71. Core::HID::NpadIdType npad_id);
  72. // Adds a new controller at an index.
  73. void AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
  74. Core::HID::NpadIdType npad_id);
  75. // Adds a new controller at an index with connection status.
  76. void UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
  77. Core::HID::NpadIdType npad_id, bool connected);
  78. Result DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id);
  79. Result IsFirmwareUpdateAvailableForSixAxisSensor(
  80. u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle,
  81. bool& is_firmware_available) const;
  82. Result ResetIsSixAxisSensorDeviceNewlyAssigned(
  83. u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle);
  84. Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
  85. Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
  86. Core::HID::NpadIdType npad_id) const;
  87. Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,
  88. bool is_enabled);
  89. void SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled);
  90. void ClearAllConnectedControllers();
  91. void DisconnectAllConnectedControllers();
  92. void ConnectAllDisconnectedControllers();
  93. void ClearAllControllers();
  94. Result MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
  95. Core::HID::NpadIdType npad_id_2);
  96. Result StartLrAssignmentMode(u64 aruid);
  97. Result StopLrAssignmentMode(u64 aruid);
  98. Result SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
  99. Core::HID::NpadIdType npad_id_2);
  100. // Logical OR for all buttons presses on all controllers
  101. // Specifically for cheat engine and other features.
  102. Core::HID::NpadButton GetAndResetPressState();
  103. Result ApplyNpadSystemCommonPolicy(u64 aruid);
  104. Result ApplyNpadSystemCommonPolicyFull(u64 aruid);
  105. Result ClearNpadSystemCommonPolicy(u64 aruid);
  106. void SetRevision(u64 aruid, NpadRevision revision);
  107. NpadRevision GetRevision(u64 aruid);
  108. Result RegisterAppletResourceUserId(u64 aruid);
  109. void UnregisterAppletResourceUserId(u64 aruid);
  110. void SetNpadExternals(std::shared_ptr<AppletResource> resource,
  111. std::recursive_mutex* shared_mutex);
  112. AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
  113. Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set,
  114. Core::HID::NpadButton button_assignment);
  115. Result ClearNpadCaptureButtonAssignment(u64 aruid);
  116. std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
  117. u64 aruid) const;
  118. Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled);
  119. Result AssigningSingleOnSlSrPress(u64 aruid, bool is_enabled);
  120. private:
  121. struct VibrationData {
  122. bool device_mounted{};
  123. Core::HID::VibrationValue latest_vibration_value{};
  124. std::chrono::steady_clock::time_point last_vibration_timepoint{};
  125. };
  126. struct NpadControllerData {
  127. NpadInternalState* shared_memory = nullptr;
  128. Core::HID::EmulatedController* device = nullptr;
  129. std::array<VibrationData, 2> vibration{};
  130. bool is_connected{};
  131. // Dual joycons can have only one side connected
  132. bool is_dual_left_connected{true};
  133. bool is_dual_right_connected{true};
  134. // Current pad state
  135. NPadGenericState npad_pad_state{};
  136. NPadGenericState npad_libnx_state{};
  137. NpadGcTriggerState npad_trigger_state{};
  138. int callback_key{};
  139. };
  140. void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
  141. void InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id);
  142. void RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id);
  143. void WriteEmptyEntry(NpadInternalState* npad);
  144. NpadControllerData& GetControllerFromHandle(
  145. u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle);
  146. const NpadControllerData& GetControllerFromHandle(
  147. u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const;
  148. NpadControllerData& GetControllerFromHandle(
  149. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
  150. const NpadControllerData& GetControllerFromHandle(
  151. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
  152. NpadControllerData& GetControllerFromNpadIdType(u64 aruid, Core::HID::NpadIdType npad_id);
  153. const NpadControllerData& GetControllerFromNpadIdType(u64 aruid,
  154. Core::HID::NpadIdType npad_id) const;
  155. Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
  156. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
  157. const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
  158. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
  159. Core::HID::HIDCore& hid_core;
  160. KernelHelpers::ServiceContext& service_context;
  161. s32 ref_counter{};
  162. mutable std::mutex mutex;
  163. NPadResource npad_resource;
  164. AppletResourceHolder applet_resource_holder{};
  165. Kernel::KEvent* input_event{nullptr};
  166. std::mutex* input_mutex{nullptr};
  167. std::atomic<u64> press_state{};
  168. bool permit_vibration_session_enabled;
  169. std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
  170. controller_data{};
  171. };
  172. } // namespace Service::HID