mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-02 11:03:34 -06:00
Kernel.Equeue: Only reset trigger state on events that clear. (#4032)
Some checks failed
Build and Release / reuse (push) Has been cancelled
Build and Release / clang-format (push) Has been cancelled
Build and Release / get-info (push) Has been cancelled
Build and Release / windows-sdl (push) Has been cancelled
Build and Release / macos-sdl (push) Has been cancelled
Build and Release / linux-sdl (push) Has been cancelled
Build and Release / linux-sdl-gcc (push) Has been cancelled
Build and Release / pre-release (push) Has been cancelled
Some checks failed
Build and Release / reuse (push) Has been cancelled
Build and Release / clang-format (push) Has been cancelled
Build and Release / get-info (push) Has been cancelled
Build and Release / windows-sdl (push) Has been cancelled
Build and Release / macos-sdl (push) Has been cancelled
Build and Release / linux-sdl (push) Has been cancelled
Build and Release / linux-sdl-gcc (push) Has been cancelled
Build and Release / pre-release (push) Has been cancelled
* 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:
parent
d189b0cc29
commit
e0850d5cfc
@ -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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user