mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-11 14:19:10 +00:00
equeue: sceGnmGetEqEventType/sceKernelGetEventData impl (#1839)
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
// Events are uniquely identified by id and filter.
|
||||
|
||||
bool EqueueInternal::AddEvent(EqueueEvent& event) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
|
||||
@@ -27,12 +29,13 @@ bool EqueueInternal::AddEvent(EqueueEvent& event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EqueueInternal::RemoveEvent(u64 id) {
|
||||
bool EqueueInternal::RemoveEvent(u64 id, s16 filter) {
|
||||
bool has_found = false;
|
||||
std::scoped_lock lock{m_mutex};
|
||||
|
||||
const auto& it =
|
||||
std::ranges::find_if(m_events, [id](auto& ev) { return ev.event.ident == id; });
|
||||
const auto& it = std::ranges::find_if(m_events, [id, filter](auto& ev) {
|
||||
return ev.event.ident == id && ev.event.filter == filter;
|
||||
});
|
||||
if (it != m_events.cend()) {
|
||||
m_events.erase(it);
|
||||
has_found = true;
|
||||
@@ -68,7 +71,7 @@ int EqueueInternal::WaitForEvents(SceKernelEvent* ev, int num, u32 micros) {
|
||||
|
||||
if (ev->flags & SceKernelEvent::Flags::OneShot) {
|
||||
for (auto ev_id = 0u; ev_id < count; ++ev_id) {
|
||||
RemoveEvent(ev->ident);
|
||||
RemoveEvent(ev->ident, ev->filter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +97,11 @@ int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) {
|
||||
int count = 0;
|
||||
for (auto& event : m_events) {
|
||||
if (event.IsTriggered()) {
|
||||
// Event should not trigger again
|
||||
event.ResetTriggerState();
|
||||
|
||||
if (event.event.flags & SceKernelEvent::Flags::Clear) {
|
||||
event.Reset();
|
||||
event.Clear();
|
||||
}
|
||||
ev[count++] = event.event;
|
||||
if (count == num) {
|
||||
@@ -334,7 +340,7 @@ int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id) {
|
||||
return ORBIS_KERNEL_ERROR_EBADF;
|
||||
}
|
||||
|
||||
if (!eq->RemoveEvent(id)) {
|
||||
if (!eq->RemoveEvent(id, SceKernelEvent::Filter::User)) {
|
||||
return ORBIS_KERNEL_ERROR_ENOENT;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
@@ -344,6 +350,10 @@ s16 PS4_SYSV_ABI sceKernelGetEventFilter(const SceKernelEvent* ev) {
|
||||
return ev->filter;
|
||||
}
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetEventData(const SceKernelEvent* ev) {
|
||||
return ev->data;
|
||||
}
|
||||
|
||||
void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue);
|
||||
LIB_FUNCTION("jpFjmgAC5AE", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteEqueue);
|
||||
@@ -356,6 +366,7 @@ void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent);
|
||||
LIB_FUNCTION("mJ7aghmgvfc", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventId);
|
||||
LIB_FUNCTION("23CPPI1tyBY", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventFilter);
|
||||
LIB_FUNCTION("kwGyyjohI50", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventData);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
||||
@@ -66,8 +66,11 @@ struct EqueueEvent {
|
||||
std::chrono::steady_clock::time_point time_added;
|
||||
std::unique_ptr<boost::asio::steady_timer> timer;
|
||||
|
||||
void Reset() {
|
||||
void ResetTriggerState() {
|
||||
is_triggered = false;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
event.fflags = 0;
|
||||
event.data = 0;
|
||||
}
|
||||
@@ -83,7 +86,7 @@ struct EqueueEvent {
|
||||
}
|
||||
|
||||
bool operator==(const EqueueEvent& ev) const {
|
||||
return ev.event.ident == event.ident;
|
||||
return ev.event.ident == event.ident && ev.event.filter == event.filter;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -99,7 +102,7 @@ public:
|
||||
}
|
||||
|
||||
bool AddEvent(EqueueEvent& event);
|
||||
bool RemoveEvent(u64 id);
|
||||
bool RemoveEvent(u64 id, s16 filter);
|
||||
int WaitForEvents(SceKernelEvent* ev, int num, u32 micros);
|
||||
bool TriggerEvent(u64 ident, s16 filter, void* trigger_data);
|
||||
int GetTriggeredEvents(SceKernelEvent* ev, int num);
|
||||
@@ -122,6 +125,8 @@ private:
|
||||
using SceKernelUseconds = u32;
|
||||
using SceKernelEqueue = EqueueInternal*;
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetEventData(const SceKernelEvent* ev);
|
||||
|
||||
void RegisterEventQueue(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
||||
Reference in New Issue
Block a user