npad.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 "core/hid/hid_types.h"
  10. #include "core/hle/service/hid/controllers/controller_base.h"
  11. #include "core/hle/service/hid/controllers/npad/npad_resource.h"
  12. #include "core/hle/service/hid/controllers/types/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. private:
  114. struct VibrationData {
  115. bool device_mounted{};
  116. Core::HID::VibrationValue latest_vibration_value{};
  117. std::chrono::steady_clock::time_point last_vibration_timepoint{};
  118. };
  119. struct NpadControllerData {
  120. NpadInternalState* shared_memory = nullptr;
  121. Core::HID::EmulatedController* device = nullptr;
  122. std::array<VibrationData, 2> vibration{};
  123. bool is_connected{};
  124. // Dual joycons can have only one side connected
  125. bool is_dual_left_connected{true};
  126. bool is_dual_right_connected{true};
  127. // Current pad state
  128. NPadGenericState npad_pad_state{};
  129. NPadGenericState npad_libnx_state{};
  130. NpadGcTriggerState npad_trigger_state{};
  131. int callback_key{};
  132. };
  133. void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
  134. void InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id);
  135. void RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id);
  136. void WriteEmptyEntry(NpadInternalState* npad);
  137. NpadControllerData& GetControllerFromHandle(
  138. u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle);
  139. const NpadControllerData& GetControllerFromHandle(
  140. u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const;
  141. NpadControllerData& GetControllerFromHandle(
  142. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
  143. const NpadControllerData& GetControllerFromHandle(
  144. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
  145. NpadControllerData& GetControllerFromNpadIdType(u64 aruid, Core::HID::NpadIdType npad_id);
  146. const NpadControllerData& GetControllerFromNpadIdType(u64 aruid,
  147. Core::HID::NpadIdType npad_id) const;
  148. Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
  149. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
  150. const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
  151. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
  152. Core::HID::HIDCore& hid_core;
  153. KernelHelpers::ServiceContext& service_context;
  154. s32 ref_counter{};
  155. mutable std::mutex mutex;
  156. NPadResource npad_resource;
  157. AppletResourceHolder applet_resource_holder{};
  158. Kernel::KEvent* input_event{nullptr};
  159. std::mutex* input_mutex{nullptr};
  160. std::atomic<u64> press_state{};
  161. bool permit_vibration_session_enabled;
  162. std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
  163. controller_data{};
  164. };
  165. } // namespace Service::HID