npad.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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/abstracted_pad/abstract_pad.h"
  11. #include "hid_core/resources/controller_base.h"
  12. #include "hid_core/resources/npad/npad_resource.h"
  13. #include "hid_core/resources/npad/npad_types.h"
  14. #include "hid_core/resources/npad/npad_vibration.h"
  15. #include "hid_core/resources/vibration/gc_vibration_device.h"
  16. #include "hid_core/resources/vibration/n64_vibration_device.h"
  17. #include "hid_core/resources/vibration/vibration_base.h"
  18. #include "hid_core/resources/vibration/vibration_device.h"
  19. namespace Core::HID {
  20. class EmulatedController;
  21. enum class ControllerTriggerType;
  22. } // namespace Core::HID
  23. namespace Kernel {
  24. class KEvent;
  25. class KReadableEvent;
  26. } // namespace Kernel
  27. namespace Service::KernelHelpers {
  28. class ServiceContext;
  29. } // namespace Service::KernelHelpers
  30. namespace Service::Set {
  31. class ISystemSettingsServer;
  32. }
  33. union Result;
  34. namespace Service::HID {
  35. class AppletResource;
  36. struct HandheldConfig;
  37. struct NpadInternalState;
  38. struct NpadSixAxisSensorLifo;
  39. struct NpadSharedMemoryFormat;
  40. class NPad final {
  41. public:
  42. explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
  43. ~NPad();
  44. Result Activate();
  45. Result Activate(u64 aruid);
  46. Result ActivateNpadResource();
  47. Result ActivateNpadResource(u64 aruid);
  48. // When the controller is requesting an update for the shared memory
  49. void OnUpdate(const Core::Timing::CoreTiming& core_timing);
  50. Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set);
  51. Result GetSupportedNpadStyleSet(u64 aruid,
  52. Core::HID::NpadStyleSet& out_supported_style_set) const;
  53. Result GetMaskedSupportedNpadStyleSet(u64 aruid,
  54. Core::HID::NpadStyleSet& out_supported_style_set) const;
  55. Result SetSupportedNpadIdType(u64 aruid,
  56. std::span<const Core::HID::NpadIdType> supported_npad_list);
  57. Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type);
  58. Result GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const;
  59. Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode);
  60. Result GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const;
  61. bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
  62. NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
  63. Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
  64. Core::HID::NpadIdType npad_id);
  65. // Adds a new controller at an index.
  66. void AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
  67. Core::HID::NpadIdType npad_id);
  68. // Adds a new controller at an index with connection status.
  69. void UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller,
  70. Core::HID::NpadIdType npad_id, bool connected);
  71. Result DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id);
  72. Result IsFirmwareUpdateAvailableForSixAxisSensor(
  73. u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle,
  74. bool& is_firmware_available) const;
  75. Result ResetIsSixAxisSensorDeviceNewlyAssigned(
  76. u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle);
  77. Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
  78. Core::HID::NpadIdType npad_id) const;
  79. Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,
  80. bool is_enabled);
  81. void SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled);
  82. void ClearAllConnectedControllers();
  83. void DisconnectAllConnectedControllers();
  84. void ConnectAllDisconnectedControllers();
  85. void ClearAllControllers();
  86. Result MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1,
  87. Core::HID::NpadIdType npad_id_2);
  88. Result StartLrAssignmentMode(u64 aruid);
  89. Result StopLrAssignmentMode(u64 aruid);
  90. Result SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
  91. Core::HID::NpadIdType npad_id_2);
  92. // Logical OR for all buttons presses on all controllers
  93. // Specifically for cheat engine and other features.
  94. Core::HID::NpadButton GetAndResetPressState();
  95. Result ApplyNpadSystemCommonPolicy(u64 aruid);
  96. Result ApplyNpadSystemCommonPolicyFull(u64 aruid);
  97. Result ClearNpadSystemCommonPolicy(u64 aruid);
  98. void SetRevision(u64 aruid, NpadRevision revision);
  99. NpadRevision GetRevision(u64 aruid);
  100. Result RegisterAppletResourceUserId(u64 aruid);
  101. void UnregisterAppletResourceUserId(u64 aruid);
  102. void SetNpadExternals(std::shared_ptr<AppletResource> resource,
  103. std::recursive_mutex* shared_mutex,
  104. std::shared_ptr<HandheldConfig> handheld_config,
  105. Kernel::KEvent* input_event, std::mutex* input_mutex,
  106. std::shared_ptr<Service::Set::ISystemSettingsServer> settings);
  107. AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
  108. Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set,
  109. Core::HID::NpadButton button_assignment);
  110. Result ClearNpadCaptureButtonAssignment(u64 aruid);
  111. std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
  112. u64 aruid) const;
  113. Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled);
  114. Result AssigningSingleOnSlSrPress(u64 aruid, bool is_enabled);
  115. Result GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const;
  116. NpadVibration* GetVibrationHandler();
  117. std::vector<NpadVibrationBase*> GetAllVibrationDevices();
  118. NpadVibrationBase* GetVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
  119. NpadN64VibrationDevice* GetN64VibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
  120. NpadVibrationDevice* GetNSVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
  121. NpadGcVibrationDevice* GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
  122. void UpdateHandheldAbstractState();
  123. void EnableAppletToGetInput(u64 aruid);
  124. private:
  125. struct NpadControllerData {
  126. NpadInternalState* shared_memory = nullptr;
  127. Core::HID::EmulatedController* device = nullptr;
  128. bool is_active{};
  129. bool is_connected{};
  130. // Dual joycons can have only one side connected
  131. bool is_dual_left_connected{true};
  132. bool is_dual_right_connected{true};
  133. // Current pad state
  134. NPadGenericState npad_pad_state{};
  135. NPadGenericState npad_libnx_state{};
  136. NpadGcTriggerState npad_trigger_state{};
  137. int callback_key{};
  138. };
  139. void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
  140. void InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id);
  141. void RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id);
  142. void WriteEmptyEntry(NpadInternalState* npad);
  143. NpadControllerData& GetControllerFromHandle(
  144. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
  145. const NpadControllerData& GetControllerFromHandle(
  146. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
  147. NpadControllerData& GetControllerFromNpadIdType(u64 aruid, Core::HID::NpadIdType npad_id);
  148. const NpadControllerData& GetControllerFromNpadIdType(u64 aruid,
  149. Core::HID::NpadIdType npad_id) const;
  150. Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
  151. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
  152. const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
  153. u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
  154. Core::HID::HIDCore& hid_core;
  155. KernelHelpers::ServiceContext& service_context;
  156. s32 ref_counter{};
  157. mutable std::mutex mutex;
  158. NPadResource npad_resource;
  159. AppletResourceHolder applet_resource_holder{};
  160. std::array<AbstractPad, MaxSupportedNpadIdTypes> abstracted_pads;
  161. NpadVibration vibration_handler{};
  162. std::atomic<u64> press_state{};
  163. std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
  164. controller_data{};
  165. };
  166. } // namespace Service::HID