hidbus.h 3.9 KB

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