Batch axis events all the way into ControlMapper

This commit is contained in:
Henrik Rydgård 2023-09-27 17:34:34 +02:00
parent b3a2b7a35c
commit ee93e4a2ca
9 changed files with 37 additions and 33 deletions

View File

@ -119,10 +119,7 @@ bool ScreenManager::key(const KeyInput &key) {
void ScreenManager::axis(const AxisInput *axes, size_t count) {
std::lock_guard<std::recursive_mutex> 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() {

View File

@ -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() {}

View File

@ -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<std::mutex> 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) {

View File

@ -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;

View File

@ -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<std::mutex> 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);
}
}
}

View File

@ -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<InputMapping, InputSample> curInput_;

View File

@ -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() {

View File

@ -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 {

View File

@ -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;