hidbus.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <functional>
  6. #include "core/hle/service/hid/hidbus/hidbus_base.h"
  7. #include "core/hle/service/kernel_helpers.h"
  8. #include "core/hle/service/service.h"
  9. namespace Core::Timing {
  10. struct EventType;
  11. } // namespace Core::Timing
  12. namespace Core {
  13. class System;
  14. } // namespace Core
  15. namespace Service::HID {
  16. class HidBus final : public ServiceFramework<HidBus> {
  17. public:
  18. explicit HidBus(Core::System& system_);
  19. ~HidBus() override;
  20. private:
  21. static const std::size_t max_number_of_handles = 0x13;
  22. enum class HidBusDeviceId : std::size_t {
  23. RingController = 0x20,
  24. FamicomRight = 0x21,
  25. Starlink = 0x28,
  26. };
  27. // This is nn::hidbus::detail::StatusManagerType
  28. enum class StatusManagerType : u32 {
  29. None,
  30. Type16,
  31. Type32,
  32. };
  33. // This is nn::hidbus::BusType
  34. enum class BusType : u8 {
  35. LeftJoyRail,
  36. RightJoyRail,
  37. InternalBus, // Lark microphone
  38. MaxBusType,
  39. };
  40. // This is nn::hidbus::BusHandle
  41. struct BusHandle {
  42. u32 abstracted_pad_id;
  43. u8 internal_index;
  44. u8 player_number;
  45. BusType bus_type;
  46. bool is_valid;
  47. };
  48. static_assert(sizeof(BusHandle) == 0x8, "BusHandle is an invalid size");
  49. // This is nn::hidbus::JoyPollingReceivedData
  50. struct JoyPollingReceivedData {
  51. std::array<u8, 0x30> data;
  52. u64 out_size;
  53. u64 sampling_number;
  54. };
  55. static_assert(sizeof(JoyPollingReceivedData) == 0x40,
  56. "JoyPollingReceivedData is an invalid size");
  57. struct HidbusStatusManagerEntry {
  58. u8 is_connected{};
  59. INSERT_PADDING_BYTES(0x3);
  60. ResultCode is_connected_result{0};
  61. u8 is_enabled{};
  62. u8 is_in_focus{};
  63. u8 is_polling_mode{};
  64. u8 reserved{};
  65. JoyPollingMode polling_mode{};
  66. INSERT_PADDING_BYTES(0x70); // Unknown
  67. };
  68. static_assert(sizeof(HidbusStatusManagerEntry) == 0x80,
  69. "HidbusStatusManagerEntry is an invalid size");
  70. struct HidbusStatusManager {
  71. std::array<HidbusStatusManagerEntry, max_number_of_handles> entries{};
  72. INSERT_PADDING_BYTES(0x680); // Unused
  73. };
  74. static_assert(sizeof(HidbusStatusManager) <= 0x1000, "HidbusStatusManager is an invalid size");
  75. struct HidbusDevice {
  76. bool is_device_initializated{};
  77. BusHandle handle{};
  78. std::unique_ptr<HidbusBase> device{nullptr};
  79. };
  80. void GetBusHandle(Kernel::HLERequestContext& ctx);
  81. void IsExternalDeviceConnected(Kernel::HLERequestContext& ctx);
  82. void Initialize(Kernel::HLERequestContext& ctx);
  83. void Finalize(Kernel::HLERequestContext& ctx);
  84. void EnableExternalDevice(Kernel::HLERequestContext& ctx);
  85. void GetExternalDeviceId(Kernel::HLERequestContext& ctx);
  86. void SendCommandAsync(Kernel::HLERequestContext& ctx);
  87. void GetSendCommandAsynceResult(Kernel::HLERequestContext& ctx);
  88. void SetEventForSendCommandAsycResult(Kernel::HLERequestContext& ctx);
  89. void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
  90. void EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx);
  91. void DisableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx);
  92. void SetStatusManagerType(Kernel::HLERequestContext& ctx);
  93. void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
  94. std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const;
  95. template <typename T>
  96. void MakeDevice(BusHandle handle) {
  97. const auto device_index = GetDeviceIndexFromHandle(handle);
  98. if (device_index) {
  99. devices[device_index.value()].device =
  100. std::make_unique<T>(system.HIDCore(), service_context);
  101. }
  102. }
  103. bool is_hidbus_enabled{false};
  104. HidbusStatusManager hidbus_status{};
  105. std::array<HidbusDevice, max_number_of_handles> devices{};
  106. std::shared_ptr<Core::Timing::EventType> hidbus_update_event;
  107. KernelHelpers::ServiceContext service_context;
  108. };
  109. } // namespace Service::HID