npad.cpp 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <array>
  6. #include <cstring>
  7. #include "common/assert.h"
  8. #include "common/bit_field.h"
  9. #include "common/common_types.h"
  10. #include "common/logging/log.h"
  11. #include "common/settings.h"
  12. #include "core/core_timing.h"
  13. #include "core/hid/emulated_controller.h"
  14. #include "core/hid/hid_core.h"
  15. #include "core/hle/kernel/k_event.h"
  16. #include "core/hle/kernel/k_readable_event.h"
  17. #include "core/hle/kernel/k_writable_event.h"
  18. #include "core/hle/service/hid/controllers/npad.h"
  19. #include "core/hle/service/kernel_helpers.h"
  20. namespace Service::HID {
  21. constexpr std::size_t NPAD_OFFSET = 0x9A00;
  22. constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
  23. Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3,
  24. Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6,
  25. Core::HID::NpadIdType::Player7, Core::HID::NpadIdType::Player8, Core::HID::NpadIdType::Other,
  26. Core::HID::NpadIdType::Handheld,
  27. };
  28. bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) {
  29. switch (npad_id) {
  30. case Core::HID::NpadIdType::Player1:
  31. case Core::HID::NpadIdType::Player2:
  32. case Core::HID::NpadIdType::Player3:
  33. case Core::HID::NpadIdType::Player4:
  34. case Core::HID::NpadIdType::Player5:
  35. case Core::HID::NpadIdType::Player6:
  36. case Core::HID::NpadIdType::Player7:
  37. case Core::HID::NpadIdType::Player8:
  38. case Core::HID::NpadIdType::Other:
  39. case Core::HID::NpadIdType::Handheld:
  40. return true;
  41. default:
  42. LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
  43. return false;
  44. }
  45. }
  46. bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
  47. return IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)) &&
  48. device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType &&
  49. device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
  50. }
  51. bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle) {
  52. return IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id)) &&
  53. device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType &&
  54. device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
  55. }
  56. Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_,
  57. KernelHelpers::ServiceContext& service_context_)
  58. : ControllerBase{hid_core_}, service_context{service_context_} {
  59. for (std::size_t i = 0; i < controller_data.size(); ++i) {
  60. auto& controller = controller_data[i];
  61. controller.device = hid_core.GetEmulatedControllerByIndex(i);
  62. controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
  63. Core::HID::DEFAULT_VIBRATION_VALUE;
  64. controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value =
  65. Core::HID::DEFAULT_VIBRATION_VALUE;
  66. Core::HID::ControllerUpdateCallback engine_callback{
  67. .on_change = [this,
  68. i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
  69. .is_npad_service = true,
  70. };
  71. controller.callback_key = controller.device->SetCallback(engine_callback);
  72. }
  73. }
  74. Controller_NPad::~Controller_NPad() {
  75. for (std::size_t i = 0; i < controller_data.size(); ++i) {
  76. auto& controller = controller_data[i];
  77. controller.device->DeleteCallback(controller.callback_key);
  78. }
  79. OnRelease();
  80. }
  81. void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
  82. std::size_t controller_idx) {
  83. if (type == Core::HID::ControllerTriggerType::All) {
  84. ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
  85. ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
  86. return;
  87. }
  88. if (controller_idx >= controller_data.size()) {
  89. return;
  90. }
  91. auto& controller = controller_data[controller_idx];
  92. const auto is_connected = controller.device->IsConnected();
  93. const auto npad_type = controller.device->GetNpadStyleIndex();
  94. const auto npad_id = controller.device->GetNpadIdType();
  95. switch (type) {
  96. case Core::HID::ControllerTriggerType::Connected:
  97. case Core::HID::ControllerTriggerType::Disconnected:
  98. if (is_connected == controller.is_connected) {
  99. return;
  100. }
  101. UpdateControllerAt(npad_type, npad_id, is_connected);
  102. break;
  103. case Core::HID::ControllerTriggerType::Battery: {
  104. if (!controller.device->IsConnected()) {
  105. return;
  106. }
  107. auto& shared_memory = controller.shared_memory_entry;
  108. const auto& battery_level = controller.device->GetBattery();
  109. shared_memory.battery_level_dual = battery_level.dual.battery_level;
  110. shared_memory.battery_level_left = battery_level.left.battery_level;
  111. shared_memory.battery_level_right = battery_level.right.battery_level;
  112. break;
  113. }
  114. default:
  115. break;
  116. }
  117. }
  118. void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
  119. auto& controller = GetControllerFromNpadIdType(npad_id);
  120. if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) {
  121. return;
  122. }
  123. LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
  124. const auto controller_type = controller.device->GetNpadStyleIndex();
  125. auto& shared_memory = controller.shared_memory_entry;
  126. if (controller_type == Core::HID::NpadStyleIndex::None) {
  127. controller.styleset_changed_event->GetWritableEvent().Signal();
  128. return;
  129. }
  130. shared_memory.style_tag.raw = Core::HID::NpadStyleSet::None;
  131. shared_memory.device_type.raw = 0;
  132. shared_memory.system_properties.raw = 0;
  133. switch (controller_type) {
  134. case Core::HID::NpadStyleIndex::None:
  135. UNREACHABLE();
  136. break;
  137. case Core::HID::NpadStyleIndex::ProController:
  138. shared_memory.style_tag.fullkey.Assign(1);
  139. shared_memory.device_type.fullkey.Assign(1);
  140. shared_memory.system_properties.is_vertical.Assign(1);
  141. shared_memory.system_properties.use_plus.Assign(1);
  142. shared_memory.system_properties.use_minus.Assign(1);
  143. shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController;
  144. break;
  145. case Core::HID::NpadStyleIndex::Handheld:
  146. shared_memory.style_tag.handheld.Assign(1);
  147. shared_memory.device_type.handheld_left.Assign(1);
  148. shared_memory.device_type.handheld_right.Assign(1);
  149. shared_memory.system_properties.is_vertical.Assign(1);
  150. shared_memory.system_properties.use_plus.Assign(1);
  151. shared_memory.system_properties.use_minus.Assign(1);
  152. shared_memory.system_properties.use_directional_buttons.Assign(1);
  153. shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
  154. shared_memory.applet_footer.type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
  155. break;
  156. case Core::HID::NpadStyleIndex::JoyconDual:
  157. shared_memory.style_tag.joycon_dual.Assign(1);
  158. if (controller.is_dual_left_connected) {
  159. shared_memory.device_type.joycon_left.Assign(1);
  160. shared_memory.system_properties.use_minus.Assign(1);
  161. }
  162. if (controller.is_dual_right_connected) {
  163. shared_memory.device_type.joycon_right.Assign(1);
  164. shared_memory.system_properties.use_plus.Assign(1);
  165. }
  166. shared_memory.system_properties.use_directional_buttons.Assign(1);
  167. shared_memory.system_properties.is_vertical.Assign(1);
  168. shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
  169. if (controller.is_dual_left_connected && controller.is_dual_right_connected) {
  170. shared_memory.applet_footer.type = AppletFooterUiType::JoyDual;
  171. } else if (controller.is_dual_left_connected) {
  172. shared_memory.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly;
  173. } else {
  174. shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
  175. }
  176. break;
  177. case Core::HID::NpadStyleIndex::JoyconLeft:
  178. shared_memory.style_tag.joycon_left.Assign(1);
  179. shared_memory.device_type.joycon_left.Assign(1);
  180. shared_memory.system_properties.is_horizontal.Assign(1);
  181. shared_memory.system_properties.use_minus.Assign(1);
  182. shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
  183. break;
  184. case Core::HID::NpadStyleIndex::JoyconRight:
  185. shared_memory.style_tag.joycon_right.Assign(1);
  186. shared_memory.device_type.joycon_right.Assign(1);
  187. shared_memory.system_properties.is_horizontal.Assign(1);
  188. shared_memory.system_properties.use_plus.Assign(1);
  189. shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
  190. break;
  191. case Core::HID::NpadStyleIndex::GameCube:
  192. shared_memory.style_tag.gamecube.Assign(1);
  193. shared_memory.device_type.fullkey.Assign(1);
  194. shared_memory.system_properties.is_vertical.Assign(1);
  195. shared_memory.system_properties.use_plus.Assign(1);
  196. break;
  197. case Core::HID::NpadStyleIndex::Pokeball:
  198. shared_memory.style_tag.palma.Assign(1);
  199. shared_memory.device_type.palma.Assign(1);
  200. break;
  201. case Core::HID::NpadStyleIndex::NES:
  202. shared_memory.style_tag.lark.Assign(1);
  203. shared_memory.device_type.fullkey.Assign(1);
  204. break;
  205. case Core::HID::NpadStyleIndex::SNES:
  206. shared_memory.style_tag.lucia.Assign(1);
  207. shared_memory.device_type.fullkey.Assign(1);
  208. shared_memory.applet_footer.type = AppletFooterUiType::Lucia;
  209. break;
  210. case Core::HID::NpadStyleIndex::N64:
  211. shared_memory.style_tag.lagoon.Assign(1);
  212. shared_memory.device_type.fullkey.Assign(1);
  213. shared_memory.applet_footer.type = AppletFooterUiType::Lagon;
  214. break;
  215. case Core::HID::NpadStyleIndex::SegaGenesis:
  216. shared_memory.style_tag.lager.Assign(1);
  217. shared_memory.device_type.fullkey.Assign(1);
  218. break;
  219. default:
  220. break;
  221. }
  222. const auto& body_colors = controller.device->GetColors();
  223. shared_memory.fullkey_color.attribute = ColorAttribute::Ok;
  224. shared_memory.fullkey_color.fullkey = body_colors.fullkey;
  225. shared_memory.joycon_color.attribute = ColorAttribute::Ok;
  226. shared_memory.joycon_color.left = body_colors.left;
  227. shared_memory.joycon_color.right = body_colors.right;
  228. // TODO: Investigate when we should report all batery types
  229. const auto& battery_level = controller.device->GetBattery();
  230. shared_memory.battery_level_dual = battery_level.dual.battery_level;
  231. shared_memory.battery_level_left = battery_level.left.battery_level;
  232. shared_memory.battery_level_right = battery_level.right.battery_level;
  233. controller.is_connected = true;
  234. controller.device->Connect();
  235. SignalStyleSetChangedEvent(npad_id);
  236. WriteEmptyEntry(controller.shared_memory_entry);
  237. }
  238. void Controller_NPad::OnInit() {
  239. if (!IsControllerActivated()) {
  240. return;
  241. }
  242. for (std::size_t i = 0; i < controller_data.size(); ++i) {
  243. auto& controller = controller_data[i];
  244. controller.styleset_changed_event =
  245. service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
  246. }
  247. supported_npad_id_types.resize(npad_id_list.size());
  248. std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
  249. npad_id_list.size() * sizeof(Core::HID::NpadIdType));
  250. // Prefill controller buffers
  251. for (auto& controller : controller_data) {
  252. auto& npad = controller.shared_memory_entry;
  253. npad.fullkey_color = {
  254. .attribute = ColorAttribute::NoController,
  255. .fullkey = {},
  256. };
  257. npad.joycon_color = {
  258. .attribute = ColorAttribute::NoController,
  259. .left = {},
  260. .right = {},
  261. };
  262. // HW seems to initialize the first 19 entries
  263. for (std::size_t i = 0; i < 19; ++i) {
  264. WriteEmptyEntry(npad);
  265. }
  266. }
  267. }
  268. void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) {
  269. NPadGenericState dummy_pad_state{};
  270. NpadGcTriggerState dummy_gc_state{};
  271. dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
  272. npad.fullkey_lifo.WriteNextEntry(dummy_pad_state);
  273. dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1;
  274. npad.handheld_lifo.WriteNextEntry(dummy_pad_state);
  275. dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
  276. npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state);
  277. dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
  278. npad.joy_left_lifo.WriteNextEntry(dummy_pad_state);
  279. dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
  280. npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
  281. dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1;
  282. npad.palma_lifo.WriteNextEntry(dummy_pad_state);
  283. dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
  284. npad.system_ext_lifo.WriteNextEntry(dummy_pad_state);
  285. dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
  286. npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
  287. }
  288. void Controller_NPad::OnRelease() {
  289. is_controller_initialized = false;
  290. for (std::size_t i = 0; i < controller_data.size(); ++i) {
  291. auto& controller = controller_data[i];
  292. service_context.CloseEvent(controller.styleset_changed_event);
  293. for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
  294. VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_idx, {});
  295. }
  296. }
  297. }
  298. void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
  299. std::lock_guard lock{mutex};
  300. auto& controller = GetControllerFromNpadIdType(npad_id);
  301. const auto controller_type = controller.device->GetNpadStyleIndex();
  302. if (!controller.device->IsConnected()) {
  303. return;
  304. }
  305. auto& pad_entry = controller.npad_pad_state;
  306. auto& trigger_entry = controller.npad_trigger_state;
  307. const auto button_state = controller.device->GetNpadButtons();
  308. const auto stick_state = controller.device->GetSticks();
  309. using btn = Core::HID::NpadButton;
  310. pad_entry.npad_buttons.raw = btn::None;
  311. if (controller_type != Core::HID::NpadStyleIndex::JoyconLeft) {
  312. constexpr btn right_button_mask = btn::A | btn::B | btn::X | btn::Y | btn::StickR | btn::R |
  313. btn::ZR | btn::Plus | btn::StickRLeft | btn::StickRUp |
  314. btn::StickRRight | btn::StickRDown;
  315. pad_entry.npad_buttons.raw = button_state.raw & right_button_mask;
  316. pad_entry.r_stick = stick_state.right;
  317. }
  318. if (controller_type != Core::HID::NpadStyleIndex::JoyconRight) {
  319. constexpr btn left_button_mask =
  320. btn::Left | btn::Up | btn::Right | btn::Down | btn::StickL | btn::L | btn::ZL |
  321. btn::Minus | btn::StickLLeft | btn::StickLUp | btn::StickLRight | btn::StickLDown;
  322. pad_entry.npad_buttons.raw |= button_state.raw & left_button_mask;
  323. pad_entry.l_stick = stick_state.left;
  324. }
  325. if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft) {
  326. pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
  327. pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
  328. }
  329. if (controller_type == Core::HID::NpadStyleIndex::JoyconRight) {
  330. pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
  331. pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
  332. }
  333. if (controller_type == Core::HID::NpadStyleIndex::GameCube) {
  334. const auto& trigger_state = controller.device->GetTriggers();
  335. trigger_entry.l_analog = trigger_state.left;
  336. trigger_entry.r_analog = trigger_state.right;
  337. pad_entry.npad_buttons.zl.Assign(false);
  338. pad_entry.npad_buttons.zr.Assign(button_state.r);
  339. pad_entry.npad_buttons.l.Assign(button_state.zl);
  340. pad_entry.npad_buttons.r.Assign(button_state.zr);
  341. }
  342. }
  343. void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
  344. std::size_t data_len) {
  345. if (!IsControllerActivated()) {
  346. return;
  347. }
  348. for (std::size_t i = 0; i < controller_data.size(); ++i) {
  349. auto& controller = controller_data[i];
  350. auto& npad = controller.shared_memory_entry;
  351. const auto& controller_type = controller.device->GetNpadStyleIndex();
  352. if (controller_type == Core::HID::NpadStyleIndex::None ||
  353. !controller.device->IsConnected()) {
  354. // Refresh shared memory
  355. std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
  356. &controller.shared_memory_entry, sizeof(NpadInternalState));
  357. continue;
  358. }
  359. RequestPadStateUpdate(controller.device->GetNpadIdType());
  360. auto& pad_state = controller.npad_pad_state;
  361. auto& libnx_state = controller.npad_libnx_state;
  362. auto& trigger_state = controller.npad_trigger_state;
  363. // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
  364. // any controllers.
  365. libnx_state.connection_status.raw = 0;
  366. libnx_state.connection_status.is_connected.Assign(1);
  367. switch (controller_type) {
  368. case Core::HID::NpadStyleIndex::None:
  369. UNREACHABLE();
  370. break;
  371. case Core::HID::NpadStyleIndex::ProController:
  372. case Core::HID::NpadStyleIndex::NES:
  373. case Core::HID::NpadStyleIndex::SNES:
  374. case Core::HID::NpadStyleIndex::N64:
  375. case Core::HID::NpadStyleIndex::SegaGenesis:
  376. pad_state.connection_status.raw = 0;
  377. pad_state.connection_status.is_connected.Assign(1);
  378. pad_state.connection_status.is_wired.Assign(1);
  379. libnx_state.connection_status.is_wired.Assign(1);
  380. pad_state.sampling_number =
  381. npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
  382. npad.fullkey_lifo.WriteNextEntry(pad_state);
  383. break;
  384. case Core::HID::NpadStyleIndex::Handheld:
  385. pad_state.connection_status.raw = 0;
  386. pad_state.connection_status.is_connected.Assign(1);
  387. pad_state.connection_status.is_wired.Assign(1);
  388. pad_state.connection_status.is_left_connected.Assign(1);
  389. pad_state.connection_status.is_right_connected.Assign(1);
  390. pad_state.connection_status.is_left_wired.Assign(1);
  391. pad_state.connection_status.is_right_wired.Assign(1);
  392. libnx_state.connection_status.is_wired.Assign(1);
  393. libnx_state.connection_status.is_left_connected.Assign(1);
  394. libnx_state.connection_status.is_right_connected.Assign(1);
  395. libnx_state.connection_status.is_left_wired.Assign(1);
  396. libnx_state.connection_status.is_right_wired.Assign(1);
  397. pad_state.sampling_number =
  398. npad.handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
  399. npad.handheld_lifo.WriteNextEntry(pad_state);
  400. break;
  401. case Core::HID::NpadStyleIndex::JoyconDual:
  402. pad_state.connection_status.raw = 0;
  403. pad_state.connection_status.is_connected.Assign(1);
  404. if (controller.is_dual_left_connected) {
  405. pad_state.connection_status.is_left_connected.Assign(1);
  406. libnx_state.connection_status.is_left_connected.Assign(1);
  407. }
  408. if (controller.is_dual_right_connected) {
  409. pad_state.connection_status.is_right_connected.Assign(1);
  410. libnx_state.connection_status.is_right_connected.Assign(1);
  411. }
  412. pad_state.sampling_number =
  413. npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
  414. npad.joy_dual_lifo.WriteNextEntry(pad_state);
  415. break;
  416. case Core::HID::NpadStyleIndex::JoyconLeft:
  417. pad_state.connection_status.raw = 0;
  418. pad_state.connection_status.is_connected.Assign(1);
  419. pad_state.connection_status.is_left_connected.Assign(1);
  420. libnx_state.connection_status.is_left_connected.Assign(1);
  421. pad_state.sampling_number =
  422. npad.joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
  423. npad.joy_left_lifo.WriteNextEntry(pad_state);
  424. break;
  425. case Core::HID::NpadStyleIndex::JoyconRight:
  426. pad_state.connection_status.raw = 0;
  427. pad_state.connection_status.is_connected.Assign(1);
  428. pad_state.connection_status.is_right_connected.Assign(1);
  429. libnx_state.connection_status.is_right_connected.Assign(1);
  430. pad_state.sampling_number =
  431. npad.joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
  432. npad.joy_right_lifo.WriteNextEntry(pad_state);
  433. break;
  434. case Core::HID::NpadStyleIndex::GameCube:
  435. pad_state.connection_status.raw = 0;
  436. pad_state.connection_status.is_connected.Assign(1);
  437. pad_state.connection_status.is_wired.Assign(1);
  438. libnx_state.connection_status.is_wired.Assign(1);
  439. pad_state.sampling_number =
  440. npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
  441. trigger_state.sampling_number =
  442. npad.gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
  443. npad.fullkey_lifo.WriteNextEntry(pad_state);
  444. npad.gc_trigger_lifo.WriteNextEntry(trigger_state);
  445. break;
  446. case Core::HID::NpadStyleIndex::Pokeball:
  447. pad_state.connection_status.raw = 0;
  448. pad_state.connection_status.is_connected.Assign(1);
  449. pad_state.sampling_number =
  450. npad.palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
  451. npad.palma_lifo.WriteNextEntry(pad_state);
  452. break;
  453. default:
  454. break;
  455. }
  456. libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
  457. libnx_state.l_stick = pad_state.l_stick;
  458. libnx_state.r_stick = pad_state.r_stick;
  459. npad.system_ext_lifo.WriteNextEntry(pad_state);
  460. press_state |= static_cast<u64>(pad_state.npad_buttons.raw);
  461. std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
  462. &controller.shared_memory_entry, sizeof(NpadInternalState));
  463. }
  464. }
  465. void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
  466. std::size_t data_len) {
  467. if (!IsControllerActivated()) {
  468. return;
  469. }
  470. for (std::size_t i = 0; i < controller_data.size(); ++i) {
  471. auto& controller = controller_data[i];
  472. const auto& controller_type = controller.device->GetNpadStyleIndex();
  473. if (controller_type == Core::HID::NpadStyleIndex::None ||
  474. !controller.device->IsConnected()) {
  475. continue;
  476. }
  477. auto& npad = controller.shared_memory_entry;
  478. const auto& motion_state = controller.device->GetMotions();
  479. auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
  480. auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
  481. auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
  482. auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
  483. auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
  484. auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
  485. if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
  486. controller.sixaxis_at_rest = true;
  487. for (std::size_t e = 0; e < motion_state.size(); ++e) {
  488. controller.sixaxis_at_rest =
  489. controller.sixaxis_at_rest && motion_state[e].is_at_rest;
  490. }
  491. }
  492. switch (controller_type) {
  493. case Core::HID::NpadStyleIndex::None:
  494. UNREACHABLE();
  495. break;
  496. case Core::HID::NpadStyleIndex::ProController:
  497. sixaxis_fullkey_state.attribute.raw = 0;
  498. if (controller.sixaxis_sensor_enabled) {
  499. sixaxis_fullkey_state.attribute.is_connected.Assign(1);
  500. sixaxis_fullkey_state.accel = motion_state[0].accel;
  501. sixaxis_fullkey_state.gyro = motion_state[0].gyro;
  502. sixaxis_fullkey_state.rotation = motion_state[0].rotation;
  503. sixaxis_fullkey_state.orientation = motion_state[0].orientation;
  504. }
  505. break;
  506. case Core::HID::NpadStyleIndex::Handheld:
  507. sixaxis_handheld_state.attribute.raw = 0;
  508. if (controller.sixaxis_sensor_enabled) {
  509. sixaxis_handheld_state.attribute.is_connected.Assign(1);
  510. sixaxis_handheld_state.accel = motion_state[0].accel;
  511. sixaxis_handheld_state.gyro = motion_state[0].gyro;
  512. sixaxis_handheld_state.rotation = motion_state[0].rotation;
  513. sixaxis_handheld_state.orientation = motion_state[0].orientation;
  514. }
  515. break;
  516. case Core::HID::NpadStyleIndex::JoyconDual:
  517. sixaxis_dual_left_state.attribute.raw = 0;
  518. sixaxis_dual_right_state.attribute.raw = 0;
  519. if (controller.sixaxis_sensor_enabled) {
  520. // Set motion for the left joycon
  521. sixaxis_dual_left_state.attribute.is_connected.Assign(1);
  522. sixaxis_dual_left_state.accel = motion_state[0].accel;
  523. sixaxis_dual_left_state.gyro = motion_state[0].gyro;
  524. sixaxis_dual_left_state.rotation = motion_state[0].rotation;
  525. sixaxis_dual_left_state.orientation = motion_state[0].orientation;
  526. }
  527. if (controller.sixaxis_sensor_enabled) {
  528. // Set motion for the right joycon
  529. sixaxis_dual_right_state.attribute.is_connected.Assign(1);
  530. sixaxis_dual_right_state.accel = motion_state[1].accel;
  531. sixaxis_dual_right_state.gyro = motion_state[1].gyro;
  532. sixaxis_dual_right_state.rotation = motion_state[1].rotation;
  533. sixaxis_dual_right_state.orientation = motion_state[1].orientation;
  534. }
  535. break;
  536. case Core::HID::NpadStyleIndex::JoyconLeft:
  537. sixaxis_left_lifo_state.attribute.raw = 0;
  538. if (controller.sixaxis_sensor_enabled) {
  539. sixaxis_left_lifo_state.attribute.is_connected.Assign(1);
  540. sixaxis_left_lifo_state.accel = motion_state[0].accel;
  541. sixaxis_left_lifo_state.gyro = motion_state[0].gyro;
  542. sixaxis_left_lifo_state.rotation = motion_state[0].rotation;
  543. sixaxis_left_lifo_state.orientation = motion_state[0].orientation;
  544. }
  545. break;
  546. case Core::HID::NpadStyleIndex::JoyconRight:
  547. sixaxis_right_lifo_state.attribute.raw = 0;
  548. if (controller.sixaxis_sensor_enabled) {
  549. sixaxis_right_lifo_state.attribute.is_connected.Assign(1);
  550. sixaxis_right_lifo_state.accel = motion_state[1].accel;
  551. sixaxis_right_lifo_state.gyro = motion_state[1].gyro;
  552. sixaxis_right_lifo_state.rotation = motion_state[1].rotation;
  553. sixaxis_right_lifo_state.orientation = motion_state[1].orientation;
  554. }
  555. break;
  556. default:
  557. break;
  558. }
  559. sixaxis_fullkey_state.sampling_number =
  560. npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
  561. sixaxis_handheld_state.sampling_number =
  562. npad.sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
  563. sixaxis_dual_left_state.sampling_number =
  564. npad.sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
  565. sixaxis_dual_right_state.sampling_number =
  566. npad.sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
  567. sixaxis_left_lifo_state.sampling_number =
  568. npad.sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
  569. sixaxis_right_lifo_state.sampling_number =
  570. npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
  571. if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
  572. // This buffer only is updated on handheld on HW
  573. npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
  574. } else {
  575. // Handheld doesn't update this buffer on HW
  576. npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
  577. }
  578. npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
  579. npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
  580. npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
  581. npad.sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
  582. std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
  583. &controller.shared_memory_entry, sizeof(NpadInternalState));
  584. }
  585. }
  586. void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
  587. hid_core.SetSupportedStyleTag(style_set);
  588. if (is_controller_initialized) {
  589. return;
  590. }
  591. // Once SetSupportedStyleSet is called controllers are fully initialized
  592. is_controller_initialized = true;
  593. // Connect all active controllers
  594. for (auto& controller : controller_data) {
  595. const auto& device = controller.device;
  596. if (device->IsConnected()) {
  597. AddNewControllerAt(device->GetNpadStyleIndex(), device->GetNpadIdType());
  598. }
  599. }
  600. }
  601. Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const {
  602. if (!is_controller_initialized) {
  603. return {Core::HID::NpadStyleSet::None};
  604. }
  605. return hid_core.GetSupportedStyleTag();
  606. }
  607. void Controller_NPad::SetSupportedNpadIdTypes(u8* data, std::size_t length) {
  608. ASSERT(length > 0 && (length % sizeof(u32)) == 0);
  609. supported_npad_id_types.clear();
  610. supported_npad_id_types.resize(length / sizeof(u32));
  611. std::memcpy(supported_npad_id_types.data(), data, length);
  612. }
  613. void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
  614. ASSERT(max_length < supported_npad_id_types.size());
  615. std::memcpy(data, supported_npad_id_types.data(), supported_npad_id_types.size());
  616. }
  617. std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
  618. return supported_npad_id_types.size();
  619. }
  620. void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
  621. hold_type = joy_hold_type;
  622. }
  623. Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const {
  624. return hold_type;
  625. }
  626. void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
  627. handheld_activation_mode = activation_mode;
  628. }
  629. Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActivationMode() const {
  630. return handheld_activation_mode;
  631. }
  632. void Controller_NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
  633. communication_mode = communication_mode_;
  634. }
  635. Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode() const {
  636. return communication_mode;
  637. }
  638. void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
  639. NpadJoyAssignmentMode assignment_mode) {
  640. if (!IsNpadIdValid(npad_id)) {
  641. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  642. return;
  643. }
  644. auto& controller = GetControllerFromNpadIdType(npad_id);
  645. if (controller.shared_memory_entry.assignment_mode != assignment_mode) {
  646. controller.shared_memory_entry.assignment_mode = assignment_mode;
  647. }
  648. if (!controller.device->IsConnected()) {
  649. return;
  650. }
  651. if (assignment_mode == NpadJoyAssignmentMode::Dual) {
  652. if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) {
  653. DisconnectNpad(npad_id);
  654. controller.is_dual_left_connected = true;
  655. controller.is_dual_right_connected = false;
  656. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
  657. return;
  658. }
  659. if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
  660. DisconnectNpad(npad_id);
  661. controller.is_dual_left_connected = false;
  662. controller.is_dual_right_connected = true;
  663. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
  664. return;
  665. }
  666. return;
  667. }
  668. // This is for NpadJoyAssignmentMode::Single
  669. // Only JoyconDual get affected by this function
  670. if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) {
  671. return;
  672. }
  673. if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
  674. DisconnectNpad(npad_id);
  675. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
  676. return;
  677. }
  678. if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
  679. DisconnectNpad(npad_id);
  680. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
  681. return;
  682. }
  683. // We have two controllers connected to the same npad_id we need to split them
  684. const auto npad_id_2 = hid_core.GetFirstDisconnectedNpadId();
  685. auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
  686. DisconnectNpad(npad_id);
  687. if (npad_device_type == NpadJoyDeviceType::Left) {
  688. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
  689. controller_2.is_dual_left_connected = false;
  690. controller_2.is_dual_right_connected = true;
  691. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
  692. } else {
  693. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
  694. controller_2.is_dual_left_connected = true;
  695. controller_2.is_dual_right_connected = false;
  696. UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
  697. }
  698. }
  699. bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
  700. std::size_t device_index,
  701. const Core::HID::VibrationValue& vibration_value) {
  702. auto& controller = GetControllerFromNpadIdType(npad_id);
  703. if (!controller.device->IsConnected()) {
  704. return false;
  705. }
  706. if (!controller.device->IsVibrationEnabled()) {
  707. if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
  708. controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
  709. // Send an empty vibration to stop any vibrations.
  710. Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f};
  711. controller.device->SetVibration(device_index, vibration);
  712. // Then reset the vibration value to its default value.
  713. controller.vibration[device_index].latest_vibration_value =
  714. Core::HID::DEFAULT_VIBRATION_VALUE;
  715. }
  716. return false;
  717. }
  718. if (!Settings::values.enable_accurate_vibrations.GetValue()) {
  719. using std::chrono::duration_cast;
  720. using std::chrono::milliseconds;
  721. using std::chrono::steady_clock;
  722. const auto now = steady_clock::now();
  723. // Filter out non-zero vibrations that are within 10ms of each other.
  724. if ((vibration_value.low_amplitude != 0.0f || vibration_value.high_amplitude != 0.0f) &&
  725. duration_cast<milliseconds>(
  726. now - controller.vibration[device_index].last_vibration_timepoint) <
  727. milliseconds(10)) {
  728. return false;
  729. }
  730. controller.vibration[device_index].last_vibration_timepoint = now;
  731. }
  732. Core::HID::VibrationValue vibration{
  733. vibration_value.low_amplitude, vibration_value.low_frequency,
  734. vibration_value.high_amplitude, vibration_value.high_frequency};
  735. return controller.device->SetVibration(device_index, vibration);
  736. }
  737. void Controller_NPad::VibrateController(
  738. const Core::HID::VibrationDeviceHandle& vibration_device_handle,
  739. const Core::HID::VibrationValue& vibration_value) {
  740. if (!IsDeviceHandleValid(vibration_device_handle)) {
  741. return;
  742. }
  743. if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
  744. return;
  745. }
  746. auto& controller = GetControllerFromHandle(vibration_device_handle);
  747. const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
  748. if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) {
  749. return;
  750. }
  751. if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) {
  752. UNREACHABLE_MSG("DeviceIndex should never be None!");
  753. return;
  754. }
  755. // Some games try to send mismatched parameters in the device handle, block these.
  756. if ((controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft &&
  757. (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconRight ||
  758. vibration_device_handle.device_index == Core::HID::DeviceIndex::Right)) ||
  759. (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight &&
  760. (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconLeft ||
  761. vibration_device_handle.device_index == Core::HID::DeviceIndex::Left))) {
  762. return;
  763. }
  764. // Filter out vibrations with equivalent values to reduce unnecessary state changes.
  765. if (vibration_value.low_amplitude ==
  766. controller.vibration[device_index].latest_vibration_value.low_amplitude &&
  767. vibration_value.high_amplitude ==
  768. controller.vibration[device_index].latest_vibration_value.high_amplitude) {
  769. return;
  770. }
  771. if (VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_index,
  772. vibration_value)) {
  773. controller.vibration[device_index].latest_vibration_value = vibration_value;
  774. }
  775. }
  776. void Controller_NPad::VibrateControllers(
  777. const std::vector<Core::HID::VibrationDeviceHandle>& vibration_device_handles,
  778. const std::vector<Core::HID::VibrationValue>& vibration_values) {
  779. if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
  780. return;
  781. }
  782. ASSERT_OR_EXECUTE_MSG(
  783. vibration_device_handles.size() == vibration_values.size(), { return; },
  784. "The amount of device handles does not match with the amount of vibration values,"
  785. "this is undefined behavior!");
  786. for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) {
  787. VibrateController(vibration_device_handles[i], vibration_values[i]);
  788. }
  789. }
  790. Core::HID::VibrationValue Controller_NPad::GetLastVibration(
  791. const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
  792. if (!IsDeviceHandleValid(vibration_device_handle)) {
  793. return {};
  794. }
  795. const auto& controller = GetControllerFromHandle(vibration_device_handle);
  796. const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
  797. return controller.vibration[device_index].latest_vibration_value;
  798. }
  799. void Controller_NPad::InitializeVibrationDevice(
  800. const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
  801. if (!IsDeviceHandleValid(vibration_device_handle)) {
  802. return;
  803. }
  804. const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id);
  805. const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
  806. InitializeVibrationDeviceAtIndex(npad_index, device_index);
  807. }
  808. void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
  809. std::size_t device_index) {
  810. auto& controller = GetControllerFromNpadIdType(npad_id);
  811. if (!Settings::values.vibration_enabled.GetValue()) {
  812. controller.vibration[device_index].device_mounted = false;
  813. return;
  814. }
  815. controller.vibration[device_index].device_mounted =
  816. controller.device->TestVibration(device_index);
  817. }
  818. void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
  819. permit_vibration_session_enabled = permit_vibration_session;
  820. }
  821. bool Controller_NPad::IsVibrationDeviceMounted(
  822. const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
  823. if (!IsDeviceHandleValid(vibration_device_handle)) {
  824. return false;
  825. }
  826. const auto& controller = GetControllerFromHandle(vibration_device_handle);
  827. const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
  828. return controller.vibration[device_index].device_mounted;
  829. }
  830. Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
  831. if (!IsNpadIdValid(npad_id)) {
  832. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  833. // Fallback to player 1
  834. const auto& controller = GetControllerFromNpadIdType(Core::HID::NpadIdType::Player1);
  835. return controller.styleset_changed_event->GetReadableEvent();
  836. }
  837. const auto& controller = GetControllerFromNpadIdType(npad_id);
  838. return controller.styleset_changed_event->GetReadableEvent();
  839. }
  840. void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
  841. const auto& controller = GetControllerFromNpadIdType(npad_id);
  842. controller.styleset_changed_event->GetWritableEvent().Signal();
  843. }
  844. void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller,
  845. Core::HID::NpadIdType npad_id) {
  846. UpdateControllerAt(controller, npad_id, true);
  847. }
  848. void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type,
  849. Core::HID::NpadIdType npad_id, bool connected) {
  850. auto& controller = GetControllerFromNpadIdType(npad_id);
  851. if (!connected) {
  852. DisconnectNpad(npad_id);
  853. return;
  854. }
  855. controller.device->SetNpadStyleIndex(type);
  856. InitNewlyAddedController(npad_id);
  857. }
  858. void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
  859. if (!IsNpadIdValid(npad_id)) {
  860. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  861. return;
  862. }
  863. LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id);
  864. auto& controller = GetControllerFromNpadIdType(npad_id);
  865. for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
  866. // Send an empty vibration to stop any vibrations.
  867. VibrateControllerAtIndex(npad_id, device_idx, {});
  868. controller.vibration[device_idx].device_mounted = false;
  869. }
  870. auto& shared_memory_entry = controller.shared_memory_entry;
  871. // Don't reset shared_memory_entry.assignment_mode this value is persistent
  872. shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
  873. shared_memory_entry.device_type.raw = 0;
  874. shared_memory_entry.system_properties.raw = 0;
  875. shared_memory_entry.button_properties.raw = 0;
  876. shared_memory_entry.battery_level_dual = 0;
  877. shared_memory_entry.battery_level_left = 0;
  878. shared_memory_entry.battery_level_right = 0;
  879. shared_memory_entry.fullkey_color = {
  880. .attribute = ColorAttribute::NoController,
  881. .fullkey = {},
  882. };
  883. shared_memory_entry.joycon_color = {
  884. .attribute = ColorAttribute::NoController,
  885. .left = {},
  886. .right = {},
  887. };
  888. shared_memory_entry.applet_footer.type = AppletFooterUiType::None;
  889. controller.is_dual_left_connected = true;
  890. controller.is_dual_right_connected = true;
  891. controller.is_connected = false;
  892. controller.device->Disconnect();
  893. SignalStyleSetChangedEvent(npad_id);
  894. WriteEmptyEntry(controller.shared_memory_entry);
  895. }
  896. void Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
  897. GyroscopeZeroDriftMode drift_mode) {
  898. if (!IsDeviceHandleValid(sixaxis_handle)) {
  899. LOG_ERROR(Service_HID, "Invalid handle");
  900. return;
  901. }
  902. auto& controller = GetControllerFromHandle(sixaxis_handle);
  903. controller.gyroscope_zero_drift_mode = drift_mode;
  904. }
  905. Controller_NPad::GyroscopeZeroDriftMode Controller_NPad::GetGyroscopeZeroDriftMode(
  906. Core::HID::SixAxisSensorHandle sixaxis_handle) const {
  907. if (!IsDeviceHandleValid(sixaxis_handle)) {
  908. LOG_ERROR(Service_HID, "Invalid handle");
  909. // Return the default value
  910. return GyroscopeZeroDriftMode::Standard;
  911. }
  912. const auto& controller = GetControllerFromHandle(sixaxis_handle);
  913. return controller.gyroscope_zero_drift_mode;
  914. }
  915. bool Controller_NPad::IsSixAxisSensorAtRest(Core::HID::SixAxisSensorHandle sixaxis_handle) const {
  916. if (!IsDeviceHandleValid(sixaxis_handle)) {
  917. LOG_ERROR(Service_HID, "Invalid handle");
  918. // Return the default value
  919. return true;
  920. }
  921. const auto& controller = GetControllerFromHandle(sixaxis_handle);
  922. return controller.sixaxis_at_rest;
  923. }
  924. void Controller_NPad::SetSixAxisEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
  925. bool sixaxis_status) {
  926. if (!IsDeviceHandleValid(sixaxis_handle)) {
  927. LOG_ERROR(Service_HID, "Invalid handle");
  928. return;
  929. }
  930. auto& controller = GetControllerFromHandle(sixaxis_handle);
  931. controller.sixaxis_sensor_enabled = sixaxis_status;
  932. }
  933. void Controller_NPad::SetSixAxisFusionEnabled(Core::HID::SixAxisSensorHandle sixaxis_handle,
  934. bool sixaxis_fusion_status) {
  935. if (!IsDeviceHandleValid(sixaxis_handle)) {
  936. LOG_ERROR(Service_HID, "Invalid handle");
  937. return;
  938. }
  939. auto& controller = GetControllerFromHandle(sixaxis_handle);
  940. controller.sixaxis_fusion_enabled = sixaxis_fusion_status;
  941. }
  942. void Controller_NPad::SetSixAxisFusionParameters(
  943. Core::HID::SixAxisSensorHandle sixaxis_handle,
  944. Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
  945. if (!IsDeviceHandleValid(sixaxis_handle)) {
  946. LOG_ERROR(Service_HID, "Invalid handle");
  947. return;
  948. }
  949. auto& controller = GetControllerFromHandle(sixaxis_handle);
  950. controller.sixaxis_fusion = sixaxis_fusion_parameters;
  951. }
  952. Core::HID::SixAxisSensorFusionParameters Controller_NPad::GetSixAxisFusionParameters(
  953. Core::HID::SixAxisSensorHandle sixaxis_handle) {
  954. if (!IsDeviceHandleValid(sixaxis_handle)) {
  955. LOG_ERROR(Service_HID, "Invalid handle");
  956. // Since these parameters are unknow just return zeros
  957. return {};
  958. }
  959. auto& controller = GetControllerFromHandle(sixaxis_handle);
  960. return controller.sixaxis_fusion;
  961. }
  962. void Controller_NPad::ResetSixAxisFusionParameters(Core::HID::SixAxisSensorHandle sixaxis_handle) {
  963. if (!IsDeviceHandleValid(sixaxis_handle)) {
  964. LOG_ERROR(Service_HID, "Invalid handle");
  965. return;
  966. }
  967. auto& controller = GetControllerFromHandle(sixaxis_handle);
  968. // Since these parameters are unknow just fill with zeros
  969. controller.sixaxis_fusion = {};
  970. }
  971. void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
  972. Core::HID::NpadIdType npad_id_2) {
  973. if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
  974. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
  975. npad_id_2);
  976. return;
  977. }
  978. auto& controller_1 = GetControllerFromNpadIdType(npad_id_1);
  979. auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
  980. const auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
  981. const auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
  982. bool merge_controllers = false;
  983. // If the controllers at both npad indices form a pair of left and right joycons, merge them.
  984. // Otherwise, do nothing.
  985. if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
  986. controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) {
  987. merge_controllers = true;
  988. }
  989. if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
  990. controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) {
  991. merge_controllers = true;
  992. }
  993. if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
  994. controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight &&
  995. controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
  996. merge_controllers = true;
  997. }
  998. if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
  999. controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
  1000. !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
  1001. merge_controllers = true;
  1002. }
  1003. if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
  1004. controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
  1005. controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
  1006. merge_controllers = true;
  1007. }
  1008. if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
  1009. controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
  1010. !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
  1011. merge_controllers = true;
  1012. }
  1013. if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
  1014. controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
  1015. controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected &&
  1016. !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
  1017. merge_controllers = true;
  1018. }
  1019. if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
  1020. controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
  1021. !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected &&
  1022. controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
  1023. merge_controllers = true;
  1024. }
  1025. if (merge_controllers) {
  1026. // Disconnect the joycon at the second id and connect the dual joycon at the first index.
  1027. DisconnectNpad(npad_id_2);
  1028. controller_1.is_dual_left_connected = true;
  1029. controller_1.is_dual_right_connected = true;
  1030. AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
  1031. return;
  1032. }
  1033. LOG_WARNING(Service_HID,
  1034. "Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, "
  1035. "dual_1(left/right):{}/{}, dual_2(left/right):{}/{}",
  1036. npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(),
  1037. controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected,
  1038. controller_1.is_dual_right_connected, controller_2.is_dual_left_connected,
  1039. controller_2.is_dual_right_connected);
  1040. }
  1041. void Controller_NPad::StartLRAssignmentMode() {
  1042. // Nothing internally is used for lr assignment mode. Since we have the ability to set the
  1043. // controller types from boot, it doesn't really matter about showing a selection screen
  1044. is_in_lr_assignment_mode = true;
  1045. }
  1046. void Controller_NPad::StopLRAssignmentMode() {
  1047. is_in_lr_assignment_mode = false;
  1048. }
  1049. bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
  1050. Core::HID::NpadIdType npad_id_2) {
  1051. if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
  1052. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
  1053. npad_id_2);
  1054. return false;
  1055. }
  1056. if (npad_id_1 == Core::HID::NpadIdType::Handheld ||
  1057. npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other ||
  1058. npad_id_2 == Core::HID::NpadIdType::Other) {
  1059. return true;
  1060. }
  1061. const auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device;
  1062. const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device;
  1063. const auto type_index_1 = controller_1->GetNpadStyleIndex();
  1064. const auto type_index_2 = controller_2->GetNpadStyleIndex();
  1065. const auto is_connected_1 = controller_1->IsConnected();
  1066. const auto is_connected_2 = controller_2->IsConnected();
  1067. if (!IsControllerSupported(type_index_1) && is_connected_1) {
  1068. return false;
  1069. }
  1070. if (!IsControllerSupported(type_index_2) && is_connected_2) {
  1071. return false;
  1072. }
  1073. UpdateControllerAt(type_index_2, npad_id_1, is_connected_2);
  1074. UpdateControllerAt(type_index_1, npad_id_2, is_connected_1);
  1075. return true;
  1076. }
  1077. Core::HID::LedPattern Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id) {
  1078. if (!IsNpadIdValid(npad_id)) {
  1079. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  1080. return Core::HID::LedPattern{0, 0, 0, 0};
  1081. }
  1082. const auto& controller = GetControllerFromNpadIdType(npad_id).device;
  1083. return controller->GetLedPattern();
  1084. }
  1085. bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(
  1086. Core::HID::NpadIdType npad_id) const {
  1087. if (!IsNpadIdValid(npad_id)) {
  1088. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  1089. // Return the default value
  1090. return false;
  1091. }
  1092. const auto& controller = GetControllerFromNpadIdType(npad_id);
  1093. return controller.unintended_home_button_input_protection;
  1094. }
  1095. void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
  1096. Core::HID::NpadIdType npad_id) {
  1097. if (!IsNpadIdValid(npad_id)) {
  1098. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  1099. return;
  1100. }
  1101. auto& controller = GetControllerFromNpadIdType(npad_id);
  1102. controller.unintended_home_button_input_protection = is_protection_enabled;
  1103. }
  1104. void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
  1105. analog_stick_use_center_clamp = use_center_clamp;
  1106. }
  1107. void Controller_NPad::ClearAllConnectedControllers() {
  1108. for (auto& controller : controller_data) {
  1109. if (controller.device->IsConnected() &&
  1110. controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) {
  1111. controller.device->Disconnect();
  1112. controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
  1113. }
  1114. }
  1115. }
  1116. void Controller_NPad::DisconnectAllConnectedControllers() {
  1117. for (auto& controller : controller_data) {
  1118. controller.device->Disconnect();
  1119. }
  1120. }
  1121. void Controller_NPad::ConnectAllDisconnectedControllers() {
  1122. for (auto& controller : controller_data) {
  1123. if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None &&
  1124. !controller.device->IsConnected()) {
  1125. controller.device->Connect();
  1126. }
  1127. }
  1128. }
  1129. void Controller_NPad::ClearAllControllers() {
  1130. for (auto& controller : controller_data) {
  1131. controller.device->Disconnect();
  1132. controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
  1133. }
  1134. }
  1135. Core::HID::NpadButton Controller_NPad::GetAndResetPressState() {
  1136. return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
  1137. }
  1138. bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
  1139. if (controller == Core::HID::NpadStyleIndex::Handheld) {
  1140. const bool support_handheld =
  1141. std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
  1142. Core::HID::NpadIdType::Handheld) != supported_npad_id_types.end();
  1143. // Handheld is not even a supported type, lets stop here
  1144. if (!support_handheld) {
  1145. return false;
  1146. }
  1147. // Handheld shouldn't be supported in docked mode
  1148. if (Settings::values.use_docked_mode.GetValue()) {
  1149. return false;
  1150. }
  1151. return true;
  1152. }
  1153. if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(),
  1154. [](Core::HID::NpadIdType npad_id) {
  1155. return npad_id <= Core::HID::NpadIdType::Player8;
  1156. })) {
  1157. Core::HID::NpadStyleTag style = GetSupportedStyleSet();
  1158. switch (controller) {
  1159. case Core::HID::NpadStyleIndex::ProController:
  1160. return style.fullkey;
  1161. case Core::HID::NpadStyleIndex::JoyconDual:
  1162. return style.joycon_dual;
  1163. case Core::HID::NpadStyleIndex::JoyconLeft:
  1164. return style.joycon_left;
  1165. case Core::HID::NpadStyleIndex::JoyconRight:
  1166. return style.joycon_right;
  1167. case Core::HID::NpadStyleIndex::GameCube:
  1168. return style.gamecube;
  1169. case Core::HID::NpadStyleIndex::Pokeball:
  1170. return style.palma;
  1171. case Core::HID::NpadStyleIndex::NES:
  1172. return style.lark;
  1173. case Core::HID::NpadStyleIndex::SNES:
  1174. return style.lucia;
  1175. case Core::HID::NpadStyleIndex::N64:
  1176. return style.lagoon;
  1177. case Core::HID::NpadStyleIndex::SegaGenesis:
  1178. return style.lager;
  1179. default:
  1180. return false;
  1181. }
  1182. }
  1183. return false;
  1184. }
  1185. Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
  1186. const Core::HID::SixAxisSensorHandle& device_handle) {
  1187. const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
  1188. return GetControllerFromNpadIdType(npad_id);
  1189. }
  1190. const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
  1191. const Core::HID::SixAxisSensorHandle& device_handle) const {
  1192. const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
  1193. return GetControllerFromNpadIdType(npad_id);
  1194. }
  1195. Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
  1196. const Core::HID::VibrationDeviceHandle& device_handle) {
  1197. const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
  1198. return GetControllerFromNpadIdType(npad_id);
  1199. }
  1200. const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle(
  1201. const Core::HID::VibrationDeviceHandle& device_handle) const {
  1202. const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
  1203. return GetControllerFromNpadIdType(npad_id);
  1204. }
  1205. Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType(
  1206. Core::HID::NpadIdType npad_id) {
  1207. if (!IsNpadIdValid(npad_id)) {
  1208. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  1209. npad_id = Core::HID::NpadIdType::Player1;
  1210. }
  1211. const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id);
  1212. return controller_data[npad_index];
  1213. }
  1214. const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType(
  1215. Core::HID::NpadIdType npad_id) const {
  1216. if (!IsNpadIdValid(npad_id)) {
  1217. LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
  1218. npad_id = Core::HID::NpadIdType::Player1;
  1219. }
  1220. const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id);
  1221. return controller_data[npad_index];
  1222. }
  1223. } // namespace Service::HID