joycon.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <fmt/format.h>
  4. #include "common/param_package.h"
  5. #include "common/settings.h"
  6. #include "common/thread.h"
  7. #include "input_common/drivers/joycon.h"
  8. #include "input_common/helpers/joycon_driver.h"
  9. #include "input_common/helpers/joycon_protocol/joycon_types.h"
  10. namespace InputCommon {
  11. Joycons::Joycons(const std::string& input_engine_) : InputEngine(input_engine_) {
  12. LOG_INFO(Input, "Joycon driver Initialization started");
  13. const int init_res = SDL_hid_init();
  14. if (init_res == 0) {
  15. Setup();
  16. } else {
  17. LOG_ERROR(Input, "Hidapi could not be initialized. failed with error = {}", init_res);
  18. }
  19. }
  20. Joycons::~Joycons() {
  21. Reset();
  22. }
  23. void Joycons::Reset() {
  24. scan_thread = {};
  25. for (const auto& device : left_joycons) {
  26. if (!device) {
  27. continue;
  28. }
  29. device->Stop();
  30. }
  31. for (const auto& device : right_joycons) {
  32. if (!device) {
  33. continue;
  34. }
  35. device->Stop();
  36. }
  37. for (const auto& device : pro_joycons) {
  38. if (!device) {
  39. continue;
  40. }
  41. device->Stop();
  42. }
  43. SDL_hid_exit();
  44. }
  45. void Joycons::Setup() {
  46. u32 port = 0;
  47. for (auto& device : left_joycons) {
  48. PreSetController(GetIdentifier(port, Joycon::ControllerType::Left));
  49. device = std::make_shared<Joycon::JoyconDriver>(port++);
  50. }
  51. for (auto& device : right_joycons) {
  52. PreSetController(GetIdentifier(port, Joycon::ControllerType::Right));
  53. device = std::make_shared<Joycon::JoyconDriver>(port++);
  54. }
  55. for (auto& device : pro_joycons) {
  56. PreSetController(GetIdentifier(port, Joycon::ControllerType::Pro));
  57. device = std::make_shared<Joycon::JoyconDriver>(port++);
  58. }
  59. if (!scan_thread_running) {
  60. scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); });
  61. }
  62. }
  63. void Joycons::ScanThread(std::stop_token stop_token) {
  64. constexpr u16 nintendo_vendor_id = 0x057e;
  65. Common::SetCurrentThreadName("yuzu:input:JoyconScanThread");
  66. scan_thread_running = true;
  67. while (!stop_token.stop_requested()) {
  68. SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0);
  69. SDL_hid_device_info* cur_dev = devs;
  70. while (cur_dev) {
  71. if (IsDeviceNew(cur_dev)) {
  72. LOG_DEBUG(Input, "Device Found,type : {:04X} {:04X}", cur_dev->vendor_id,
  73. cur_dev->product_id);
  74. RegisterNewDevice(cur_dev);
  75. }
  76. cur_dev = cur_dev->next;
  77. }
  78. std::this_thread::sleep_for(std::chrono::seconds(5));
  79. }
  80. scan_thread_running = false;
  81. }
  82. bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const {
  83. Joycon::ControllerType type{};
  84. Joycon::SerialNumber serial_number{};
  85. const auto result = Joycon::JoyconDriver::GetDeviceType(device_info, type);
  86. if (result != Joycon::DriverResult::Success) {
  87. return false;
  88. }
  89. const auto result2 = Joycon::JoyconDriver::GetSerialNumber(device_info, serial_number);
  90. if (result2 != Joycon::DriverResult::Success) {
  91. return false;
  92. }
  93. auto is_handle_identical = [&](std::shared_ptr<Joycon::JoyconDriver> device) {
  94. if (!device) {
  95. return false;
  96. }
  97. if (!device->IsConnected()) {
  98. return false;
  99. }
  100. if (device->GetHandleSerialNumber() != serial_number) {
  101. return false;
  102. }
  103. return true;
  104. };
  105. // Check if device already exist
  106. switch (type) {
  107. case Joycon::ControllerType::Left:
  108. for (const auto& device : left_joycons) {
  109. if (is_handle_identical(device)) {
  110. return false;
  111. }
  112. }
  113. break;
  114. case Joycon::ControllerType::Right:
  115. for (const auto& device : right_joycons) {
  116. if (is_handle_identical(device)) {
  117. return false;
  118. }
  119. }
  120. break;
  121. case Joycon::ControllerType::Pro:
  122. case Joycon::ControllerType::Grip:
  123. for (const auto& device : pro_joycons) {
  124. if (is_handle_identical(device)) {
  125. return false;
  126. }
  127. }
  128. break;
  129. default:
  130. return false;
  131. }
  132. return true;
  133. }
  134. void Joycons::RegisterNewDevice(SDL_hid_device_info* device_info) {
  135. Joycon::ControllerType type{};
  136. auto result = Joycon::JoyconDriver::GetDeviceType(device_info, type);
  137. auto handle = GetNextFreeHandle(type);
  138. if (handle == nullptr) {
  139. LOG_WARNING(Input, "No free handles available");
  140. return;
  141. }
  142. if (result == Joycon::DriverResult::Success) {
  143. result = handle->RequestDeviceAccess(device_info);
  144. }
  145. if (result == Joycon::DriverResult::Success) {
  146. LOG_WARNING(Input, "Initialize device");
  147. std::function<void(Joycon::Battery)> on_battery_data;
  148. std::function<void(Joycon::Color)> on_button_data;
  149. std::function<void(int, f32)> on_stick_data;
  150. std::function<void(int, std::array<u8, 6>)> on_motion_data;
  151. std::function<void(s16)> on_ring_data;
  152. std::function<void(const std::vector<u8>&)> on_amiibo_data;
  153. const std::size_t port = handle->GetDevicePort();
  154. handle->on_battery_data = {
  155. [this, port, type](Joycon::Battery value) { OnBatteryUpdate(port, type, value); }};
  156. handle->on_color_data = {
  157. [this, port, type](Joycon::Color value) { OnColorUpdate(port, type, value); }};
  158. handle->on_button_data = {
  159. [this, port, type](int id, bool value) { OnButtonUpdate(port, type, id, value); }};
  160. handle->on_stick_data = {
  161. [this, port, type](int id, f32 value) { OnStickUpdate(port, type, id, value); }};
  162. handle->on_motion_data = {[this, port, type](int id, Joycon::MotionData value) {
  163. OnMotionUpdate(port, type, id, value);
  164. }};
  165. handle->on_ring_data = {[this](f32 ring_data) { OnRingConUpdate(ring_data); }};
  166. handle->on_amiibo_data = {[this, port](const std::vector<u8>& amiibo_data) {
  167. OnAmiiboUpdate(port, amiibo_data);
  168. }};
  169. handle->InitializeDevice();
  170. }
  171. }
  172. std::shared_ptr<Joycon::JoyconDriver> Joycons::GetNextFreeHandle(
  173. Joycon::ControllerType type) const {
  174. if (type == Joycon::ControllerType::Left) {
  175. for (const auto& device : left_joycons) {
  176. if (!device->IsConnected()) {
  177. return device;
  178. }
  179. }
  180. }
  181. if (type == Joycon::ControllerType::Right) {
  182. for (const auto& device : right_joycons) {
  183. if (!device->IsConnected()) {
  184. return device;
  185. }
  186. }
  187. }
  188. if (type == Joycon::ControllerType::Pro || type == Joycon::ControllerType::Grip) {
  189. for (const auto& device : pro_joycons) {
  190. if (!device->IsConnected()) {
  191. return device;
  192. }
  193. }
  194. }
  195. return nullptr;
  196. }
  197. bool Joycons::IsVibrationEnabled(const PadIdentifier& identifier) {
  198. const auto handle = GetHandle(identifier);
  199. if (handle == nullptr) {
  200. return false;
  201. }
  202. return handle->IsVibrationEnabled();
  203. }
  204. Common::Input::VibrationError Joycons::SetVibration(
  205. const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
  206. const Joycon::VibrationValue native_vibration{
  207. .low_amplitude = vibration.low_amplitude,
  208. .low_frequency = vibration.low_frequency,
  209. .high_amplitude = vibration.high_amplitude,
  210. .high_frequency = vibration.high_amplitude,
  211. };
  212. auto handle = GetHandle(identifier);
  213. if (handle == nullptr) {
  214. return Common::Input::VibrationError::InvalidHandle;
  215. }
  216. handle->SetVibration(native_vibration);
  217. return Common::Input::VibrationError::None;
  218. }
  219. void Joycons::SetLeds(const PadIdentifier& identifier, const Common::Input::LedStatus& led_status) {
  220. auto handle = GetHandle(identifier);
  221. if (handle == nullptr) {
  222. return;
  223. }
  224. int led_config = led_status.led_1 ? 1 : 0;
  225. led_config += led_status.led_2 ? 2 : 0;
  226. led_config += led_status.led_3 ? 4 : 0;
  227. led_config += led_status.led_4 ? 8 : 0;
  228. const auto result = handle->SetLedConfig(static_cast<u8>(led_config));
  229. if (result != Joycon::DriverResult::Success) {
  230. LOG_ERROR(Input, "Failed to set led config");
  231. }
  232. }
  233. Common::Input::CameraError Joycons::SetCameraFormat(const PadIdentifier& identifier_,
  234. Common::Input::CameraFormat camera_format) {
  235. return Common::Input::CameraError::NotSupported;
  236. };
  237. Common::Input::NfcState Joycons::SupportsNfc(const PadIdentifier& identifier_) const {
  238. return Common::Input::NfcState::Success;
  239. };
  240. Common::Input::NfcState Joycons::WriteNfcData(const PadIdentifier& identifier_,
  241. const std::vector<u8>& data) {
  242. return Common::Input::NfcState::NotSupported;
  243. };
  244. Common::Input::PollingError Joycons::SetPollingMode(const PadIdentifier& identifier,
  245. const Common::Input::PollingMode polling_mode) {
  246. auto handle = GetHandle(identifier);
  247. if (handle == nullptr) {
  248. LOG_ERROR(Input, "Invalid handle {}", identifier.port);
  249. return Common::Input::PollingError::InvalidHandle;
  250. }
  251. switch (polling_mode) {
  252. case Common::Input::PollingMode::NFC:
  253. handle->SetNfcMode();
  254. break;
  255. case Common::Input::PollingMode::Active:
  256. handle->SetActiveMode();
  257. break;
  258. case Common::Input::PollingMode::Pasive:
  259. handle->SetPasiveMode();
  260. break;
  261. case Common::Input::PollingMode::Ring:
  262. handle->SetRingConMode();
  263. break;
  264. default:
  265. return Common::Input::PollingError::NotSupported;
  266. }
  267. return Common::Input::PollingError::None;
  268. }
  269. void Joycons::OnBatteryUpdate(std::size_t port, Joycon::ControllerType type,
  270. Joycon::Battery value) {
  271. const auto identifier = GetIdentifier(port, type);
  272. if (value.charging != 0) {
  273. SetBattery(identifier, Common::Input::BatteryLevel::Charging);
  274. return;
  275. }
  276. Common::Input::BatteryLevel battery{value.status.Value()};
  277. switch (value.status) {
  278. case 0:
  279. battery = Common::Input::BatteryLevel::Empty;
  280. break;
  281. case 1:
  282. battery = Common::Input::BatteryLevel::Critical;
  283. break;
  284. case 2:
  285. battery = Common::Input::BatteryLevel::Low;
  286. break;
  287. case 3:
  288. battery = Common::Input::BatteryLevel::Medium;
  289. break;
  290. case 4:
  291. default:
  292. battery = Common::Input::BatteryLevel::Full;
  293. break;
  294. }
  295. SetBattery(identifier, battery);
  296. }
  297. void Joycons::OnColorUpdate(std::size_t port, Joycon::ControllerType type,
  298. const Joycon::Color& value) {}
  299. void Joycons::OnButtonUpdate(std::size_t port, Joycon::ControllerType type, int id, bool value) {
  300. const auto identifier = GetIdentifier(port, type);
  301. SetButton(identifier, id, value);
  302. }
  303. void Joycons::OnStickUpdate(std::size_t port, Joycon::ControllerType type, int id, f32 value) {
  304. const auto identifier = GetIdentifier(port, type);
  305. SetAxis(identifier, id, value);
  306. }
  307. void Joycons::OnMotionUpdate(std::size_t port, Joycon::ControllerType type, int id,
  308. const Joycon::MotionData& value) {
  309. const auto identifier = GetIdentifier(port, type);
  310. BasicMotion motion_data{
  311. .gyro_x = value.gyro_x,
  312. .gyro_y = value.gyro_y,
  313. .gyro_z = value.gyro_z,
  314. .accel_x = value.accel_x,
  315. .accel_y = value.accel_y,
  316. .accel_z = value.accel_z,
  317. .delta_timestamp = 15000,
  318. };
  319. SetMotion(identifier, id, motion_data);
  320. }
  321. void Joycons::OnRingConUpdate(f32 ring_data) {
  322. // To simplify ring detection it will always be mapped to an empty identifier for all
  323. // controllers
  324. constexpr PadIdentifier identifier = {
  325. .guid = Common::UUID{},
  326. .port = 0,
  327. .pad = 0,
  328. };
  329. SetAxis(identifier, 100, ring_data);
  330. }
  331. void Joycons::OnAmiiboUpdate(std::size_t port, const std::vector<u8>& amiibo_data) {
  332. const auto identifier = GetIdentifier(port, Joycon::ControllerType::Right);
  333. SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, amiibo_data});
  334. }
  335. std::shared_ptr<Joycon::JoyconDriver> Joycons::GetHandle(PadIdentifier identifier) const {
  336. auto is_handle_active = [&](std::shared_ptr<Joycon::JoyconDriver> device) {
  337. if (!device) {
  338. return false;
  339. }
  340. if (!device->IsConnected()) {
  341. return false;
  342. }
  343. if (device->GetDevicePort() == identifier.port) {
  344. return true;
  345. }
  346. return false;
  347. };
  348. const auto type = static_cast<Joycon::ControllerType>(identifier.pad);
  349. if (type == Joycon::ControllerType::Left) {
  350. for (const auto& device : left_joycons) {
  351. if (is_handle_active(device)) {
  352. return device;
  353. }
  354. }
  355. }
  356. if (type == Joycon::ControllerType::Right) {
  357. for (const auto& device : right_joycons) {
  358. if (is_handle_active(device)) {
  359. return device;
  360. }
  361. }
  362. }
  363. if (type == Joycon::ControllerType::Pro || type == Joycon::ControllerType::Grip) {
  364. for (const auto& device : pro_joycons) {
  365. if (is_handle_active(device)) {
  366. return device;
  367. }
  368. }
  369. }
  370. return nullptr;
  371. }
  372. PadIdentifier Joycons::GetIdentifier(std::size_t port, Joycon::ControllerType type) const {
  373. return {
  374. .guid = Common::UUID{Common::InvalidUUID},
  375. .port = port,
  376. .pad = static_cast<std::size_t>(type),
  377. };
  378. }
  379. std::vector<Common::ParamPackage> Joycons::GetInputDevices() const {
  380. std::vector<Common::ParamPackage> devices{};
  381. auto add_entry = [&](std::shared_ptr<Joycon::JoyconDriver> device) {
  382. if (!device) {
  383. return;
  384. }
  385. if (!device->IsConnected()) {
  386. return;
  387. }
  388. std::string name = fmt::format("{} {}", JoyconName(device->GetHandleDeviceType()),
  389. device->GetDevicePort());
  390. devices.emplace_back(Common::ParamPackage{
  391. {"engine", GetEngineName()},
  392. {"display", std::move(name)},
  393. {"port", std::to_string(device->GetDevicePort())},
  394. {"pad", std::to_string(static_cast<std::size_t>(device->GetHandleDeviceType()))},
  395. });
  396. };
  397. for (const auto& controller : left_joycons) {
  398. add_entry(controller);
  399. }
  400. for (const auto& controller : right_joycons) {
  401. add_entry(controller);
  402. }
  403. for (const auto& controller : pro_joycons) {
  404. add_entry(controller);
  405. }
  406. return devices;
  407. }
  408. ButtonMapping Joycons::GetButtonMappingForDevice(const Common::ParamPackage& params) {
  409. static constexpr std::array<std::pair<Settings::NativeButton::Values, Joycon::PadButton>, 20>
  410. switch_to_joycon_button = {
  411. std::pair{Settings::NativeButton::A, Joycon::PadButton::A},
  412. {Settings::NativeButton::B, Joycon::PadButton::B},
  413. {Settings::NativeButton::X, Joycon::PadButton::X},
  414. {Settings::NativeButton::Y, Joycon::PadButton::Y},
  415. {Settings::NativeButton::DLeft, Joycon::PadButton::Left},
  416. {Settings::NativeButton::DUp, Joycon::PadButton::Up},
  417. {Settings::NativeButton::DRight, Joycon::PadButton::Right},
  418. {Settings::NativeButton::DDown, Joycon::PadButton::Down},
  419. {Settings::NativeButton::SL, Joycon::PadButton::LeftSL},
  420. {Settings::NativeButton::SR, Joycon::PadButton::LeftSR},
  421. {Settings::NativeButton::L, Joycon::PadButton::L},
  422. {Settings::NativeButton::R, Joycon::PadButton::R},
  423. {Settings::NativeButton::ZL, Joycon::PadButton::ZL},
  424. {Settings::NativeButton::ZR, Joycon::PadButton::ZR},
  425. {Settings::NativeButton::Plus, Joycon::PadButton::Plus},
  426. {Settings::NativeButton::Minus, Joycon::PadButton::Minus},
  427. {Settings::NativeButton::Home, Joycon::PadButton::Home},
  428. {Settings::NativeButton::Screenshot, Joycon::PadButton::Capture},
  429. {Settings::NativeButton::LStick, Joycon::PadButton::StickL},
  430. {Settings::NativeButton::RStick, Joycon::PadButton::StickR},
  431. };
  432. if (!params.Has("port")) {
  433. return {};
  434. }
  435. ButtonMapping mapping{};
  436. for (const auto& [switch_button, joycon_button] : switch_to_joycon_button) {
  437. Common::ParamPackage button_params{};
  438. button_params.Set("engine", GetEngineName());
  439. button_params.Set("port", params.Get("port", 0));
  440. button_params.Set("button", static_cast<int>(joycon_button));
  441. mapping.insert_or_assign(switch_button, std::move(button_params));
  442. }
  443. return mapping;
  444. }
  445. AnalogMapping Joycons::GetAnalogMappingForDevice(const Common::ParamPackage& params) {
  446. if (!params.Has("port")) {
  447. return {};
  448. }
  449. AnalogMapping mapping = {};
  450. Common::ParamPackage left_analog_params;
  451. left_analog_params.Set("engine", GetEngineName());
  452. left_analog_params.Set("port", params.Get("port", 0));
  453. left_analog_params.Set("axis_x", static_cast<int>(Joycon::PadAxes::LeftStickX));
  454. left_analog_params.Set("axis_y", static_cast<int>(Joycon::PadAxes::LeftStickY));
  455. mapping.insert_or_assign(Settings::NativeAnalog::LStick, std::move(left_analog_params));
  456. Common::ParamPackage right_analog_params;
  457. right_analog_params.Set("engine", GetEngineName());
  458. right_analog_params.Set("port", params.Get("port", 0));
  459. right_analog_params.Set("axis_x", static_cast<int>(Joycon::PadAxes::RightStickX));
  460. right_analog_params.Set("axis_y", static_cast<int>(Joycon::PadAxes::RightStickY));
  461. mapping.insert_or_assign(Settings::NativeAnalog::RStick, std::move(right_analog_params));
  462. return mapping;
  463. }
  464. MotionMapping Joycons::GetMotionMappingForDevice(const Common::ParamPackage& params) {
  465. if (!params.Has("port")) {
  466. return {};
  467. }
  468. MotionMapping mapping = {};
  469. Common::ParamPackage left_motion_params;
  470. left_motion_params.Set("engine", GetEngineName());
  471. left_motion_params.Set("port", params.Get("port", 0));
  472. left_motion_params.Set("motion", 0);
  473. mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, std::move(left_motion_params));
  474. Common::ParamPackage right_Motion_params;
  475. right_Motion_params.Set("engine", GetEngineName());
  476. right_Motion_params.Set("port", params.Get("port", 0));
  477. right_Motion_params.Set("motion", 1);
  478. mapping.insert_or_assign(Settings::NativeMotion::MotionRight, std::move(right_Motion_params));
  479. return mapping;
  480. }
  481. Common::Input::ButtonNames Joycons::GetUIButtonName(const Common::ParamPackage& params) const {
  482. const auto button = static_cast<Joycon::PadButton>(params.Get("button", 0));
  483. switch (button) {
  484. case Joycon::PadButton::Left:
  485. return Common::Input::ButtonNames::ButtonLeft;
  486. case Joycon::PadButton::Right:
  487. return Common::Input::ButtonNames::ButtonRight;
  488. case Joycon::PadButton::Down:
  489. return Common::Input::ButtonNames::ButtonDown;
  490. case Joycon::PadButton::Up:
  491. return Common::Input::ButtonNames::ButtonUp;
  492. case Joycon::PadButton::LeftSL:
  493. case Joycon::PadButton::RightSL:
  494. return Common::Input::ButtonNames::TriggerSL;
  495. case Joycon::PadButton::LeftSR:
  496. case Joycon::PadButton::RightSR:
  497. return Common::Input::ButtonNames::TriggerSR;
  498. case Joycon::PadButton::L:
  499. return Common::Input::ButtonNames::TriggerL;
  500. case Joycon::PadButton::R:
  501. return Common::Input::ButtonNames::TriggerR;
  502. case Joycon::PadButton::ZL:
  503. return Common::Input::ButtonNames::TriggerZL;
  504. case Joycon::PadButton::ZR:
  505. return Common::Input::ButtonNames::TriggerZR;
  506. case Joycon::PadButton::A:
  507. return Common::Input::ButtonNames::ButtonA;
  508. case Joycon::PadButton::B:
  509. return Common::Input::ButtonNames::ButtonB;
  510. case Joycon::PadButton::X:
  511. return Common::Input::ButtonNames::ButtonX;
  512. case Joycon::PadButton::Y:
  513. return Common::Input::ButtonNames::ButtonY;
  514. case Joycon::PadButton::Plus:
  515. return Common::Input::ButtonNames::ButtonPlus;
  516. case Joycon::PadButton::Minus:
  517. return Common::Input::ButtonNames::ButtonMinus;
  518. case Joycon::PadButton::Home:
  519. return Common::Input::ButtonNames::ButtonHome;
  520. case Joycon::PadButton::Capture:
  521. return Common::Input::ButtonNames::ButtonCapture;
  522. case Joycon::PadButton::StickL:
  523. return Common::Input::ButtonNames::ButtonStickL;
  524. case Joycon::PadButton::StickR:
  525. return Common::Input::ButtonNames::ButtonStickR;
  526. default:
  527. return Common::Input::ButtonNames::Undefined;
  528. }
  529. }
  530. Common::Input::ButtonNames Joycons::GetUIName(const Common::ParamPackage& params) const {
  531. if (params.Has("button")) {
  532. return GetUIButtonName(params);
  533. }
  534. if (params.Has("axis")) {
  535. return Common::Input::ButtonNames::Value;
  536. }
  537. if (params.Has("motion")) {
  538. return Common::Input::ButtonNames::Engine;
  539. }
  540. return Common::Input::ButtonNames::Invalid;
  541. }
  542. std::string Joycons::JoyconName(Joycon::ControllerType type) const {
  543. switch (type) {
  544. case Joycon::ControllerType::Left:
  545. return "Left Joycon";
  546. case Joycon::ControllerType::Right:
  547. return "Right Joycon";
  548. case Joycon::ControllerType::Pro:
  549. return "Pro Controller";
  550. case Joycon::ControllerType::Grip:
  551. return "Grip Controller";
  552. default:
  553. return "Unknow Joycon";
  554. }
  555. }
  556. } // namespace InputCommon