Fix event data for VideoOut events

Fix is based on some decompilation work shared by red_prig.
This commit is contained in:
Stephen Miller 2025-02-01 20:35:34 -06:00
parent 1d8c607c15
commit ae984b5ff5
3 changed files with 30 additions and 2 deletions

View File

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

View File

@ -81,6 +81,30 @@ struct EqueueEvent {
event.data = reinterpret_cast<uintptr_t>(data);
}
void TriggerDisplay(void* data) {
is_triggered = true;
auto hint = reinterpret_cast<u64>(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;
}

View File

@ -187,7 +187,7 @@ void VideoOutDriver::Flip(const Request& req) {
if (event != nullptr) {
event->TriggerEvent(u64(OrbisVideoOutEventId::Flip),
Kernel::SceKernelEvent::Filter::VideoOut,
reinterpret_cast<void*>(req.flip_arg));
(void*)(u64(OrbisVideoOutEventId::Flip) | (req.flip_arg << 16)));
}
}