diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index 64d4966c0..a4916208a 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -84,7 +84,11 @@ bool EqueueInternal::TriggerEvent(u64 ident, s16 filter, void* trigger_data) { std::scoped_lock lock{m_mutex}; for (auto& event : m_events) { if (event.event.ident == ident && event.event.filter == filter) { - event.Trigger(trigger_data); + if (filter == SceKernelEvent::Filter::VideoOut) { + event.TriggerDisplay(trigger_data); + } else { + event.Trigger(trigger_data); + } has_found = true; } } diff --git a/src/core/libraries/kernel/equeue.h b/src/core/libraries/kernel/equeue.h index 2db5e6ca7..b5c716ddb 100644 --- a/src/core/libraries/kernel/equeue.h +++ b/src/core/libraries/kernel/equeue.h @@ -81,6 +81,30 @@ struct EqueueEvent { event.data = reinterpret_cast(data); } + void TriggerDisplay(void* data) { + is_triggered = true; + auto hint = reinterpret_cast(data); + if (data == 0) { + event.data = (hint >> 12) & 0xF; + } else { + auto event_id = event.ident << 48; + auto hint_h = u32(hint >> 8) & 0xFFFFFF; + auto ident_h = u32(event.ident >> 40); + auto i = 0; + if ((u32(hint) & 0xFF) == event_id && event_id != 0xFE && ((hint_h ^ ident_h) & 0xFF) == 0) { + auto time = __rdtsc(); + auto mask = 0xF000; + if ((u32(event.data) & 0xF000) != 0xF000) { + mask = (u32(event.data) + 0x1000) & 0xF000; + } + i = 1; + event.data = (mask | u64(u32(time) & 0xFFF) | (hint & 0xFFFFFFFFFFFF0000)); + } else { + event.data = 1; + } + } + } + bool IsTriggered() const { return is_triggered; } diff --git a/src/core/libraries/videoout/driver.cpp b/src/core/libraries/videoout/driver.cpp index de5421fd7..a624bf899 100644 --- a/src/core/libraries/videoout/driver.cpp +++ b/src/core/libraries/videoout/driver.cpp @@ -187,7 +187,7 @@ void VideoOutDriver::Flip(const Request& req) { if (event != nullptr) { event->TriggerEvent(u64(OrbisVideoOutEventId::Flip), Kernel::SceKernelEvent::Filter::VideoOut, - reinterpret_cast(req.flip_arg)); + (void*)(u64(OrbisVideoOutEventId::Flip) | (req.flip_arg << 16))); } }