mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-18 01:41:02 +00:00
Kernel.Equeue: Only reset trigger state on events that clear. (#4032)
* Don't clear events that don't need clearing Unless the event has the clear flag, it will be returned multiple times after triggering. * Fix event flags As older code suggests, the PS4 kernel does append the clear flag to various event types internally. This is visible when observing the returned event data from sceKernelWaitEqueue (or kevent, if you're feeling ambitious) Add flag is also removed from events internally.
This commit is contained in:
@@ -32,6 +32,14 @@ bool EqueueInternal::AddEvent(EqueueEvent& event) {
|
||||
event.timer_interval = std::chrono::microseconds(event.event.data - offset);
|
||||
}
|
||||
|
||||
// Remove add flag from event
|
||||
event.event.flags &= ~SceKernelEvent::Flags::Add;
|
||||
|
||||
// Clear flag is appended to most event types internally.
|
||||
if (event.event.filter != SceKernelEvent::Filter::User) {
|
||||
event.event.flags |= SceKernelEvent::Flags::Clear;
|
||||
}
|
||||
|
||||
const auto& it = std::ranges::find(m_events, event);
|
||||
if (it != m_events.cend()) {
|
||||
*it = std::move(event);
|
||||
@@ -165,10 +173,6 @@ int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) {
|
||||
for (auto it = m_events.begin(); it != m_events.end();) {
|
||||
if (it->IsTriggered()) {
|
||||
ev[count++] = it->event;
|
||||
|
||||
// Event should not trigger again
|
||||
it->ResetTriggerState();
|
||||
|
||||
if (it->event.flags & SceKernelEvent::Flags::Clear) {
|
||||
it->Clear();
|
||||
}
|
||||
|
||||
@@ -84,11 +84,8 @@ struct EqueueEvent {
|
||||
std::chrono::microseconds timer_interval;
|
||||
std::unique_ptr<boost::asio::steady_timer> timer;
|
||||
|
||||
void ResetTriggerState() {
|
||||
is_triggered = false;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
is_triggered = false;
|
||||
event.fflags = 0;
|
||||
event.data = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user