diff options
| author | 2021-11-26 15:45:37 -0600 | |
|---|---|---|
| committer | 2021-11-26 15:46:36 -0600 | |
| commit | 639402850ac65c694967ef6519becb65abe89b39 (patch) | |
| tree | 55ab559c417a519ac8b93a746428842e53c19a31 /src/input_common/drivers/udp_client.cpp | |
| parent | service/hid: Finish converting LIFO objects and address some nits (diff) | |
| download | yuzu-639402850ac65c694967ef6519becb65abe89b39.tar.gz yuzu-639402850ac65c694967ef6519becb65abe89b39.tar.xz yuzu-639402850ac65c694967ef6519becb65abe89b39.zip | |
input_common: Fully implement UDP controllers
Diffstat (limited to 'src/input_common/drivers/udp_client.cpp')
| -rw-r--r-- | src/input_common/drivers/udp_client.cpp | 206 |
1 files changed, 198 insertions, 8 deletions
diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp index 7cab707da..fdee0f2d5 100644 --- a/src/input_common/drivers/udp_client.cpp +++ b/src/input_common/drivers/udp_client.cpp | |||
| @@ -103,7 +103,7 @@ private: | |||
| 103 | 103 | ||
| 104 | // Send a request for getting pad data for the pad | 104 | // Send a request for getting pad data for the pad |
| 105 | const Request::PadData pad_data{ | 105 | const Request::PadData pad_data{ |
| 106 | Request::PadData::Flags::AllPorts, | 106 | Request::RegisterFlags::AllPads, |
| 107 | 0, | 107 | 0, |
| 108 | EMPTY_MAC_ADDRESS, | 108 | EMPTY_MAC_ADDRESS, |
| 109 | }; | 109 | }; |
| @@ -247,7 +247,12 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) { | |||
| 247 | 247 | ||
| 248 | for (std::size_t id = 0; id < data.touch.size(); ++id) { | 248 | for (std::size_t id = 0; id < data.touch.size(); ++id) { |
| 249 | const auto touch_pad = data.touch[id]; | 249 | const auto touch_pad = data.touch[id]; |
| 250 | const int touch_id = static_cast<int>(client * 2 + id); | 250 | const auto touch_axis_x_id = |
| 251 | static_cast<int>(id == 0 ? PadAxes::Touch1X : PadAxes::Touch2X); | ||
| 252 | const auto touch_axis_y_id = | ||
| 253 | static_cast<int>(id == 0 ? PadAxes::Touch1Y : PadAxes::Touch2Y); | ||
| 254 | const auto touch_button_id = | ||
| 255 | static_cast<int>(id == 0 ? PadButton::Touch1 : PadButton::touch2); | ||
| 251 | 256 | ||
| 252 | // TODO: Use custom calibration per device | 257 | // TODO: Use custom calibration per device |
| 253 | const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue()); | 258 | const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue()); |
| @@ -264,14 +269,35 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) { | |||
| 264 | static_cast<f32>(max_y - min_y); | 269 | static_cast<f32>(max_y - min_y); |
| 265 | 270 | ||
| 266 | if (touch_pad.is_active) { | 271 | if (touch_pad.is_active) { |
| 267 | SetAxis(identifier, touch_id * 2, x); | 272 | SetAxis(identifier, touch_axis_x_id, x); |
| 268 | SetAxis(identifier, touch_id * 2 + 1, y); | 273 | SetAxis(identifier, touch_axis_y_id, y); |
| 269 | SetButton(identifier, touch_id, true); | 274 | SetButton(identifier, touch_button_id, true); |
| 270 | continue; | 275 | continue; |
| 271 | } | 276 | } |
| 272 | SetAxis(identifier, touch_id * 2, 0); | 277 | SetAxis(identifier, touch_axis_x_id, 0); |
| 273 | SetAxis(identifier, touch_id * 2 + 1, 0); | 278 | SetAxis(identifier, touch_axis_y_id, 0); |
| 274 | SetButton(identifier, touch_id, false); | 279 | SetButton(identifier, touch_button_id, false); |
| 280 | } | ||
| 281 | |||
| 282 | SetAxis(identifier, static_cast<int>(PadAxes::LeftStickX), | ||
| 283 | (data.left_stick_x - 127.0f) / 127.0f); | ||
| 284 | SetAxis(identifier, static_cast<int>(PadAxes::LeftStickY), | ||
| 285 | (data.left_stick_y - 127.0f) / 127.0f); | ||
| 286 | SetAxis(identifier, static_cast<int>(PadAxes::RightStickX), | ||
| 287 | (data.right_stick_x - 127.0f) / 127.0f); | ||
| 288 | SetAxis(identifier, static_cast<int>(PadAxes::RightStickY), | ||
| 289 | (data.right_stick_y - 127.0f) / 127.0f); | ||
| 290 | |||
| 291 | static constexpr std::array<PadButton, 16> buttons{ | ||
| 292 | PadButton::Share, PadButton::L3, PadButton::R3, PadButton::Options, | ||
| 293 | PadButton::Up, PadButton::Right, PadButton::Down, PadButton::Left, | ||
| 294 | PadButton::L2, PadButton::R2, PadButton::L1, PadButton::R1, | ||
| 295 | PadButton::Triangle, PadButton::Circle, PadButton::Cross, PadButton::Square}; | ||
| 296 | |||
| 297 | for (std::size_t i = 0; i < buttons.size(); ++i) { | ||
| 298 | const bool button_status = (data.digital_button & (1U << i)) != 0; | ||
| 299 | const int button = static_cast<int>(buttons[i]); | ||
| 300 | SetButton(identifier, button, button_status); | ||
| 275 | } | 301 | } |
| 276 | } | 302 | } |
| 277 | 303 | ||
| @@ -317,6 +343,170 @@ void UDPClient::Reset() { | |||
| 317 | } | 343 | } |
| 318 | } | 344 | } |
| 319 | 345 | ||
| 346 | std::vector<Common::ParamPackage> UDPClient::GetInputDevices() const { | ||
| 347 | std::vector<Common::ParamPackage> devices; | ||
| 348 | if (!Settings::values.enable_udp_controller) { | ||
| 349 | return devices; | ||
| 350 | } | ||
| 351 | for (std::size_t client = 0; client < clients.size(); client++) { | ||
| 352 | if (clients[client].active != 1) { | ||
| 353 | continue; | ||
| 354 | } | ||
| 355 | for (std::size_t index = 0; index < PADS_PER_CLIENT; ++index) { | ||
| 356 | const std::size_t pad_index = client * PADS_PER_CLIENT + index; | ||
| 357 | if (!pads[pad_index].connected) { | ||
| 358 | continue; | ||
| 359 | } | ||
| 360 | const auto pad_identifier = GetPadIdentifier(pad_index); | ||
| 361 | Common::ParamPackage identifier{}; | ||
| 362 | identifier.Set("engine", GetEngineName()); | ||
| 363 | identifier.Set("display", fmt::format("UDP Controller {}", pad_identifier.pad)); | ||
| 364 | identifier.Set("guid", pad_identifier.guid.Format()); | ||
| 365 | identifier.Set("port", static_cast<int>(pad_identifier.port)); | ||
| 366 | identifier.Set("pad", static_cast<int>(pad_identifier.pad)); | ||
| 367 | devices.emplace_back(identifier); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | return devices; | ||
| 371 | } | ||
| 372 | |||
| 373 | ButtonMapping UDPClient::GetButtonMappingForDevice(const Common::ParamPackage& params) { | ||
| 374 | // This list excludes any button that can't be really mapped | ||
| 375 | static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 18> | ||
| 376 | switch_to_dsu_button = { | ||
| 377 | std::pair{Settings::NativeButton::A, PadButton::Circle}, | ||
| 378 | {Settings::NativeButton::B, PadButton::Cross}, | ||
| 379 | {Settings::NativeButton::X, PadButton::Triangle}, | ||
| 380 | {Settings::NativeButton::Y, PadButton::Square}, | ||
| 381 | {Settings::NativeButton::Plus, PadButton::Options}, | ||
| 382 | {Settings::NativeButton::Minus, PadButton::Share}, | ||
| 383 | {Settings::NativeButton::DLeft, PadButton::Left}, | ||
| 384 | {Settings::NativeButton::DUp, PadButton::Up}, | ||
| 385 | {Settings::NativeButton::DRight, PadButton::Right}, | ||
| 386 | {Settings::NativeButton::DDown, PadButton::Down}, | ||
| 387 | {Settings::NativeButton::L, PadButton::L1}, | ||
| 388 | {Settings::NativeButton::R, PadButton::R1}, | ||
| 389 | {Settings::NativeButton::ZL, PadButton::L2}, | ||
| 390 | {Settings::NativeButton::ZR, PadButton::R2}, | ||
| 391 | {Settings::NativeButton::SL, PadButton::L2}, | ||
| 392 | {Settings::NativeButton::SR, PadButton::R2}, | ||
| 393 | {Settings::NativeButton::LStick, PadButton::L3}, | ||
| 394 | {Settings::NativeButton::RStick, PadButton::R3}, | ||
| 395 | }; | ||
| 396 | if (!params.Has("guid") || !params.Has("port") || !params.Has("pad")) { | ||
| 397 | return {}; | ||
| 398 | } | ||
| 399 | |||
| 400 | ButtonMapping mapping{}; | ||
| 401 | for (const auto& [switch_button, dsu_button] : switch_to_dsu_button) { | ||
| 402 | Common::ParamPackage button_params{}; | ||
| 403 | button_params.Set("engine", GetEngineName()); | ||
| 404 | button_params.Set("guid", params.Get("guid", "")); | ||
| 405 | button_params.Set("port", params.Get("port", 0)); | ||
| 406 | button_params.Set("pad", params.Get("pad", 0)); | ||
| 407 | button_params.Set("button", static_cast<int>(dsu_button)); | ||
| 408 | mapping.insert_or_assign(switch_button, std::move(button_params)); | ||
| 409 | } | ||
| 410 | |||
| 411 | return mapping; | ||
| 412 | } | ||
| 413 | |||
| 414 | AnalogMapping UDPClient::GetAnalogMappingForDevice(const Common::ParamPackage& params) { | ||
| 415 | if (!params.Has("guid") || !params.Has("port") || !params.Has("pad")) { | ||
| 416 | return {}; | ||
| 417 | } | ||
| 418 | |||
| 419 | AnalogMapping mapping = {}; | ||
| 420 | Common::ParamPackage left_analog_params; | ||
| 421 | left_analog_params.Set("engine", GetEngineName()); | ||
| 422 | left_analog_params.Set("guid", params.Get("guid", "")); | ||
| 423 | left_analog_params.Set("port", params.Get("port", 0)); | ||
| 424 | left_analog_params.Set("pad", params.Get("pad", 0)); | ||
| 425 | left_analog_params.Set("axis_x", static_cast<int>(PadAxes::LeftStickX)); | ||
| 426 | left_analog_params.Set("axis_y", static_cast<int>(PadAxes::LeftStickY)); | ||
| 427 | mapping.insert_or_assign(Settings::NativeAnalog::LStick, std::move(left_analog_params)); | ||
| 428 | Common::ParamPackage right_analog_params; | ||
| 429 | right_analog_params.Set("engine", GetEngineName()); | ||
| 430 | right_analog_params.Set("guid", params.Get("guid", "")); | ||
| 431 | right_analog_params.Set("port", params.Get("port", 0)); | ||
| 432 | right_analog_params.Set("pad", params.Get("pad", 0)); | ||
| 433 | right_analog_params.Set("axis_x", static_cast<int>(PadAxes::RightStickX)); | ||
| 434 | right_analog_params.Set("axis_y", static_cast<int>(PadAxes::RightStickY)); | ||
| 435 | mapping.insert_or_assign(Settings::NativeAnalog::RStick, std::move(right_analog_params)); | ||
| 436 | return mapping; | ||
| 437 | } | ||
| 438 | |||
| 439 | MotionMapping UDPClient::GetMotionMappingForDevice(const Common::ParamPackage& params) { | ||
| 440 | if (!params.Has("guid") || !params.Has("port") || !params.Has("pad")) { | ||
| 441 | return {}; | ||
| 442 | } | ||
| 443 | |||
| 444 | MotionMapping mapping = {}; | ||
| 445 | Common::ParamPackage motion_params; | ||
| 446 | motion_params.Set("engine", GetEngineName()); | ||
| 447 | motion_params.Set("guid", params.Get("guid", "")); | ||
| 448 | motion_params.Set("port", params.Get("port", 0)); | ||
| 449 | motion_params.Set("pad", params.Get("pad", 0)); | ||
| 450 | motion_params.Set("motion", 0); | ||
| 451 | mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, std::move(motion_params)); | ||
| 452 | mapping.insert_or_assign(Settings::NativeMotion::MotionRight, std::move(motion_params)); | ||
| 453 | return mapping; | ||
| 454 | } | ||
| 455 | |||
| 456 | Common::Input::ButtonNames UDPClient::GetUIButtonName(const Common::ParamPackage& params) const { | ||
| 457 | PadButton button = static_cast<PadButton>(params.Get("button", 0)); | ||
| 458 | switch (button) { | ||
| 459 | case PadButton::Left: | ||
| 460 | return Common::Input::ButtonNames::ButtonLeft; | ||
| 461 | case PadButton::Right: | ||
| 462 | return Common::Input::ButtonNames::ButtonRight; | ||
| 463 | case PadButton::Down: | ||
| 464 | return Common::Input::ButtonNames::ButtonDown; | ||
| 465 | case PadButton::Up: | ||
| 466 | return Common::Input::ButtonNames::ButtonUp; | ||
| 467 | case PadButton::L1: | ||
| 468 | return Common::Input::ButtonNames::L1; | ||
| 469 | case PadButton::L2: | ||
| 470 | return Common::Input::ButtonNames::L2; | ||
| 471 | case PadButton::L3: | ||
| 472 | return Common::Input::ButtonNames::L3; | ||
| 473 | case PadButton::R1: | ||
| 474 | return Common::Input::ButtonNames::R1; | ||
| 475 | case PadButton::R2: | ||
| 476 | return Common::Input::ButtonNames::R2; | ||
| 477 | case PadButton::R3: | ||
| 478 | return Common::Input::ButtonNames::R3; | ||
| 479 | case PadButton::Circle: | ||
| 480 | return Common::Input::ButtonNames::Circle; | ||
| 481 | case PadButton::Cross: | ||
| 482 | return Common::Input::ButtonNames::Cross; | ||
| 483 | case PadButton::Square: | ||
| 484 | return Common::Input::ButtonNames::Square; | ||
| 485 | case PadButton::Triangle: | ||
| 486 | return Common::Input::ButtonNames::Triangle; | ||
| 487 | case PadButton::Share: | ||
| 488 | return Common::Input::ButtonNames::Share; | ||
| 489 | case PadButton::Options: | ||
| 490 | return Common::Input::ButtonNames::Options; | ||
| 491 | default: | ||
| 492 | return Common::Input::ButtonNames::Undefined; | ||
| 493 | } | ||
| 494 | } | ||
| 495 | |||
| 496 | Common::Input::ButtonNames UDPClient::GetUIName(const Common::ParamPackage& params) const { | ||
| 497 | if (params.Has("button")) { | ||
| 498 | return GetUIButtonName(params); | ||
| 499 | } | ||
| 500 | if (params.Has("axis")) { | ||
| 501 | return Common::Input::ButtonNames::Value; | ||
| 502 | } | ||
| 503 | if (params.Has("motion")) { | ||
| 504 | return Common::Input::ButtonNames::Engine; | ||
| 505 | } | ||
| 506 | |||
| 507 | return Common::Input::ButtonNames::Invalid; | ||
| 508 | } | ||
| 509 | |||
| 320 | void TestCommunication(const std::string& host, u16 port, | 510 | void TestCommunication(const std::string& host, u16 port, |
| 321 | const std::function<void()>& success_callback, | 511 | const std::function<void()>& success_callback, |
| 322 | const std::function<void()>& failure_callback) { | 512 | const std::function<void()>& failure_callback) { |