diff options
Diffstat (limited to 'src/core/hid/emulated_controller.cpp')
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 259 |
1 files changed, 136 insertions, 123 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 7ef6ef118..e102c9437 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -94,7 +94,6 @@ void EmulatedController::ReloadFromSettings() { | |||
| 94 | void EmulatedController::ReloadInput() { | 94 | void EmulatedController::ReloadInput() { |
| 95 | //LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type)); | 95 | //LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type)); |
| 96 | // If you load any device here add the equivalent to the UnloadInput() function | 96 | // If you load any device here add the equivalent to the UnloadInput() function |
| 97 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||
| 98 | const auto left_side = button_params[Settings::NativeButton::ZL]; | 97 | const auto left_side = button_params[Settings::NativeButton::ZL]; |
| 99 | const auto right_side = button_params[Settings::NativeButton::ZR]; | 98 | const auto right_side = button_params[Settings::NativeButton::ZR]; |
| 100 | 99 | ||
| @@ -337,120 +336,130 @@ void EmulatedController::SetButton(Input::CallbackStatus callback, std::size_t i | |||
| 337 | if (index >= controller.button_values.size()) { | 336 | if (index >= controller.button_values.size()) { |
| 338 | return; | 337 | return; |
| 339 | } | 338 | } |
| 340 | std::lock_guard lock{mutex}; | 339 | { |
| 341 | bool value_changed = false; | 340 | std::lock_guard lock{mutex}; |
| 342 | const auto new_status = TransformToButton(callback); | 341 | bool value_changed = false; |
| 343 | auto& current_status = controller.button_values[index]; | 342 | const auto new_status = TransformToButton(callback); |
| 344 | current_status.toggle = new_status.toggle; | 343 | auto& current_status = controller.button_values[index]; |
| 345 | 344 | current_status.toggle = new_status.toggle; | |
| 346 | // Update button status with current | ||
| 347 | if (!current_status.toggle) { | ||
| 348 | current_status.locked = false; | ||
| 349 | if (current_status.value != new_status.value) { | ||
| 350 | current_status.value = new_status.value; | ||
| 351 | value_changed = true; | ||
| 352 | } | ||
| 353 | } else { | ||
| 354 | // Toggle button and lock status | ||
| 355 | if (new_status.value && !current_status.locked) { | ||
| 356 | current_status.locked = true; | ||
| 357 | current_status.value = !current_status.value; | ||
| 358 | value_changed = true; | ||
| 359 | } | ||
| 360 | 345 | ||
| 361 | // Unlock button ready for next press | 346 | // Update button status with current |
| 362 | if (!new_status.value && current_status.locked) { | 347 | if (!current_status.toggle) { |
| 363 | current_status.locked = false; | 348 | current_status.locked = false; |
| 349 | if (current_status.value != new_status.value) { | ||
| 350 | current_status.value = new_status.value; | ||
| 351 | value_changed = true; | ||
| 352 | } | ||
| 353 | } else { | ||
| 354 | // Toggle button and lock status | ||
| 355 | if (new_status.value && !current_status.locked) { | ||
| 356 | current_status.locked = true; | ||
| 357 | current_status.value = !current_status.value; | ||
| 358 | value_changed = true; | ||
| 359 | } | ||
| 360 | |||
| 361 | // Unlock button ready for next press | ||
| 362 | if (!new_status.value && current_status.locked) { | ||
| 363 | current_status.locked = false; | ||
| 364 | } | ||
| 364 | } | 365 | } |
| 365 | } | ||
| 366 | 366 | ||
| 367 | if (!value_changed) { | 367 | if (!value_changed) { |
| 368 | return; | 368 | return; |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | if (is_configuring) { | 371 | if (is_configuring) { |
| 372 | controller.npad_button_state.raw = NpadButton::None; | 372 | controller.npad_button_state.raw = NpadButton::None; |
| 373 | controller.debug_pad_button_state.raw = 0; | 373 | controller.debug_pad_button_state.raw = 0; |
| 374 | TriggerOnChange(ControllerTriggerType::Button); | 374 | TriggerOnChange(ControllerTriggerType::Button, false); |
| 375 | return; | 375 | return; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | switch (index) { | 378 | switch (index) { |
| 379 | case Settings::NativeButton::A: | 379 | case Settings::NativeButton::A: |
| 380 | controller.npad_button_state.a.Assign(current_status.value); | 380 | controller.npad_button_state.a.Assign(current_status.value); |
| 381 | controller.debug_pad_button_state.a.Assign(current_status.value); | 381 | controller.debug_pad_button_state.a.Assign(current_status.value); |
| 382 | break; | 382 | break; |
| 383 | case Settings::NativeButton::B: | 383 | case Settings::NativeButton::B: |
| 384 | controller.npad_button_state.b.Assign(current_status.value); | 384 | controller.npad_button_state.b.Assign(current_status.value); |
| 385 | controller.debug_pad_button_state.b.Assign(current_status.value); | 385 | controller.debug_pad_button_state.b.Assign(current_status.value); |
| 386 | break; | 386 | break; |
| 387 | case Settings::NativeButton::X: | 387 | case Settings::NativeButton::X: |
| 388 | controller.npad_button_state.x.Assign(current_status.value); | 388 | controller.npad_button_state.x.Assign(current_status.value); |
| 389 | controller.debug_pad_button_state.x.Assign(current_status.value); | 389 | controller.debug_pad_button_state.x.Assign(current_status.value); |
| 390 | break; | 390 | break; |
| 391 | case Settings::NativeButton::Y: | 391 | case Settings::NativeButton::Y: |
| 392 | controller.npad_button_state.y.Assign(current_status.value); | 392 | controller.npad_button_state.y.Assign(current_status.value); |
| 393 | controller.debug_pad_button_state.y.Assign(current_status.value); | 393 | controller.debug_pad_button_state.y.Assign(current_status.value); |
| 394 | break; | 394 | break; |
| 395 | case Settings::NativeButton::LStick: | 395 | case Settings::NativeButton::LStick: |
| 396 | controller.npad_button_state.stick_l.Assign(current_status.value); | 396 | controller.npad_button_state.stick_l.Assign(current_status.value); |
| 397 | break; | 397 | break; |
| 398 | case Settings::NativeButton::RStick: | 398 | case Settings::NativeButton::RStick: |
| 399 | controller.npad_button_state.stick_r.Assign(current_status.value); | 399 | controller.npad_button_state.stick_r.Assign(current_status.value); |
| 400 | break; | 400 | break; |
| 401 | case Settings::NativeButton::L: | 401 | case Settings::NativeButton::L: |
| 402 | controller.npad_button_state.l.Assign(current_status.value); | 402 | controller.npad_button_state.l.Assign(current_status.value); |
| 403 | controller.debug_pad_button_state.l.Assign(current_status.value); | 403 | controller.debug_pad_button_state.l.Assign(current_status.value); |
| 404 | break; | 404 | break; |
| 405 | case Settings::NativeButton::R: | 405 | case Settings::NativeButton::R: |
| 406 | controller.npad_button_state.r.Assign(current_status.value); | 406 | controller.npad_button_state.r.Assign(current_status.value); |
| 407 | controller.debug_pad_button_state.r.Assign(current_status.value); | 407 | controller.debug_pad_button_state.r.Assign(current_status.value); |
| 408 | break; | 408 | break; |
| 409 | case Settings::NativeButton::ZL: | 409 | case Settings::NativeButton::ZL: |
| 410 | controller.npad_button_state.zl.Assign(current_status.value); | 410 | controller.npad_button_state.zl.Assign(current_status.value); |
| 411 | controller.debug_pad_button_state.zl.Assign(current_status.value); | 411 | controller.debug_pad_button_state.zl.Assign(current_status.value); |
| 412 | break; | 412 | break; |
| 413 | case Settings::NativeButton::ZR: | 413 | case Settings::NativeButton::ZR: |
| 414 | controller.npad_button_state.zr.Assign(current_status.value); | 414 | controller.npad_button_state.zr.Assign(current_status.value); |
| 415 | controller.debug_pad_button_state.zr.Assign(current_status.value); | 415 | controller.debug_pad_button_state.zr.Assign(current_status.value); |
| 416 | break; | 416 | break; |
| 417 | case Settings::NativeButton::Plus: | 417 | case Settings::NativeButton::Plus: |
| 418 | controller.npad_button_state.plus.Assign(current_status.value); | 418 | controller.npad_button_state.plus.Assign(current_status.value); |
| 419 | controller.debug_pad_button_state.plus.Assign(current_status.value); | 419 | controller.debug_pad_button_state.plus.Assign(current_status.value); |
| 420 | break; | 420 | break; |
| 421 | case Settings::NativeButton::Minus: | 421 | case Settings::NativeButton::Minus: |
| 422 | controller.npad_button_state.minus.Assign(current_status.value); | 422 | controller.npad_button_state.minus.Assign(current_status.value); |
| 423 | controller.debug_pad_button_state.minus.Assign(current_status.value); | 423 | controller.debug_pad_button_state.minus.Assign(current_status.value); |
| 424 | break; | 424 | break; |
| 425 | case Settings::NativeButton::DLeft: | 425 | case Settings::NativeButton::DLeft: |
| 426 | controller.npad_button_state.left.Assign(current_status.value); | 426 | controller.npad_button_state.left.Assign(current_status.value); |
| 427 | controller.debug_pad_button_state.d_left.Assign(current_status.value); | 427 | controller.debug_pad_button_state.d_left.Assign(current_status.value); |
| 428 | break; | 428 | break; |
| 429 | case Settings::NativeButton::DUp: | 429 | case Settings::NativeButton::DUp: |
| 430 | controller.npad_button_state.up.Assign(current_status.value); | 430 | controller.npad_button_state.up.Assign(current_status.value); |
| 431 | controller.debug_pad_button_state.d_up.Assign(current_status.value); | 431 | controller.debug_pad_button_state.d_up.Assign(current_status.value); |
| 432 | break; | 432 | break; |
| 433 | case Settings::NativeButton::DRight: | 433 | case Settings::NativeButton::DRight: |
| 434 | controller.npad_button_state.right.Assign(current_status.value); | 434 | controller.npad_button_state.right.Assign(current_status.value); |
| 435 | controller.debug_pad_button_state.d_right.Assign(current_status.value); | 435 | controller.debug_pad_button_state.d_right.Assign(current_status.value); |
| 436 | break; | 436 | break; |
| 437 | case Settings::NativeButton::DDown: | 437 | case Settings::NativeButton::DDown: |
| 438 | controller.npad_button_state.down.Assign(current_status.value); | 438 | controller.npad_button_state.down.Assign(current_status.value); |
| 439 | controller.debug_pad_button_state.d_down.Assign(current_status.value); | 439 | controller.debug_pad_button_state.d_down.Assign(current_status.value); |
| 440 | break; | 440 | break; |
| 441 | case Settings::NativeButton::SL: | 441 | case Settings::NativeButton::SL: |
| 442 | controller.npad_button_state.left_sl.Assign(current_status.value); | 442 | controller.npad_button_state.left_sl.Assign(current_status.value); |
| 443 | controller.npad_button_state.right_sl.Assign(current_status.value); | 443 | controller.npad_button_state.right_sl.Assign(current_status.value); |
| 444 | break; | 444 | break; |
| 445 | case Settings::NativeButton::SR: | 445 | case Settings::NativeButton::SR: |
| 446 | controller.npad_button_state.left_sr.Assign(current_status.value); | 446 | controller.npad_button_state.left_sr.Assign(current_status.value); |
| 447 | controller.npad_button_state.right_sr.Assign(current_status.value); | 447 | controller.npad_button_state.right_sr.Assign(current_status.value); |
| 448 | break; | 448 | break; |
| 449 | case Settings::NativeButton::Home: | 449 | case Settings::NativeButton::Home: |
| 450 | case Settings::NativeButton::Screenshot: | 450 | case Settings::NativeButton::Screenshot: |
| 451 | break; | 451 | break; |
| 452 | } | ||
| 453 | } | ||
| 454 | if (!is_connected) { | ||
| 455 | if (npad_id_type == NpadIdType::Player1 && npad_type != NpadType::Handheld) { | ||
| 456 | Connect(); | ||
| 457 | } | ||
| 458 | if (npad_id_type == NpadIdType::Handheld && npad_type == NpadType::Handheld) { | ||
| 459 | Connect(); | ||
| 460 | } | ||
| 452 | } | 461 | } |
| 453 | TriggerOnChange(ControllerTriggerType::Button); | 462 | TriggerOnChange(ControllerTriggerType::Button, true); |
| 454 | } | 463 | } |
| 455 | 464 | ||
| 456 | void EmulatedController::SetStick(Input::CallbackStatus callback, std::size_t index) { | 465 | void EmulatedController::SetStick(Input::CallbackStatus callback, std::size_t index) { |
| @@ -463,7 +472,7 @@ void EmulatedController::SetStick(Input::CallbackStatus callback, std::size_t in | |||
| 463 | if (is_configuring) { | 472 | if (is_configuring) { |
| 464 | controller.analog_stick_state.left = {}; | 473 | controller.analog_stick_state.left = {}; |
| 465 | controller.analog_stick_state.right = {}; | 474 | controller.analog_stick_state.right = {}; |
| 466 | TriggerOnChange(ControllerTriggerType::Stick); | 475 | TriggerOnChange(ControllerTriggerType::Stick, false); |
| 467 | return; | 476 | return; |
| 468 | } | 477 | } |
| 469 | 478 | ||
| @@ -489,7 +498,7 @@ void EmulatedController::SetStick(Input::CallbackStatus callback, std::size_t in | |||
| 489 | break; | 498 | break; |
| 490 | } | 499 | } |
| 491 | 500 | ||
| 492 | TriggerOnChange(ControllerTriggerType::Stick); | 501 | TriggerOnChange(ControllerTriggerType::Stick, true); |
| 493 | } | 502 | } |
| 494 | 503 | ||
| 495 | void EmulatedController::SetTrigger(Input::CallbackStatus callback, std::size_t index) { | 504 | void EmulatedController::SetTrigger(Input::CallbackStatus callback, std::size_t index) { |
| @@ -502,7 +511,7 @@ void EmulatedController::SetTrigger(Input::CallbackStatus callback, std::size_t | |||
| 502 | if (is_configuring) { | 511 | if (is_configuring) { |
| 503 | controller.gc_trigger_state.left = 0; | 512 | controller.gc_trigger_state.left = 0; |
| 504 | controller.gc_trigger_state.right = 0; | 513 | controller.gc_trigger_state.right = 0; |
| 505 | TriggerOnChange(ControllerTriggerType::Trigger); | 514 | TriggerOnChange(ControllerTriggerType::Trigger, false); |
| 506 | return; | 515 | return; |
| 507 | } | 516 | } |
| 508 | 517 | ||
| @@ -520,7 +529,7 @@ void EmulatedController::SetTrigger(Input::CallbackStatus callback, std::size_t | |||
| 520 | break; | 529 | break; |
| 521 | } | 530 | } |
| 522 | 531 | ||
| 523 | TriggerOnChange(ControllerTriggerType::Trigger); | 532 | TriggerOnChange(ControllerTriggerType::Trigger, true); |
| 524 | } | 533 | } |
| 525 | 534 | ||
| 526 | void EmulatedController::SetMotion(Input::CallbackStatus callback, std::size_t index) { | 535 | void EmulatedController::SetMotion(Input::CallbackStatus callback, std::size_t index) { |
| @@ -546,7 +555,7 @@ void EmulatedController::SetMotion(Input::CallbackStatus callback, std::size_t i | |||
| 546 | emulated.UpdateOrientation(raw_status.delta_timestamp); | 555 | emulated.UpdateOrientation(raw_status.delta_timestamp); |
| 547 | 556 | ||
| 548 | if (is_configuring) { | 557 | if (is_configuring) { |
| 549 | TriggerOnChange(ControllerTriggerType::Motion); | 558 | TriggerOnChange(ControllerTriggerType::Motion, false); |
| 550 | return; | 559 | return; |
| 551 | } | 560 | } |
| 552 | 561 | ||
| @@ -557,7 +566,7 @@ void EmulatedController::SetMotion(Input::CallbackStatus callback, std::size_t i | |||
| 557 | motion.orientation = emulated.GetOrientation(); | 566 | motion.orientation = emulated.GetOrientation(); |
| 558 | motion.is_at_rest = emulated.IsMoving(motion_sensitivity); | 567 | motion.is_at_rest = emulated.IsMoving(motion_sensitivity); |
| 559 | 568 | ||
| 560 | TriggerOnChange(ControllerTriggerType::Motion); | 569 | TriggerOnChange(ControllerTriggerType::Motion, true); |
| 561 | } | 570 | } |
| 562 | 571 | ||
| 563 | void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t index) { | 572 | void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t index) { |
| @@ -568,7 +577,7 @@ void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t | |||
| 568 | controller.battery_values[index] = TransformToBattery(callback); | 577 | controller.battery_values[index] = TransformToBattery(callback); |
| 569 | 578 | ||
| 570 | if (is_configuring) { | 579 | if (is_configuring) { |
| 571 | TriggerOnChange(ControllerTriggerType::Battery); | 580 | TriggerOnChange(ControllerTriggerType::Battery, false); |
| 572 | return; | 581 | return; |
| 573 | } | 582 | } |
| 574 | 583 | ||
| @@ -593,6 +602,7 @@ void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t | |||
| 593 | case Input::BatteryLevel::Empty: | 602 | case Input::BatteryLevel::Empty: |
| 594 | battery_level = 0; | 603 | battery_level = 0; |
| 595 | break; | 604 | break; |
| 605 | case Input::BatteryLevel::None: | ||
| 596 | case Input::BatteryLevel::Full: | 606 | case Input::BatteryLevel::Full: |
| 597 | default: | 607 | default: |
| 598 | is_powered = true; | 608 | is_powered = true; |
| @@ -623,7 +633,7 @@ void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t | |||
| 623 | }; | 633 | }; |
| 624 | break; | 634 | break; |
| 625 | } | 635 | } |
| 626 | TriggerOnChange(ControllerTriggerType::Battery); | 636 | TriggerOnChange(ControllerTriggerType::Battery, true); |
| 627 | } | 637 | } |
| 628 | 638 | ||
| 629 | bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { | 639 | bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { |
| @@ -677,7 +687,7 @@ void EmulatedController::Connect() { | |||
| 677 | std::lock_guard lock{mutex}; | 687 | std::lock_guard lock{mutex}; |
| 678 | if (is_configuring) { | 688 | if (is_configuring) { |
| 679 | temporary_is_connected = true; | 689 | temporary_is_connected = true; |
| 680 | TriggerOnChange(ControllerTriggerType::Connected); | 690 | TriggerOnChange(ControllerTriggerType::Connected,false); |
| 681 | return; | 691 | return; |
| 682 | } | 692 | } |
| 683 | 693 | ||
| @@ -687,7 +697,7 @@ void EmulatedController::Connect() { | |||
| 687 | is_connected = true; | 697 | is_connected = true; |
| 688 | } | 698 | } |
| 689 | LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type)); | 699 | LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type)); |
| 690 | TriggerOnChange(ControllerTriggerType::Connected); | 700 | TriggerOnChange(ControllerTriggerType::Connected,true); |
| 691 | } | 701 | } |
| 692 | 702 | ||
| 693 | void EmulatedController::Disconnect() { | 703 | void EmulatedController::Disconnect() { |
| @@ -697,7 +707,7 @@ void EmulatedController::Disconnect() { | |||
| 697 | temporary_is_connected = false; | 707 | temporary_is_connected = false; |
| 698 | LOG_ERROR(Service_HID, "Disconnected temporal controller {}", | 708 | LOG_ERROR(Service_HID, "Disconnected temporal controller {}", |
| 699 | NpadIdTypeToIndex(npad_id_type)); | 709 | NpadIdTypeToIndex(npad_id_type)); |
| 700 | TriggerOnChange(ControllerTriggerType::Disconnected); | 710 | TriggerOnChange(ControllerTriggerType::Disconnected,false); |
| 701 | return; | 711 | return; |
| 702 | } | 712 | } |
| 703 | 713 | ||
| @@ -707,7 +717,7 @@ void EmulatedController::Disconnect() { | |||
| 707 | is_connected = false; | 717 | is_connected = false; |
| 708 | } | 718 | } |
| 709 | LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type)); | 719 | LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type)); |
| 710 | TriggerOnChange(ControllerTriggerType::Disconnected); | 720 | TriggerOnChange(ControllerTriggerType::Disconnected,true); |
| 711 | } | 721 | } |
| 712 | 722 | ||
| 713 | bool EmulatedController::IsConnected(bool temporary) const { | 723 | bool EmulatedController::IsConnected(bool temporary) const { |
| @@ -741,7 +751,7 @@ void EmulatedController::SetNpadType(NpadType npad_type_) { | |||
| 741 | return; | 751 | return; |
| 742 | } | 752 | } |
| 743 | temporary_npad_type = npad_type_; | 753 | temporary_npad_type = npad_type_; |
| 744 | TriggerOnChange(ControllerTriggerType::Type); | 754 | TriggerOnChange(ControllerTriggerType::Type,false); |
| 745 | return; | 755 | return; |
| 746 | } | 756 | } |
| 747 | 757 | ||
| @@ -754,7 +764,7 @@ void EmulatedController::SetNpadType(NpadType npad_type_) { | |||
| 754 | } | 764 | } |
| 755 | npad_type = npad_type_; | 765 | npad_type = npad_type_; |
| 756 | } | 766 | } |
| 757 | TriggerOnChange(ControllerTriggerType::Type); | 767 | TriggerOnChange(ControllerTriggerType::Type,true); |
| 758 | } | 768 | } |
| 759 | 769 | ||
| 760 | LedPattern EmulatedController::GetLedPattern() const { | 770 | LedPattern EmulatedController::GetLedPattern() const { |
| @@ -844,9 +854,12 @@ BatteryLevelState EmulatedController::GetBattery() const { | |||
| 844 | return controller.battery_state; | 854 | return controller.battery_state; |
| 845 | } | 855 | } |
| 846 | 856 | ||
| 847 | void EmulatedController::TriggerOnChange(ControllerTriggerType type) { | 857 | void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_service_update) { |
| 848 | for (const std::pair<int, ControllerUpdateCallback> poller_pair : callback_list) { | 858 | for (const std::pair<int, ControllerUpdateCallback> poller_pair : callback_list) { |
| 849 | const ControllerUpdateCallback& poller = poller_pair.second; | 859 | const ControllerUpdateCallback& poller = poller_pair.second; |
| 860 | if (!is_service_update && poller.is_service) { | ||
| 861 | continue; | ||
| 862 | } | ||
| 850 | if (poller.on_change) { | 863 | if (poller.on_change) { |
| 851 | poller.on_change(type); | 864 | poller.on_change(type); |
| 852 | } | 865 | } |