diff --git a/Common/UI/Screen.cpp b/Common/UI/Screen.cpp index 9282005097..c66e665494 100644 --- a/Common/UI/Screen.cpp +++ b/Common/UI/Screen.cpp @@ -119,10 +119,7 @@ bool ScreenManager::key(const KeyInput &key) { void ScreenManager::axis(const AxisInput *axes, size_t count) { std::lock_guard guard(inputLock_); - for (size_t i = 0; i < count; i++) { - const AxisInput &axis = axes[i]; - stack_.back().screen->UnsyncAxis(axis); - } + stack_.back().screen->UnsyncAxis(axes, count); } void ScreenManager::deviceLost() { diff --git a/Common/UI/Screen.h b/Common/UI/Screen.h index afbe117a25..337c14dcee 100644 --- a/Common/UI/Screen.h +++ b/Common/UI/Screen.h @@ -63,7 +63,7 @@ public: virtual bool UnsyncTouch(const TouchInput &touch) = 0; // Return value of UnsyncKey is used to not block certain system keys like volume when unhandled, on Android. virtual bool UnsyncKey(const KeyInput &touch) = 0; - virtual void UnsyncAxis(const AxisInput &touch) = 0; + virtual void UnsyncAxis(const AxisInput *axes, size_t count) = 0; virtual void RecreateViews() {} diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index 520375dae5..1e136c9b99 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -99,12 +99,14 @@ bool UIScreen::UnsyncTouch(const TouchInput &touch) { return false; } -void UIScreen::UnsyncAxis(const AxisInput &axis) { +void UIScreen::UnsyncAxis(const AxisInput *axes, size_t count) { QueuedEvent ev{}; ev.type = QueuedEventType::AXIS; - ev.axis = axis; std::lock_guard guard(eventQueueLock_); - eventQueue_.push_back(ev); + for (size_t i = 0; i < count; i++) { + ev.axis = axes[i]; + eventQueue_.push_back(ev); + } } bool UIScreen::UnsyncKey(const KeyInput &key) { diff --git a/Common/UI/UIScreen.h b/Common/UI/UIScreen.h index f5e232f26c..956ebb228f 100644 --- a/Common/UI/UIScreen.h +++ b/Common/UI/UIScreen.h @@ -48,7 +48,7 @@ public: bool UnsyncTouch(const TouchInput &touch) override; bool UnsyncKey(const KeyInput &key) override; - void UnsyncAxis(const AxisInput &axis) override; + void UnsyncAxis(const AxisInput *axes, size_t count) override; TouchInput transformTouch(const TouchInput &touch) override; diff --git a/Core/ControlMapper.cpp b/Core/ControlMapper.cpp index b27a619cfa..629b1eaca3 100644 --- a/Core/ControlMapper.cpp +++ b/Core/ControlMapper.cpp @@ -476,28 +476,31 @@ void ControlMapper::ToggleSwapAxes() { UpdateAnalogOutput(1); } -void ControlMapper::Axis(const AxisInput &axis) { +void ControlMapper::Axis(const AxisInput *axes, size_t count) { double now = time_now_d(); std::lock_guard guard(mutex_); - size_t deviceIndex = (size_t)axis.deviceId; // this'll wrap around ANY (-1) to max, which will eliminate it on the next line, if such an event appears by mistake. - if (deviceIndex < (size_t)DEVICE_ID_COUNT) { - deviceTimestamps_[deviceIndex] = now; - } - if (axis.value >= 0.0f) { - InputMapping mapping(axis.deviceId, axis.axisId, 1); - InputMapping opposite(axis.deviceId, axis.axisId, -1); - curInput_[mapping] = { axis.value, now }; - curInput_[opposite] = { 0.0f, now }; - UpdatePSPState(mapping, now); - UpdatePSPState(opposite, now); - } else if (axis.value < 0.0f) { - InputMapping mapping(axis.deviceId, axis.axisId, -1); - InputMapping opposite(axis.deviceId, axis.axisId, 1); - curInput_[mapping] = { -axis.value, now }; - curInput_[opposite] = { 0.0f, now }; - UpdatePSPState(mapping, now); - UpdatePSPState(opposite, now); + for (size_t i = 0; i < count; i++) { + const AxisInput &axis = axes[i]; + size_t deviceIndex = (size_t)axis.deviceId; // this wraps -1 up high, so will get rejected on the next line. + if (deviceIndex < (size_t)DEVICE_ID_COUNT) { + deviceTimestamps_[deviceIndex] = now; + } + if (axis.value >= 0.0f) { + InputMapping mapping(axis.deviceId, axis.axisId, 1); + InputMapping opposite(axis.deviceId, axis.axisId, -1); + curInput_[mapping] = { axis.value, now }; + curInput_[opposite] = { 0.0f, now }; + UpdatePSPState(mapping, now); + UpdatePSPState(opposite, now); + } else if (axis.value < 0.0f) { + InputMapping mapping(axis.deviceId, axis.axisId, -1); + InputMapping opposite(axis.deviceId, axis.axisId, 1); + curInput_[mapping] = { -axis.value, now }; + curInput_[opposite] = { 0.0f, now }; + UpdatePSPState(mapping, now); + UpdatePSPState(opposite, now); + } } } diff --git a/Core/ControlMapper.h b/Core/ControlMapper.h index c2d6c4cd16..24c70a0527 100644 --- a/Core/ControlMapper.h +++ b/Core/ControlMapper.h @@ -16,7 +16,7 @@ public: // Inputs to the table-based mapping // These functions are free-threaded. bool Key(const KeyInput &key, bool *pauseTrigger); - void Axis(const AxisInput &axis); + void Axis(const AxisInput *axes, size_t count); // Required callbacks. // TODO: These are so many now that a virtual interface might be more appropriate.. @@ -76,6 +76,8 @@ private: bool swapAxes_ = false; // Protects basically all the state. + // TODO: Maybe we should piggyback on the screenmanager mutex - it's always locked + // when events come in here. std::mutex mutex_; std::map curInput_; diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 9a4836dc34..48a11adb68 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -535,7 +535,7 @@ void AnalogSetupScreen::axis(const AxisInput &axis) { // UIScreen::axis(axis); // Instead we just send the input directly to the mapper, that we'll visualize. - mapper_.Axis(axis); + mapper_.Axis(&axis, 1); } void AnalogSetupScreen::CreateViews() { diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 09ddf81411..2397519624 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -865,9 +865,9 @@ bool EmuScreen::key(const KeyInput &key) { return retval; } -void EmuScreen::UnsyncAxis(const AxisInput &axis) { +void EmuScreen::UnsyncAxis(const AxisInput *axes, size_t count) { System_Notify(SystemNotification::ACTIVITY); - return controlMapper_.Axis(axis); + return controlMapper_.Axis(axes, count); } class GameInfoBGView : public UI::InertView { diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 970844ba18..e22695cb6d 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -53,7 +53,7 @@ public: // to get minimal latency and full control. We forward to UIScreen when needed. bool UnsyncTouch(const TouchInput &touch) override; bool UnsyncKey(const KeyInput &key) override; - void UnsyncAxis(const AxisInput &axis) override; + void UnsyncAxis(const AxisInput *axes, size_t count) override; // We also need to do some special handling of queued UI events to handle closing the chat window. bool key(const KeyInput &key) override;