From f1b1eacb67f4e76581196af23d57a640a104c417 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 10 Sep 2023 01:06:14 +0300 Subject: [PATCH 1/3] finished sceKernelWaitEqueue implementation --- src/Core/PS4/HLE/Graphics/video_out.cpp | 9 +++- .../PS4/HLE/Kernel/Objects/event_queue.cpp | 49 +++++++++++++++++++ src/Core/PS4/HLE/Kernel/Objects/event_queue.h | 5 +- src/Core/PS4/HLE/Kernel/event_queues.cpp | 2 +- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/Core/PS4/HLE/Graphics/video_out.cpp b/src/Core/PS4/HLE/Graphics/video_out.cpp index aaa90544e..26b5813ab 100644 --- a/src/Core/PS4/HLE/Graphics/video_out.cpp +++ b/src/Core/PS4/HLE/Graphics/video_out.cpp @@ -9,8 +9,8 @@ #include #include -#include "Objects/video_out_ctx.h" +#include "Objects/video_out_ctx.h" #include "Util/Singleton.h" namespace HLE::Libs::Graphics::VideoOut { @@ -59,6 +59,11 @@ void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attr attribute->option = SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE; } +static void flip_reset_event_func(HLE::Kernel::Objects::EqueueEvent* event) { + event->isTriggered = false; + event->event.fflags = 0; + event->event.data = 0; +} s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue eq, s32 handle, void* udata) { PRINT_FUNCTION_NAME(); auto* videoOut = Singleton::Instance(); @@ -82,7 +87,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue event.event.fflags = 0; event.event.data = 0; // event.filter.delete_event_func = flip_event_delete_func;//called in sceKernelDeleteEvent //TODO - // event.filter.reset_event_func = flip_event_reset_func;//called in sceKernelWaitEqueue //TODO + event.filter.reset_event_func = flip_reset_event_func; // event.filter.trigger_event_func = flip_event_trigger_func;//called in sceKernelTriggerEvent //TODO event.filter.data = ctx; diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp index 7b60822d1..a92e90406 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp @@ -1,5 +1,7 @@ #include "event_queue.h" +#include + #include "debug.h" namespace HLE::Kernel::Objects { @@ -21,4 +23,51 @@ int EqueueInternal::addEvent(const EqueueEvent& event) { return 0; } +int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { + Lib::LockMutexGuard lock(m_mutex); + + u32 timeElapsed = 0; + Lib::Timer t; + t.Start(); + + for (;;) { + int ret = getTriggeredEvents(ev, num); + + if (ret > 0 || (timeElapsed >= micros && micros != 0)) { + return ret; + } + + if (micros == 0) { + m_cond.WaitCondVar(&m_mutex); + } else { + m_cond.WaitCondVarFor(&m_mutex, micros - timeElapsed); + } + + timeElapsed = static_cast(t.GetTimeSec() * 1000000.0); + } + + return 0; +} + +int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) { + Lib::LockMutexGuard lock(m_mutex); + + int ret = 0; + + if (m_events.size() > 1) { + BREAKPOINT(); // we currently support one event + } + auto& event = m_events[0]; + + if (event.isTriggered) { + ev[ret++] = event.event; + + if (event.filter.reset_event_func != nullptr) { + event.filter.reset_event_func(&event); + } + } + + return ret; +} + }; // namespace HLE::Kernel::Objects \ No newline at end of file diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.h b/src/Core/PS4/HLE/Kernel/Objects/event_queue.h index 8e5bdd769..577d36278 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.h +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.h @@ -50,7 +50,7 @@ struct SceKernelEvent { struct Filter { void* data = nullptr; TriggerFunc trigger_event_func = nullptr; - ResetFunc reset__event_func = nullptr; + ResetFunc reset_event_func = nullptr; DeleteFunc delete_event_func = nullptr; }; @@ -66,9 +66,12 @@ class EqueueInternal { virtual ~EqueueInternal(); void setName(const std::string& m_name) { this->m_name = m_name; } int addEvent(const EqueueEvent& event); + int waitForEvents(SceKernelEvent* ev, int num, u32 micros); + int getTriggeredEvents(SceKernelEvent* ev, int num); private: std::string m_name; Lib::Mutex m_mutex; std::vector m_events; + Lib::ConditionVariable m_cond; }; }; // namespace HLE::Kernel::Objects \ No newline at end of file diff --git a/src/Core/PS4/HLE/Kernel/event_queues.cpp b/src/Core/PS4/HLE/Kernel/event_queues.cpp index 15940584f..dc26f820c 100644 --- a/src/Core/PS4/HLE/Kernel/event_queues.cpp +++ b/src/Core/PS4/HLE/Kernel/event_queues.cpp @@ -51,7 +51,7 @@ int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, HLE::Kernel::Objects::S return SCE_KERNEL_ERROR_EINVAL; } if (timo == nullptr) { // wait until an event arrives without timing out - // BREAKPOINT();//NOT supported yet TODO + *out = eq->waitForEvents(ev, num, 0); } if (timo != nullptr) { if (*timo == 0) {//only events that have already arrived at the time of this function call can be received From 0c39b808bf13de75a442b55a321c554c7bade001 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 10 Sep 2023 12:59:21 +0300 Subject: [PATCH 2/3] sceVideoOutSubmitFlip implementation --- src/Core/PS4/HLE/ErrorCodes.h | 4 ++- .../HLE/Graphics/Objects/video_out_ctx.cpp | 24 +++++++++++++++++ .../PS4/HLE/Graphics/Objects/video_out_ctx.h | 12 ++++++++- src/Core/PS4/HLE/Graphics/video_out.cpp | 27 ++++++++++++++++--- src/Core/PS4/HLE/LibKernel.cpp | 7 +++++ src/Core/PS4/HLE/LibKernel.h | 2 +- 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/Core/PS4/HLE/ErrorCodes.h b/src/Core/PS4/HLE/ErrorCodes.h index 9b7d65b86..04edb64ee 100644 --- a/src/Core/PS4/HLE/ErrorCodes.h +++ b/src/Core/PS4/HLE/ErrorCodes.h @@ -1,7 +1,7 @@ #pragma once constexpr int SCE_OK = 0; -constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009; +constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009; constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c; // Insufficient memory constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000e; // Invalid address pointer constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; // null or invalid states @@ -11,5 +11,7 @@ constexpr int SCE_KERNEL_ERROR_ENAMETOOLONG = 0x8002003f; // character strings // videoOut constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already opened +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; // invalid buffer index constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue +constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp index ccf25e925..cdcdfeed8 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp @@ -1,4 +1,5 @@ #include "video_out_ctx.h" +#include namespace HLE::Graphics::Objects { @@ -38,5 +39,28 @@ void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* o *out = cfg->m_flip_status; } +bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { + Lib::LockMutexGuard lock(m_mutex); + + if (m_requests.size() >= 2) { + return false; + } + + Request r{}; + r.cfg = cfg; + r.index = index; + r.flip_arg = flip_arg; + r.submit_tsc = HLE::Libs::LibKernel::sceKernelReadTsc(); + + m_requests.push_back(r); + + cfg->m_flip_status.flipPendingNum = static_cast(m_requests.size()); + cfg->m_flip_status.gcQueueNum = 0; + + m_submit_cond.SignalCondVar(); + + return true; +} + }; // namespace HLE::Graphics::Objects diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h index 477ce3eb2..570898f2b 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h @@ -24,9 +24,19 @@ class FlipQueue { virtual ~FlipQueue() {} void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out); - + bool submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg); private: + struct Request { + VideoConfigInternal* cfg; + int index; + int64_t flip_arg; + uint64_t submit_tsc; + }; + Lib::Mutex m_mutex; + Lib::ConditionVariable m_submit_cond; + Lib::ConditionVariable m_done_cond; + std::vector m_requests; }; class VideoOutCtx { diff --git a/src/Core/PS4/HLE/Graphics/video_out.cpp b/src/Core/PS4/HLE/Graphics/video_out.cpp index 26b5813ab..1c4020a3c 100644 --- a/src/Core/PS4/HLE/Graphics/video_out.cpp +++ b/src/Core/PS4/HLE/Graphics/video_out.cpp @@ -116,9 +116,30 @@ s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) { return 0; } s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg) { - // BREAKPOINT(); - PRINT_DUMMY_FUNCTION_NAME(); - return 0; + PRINT_FUNCTION_NAME(); + auto* videoOut = Singleton::Instance(); + auto* ctx = videoOut->getCtx(handle); + + if (flipMode != 1) { + BREAKPOINT(); // only flipmode==1 is supported + } + if (bufferIndex == -1) { + BREAKPOINT(); // blank output not supported + } + if (bufferIndex < -1 || bufferIndex > 15) { + LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n",bufferIndex); + return SCE_VIDEO_OUT_ERROR_INVALID_INDEX; + } + LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex); + LOG_INFO_IF(log_file_videoout, "flipMode = {}\n", flipMode); + LOG_INFO_IF(log_file_videoout, "flipArg = {}\n", flipArg); + + if (!videoOut->getFlipQueue().submitFlip(ctx, bufferIndex, flipArg)) { + LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flip queue is full\n"); + return SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL; + } + + return SCE_OK; } s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, SceVideoOutFlipStatus* status) { PRINT_FUNCTION_NAME(); diff --git a/src/Core/PS4/HLE/LibKernel.cpp b/src/Core/PS4/HLE/LibKernel.cpp index a35fcb4b1..cc86aedb4 100644 --- a/src/Core/PS4/HLE/LibKernel.cpp +++ b/src/Core/PS4/HLE/LibKernel.cpp @@ -21,6 +21,11 @@ namespace HLE::Libs::LibKernel { static PS4_SYSV_ABI void stack_chk_fail() { BREAKPOINT(); } + u64 PS4_SYSV_ABI sceKernelReadTsc() { + LARGE_INTEGER c; + QueryPerformanceCounter(&c); + return c.QuadPart; + } void LibKernel_Register(SymbolsResolver* sym) { //obj LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard); @@ -35,6 +40,8 @@ namespace HLE::Libs::LibKernel { //misc LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, CPUManagement::sceKernelIsNeoMode); LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail); + //time + LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc); } }; \ No newline at end of file diff --git a/src/Core/PS4/HLE/LibKernel.h b/src/Core/PS4/HLE/LibKernel.h index 4f4f851ab..903aef847 100644 --- a/src/Core/PS4/HLE/LibKernel.h +++ b/src/Core/PS4/HLE/LibKernel.h @@ -6,6 +6,6 @@ void LibKernel_Register(SymbolsResolver* sym); // functions - +u64 PS4_SYSV_ABI sceKernelReadTsc(); int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len); }; // namespace HLE::Libs::LibKernel \ No newline at end of file From ab932e7503a28d8ce1a86cf10d6dd523670c6765 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 11 Sep 2023 13:14:13 +0300 Subject: [PATCH 3/3] event queue events now process nicely --- .../HLE/Graphics/Objects/video_out_ctx.cpp | 43 +++++++++++++++++-- .../PS4/HLE/Graphics/Objects/video_out_ctx.h | 1 + src/Core/PS4/HLE/Graphics/video_out.cpp | 21 +++++++-- src/Core/PS4/HLE/Graphics/video_out.h | 1 + .../PS4/HLE/Kernel/Objects/event_queue.cpp | 19 ++++++++ src/Core/PS4/HLE/Kernel/Objects/event_queue.h | 1 + src/emulator.cpp | 2 + 7 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp index cdcdfeed8..afc6426fb 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp @@ -1,4 +1,5 @@ #include "video_out_ctx.h" + #include namespace HLE::Graphics::Objects { @@ -30,7 +31,7 @@ int VideoOutCtx::Open() { VideoConfigInternal* VideoOutCtx::getCtx(int handle) { if (handle != 1) return nullptr; - return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more + return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more } void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out) { @@ -39,7 +40,7 @@ void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* o *out = cfg->m_flip_status; } -bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { +bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { Lib::LockMutexGuard lock(m_mutex); if (m_requests.size() >= 2) { @@ -62,5 +63,41 @@ bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { return true; } -}; // namespace HLE::Graphics::Objects +bool FlipQueue::flip(u32 micros) { + m_mutex.LockMutex(); + if (m_requests.size() == 0) { + m_submit_cond.WaitCondVarFor(&m_mutex, micros); + if (m_requests.size() == 0) { + m_mutex.UnlockMutex(); + return false; + } + } + auto request = m_requests.at(0); // proceed first request + m_mutex.UnlockMutex(); + + request.cfg->m_mutex.LockMutex(); + for (auto& flip_eq : request.cfg->m_flip_evtEq) { + if (flip_eq != nullptr) { + flip_eq->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, HLE::Kernel::Objects::EVFILT_VIDEO_OUT, reinterpret_cast(request.flip_arg)); + } + } + request.cfg->m_mutex.UnlockMutex(); + + m_requests.erase(m_requests.begin()); + m_done_cond.SignalCondVar(); + + request.cfg->m_flip_status.count++; + //TODO request.cfg->m_flip_status.processTime = LibKernel::KernelGetProcessTime(); + request.cfg->m_flip_status.tsc = HLE::Libs::LibKernel::sceKernelReadTsc(); + request.cfg->m_flip_status.submitTsc = request.submit_tsc; + request.cfg->m_flip_status.flipArg = request.flip_arg; + request.cfg->m_flip_status.currentBuffer = request.index; + request.cfg->m_flip_status.flipPendingNum = static_cast(m_requests.size()); + + m_mutex.UnlockMutex(); + + return false; +} + +}; // namespace HLE::Graphics::Objects diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h index 570898f2b..1017fbc0a 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h @@ -25,6 +25,7 @@ class FlipQueue { void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out); bool submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg); + bool flip(u32 micros); private: struct Request { VideoConfigInternal* cfg; diff --git a/src/Core/PS4/HLE/Graphics/video_out.cpp b/src/Core/PS4/HLE/Graphics/video_out.cpp index 1c4020a3c..a9356b3fc 100644 --- a/src/Core/PS4/HLE/Graphics/video_out.cpp +++ b/src/Core/PS4/HLE/Graphics/video_out.cpp @@ -21,6 +21,12 @@ void videoOutInit(u32 width, u32 height) { auto* videoOut = Singleton::Instance(); videoOut->Init(width, height); } + +bool videoOutFlip(u32 micros) { + auto* videoOut = Singleton::Instance(); + return videoOut->getFlipQueue().flip(micros); +} + std::string getPixelFormatString(s32 format) { switch (format) { case SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB: return "PIXEL_FORMAT_A8R8G8B8_SRGB"; @@ -64,6 +70,15 @@ static void flip_reset_event_func(HLE::Kernel::Objects::EqueueEvent* event) { event->event.fflags = 0; event->event.data = 0; } +static void flip_trigger_event_func(HLE::Kernel::Objects::EqueueEvent* event, void* trigger_data) { + event->isTriggered = true; + event->event.fflags++; + event->event.data = reinterpret_cast(trigger_data); +} +static void flip_delete_event_func(LibKernel::EventQueues::SceKernelEqueue eq, HLE::Kernel::Objects::EqueueEvent* event) { + BREAKPOINT(); // TODO +} + s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue eq, s32 handle, void* udata) { PRINT_FUNCTION_NAME(); auto* videoOut = Singleton::Instance(); @@ -86,9 +101,9 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue event.event.udata = udata; event.event.fflags = 0; event.event.data = 0; - // event.filter.delete_event_func = flip_event_delete_func;//called in sceKernelDeleteEvent //TODO + event.filter.delete_event_func = flip_delete_event_func; event.filter.reset_event_func = flip_reset_event_func; - // event.filter.trigger_event_func = flip_event_trigger_func;//called in sceKernelTriggerEvent //TODO + event.filter.trigger_event_func = flip_trigger_event_func; event.filter.data = ctx; int result = eq->addEvent(event); @@ -127,7 +142,7 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode BREAKPOINT(); // blank output not supported } if (bufferIndex < -1 || bufferIndex > 15) { - LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n",bufferIndex); + LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n", bufferIndex); return SCE_VIDEO_OUT_ERROR_INVALID_INDEX; } LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex); diff --git a/src/Core/PS4/HLE/Graphics/video_out.h b/src/Core/PS4/HLE/Graphics/video_out.h index dfa5e38a2..3ea6fb54d 100644 --- a/src/Core/PS4/HLE/Graphics/video_out.h +++ b/src/Core/PS4/HLE/Graphics/video_out.h @@ -90,6 +90,7 @@ struct SceVideoOutVblankStatus { void videoOutInit(u32 width, u32 height); std::string getPixelFormatString(s32 format); void videoOutRegisterLib(SymbolsResolver* sym); +bool videoOutFlip(u32 micros); void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, u32 pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, u32 height, u32 pitchInPixel); diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp index a92e90406..6eff9949d 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp @@ -49,6 +49,25 @@ int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { return 0; } +bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) { + Lib::LockMutexGuard lock(m_mutex); + + if (m_events.size() > 1) { + BREAKPOINT(); // we currently support one event + } + auto& event = m_events[0]; + + if (event.filter.trigger_event_func != nullptr) { + event.filter.trigger_event_func(&event, trigger_data); + } else { + event.isTriggered = true; + } + + m_cond.SignalCondVar(); + + return true; +} + int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) { Lib::LockMutexGuard lock(m_mutex); diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.h b/src/Core/PS4/HLE/Kernel/Objects/event_queue.h index 577d36278..b24151d54 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.h +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.h @@ -67,6 +67,7 @@ class EqueueInternal { void setName(const std::string& m_name) { this->m_name = m_name; } int addEvent(const EqueueEvent& event); int waitForEvents(SceKernelEvent* ev, int num, u32 micros); + bool triggerEvent(u64 ident, s16 filter, void* trigger_data); int getTriggeredEvents(SceKernelEvent* ev, int num); private: std::string m_name; diff --git a/src/emulator.cpp b/src/emulator.cpp index f079b36f2..982274998 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -1,9 +1,11 @@ #include "emulator.h" +#include "Core/PS4/HLE/Graphics/video_out.h" namespace Emulator { void emuInit() {} void emuRun() { for (;;) { + HLE::Libs::Graphics::VideoOut::videoOutFlip(100000);//flip every 0.1 sec } } } // namespace emulator \ No newline at end of file