diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hid/emulated_console.cpp | 17 | ||||
| -rw-r--r-- | src/core/hid/emulated_console.h | 1 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 367 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.h | 3 | ||||
| -rw-r--r-- | src/core/hid/emulated_devices.cpp | 33 | ||||
| -rw-r--r-- | src/core/hid/emulated_devices.h | 1 |
6 files changed, 246 insertions, 176 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp index eef0ff493..639f61809 100644 --- a/src/core/hid/emulated_console.cpp +++ b/src/core/hid/emulated_console.cpp | |||
| @@ -132,7 +132,7 @@ void EmulatedConsole::SetMotionParam(Common::ParamPackage param) { | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) { | 134 | void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) { |
| 135 | std::lock_guard lock{mutex}; | 135 | std::unique_lock lock{mutex}; |
| 136 | auto& raw_status = console.motion_values.raw_status; | 136 | auto& raw_status = console.motion_values.raw_status; |
| 137 | auto& emulated = console.motion_values.emulated; | 137 | auto& emulated = console.motion_values.emulated; |
| 138 | 138 | ||
| @@ -151,6 +151,7 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) { | |||
| 151 | emulated.UpdateOrientation(raw_status.delta_timestamp); | 151 | emulated.UpdateOrientation(raw_status.delta_timestamp); |
| 152 | 152 | ||
| 153 | if (is_configuring) { | 153 | if (is_configuring) { |
| 154 | lock.unlock(); | ||
| 154 | TriggerOnChange(ConsoleTriggerType::Motion); | 155 | TriggerOnChange(ConsoleTriggerType::Motion); |
| 155 | return; | 156 | return; |
| 156 | } | 157 | } |
| @@ -166,6 +167,7 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) { | |||
| 166 | // Find what is this value | 167 | // Find what is this value |
| 167 | motion.verticalization_error = 0.0f; | 168 | motion.verticalization_error = 0.0f; |
| 168 | 169 | ||
| 170 | lock.unlock(); | ||
| 169 | TriggerOnChange(ConsoleTriggerType::Motion); | 171 | TriggerOnChange(ConsoleTriggerType::Motion); |
| 170 | } | 172 | } |
| 171 | 173 | ||
| @@ -173,11 +175,12 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st | |||
| 173 | if (index >= console.touch_values.size()) { | 175 | if (index >= console.touch_values.size()) { |
| 174 | return; | 176 | return; |
| 175 | } | 177 | } |
| 176 | std::lock_guard lock{mutex}; | 178 | std::unique_lock lock{mutex}; |
| 177 | 179 | ||
| 178 | console.touch_values[index] = TransformToTouch(callback); | 180 | console.touch_values[index] = TransformToTouch(callback); |
| 179 | 181 | ||
| 180 | if (is_configuring) { | 182 | if (is_configuring) { |
| 183 | lock.unlock(); | ||
| 181 | TriggerOnChange(ConsoleTriggerType::Touch); | 184 | TriggerOnChange(ConsoleTriggerType::Touch); |
| 182 | return; | 185 | return; |
| 183 | } | 186 | } |
| @@ -189,26 +192,32 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st | |||
| 189 | .pressed = console.touch_values[index].pressed.value, | 192 | .pressed = console.touch_values[index].pressed.value, |
| 190 | }; | 193 | }; |
| 191 | 194 | ||
| 195 | lock.unlock(); | ||
| 192 | TriggerOnChange(ConsoleTriggerType::Touch); | 196 | TriggerOnChange(ConsoleTriggerType::Touch); |
| 193 | } | 197 | } |
| 194 | 198 | ||
| 195 | ConsoleMotionValues EmulatedConsole::GetMotionValues() const { | 199 | ConsoleMotionValues EmulatedConsole::GetMotionValues() const { |
| 200 | std::lock_guard lock{mutex}; | ||
| 196 | return console.motion_values; | 201 | return console.motion_values; |
| 197 | } | 202 | } |
| 198 | 203 | ||
| 199 | TouchValues EmulatedConsole::GetTouchValues() const { | 204 | TouchValues EmulatedConsole::GetTouchValues() const { |
| 205 | std::lock_guard lock{mutex}; | ||
| 200 | return console.touch_values; | 206 | return console.touch_values; |
| 201 | } | 207 | } |
| 202 | 208 | ||
| 203 | ConsoleMotion EmulatedConsole::GetMotion() const { | 209 | ConsoleMotion EmulatedConsole::GetMotion() const { |
| 210 | std::lock_guard lock{mutex}; | ||
| 204 | return console.motion_state; | 211 | return console.motion_state; |
| 205 | } | 212 | } |
| 206 | 213 | ||
| 207 | TouchFingerState EmulatedConsole::GetTouch() const { | 214 | TouchFingerState EmulatedConsole::GetTouch() const { |
| 215 | std::lock_guard lock{mutex}; | ||
| 208 | return console.touch_state; | 216 | return console.touch_state; |
| 209 | } | 217 | } |
| 210 | 218 | ||
| 211 | void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) { | 219 | void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) { |
| 220 | std::lock_guard lock{callback_mutex}; | ||
| 212 | for (const auto& poller_pair : callback_list) { | 221 | for (const auto& poller_pair : callback_list) { |
| 213 | const ConsoleUpdateCallback& poller = poller_pair.second; | 222 | const ConsoleUpdateCallback& poller = poller_pair.second; |
| 214 | if (poller.on_change) { | 223 | if (poller.on_change) { |
| @@ -218,13 +227,13 @@ void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) { | |||
| 218 | } | 227 | } |
| 219 | 228 | ||
| 220 | int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) { | 229 | int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) { |
| 221 | std::lock_guard lock{mutex}; | 230 | std::lock_guard lock{callback_mutex}; |
| 222 | callback_list.insert_or_assign(last_callback_key, update_callback); | 231 | callback_list.insert_or_assign(last_callback_key, update_callback); |
| 223 | return last_callback_key++; | 232 | return last_callback_key++; |
| 224 | } | 233 | } |
| 225 | 234 | ||
| 226 | void EmulatedConsole::DeleteCallback(int key) { | 235 | void EmulatedConsole::DeleteCallback(int key) { |
| 227 | std::lock_guard lock{mutex}; | 236 | std::lock_guard lock{callback_mutex}; |
| 228 | const auto& iterator = callback_list.find(key); | 237 | const auto& iterator = callback_list.find(key); |
| 229 | if (iterator == callback_list.end()) { | 238 | if (iterator == callback_list.end()) { |
| 230 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); | 239 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); |
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h index 5eb170823..53677bdc5 100644 --- a/src/core/hid/emulated_console.h +++ b/src/core/hid/emulated_console.h | |||
| @@ -183,6 +183,7 @@ private: | |||
| 183 | TouchDevices touch_devices; | 183 | TouchDevices touch_devices; |
| 184 | 184 | ||
| 185 | mutable std::mutex mutex; | 185 | mutable std::mutex mutex; |
| 186 | mutable std::mutex callback_mutex; | ||
| 186 | std::unordered_map<int, ConsoleUpdateCallback> callback_list; | 187 | std::unordered_map<int, ConsoleUpdateCallback> callback_list; |
| 187 | int last_callback_key = 0; | 188 | int last_callback_key = 0; |
| 188 | 189 | ||
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 7e05666d6..4f3676ec3 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -353,14 +353,17 @@ void EmulatedController::DisableConfiguration() { | |||
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | void EmulatedController::EnableSystemButtons() { | 355 | void EmulatedController::EnableSystemButtons() { |
| 356 | std::lock_guard lock{mutex}; | ||
| 356 | system_buttons_enabled = true; | 357 | system_buttons_enabled = true; |
| 357 | } | 358 | } |
| 358 | 359 | ||
| 359 | void EmulatedController::DisableSystemButtons() { | 360 | void EmulatedController::DisableSystemButtons() { |
| 361 | std::lock_guard lock{mutex}; | ||
| 360 | system_buttons_enabled = false; | 362 | system_buttons_enabled = false; |
| 361 | } | 363 | } |
| 362 | 364 | ||
| 363 | void EmulatedController::ResetSystemButtons() { | 365 | void EmulatedController::ResetSystemButtons() { |
| 366 | std::lock_guard lock{mutex}; | ||
| 364 | controller.home_button_state.home.Assign(false); | 367 | controller.home_button_state.home.Assign(false); |
| 365 | controller.capture_button_state.capture.Assign(false); | 368 | controller.capture_button_state.capture.Assign(false); |
| 366 | } | 369 | } |
| @@ -494,139 +497,141 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback | |||
| 494 | if (index >= controller.button_values.size()) { | 497 | if (index >= controller.button_values.size()) { |
| 495 | return; | 498 | return; |
| 496 | } | 499 | } |
| 497 | { | 500 | std::unique_lock lock{mutex}; |
| 498 | std::lock_guard lock{mutex}; | 501 | bool value_changed = false; |
| 499 | bool value_changed = false; | 502 | const auto new_status = TransformToButton(callback); |
| 500 | const auto new_status = TransformToButton(callback); | 503 | auto& current_status = controller.button_values[index]; |
| 501 | auto& current_status = controller.button_values[index]; | ||
| 502 | 504 | ||
| 503 | // Only read button values that have the same uuid or are pressed once | 505 | // Only read button values that have the same uuid or are pressed once |
| 504 | if (current_status.uuid != uuid) { | 506 | if (current_status.uuid != uuid) { |
| 505 | if (!new_status.value) { | 507 | if (!new_status.value) { |
| 506 | return; | 508 | return; |
| 507 | } | ||
| 508 | } | 509 | } |
| 510 | } | ||
| 509 | 511 | ||
| 510 | current_status.toggle = new_status.toggle; | 512 | current_status.toggle = new_status.toggle; |
| 511 | current_status.uuid = uuid; | 513 | current_status.uuid = uuid; |
| 512 | |||
| 513 | // Update button status with current | ||
| 514 | if (!current_status.toggle) { | ||
| 515 | current_status.locked = false; | ||
| 516 | if (current_status.value != new_status.value) { | ||
| 517 | current_status.value = new_status.value; | ||
| 518 | value_changed = true; | ||
| 519 | } | ||
| 520 | } else { | ||
| 521 | // Toggle button and lock status | ||
| 522 | if (new_status.value && !current_status.locked) { | ||
| 523 | current_status.locked = true; | ||
| 524 | current_status.value = !current_status.value; | ||
| 525 | value_changed = true; | ||
| 526 | } | ||
| 527 | 514 | ||
| 528 | // Unlock button ready for next press | 515 | // Update button status with current |
| 529 | if (!new_status.value && current_status.locked) { | 516 | if (!current_status.toggle) { |
| 530 | current_status.locked = false; | 517 | current_status.locked = false; |
| 531 | } | 518 | if (current_status.value != new_status.value) { |
| 519 | current_status.value = new_status.value; | ||
| 520 | value_changed = true; | ||
| 532 | } | 521 | } |
| 533 | 522 | } else { | |
| 534 | if (!value_changed) { | 523 | // Toggle button and lock status |
| 535 | return; | 524 | if (new_status.value && !current_status.locked) { |
| 525 | current_status.locked = true; | ||
| 526 | current_status.value = !current_status.value; | ||
| 527 | value_changed = true; | ||
| 536 | } | 528 | } |
| 537 | 529 | ||
| 538 | if (is_configuring) { | 530 | // Unlock button ready for next press |
| 539 | controller.npad_button_state.raw = NpadButton::None; | 531 | if (!new_status.value && current_status.locked) { |
| 540 | controller.debug_pad_button_state.raw = 0; | 532 | current_status.locked = false; |
| 541 | TriggerOnChange(ControllerTriggerType::Button, false); | ||
| 542 | return; | ||
| 543 | } | 533 | } |
| 534 | } | ||
| 544 | 535 | ||
| 545 | switch (index) { | 536 | if (!value_changed) { |
| 546 | case Settings::NativeButton::A: | 537 | return; |
| 547 | controller.npad_button_state.a.Assign(current_status.value); | 538 | } |
| 548 | controller.debug_pad_button_state.a.Assign(current_status.value); | 539 | |
| 549 | break; | 540 | if (is_configuring) { |
| 550 | case Settings::NativeButton::B: | 541 | controller.npad_button_state.raw = NpadButton::None; |
| 551 | controller.npad_button_state.b.Assign(current_status.value); | 542 | controller.debug_pad_button_state.raw = 0; |
| 552 | controller.debug_pad_button_state.b.Assign(current_status.value); | 543 | lock.unlock(); |
| 553 | break; | 544 | TriggerOnChange(ControllerTriggerType::Button, false); |
| 554 | case Settings::NativeButton::X: | 545 | return; |
| 555 | controller.npad_button_state.x.Assign(current_status.value); | 546 | } |
| 556 | controller.debug_pad_button_state.x.Assign(current_status.value); | 547 | |
| 557 | break; | 548 | switch (index) { |
| 558 | case Settings::NativeButton::Y: | 549 | case Settings::NativeButton::A: |
| 559 | controller.npad_button_state.y.Assign(current_status.value); | 550 | controller.npad_button_state.a.Assign(current_status.value); |
| 560 | controller.debug_pad_button_state.y.Assign(current_status.value); | 551 | controller.debug_pad_button_state.a.Assign(current_status.value); |
| 561 | break; | 552 | break; |
| 562 | case Settings::NativeButton::LStick: | 553 | case Settings::NativeButton::B: |
| 563 | controller.npad_button_state.stick_l.Assign(current_status.value); | 554 | controller.npad_button_state.b.Assign(current_status.value); |
| 564 | break; | 555 | controller.debug_pad_button_state.b.Assign(current_status.value); |
| 565 | case Settings::NativeButton::RStick: | 556 | break; |
| 566 | controller.npad_button_state.stick_r.Assign(current_status.value); | 557 | case Settings::NativeButton::X: |
| 567 | break; | 558 | controller.npad_button_state.x.Assign(current_status.value); |
| 568 | case Settings::NativeButton::L: | 559 | controller.debug_pad_button_state.x.Assign(current_status.value); |
| 569 | controller.npad_button_state.l.Assign(current_status.value); | 560 | break; |
| 570 | controller.debug_pad_button_state.l.Assign(current_status.value); | 561 | case Settings::NativeButton::Y: |
| 571 | break; | 562 | controller.npad_button_state.y.Assign(current_status.value); |
| 572 | case Settings::NativeButton::R: | 563 | controller.debug_pad_button_state.y.Assign(current_status.value); |
| 573 | controller.npad_button_state.r.Assign(current_status.value); | 564 | break; |
| 574 | controller.debug_pad_button_state.r.Assign(current_status.value); | 565 | case Settings::NativeButton::LStick: |
| 575 | break; | 566 | controller.npad_button_state.stick_l.Assign(current_status.value); |
| 576 | case Settings::NativeButton::ZL: | 567 | break; |
| 577 | controller.npad_button_state.zl.Assign(current_status.value); | 568 | case Settings::NativeButton::RStick: |
| 578 | controller.debug_pad_button_state.zl.Assign(current_status.value); | 569 | controller.npad_button_state.stick_r.Assign(current_status.value); |
| 579 | break; | 570 | break; |
| 580 | case Settings::NativeButton::ZR: | 571 | case Settings::NativeButton::L: |
| 581 | controller.npad_button_state.zr.Assign(current_status.value); | 572 | controller.npad_button_state.l.Assign(current_status.value); |
| 582 | controller.debug_pad_button_state.zr.Assign(current_status.value); | 573 | controller.debug_pad_button_state.l.Assign(current_status.value); |
| 583 | break; | 574 | break; |
| 584 | case Settings::NativeButton::Plus: | 575 | case Settings::NativeButton::R: |
| 585 | controller.npad_button_state.plus.Assign(current_status.value); | 576 | controller.npad_button_state.r.Assign(current_status.value); |
| 586 | controller.debug_pad_button_state.plus.Assign(current_status.value); | 577 | controller.debug_pad_button_state.r.Assign(current_status.value); |
| 587 | break; | 578 | break; |
| 588 | case Settings::NativeButton::Minus: | 579 | case Settings::NativeButton::ZL: |
| 589 | controller.npad_button_state.minus.Assign(current_status.value); | 580 | controller.npad_button_state.zl.Assign(current_status.value); |
| 590 | controller.debug_pad_button_state.minus.Assign(current_status.value); | 581 | controller.debug_pad_button_state.zl.Assign(current_status.value); |
| 591 | break; | 582 | break; |
| 592 | case Settings::NativeButton::DLeft: | 583 | case Settings::NativeButton::ZR: |
| 593 | controller.npad_button_state.left.Assign(current_status.value); | 584 | controller.npad_button_state.zr.Assign(current_status.value); |
| 594 | controller.debug_pad_button_state.d_left.Assign(current_status.value); | 585 | controller.debug_pad_button_state.zr.Assign(current_status.value); |
| 595 | break; | 586 | break; |
| 596 | case Settings::NativeButton::DUp: | 587 | case Settings::NativeButton::Plus: |
| 597 | controller.npad_button_state.up.Assign(current_status.value); | 588 | controller.npad_button_state.plus.Assign(current_status.value); |
| 598 | controller.debug_pad_button_state.d_up.Assign(current_status.value); | 589 | controller.debug_pad_button_state.plus.Assign(current_status.value); |
| 599 | break; | 590 | break; |
| 600 | case Settings::NativeButton::DRight: | 591 | case Settings::NativeButton::Minus: |
| 601 | controller.npad_button_state.right.Assign(current_status.value); | 592 | controller.npad_button_state.minus.Assign(current_status.value); |
| 602 | controller.debug_pad_button_state.d_right.Assign(current_status.value); | 593 | controller.debug_pad_button_state.minus.Assign(current_status.value); |
| 603 | break; | 594 | break; |
| 604 | case Settings::NativeButton::DDown: | 595 | case Settings::NativeButton::DLeft: |
| 605 | controller.npad_button_state.down.Assign(current_status.value); | 596 | controller.npad_button_state.left.Assign(current_status.value); |
| 606 | controller.debug_pad_button_state.d_down.Assign(current_status.value); | 597 | controller.debug_pad_button_state.d_left.Assign(current_status.value); |
| 607 | break; | 598 | break; |
| 608 | case Settings::NativeButton::SL: | 599 | case Settings::NativeButton::DUp: |
| 609 | controller.npad_button_state.left_sl.Assign(current_status.value); | 600 | controller.npad_button_state.up.Assign(current_status.value); |
| 610 | controller.npad_button_state.right_sl.Assign(current_status.value); | 601 | controller.debug_pad_button_state.d_up.Assign(current_status.value); |
| 611 | break; | 602 | break; |
| 612 | case Settings::NativeButton::SR: | 603 | case Settings::NativeButton::DRight: |
| 613 | controller.npad_button_state.left_sr.Assign(current_status.value); | 604 | controller.npad_button_state.right.Assign(current_status.value); |
| 614 | controller.npad_button_state.right_sr.Assign(current_status.value); | 605 | controller.debug_pad_button_state.d_right.Assign(current_status.value); |
| 615 | break; | 606 | break; |
| 616 | case Settings::NativeButton::Home: | 607 | case Settings::NativeButton::DDown: |
| 617 | if (!system_buttons_enabled) { | 608 | controller.npad_button_state.down.Assign(current_status.value); |
| 618 | break; | 609 | controller.debug_pad_button_state.d_down.Assign(current_status.value); |
| 619 | } | 610 | break; |
| 620 | controller.home_button_state.home.Assign(current_status.value); | 611 | case Settings::NativeButton::SL: |
| 612 | controller.npad_button_state.left_sl.Assign(current_status.value); | ||
| 613 | controller.npad_button_state.right_sl.Assign(current_status.value); | ||
| 614 | break; | ||
| 615 | case Settings::NativeButton::SR: | ||
| 616 | controller.npad_button_state.left_sr.Assign(current_status.value); | ||
| 617 | controller.npad_button_state.right_sr.Assign(current_status.value); | ||
| 618 | break; | ||
| 619 | case Settings::NativeButton::Home: | ||
| 620 | if (!system_buttons_enabled) { | ||
| 621 | break; | 621 | break; |
| 622 | case Settings::NativeButton::Screenshot: | 622 | } |
| 623 | if (!system_buttons_enabled) { | 623 | controller.home_button_state.home.Assign(current_status.value); |
| 624 | break; | 624 | break; |
| 625 | } | 625 | case Settings::NativeButton::Screenshot: |
| 626 | controller.capture_button_state.capture.Assign(current_status.value); | 626 | if (!system_buttons_enabled) { |
| 627 | break; | 627 | break; |
| 628 | } | 628 | } |
| 629 | controller.capture_button_state.capture.Assign(current_status.value); | ||
| 630 | break; | ||
| 629 | } | 631 | } |
| 632 | |||
| 633 | lock.unlock(); | ||
| 634 | |||
| 630 | if (!is_connected) { | 635 | if (!is_connected) { |
| 631 | if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) { | 636 | if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) { |
| 632 | Connect(); | 637 | Connect(); |
| @@ -643,7 +648,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 643 | if (index >= controller.stick_values.size()) { | 648 | if (index >= controller.stick_values.size()) { |
| 644 | return; | 649 | return; |
| 645 | } | 650 | } |
| 646 | std::lock_guard lock{mutex}; | 651 | std::unique_lock lock{mutex}; |
| 647 | const auto stick_value = TransformToStick(callback); | 652 | const auto stick_value = TransformToStick(callback); |
| 648 | 653 | ||
| 649 | // Only read stick values that have the same uuid or are over the threshold to avoid flapping | 654 | // Only read stick values that have the same uuid or are over the threshold to avoid flapping |
| @@ -659,6 +664,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 659 | if (is_configuring) { | 664 | if (is_configuring) { |
| 660 | controller.analog_stick_state.left = {}; | 665 | controller.analog_stick_state.left = {}; |
| 661 | controller.analog_stick_state.right = {}; | 666 | controller.analog_stick_state.right = {}; |
| 667 | lock.unlock(); | ||
| 662 | TriggerOnChange(ControllerTriggerType::Stick, false); | 668 | TriggerOnChange(ControllerTriggerType::Stick, false); |
| 663 | return; | 669 | return; |
| 664 | } | 670 | } |
| @@ -685,6 +691,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 685 | break; | 691 | break; |
| 686 | } | 692 | } |
| 687 | 693 | ||
| 694 | lock.unlock(); | ||
| 688 | TriggerOnChange(ControllerTriggerType::Stick, true); | 695 | TriggerOnChange(ControllerTriggerType::Stick, true); |
| 689 | } | 696 | } |
| 690 | 697 | ||
| @@ -693,7 +700,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 693 | if (index >= controller.trigger_values.size()) { | 700 | if (index >= controller.trigger_values.size()) { |
| 694 | return; | 701 | return; |
| 695 | } | 702 | } |
| 696 | std::lock_guard lock{mutex}; | 703 | std::unique_lock lock{mutex}; |
| 697 | const auto trigger_value = TransformToTrigger(callback); | 704 | const auto trigger_value = TransformToTrigger(callback); |
| 698 | 705 | ||
| 699 | // Only read trigger values that have the same uuid or are pressed once | 706 | // Only read trigger values that have the same uuid or are pressed once |
| @@ -709,6 +716,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 709 | if (is_configuring) { | 716 | if (is_configuring) { |
| 710 | controller.gc_trigger_state.left = 0; | 717 | controller.gc_trigger_state.left = 0; |
| 711 | controller.gc_trigger_state.right = 0; | 718 | controller.gc_trigger_state.right = 0; |
| 719 | lock.unlock(); | ||
| 712 | TriggerOnChange(ControllerTriggerType::Trigger, false); | 720 | TriggerOnChange(ControllerTriggerType::Trigger, false); |
| 713 | return; | 721 | return; |
| 714 | } | 722 | } |
| @@ -727,6 +735,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 727 | break; | 735 | break; |
| 728 | } | 736 | } |
| 729 | 737 | ||
| 738 | lock.unlock(); | ||
| 730 | TriggerOnChange(ControllerTriggerType::Trigger, true); | 739 | TriggerOnChange(ControllerTriggerType::Trigger, true); |
| 731 | } | 740 | } |
| 732 | 741 | ||
| @@ -735,7 +744,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 735 | if (index >= controller.motion_values.size()) { | 744 | if (index >= controller.motion_values.size()) { |
| 736 | return; | 745 | return; |
| 737 | } | 746 | } |
| 738 | std::lock_guard lock{mutex}; | 747 | std::unique_lock lock{mutex}; |
| 739 | auto& raw_status = controller.motion_values[index].raw_status; | 748 | auto& raw_status = controller.motion_values[index].raw_status; |
| 740 | auto& emulated = controller.motion_values[index].emulated; | 749 | auto& emulated = controller.motion_values[index].emulated; |
| 741 | 750 | ||
| @@ -756,6 +765,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 756 | force_update_motion = raw_status.force_update; | 765 | force_update_motion = raw_status.force_update; |
| 757 | 766 | ||
| 758 | if (is_configuring) { | 767 | if (is_configuring) { |
| 768 | lock.unlock(); | ||
| 759 | TriggerOnChange(ControllerTriggerType::Motion, false); | 769 | TriggerOnChange(ControllerTriggerType::Motion, false); |
| 760 | return; | 770 | return; |
| 761 | } | 771 | } |
| @@ -767,6 +777,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 767 | motion.orientation = emulated.GetOrientation(); | 777 | motion.orientation = emulated.GetOrientation(); |
| 768 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); | 778 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); |
| 769 | 779 | ||
| 780 | lock.unlock(); | ||
| 770 | TriggerOnChange(ControllerTriggerType::Motion, true); | 781 | TriggerOnChange(ControllerTriggerType::Motion, true); |
| 771 | } | 782 | } |
| 772 | 783 | ||
| @@ -775,10 +786,11 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac | |||
| 775 | if (index >= controller.battery_values.size()) { | 786 | if (index >= controller.battery_values.size()) { |
| 776 | return; | 787 | return; |
| 777 | } | 788 | } |
| 778 | std::lock_guard lock{mutex}; | 789 | std::unique_lock lock{mutex}; |
| 779 | controller.battery_values[index] = TransformToBattery(callback); | 790 | controller.battery_values[index] = TransformToBattery(callback); |
| 780 | 791 | ||
| 781 | if (is_configuring) { | 792 | if (is_configuring) { |
| 793 | lock.unlock(); | ||
| 782 | TriggerOnChange(ControllerTriggerType::Battery, false); | 794 | TriggerOnChange(ControllerTriggerType::Battery, false); |
| 783 | return; | 795 | return; |
| 784 | } | 796 | } |
| @@ -835,6 +847,8 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac | |||
| 835 | }; | 847 | }; |
| 836 | break; | 848 | break; |
| 837 | } | 849 | } |
| 850 | |||
| 851 | lock.unlock(); | ||
| 838 | TriggerOnChange(ControllerTriggerType::Battery, true); | 852 | TriggerOnChange(ControllerTriggerType::Battery, true); |
| 839 | } | 853 | } |
| 840 | 854 | ||
| @@ -932,6 +946,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) | |||
| 932 | } | 946 | } |
| 933 | 947 | ||
| 934 | bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { | 948 | bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { |
| 949 | std::lock_guard lock{mutex}; | ||
| 935 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; | 950 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; |
| 936 | switch (type) { | 951 | switch (type) { |
| 937 | case NpadStyleIndex::ProController: | 952 | case NpadStyleIndex::ProController: |
| @@ -947,6 +962,7 @@ bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { | |||
| 947 | } | 962 | } |
| 948 | 963 | ||
| 949 | bool EmulatedController::IsControllerSupported(bool use_temporary_value) const { | 964 | bool EmulatedController::IsControllerSupported(bool use_temporary_value) const { |
| 965 | std::lock_guard lock{mutex}; | ||
| 950 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; | 966 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; |
| 951 | switch (type) { | 967 | switch (type) { |
| 952 | case NpadStyleIndex::ProController: | 968 | case NpadStyleIndex::ProController: |
| @@ -982,40 +998,44 @@ void EmulatedController::Connect(bool use_temporary_value) { | |||
| 982 | LOG_ERROR(Service_HID, "Controller type {} is not supported", type); | 998 | LOG_ERROR(Service_HID, "Controller type {} is not supported", type); |
| 983 | return; | 999 | return; |
| 984 | } | 1000 | } |
| 985 | { | ||
| 986 | std::lock_guard lock{mutex}; | ||
| 987 | if (is_configuring) { | ||
| 988 | tmp_is_connected = true; | ||
| 989 | TriggerOnChange(ControllerTriggerType::Connected, false); | ||
| 990 | return; | ||
| 991 | } | ||
| 992 | 1001 | ||
| 993 | if (is_connected) { | 1002 | std::unique_lock lock{mutex}; |
| 994 | return; | 1003 | if (is_configuring) { |
| 995 | } | 1004 | tmp_is_connected = true; |
| 996 | is_connected = true; | 1005 | lock.unlock(); |
| 1006 | TriggerOnChange(ControllerTriggerType::Connected, false); | ||
| 1007 | return; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | if (is_connected) { | ||
| 1011 | return; | ||
| 997 | } | 1012 | } |
| 1013 | is_connected = true; | ||
| 1014 | |||
| 1015 | lock.unlock(); | ||
| 998 | TriggerOnChange(ControllerTriggerType::Connected, true); | 1016 | TriggerOnChange(ControllerTriggerType::Connected, true); |
| 999 | } | 1017 | } |
| 1000 | 1018 | ||
| 1001 | void EmulatedController::Disconnect() { | 1019 | void EmulatedController::Disconnect() { |
| 1002 | { | 1020 | std::unique_lock lock{mutex}; |
| 1003 | std::lock_guard lock{mutex}; | 1021 | if (is_configuring) { |
| 1004 | if (is_configuring) { | 1022 | tmp_is_connected = false; |
| 1005 | tmp_is_connected = false; | 1023 | lock.unlock(); |
| 1006 | TriggerOnChange(ControllerTriggerType::Disconnected, false); | 1024 | TriggerOnChange(ControllerTriggerType::Disconnected, false); |
| 1007 | return; | 1025 | return; |
| 1008 | } | 1026 | } |
| 1009 | 1027 | ||
| 1010 | if (!is_connected) { | 1028 | if (!is_connected) { |
| 1011 | return; | 1029 | return; |
| 1012 | } | ||
| 1013 | is_connected = false; | ||
| 1014 | } | 1030 | } |
| 1031 | is_connected = false; | ||
| 1032 | |||
| 1033 | lock.unlock(); | ||
| 1015 | TriggerOnChange(ControllerTriggerType::Disconnected, true); | 1034 | TriggerOnChange(ControllerTriggerType::Disconnected, true); |
| 1016 | } | 1035 | } |
| 1017 | 1036 | ||
| 1018 | bool EmulatedController::IsConnected(bool get_temporary_value) const { | 1037 | bool EmulatedController::IsConnected(bool get_temporary_value) const { |
| 1038 | std::lock_guard lock{mutex}; | ||
| 1019 | if (get_temporary_value && is_configuring) { | 1039 | if (get_temporary_value && is_configuring) { |
| 1020 | return tmp_is_connected; | 1040 | return tmp_is_connected; |
| 1021 | } | 1041 | } |
| @@ -1029,10 +1049,12 @@ bool EmulatedController::IsVibrationEnabled() const { | |||
| 1029 | } | 1049 | } |
| 1030 | 1050 | ||
| 1031 | NpadIdType EmulatedController::GetNpadIdType() const { | 1051 | NpadIdType EmulatedController::GetNpadIdType() const { |
| 1052 | std::lock_guard lock{mutex}; | ||
| 1032 | return npad_id_type; | 1053 | return npad_id_type; |
| 1033 | } | 1054 | } |
| 1034 | 1055 | ||
| 1035 | NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const { | 1056 | NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const { |
| 1057 | std::lock_guard lock{mutex}; | ||
| 1036 | if (get_temporary_value && is_configuring) { | 1058 | if (get_temporary_value && is_configuring) { |
| 1037 | return tmp_npad_type; | 1059 | return tmp_npad_type; |
| 1038 | } | 1060 | } |
| @@ -1040,27 +1062,28 @@ NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) c | |||
| 1040 | } | 1062 | } |
| 1041 | 1063 | ||
| 1042 | void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { | 1064 | void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { |
| 1043 | { | 1065 | std::unique_lock lock{mutex}; |
| 1044 | std::lock_guard lock{mutex}; | ||
| 1045 | 1066 | ||
| 1046 | if (is_configuring) { | 1067 | if (is_configuring) { |
| 1047 | if (tmp_npad_type == npad_type_) { | 1068 | if (tmp_npad_type == npad_type_) { |
| 1048 | return; | ||
| 1049 | } | ||
| 1050 | tmp_npad_type = npad_type_; | ||
| 1051 | TriggerOnChange(ControllerTriggerType::Type, false); | ||
| 1052 | return; | 1069 | return; |
| 1053 | } | 1070 | } |
| 1071 | tmp_npad_type = npad_type_; | ||
| 1072 | lock.unlock(); | ||
| 1073 | TriggerOnChange(ControllerTriggerType::Type, false); | ||
| 1074 | return; | ||
| 1075 | } | ||
| 1054 | 1076 | ||
| 1055 | if (npad_type == npad_type_) { | 1077 | if (npad_type == npad_type_) { |
| 1056 | return; | 1078 | return; |
| 1057 | } | ||
| 1058 | if (is_connected) { | ||
| 1059 | LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", | ||
| 1060 | NpadIdTypeToIndex(npad_id_type)); | ||
| 1061 | } | ||
| 1062 | npad_type = npad_type_; | ||
| 1063 | } | 1079 | } |
| 1080 | if (is_connected) { | ||
| 1081 | LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", | ||
| 1082 | NpadIdTypeToIndex(npad_id_type)); | ||
| 1083 | } | ||
| 1084 | npad_type = npad_type_; | ||
| 1085 | |||
| 1086 | lock.unlock(); | ||
| 1064 | TriggerOnChange(ControllerTriggerType::Type, true); | 1087 | TriggerOnChange(ControllerTriggerType::Type, true); |
| 1065 | } | 1088 | } |
| 1066 | 1089 | ||
| @@ -1088,30 +1111,37 @@ LedPattern EmulatedController::GetLedPattern() const { | |||
| 1088 | } | 1111 | } |
| 1089 | 1112 | ||
| 1090 | ButtonValues EmulatedController::GetButtonsValues() const { | 1113 | ButtonValues EmulatedController::GetButtonsValues() const { |
| 1114 | std::lock_guard lock{mutex}; | ||
| 1091 | return controller.button_values; | 1115 | return controller.button_values; |
| 1092 | } | 1116 | } |
| 1093 | 1117 | ||
| 1094 | SticksValues EmulatedController::GetSticksValues() const { | 1118 | SticksValues EmulatedController::GetSticksValues() const { |
| 1119 | std::lock_guard lock{mutex}; | ||
| 1095 | return controller.stick_values; | 1120 | return controller.stick_values; |
| 1096 | } | 1121 | } |
| 1097 | 1122 | ||
| 1098 | TriggerValues EmulatedController::GetTriggersValues() const { | 1123 | TriggerValues EmulatedController::GetTriggersValues() const { |
| 1124 | std::lock_guard lock{mutex}; | ||
| 1099 | return controller.trigger_values; | 1125 | return controller.trigger_values; |
| 1100 | } | 1126 | } |
| 1101 | 1127 | ||
| 1102 | ControllerMotionValues EmulatedController::GetMotionValues() const { | 1128 | ControllerMotionValues EmulatedController::GetMotionValues() const { |
| 1129 | std::lock_guard lock{mutex}; | ||
| 1103 | return controller.motion_values; | 1130 | return controller.motion_values; |
| 1104 | } | 1131 | } |
| 1105 | 1132 | ||
| 1106 | ColorValues EmulatedController::GetColorsValues() const { | 1133 | ColorValues EmulatedController::GetColorsValues() const { |
| 1134 | std::lock_guard lock{mutex}; | ||
| 1107 | return controller.color_values; | 1135 | return controller.color_values; |
| 1108 | } | 1136 | } |
| 1109 | 1137 | ||
| 1110 | BatteryValues EmulatedController::GetBatteryValues() const { | 1138 | BatteryValues EmulatedController::GetBatteryValues() const { |
| 1139 | std::lock_guard lock{mutex}; | ||
| 1111 | return controller.battery_values; | 1140 | return controller.battery_values; |
| 1112 | } | 1141 | } |
| 1113 | 1142 | ||
| 1114 | HomeButtonState EmulatedController::GetHomeButtons() const { | 1143 | HomeButtonState EmulatedController::GetHomeButtons() const { |
| 1144 | std::lock_guard lock{mutex}; | ||
| 1115 | if (is_configuring) { | 1145 | if (is_configuring) { |
| 1116 | return {}; | 1146 | return {}; |
| 1117 | } | 1147 | } |
| @@ -1119,6 +1149,7 @@ HomeButtonState EmulatedController::GetHomeButtons() const { | |||
| 1119 | } | 1149 | } |
| 1120 | 1150 | ||
| 1121 | CaptureButtonState EmulatedController::GetCaptureButtons() const { | 1151 | CaptureButtonState EmulatedController::GetCaptureButtons() const { |
| 1152 | std::lock_guard lock{mutex}; | ||
| 1122 | if (is_configuring) { | 1153 | if (is_configuring) { |
| 1123 | return {}; | 1154 | return {}; |
| 1124 | } | 1155 | } |
| @@ -1126,6 +1157,7 @@ CaptureButtonState EmulatedController::GetCaptureButtons() const { | |||
| 1126 | } | 1157 | } |
| 1127 | 1158 | ||
| 1128 | NpadButtonState EmulatedController::GetNpadButtons() const { | 1159 | NpadButtonState EmulatedController::GetNpadButtons() const { |
| 1160 | std::lock_guard lock{mutex}; | ||
| 1129 | if (is_configuring) { | 1161 | if (is_configuring) { |
| 1130 | return {}; | 1162 | return {}; |
| 1131 | } | 1163 | } |
| @@ -1133,6 +1165,7 @@ NpadButtonState EmulatedController::GetNpadButtons() const { | |||
| 1133 | } | 1165 | } |
| 1134 | 1166 | ||
| 1135 | DebugPadButton EmulatedController::GetDebugPadButtons() const { | 1167 | DebugPadButton EmulatedController::GetDebugPadButtons() const { |
| 1168 | std::lock_guard lock{mutex}; | ||
| 1136 | if (is_configuring) { | 1169 | if (is_configuring) { |
| 1137 | return {}; | 1170 | return {}; |
| 1138 | } | 1171 | } |
| @@ -1140,6 +1173,7 @@ DebugPadButton EmulatedController::GetDebugPadButtons() const { | |||
| 1140 | } | 1173 | } |
| 1141 | 1174 | ||
| 1142 | AnalogSticks EmulatedController::GetSticks() const { | 1175 | AnalogSticks EmulatedController::GetSticks() const { |
| 1176 | std::lock_guard lock{mutex}; | ||
| 1143 | if (is_configuring) { | 1177 | if (is_configuring) { |
| 1144 | return {}; | 1178 | return {}; |
| 1145 | } | 1179 | } |
| @@ -1154,6 +1188,7 @@ AnalogSticks EmulatedController::GetSticks() const { | |||
| 1154 | } | 1188 | } |
| 1155 | 1189 | ||
| 1156 | NpadGcTriggerState EmulatedController::GetTriggers() const { | 1190 | NpadGcTriggerState EmulatedController::GetTriggers() const { |
| 1191 | std::lock_guard lock{mutex}; | ||
| 1157 | if (is_configuring) { | 1192 | if (is_configuring) { |
| 1158 | return {}; | 1193 | return {}; |
| 1159 | } | 1194 | } |
| @@ -1161,6 +1196,7 @@ NpadGcTriggerState EmulatedController::GetTriggers() const { | |||
| 1161 | } | 1196 | } |
| 1162 | 1197 | ||
| 1163 | MotionState EmulatedController::GetMotions() const { | 1198 | MotionState EmulatedController::GetMotions() const { |
| 1199 | std::lock_guard lock{mutex}; | ||
| 1164 | if (force_update_motion) { | 1200 | if (force_update_motion) { |
| 1165 | for (auto& device : motion_devices) { | 1201 | for (auto& device : motion_devices) { |
| 1166 | if (!device) { | 1202 | if (!device) { |
| @@ -1173,14 +1209,17 @@ MotionState EmulatedController::GetMotions() const { | |||
| 1173 | } | 1209 | } |
| 1174 | 1210 | ||
| 1175 | ControllerColors EmulatedController::GetColors() const { | 1211 | ControllerColors EmulatedController::GetColors() const { |
| 1212 | std::lock_guard lock{mutex}; | ||
| 1176 | return controller.colors_state; | 1213 | return controller.colors_state; |
| 1177 | } | 1214 | } |
| 1178 | 1215 | ||
| 1179 | BatteryLevelState EmulatedController::GetBattery() const { | 1216 | BatteryLevelState EmulatedController::GetBattery() const { |
| 1217 | std::lock_guard lock{mutex}; | ||
| 1180 | return controller.battery_state; | 1218 | return controller.battery_state; |
| 1181 | } | 1219 | } |
| 1182 | 1220 | ||
| 1183 | void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { | 1221 | void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { |
| 1222 | std::lock_guard lock{callback_mutex}; | ||
| 1184 | for (const auto& poller_pair : callback_list) { | 1223 | for (const auto& poller_pair : callback_list) { |
| 1185 | const ControllerUpdateCallback& poller = poller_pair.second; | 1224 | const ControllerUpdateCallback& poller = poller_pair.second; |
| 1186 | if (!is_npad_service_update && poller.is_npad_service) { | 1225 | if (!is_npad_service_update && poller.is_npad_service) { |
| @@ -1193,13 +1232,13 @@ void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npa | |||
| 1193 | } | 1232 | } |
| 1194 | 1233 | ||
| 1195 | int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) { | 1234 | int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) { |
| 1196 | std::lock_guard lock{mutex}; | 1235 | std::lock_guard lock{callback_mutex}; |
| 1197 | callback_list.insert_or_assign(last_callback_key, std::move(update_callback)); | 1236 | callback_list.insert_or_assign(last_callback_key, std::move(update_callback)); |
| 1198 | return last_callback_key++; | 1237 | return last_callback_key++; |
| 1199 | } | 1238 | } |
| 1200 | 1239 | ||
| 1201 | void EmulatedController::DeleteCallback(int key) { | 1240 | void EmulatedController::DeleteCallback(int key) { |
| 1202 | std::lock_guard lock{mutex}; | 1241 | std::lock_guard lock{callback_mutex}; |
| 1203 | const auto& iterator = callback_list.find(key); | 1242 | const auto& iterator = callback_list.find(key); |
| 1204 | if (iterator == callback_list.end()) { | 1243 | if (iterator == callback_list.end()) { |
| 1205 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); | 1244 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index aa52f9572..1e224685d 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -400,7 +400,7 @@ private: | |||
| 400 | */ | 400 | */ |
| 401 | void TriggerOnChange(ControllerTriggerType type, bool is_service_update); | 401 | void TriggerOnChange(ControllerTriggerType type, bool is_service_update); |
| 402 | 402 | ||
| 403 | NpadIdType npad_id_type; | 403 | const NpadIdType npad_id_type; |
| 404 | NpadStyleIndex npad_type{NpadStyleIndex::None}; | 404 | NpadStyleIndex npad_type{NpadStyleIndex::None}; |
| 405 | NpadStyleTag supported_style_tag{NpadStyleSet::All}; | 405 | NpadStyleTag supported_style_tag{NpadStyleSet::All}; |
| 406 | bool is_connected{false}; | 406 | bool is_connected{false}; |
| @@ -434,6 +434,7 @@ private: | |||
| 434 | StickDevices tas_stick_devices; | 434 | StickDevices tas_stick_devices; |
| 435 | 435 | ||
| 436 | mutable std::mutex mutex; | 436 | mutable std::mutex mutex; |
| 437 | mutable std::mutex callback_mutex; | ||
| 437 | std::unordered_map<int, ControllerUpdateCallback> callback_list; | 438 | std::unordered_map<int, ControllerUpdateCallback> callback_list; |
| 438 | int last_callback_key = 0; | 439 | int last_callback_key = 0; |
| 439 | 440 | ||
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp index 708480f2d..f899f8ac0 100644 --- a/src/core/hid/emulated_devices.cpp +++ b/src/core/hid/emulated_devices.cpp | |||
| @@ -169,7 +169,7 @@ void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& cal | |||
| 169 | if (index >= device_status.keyboard_values.size()) { | 169 | if (index >= device_status.keyboard_values.size()) { |
| 170 | return; | 170 | return; |
| 171 | } | 171 | } |
| 172 | std::lock_guard lock{mutex}; | 172 | std::unique_lock lock{mutex}; |
| 173 | bool value_changed = false; | 173 | bool value_changed = false; |
| 174 | const auto new_status = TransformToButton(callback); | 174 | const auto new_status = TransformToButton(callback); |
| 175 | auto& current_status = device_status.keyboard_values[index]; | 175 | auto& current_status = device_status.keyboard_values[index]; |
| @@ -201,6 +201,7 @@ void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& cal | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | if (is_configuring) { | 203 | if (is_configuring) { |
| 204 | lock.unlock(); | ||
| 204 | TriggerOnChange(DeviceTriggerType::Keyboard); | 205 | TriggerOnChange(DeviceTriggerType::Keyboard); |
| 205 | return; | 206 | return; |
| 206 | } | 207 | } |
| @@ -208,6 +209,7 @@ void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& cal | |||
| 208 | // Index should be converted from NativeKeyboard to KeyboardKeyIndex | 209 | // Index should be converted from NativeKeyboard to KeyboardKeyIndex |
| 209 | UpdateKey(index, current_status.value); | 210 | UpdateKey(index, current_status.value); |
| 210 | 211 | ||
| 212 | lock.unlock(); | ||
| 211 | TriggerOnChange(DeviceTriggerType::Keyboard); | 213 | TriggerOnChange(DeviceTriggerType::Keyboard); |
| 212 | } | 214 | } |
| 213 | 215 | ||
| @@ -227,7 +229,7 @@ void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& c | |||
| 227 | if (index >= device_status.keyboard_moddifier_values.size()) { | 229 | if (index >= device_status.keyboard_moddifier_values.size()) { |
| 228 | return; | 230 | return; |
| 229 | } | 231 | } |
| 230 | std::lock_guard lock{mutex}; | 232 | std::unique_lock lock{mutex}; |
| 231 | bool value_changed = false; | 233 | bool value_changed = false; |
| 232 | const auto new_status = TransformToButton(callback); | 234 | const auto new_status = TransformToButton(callback); |
| 233 | auto& current_status = device_status.keyboard_moddifier_values[index]; | 235 | auto& current_status = device_status.keyboard_moddifier_values[index]; |
| @@ -259,6 +261,7 @@ void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& c | |||
| 259 | } | 261 | } |
| 260 | 262 | ||
| 261 | if (is_configuring) { | 263 | if (is_configuring) { |
| 264 | lock.unlock(); | ||
| 262 | TriggerOnChange(DeviceTriggerType::KeyboardModdifier); | 265 | TriggerOnChange(DeviceTriggerType::KeyboardModdifier); |
| 263 | return; | 266 | return; |
| 264 | } | 267 | } |
| @@ -289,6 +292,7 @@ void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& c | |||
| 289 | break; | 292 | break; |
| 290 | } | 293 | } |
| 291 | 294 | ||
| 295 | lock.unlock(); | ||
| 292 | TriggerOnChange(DeviceTriggerType::KeyboardModdifier); | 296 | TriggerOnChange(DeviceTriggerType::KeyboardModdifier); |
| 293 | } | 297 | } |
| 294 | 298 | ||
| @@ -297,7 +301,7 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba | |||
| 297 | if (index >= device_status.mouse_button_values.size()) { | 301 | if (index >= device_status.mouse_button_values.size()) { |
| 298 | return; | 302 | return; |
| 299 | } | 303 | } |
| 300 | std::lock_guard lock{mutex}; | 304 | std::unique_lock lock{mutex}; |
| 301 | bool value_changed = false; | 305 | bool value_changed = false; |
| 302 | const auto new_status = TransformToButton(callback); | 306 | const auto new_status = TransformToButton(callback); |
| 303 | auto& current_status = device_status.mouse_button_values[index]; | 307 | auto& current_status = device_status.mouse_button_values[index]; |
| @@ -329,6 +333,7 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba | |||
| 329 | } | 333 | } |
| 330 | 334 | ||
| 331 | if (is_configuring) { | 335 | if (is_configuring) { |
| 336 | lock.unlock(); | ||
| 332 | TriggerOnChange(DeviceTriggerType::Mouse); | 337 | TriggerOnChange(DeviceTriggerType::Mouse); |
| 333 | return; | 338 | return; |
| 334 | } | 339 | } |
| @@ -351,6 +356,7 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba | |||
| 351 | break; | 356 | break; |
| 352 | } | 357 | } |
| 353 | 358 | ||
| 359 | lock.unlock(); | ||
| 354 | TriggerOnChange(DeviceTriggerType::Mouse); | 360 | TriggerOnChange(DeviceTriggerType::Mouse); |
| 355 | } | 361 | } |
| 356 | 362 | ||
| @@ -359,13 +365,14 @@ void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callba | |||
| 359 | if (index >= device_status.mouse_analog_values.size()) { | 365 | if (index >= device_status.mouse_analog_values.size()) { |
| 360 | return; | 366 | return; |
| 361 | } | 367 | } |
| 362 | std::lock_guard lock{mutex}; | 368 | std::unique_lock lock{mutex}; |
| 363 | const auto analog_value = TransformToAnalog(callback); | 369 | const auto analog_value = TransformToAnalog(callback); |
| 364 | 370 | ||
| 365 | device_status.mouse_analog_values[index] = analog_value; | 371 | device_status.mouse_analog_values[index] = analog_value; |
| 366 | 372 | ||
| 367 | if (is_configuring) { | 373 | if (is_configuring) { |
| 368 | device_status.mouse_position_state = {}; | 374 | device_status.mouse_position_state = {}; |
| 375 | lock.unlock(); | ||
| 369 | TriggerOnChange(DeviceTriggerType::Mouse); | 376 | TriggerOnChange(DeviceTriggerType::Mouse); |
| 370 | return; | 377 | return; |
| 371 | } | 378 | } |
| @@ -379,17 +386,19 @@ void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callba | |||
| 379 | break; | 386 | break; |
| 380 | } | 387 | } |
| 381 | 388 | ||
| 389 | lock.unlock(); | ||
| 382 | TriggerOnChange(DeviceTriggerType::Mouse); | 390 | TriggerOnChange(DeviceTriggerType::Mouse); |
| 383 | } | 391 | } |
| 384 | 392 | ||
| 385 | void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callback) { | 393 | void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callback) { |
| 386 | std::lock_guard lock{mutex}; | 394 | std::unique_lock lock{mutex}; |
| 387 | const auto touch_value = TransformToTouch(callback); | 395 | const auto touch_value = TransformToTouch(callback); |
| 388 | 396 | ||
| 389 | device_status.mouse_stick_value = touch_value; | 397 | device_status.mouse_stick_value = touch_value; |
| 390 | 398 | ||
| 391 | if (is_configuring) { | 399 | if (is_configuring) { |
| 392 | device_status.mouse_position_state = {}; | 400 | device_status.mouse_position_state = {}; |
| 401 | lock.unlock(); | ||
| 393 | TriggerOnChange(DeviceTriggerType::Mouse); | 402 | TriggerOnChange(DeviceTriggerType::Mouse); |
| 394 | return; | 403 | return; |
| 395 | } | 404 | } |
| @@ -397,42 +406,52 @@ void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callbac | |||
| 397 | device_status.mouse_position_state.x = touch_value.x.value; | 406 | device_status.mouse_position_state.x = touch_value.x.value; |
| 398 | device_status.mouse_position_state.y = touch_value.y.value; | 407 | device_status.mouse_position_state.y = touch_value.y.value; |
| 399 | 408 | ||
| 409 | lock.unlock(); | ||
| 400 | TriggerOnChange(DeviceTriggerType::Mouse); | 410 | TriggerOnChange(DeviceTriggerType::Mouse); |
| 401 | } | 411 | } |
| 402 | 412 | ||
| 403 | KeyboardValues EmulatedDevices::GetKeyboardValues() const { | 413 | KeyboardValues EmulatedDevices::GetKeyboardValues() const { |
| 414 | std::lock_guard lock{mutex}; | ||
| 404 | return device_status.keyboard_values; | 415 | return device_status.keyboard_values; |
| 405 | } | 416 | } |
| 406 | 417 | ||
| 407 | KeyboardModifierValues EmulatedDevices::GetKeyboardModdifierValues() const { | 418 | KeyboardModifierValues EmulatedDevices::GetKeyboardModdifierValues() const { |
| 419 | std::lock_guard lock{mutex}; | ||
| 408 | return device_status.keyboard_moddifier_values; | 420 | return device_status.keyboard_moddifier_values; |
| 409 | } | 421 | } |
| 410 | 422 | ||
| 411 | MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const { | 423 | MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const { |
| 424 | std::lock_guard lock{mutex}; | ||
| 412 | return device_status.mouse_button_values; | 425 | return device_status.mouse_button_values; |
| 413 | } | 426 | } |
| 414 | 427 | ||
| 415 | KeyboardKey EmulatedDevices::GetKeyboard() const { | 428 | KeyboardKey EmulatedDevices::GetKeyboard() const { |
| 429 | std::lock_guard lock{mutex}; | ||
| 416 | return device_status.keyboard_state; | 430 | return device_status.keyboard_state; |
| 417 | } | 431 | } |
| 418 | 432 | ||
| 419 | KeyboardModifier EmulatedDevices::GetKeyboardModifier() const { | 433 | KeyboardModifier EmulatedDevices::GetKeyboardModifier() const { |
| 434 | std::lock_guard lock{mutex}; | ||
| 420 | return device_status.keyboard_moddifier_state; | 435 | return device_status.keyboard_moddifier_state; |
| 421 | } | 436 | } |
| 422 | 437 | ||
| 423 | MouseButton EmulatedDevices::GetMouseButtons() const { | 438 | MouseButton EmulatedDevices::GetMouseButtons() const { |
| 439 | std::lock_guard lock{mutex}; | ||
| 424 | return device_status.mouse_button_state; | 440 | return device_status.mouse_button_state; |
| 425 | } | 441 | } |
| 426 | 442 | ||
| 427 | MousePosition EmulatedDevices::GetMousePosition() const { | 443 | MousePosition EmulatedDevices::GetMousePosition() const { |
| 444 | std::lock_guard lock{mutex}; | ||
| 428 | return device_status.mouse_position_state; | 445 | return device_status.mouse_position_state; |
| 429 | } | 446 | } |
| 430 | 447 | ||
| 431 | AnalogStickState EmulatedDevices::GetMouseWheel() const { | 448 | AnalogStickState EmulatedDevices::GetMouseWheel() const { |
| 449 | std::lock_guard lock{mutex}; | ||
| 432 | return device_status.mouse_wheel_state; | 450 | return device_status.mouse_wheel_state; |
| 433 | } | 451 | } |
| 434 | 452 | ||
| 435 | void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { | 453 | void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { |
| 454 | std::lock_guard lock{callback_mutex}; | ||
| 436 | for (const auto& poller_pair : callback_list) { | 455 | for (const auto& poller_pair : callback_list) { |
| 437 | const InterfaceUpdateCallback& poller = poller_pair.second; | 456 | const InterfaceUpdateCallback& poller = poller_pair.second; |
| 438 | if (poller.on_change) { | 457 | if (poller.on_change) { |
| @@ -442,13 +461,13 @@ void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { | |||
| 442 | } | 461 | } |
| 443 | 462 | ||
| 444 | int EmulatedDevices::SetCallback(InterfaceUpdateCallback update_callback) { | 463 | int EmulatedDevices::SetCallback(InterfaceUpdateCallback update_callback) { |
| 445 | std::lock_guard lock{mutex}; | 464 | std::lock_guard lock{callback_mutex}; |
| 446 | callback_list.insert_or_assign(last_callback_key, std::move(update_callback)); | 465 | callback_list.insert_or_assign(last_callback_key, std::move(update_callback)); |
| 447 | return last_callback_key++; | 466 | return last_callback_key++; |
| 448 | } | 467 | } |
| 449 | 468 | ||
| 450 | void EmulatedDevices::DeleteCallback(int key) { | 469 | void EmulatedDevices::DeleteCallback(int key) { |
| 451 | std::lock_guard lock{mutex}; | 470 | std::lock_guard lock{callback_mutex}; |
| 452 | const auto& iterator = callback_list.find(key); | 471 | const auto& iterator = callback_list.find(key); |
| 453 | if (iterator == callback_list.end()) { | 472 | if (iterator == callback_list.end()) { |
| 454 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); | 473 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); |
diff --git a/src/core/hid/emulated_devices.h b/src/core/hid/emulated_devices.h index 790d3b411..73e9f0293 100644 --- a/src/core/hid/emulated_devices.h +++ b/src/core/hid/emulated_devices.h | |||
| @@ -200,6 +200,7 @@ private: | |||
| 200 | MouseStickDevice mouse_stick_device; | 200 | MouseStickDevice mouse_stick_device; |
| 201 | 201 | ||
| 202 | mutable std::mutex mutex; | 202 | mutable std::mutex mutex; |
| 203 | mutable std::mutex callback_mutex; | ||
| 203 | std::unordered_map<int, InterfaceUpdateCallback> callback_list; | 204 | std::unordered_map<int, InterfaceUpdateCallback> callback_list; |
| 204 | int last_callback_key = 0; | 205 | int last_callback_key = 0; |
| 205 | 206 | ||