From cd392563616140859bc6374640644905d03c06b7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 11 Sep 2014 23:18:19 +0400 Subject: [PATCH] CallbackManager rewritten --- Utilities/Thread.cpp | 27 ++- rpcs3/Emu/Memory/Memory.h | 1 - rpcs3/Emu/Memory/vm_ptr.h | 129 +++----------- rpcs3/Emu/RSX/GL/GLProgram.cpp | 1 + rpcs3/Emu/RSX/GSManager.cpp | 2 +- rpcs3/Emu/RSX/GSRender.cpp | 1 + rpcs3/Emu/RSX/RSXTexture.cpp | 1 + rpcs3/Emu/RSX/RSXThread.cpp | 36 ++-- rpcs3/Emu/RSX/RSXThread.h | 9 +- rpcs3/Emu/SysCalls/CB_FUNC.h | 34 ++++ rpcs3/Emu/SysCalls/Callback.cpp | 176 +++++++------------ rpcs3/Emu/SysCalls/Callback.h | 168 ++---------------- rpcs3/Emu/SysCalls/ModuleManager.cpp | 3 +- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 1 + rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 18 +- rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp | 16 +- rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp | 5 +- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 1 + rpcs3/Emu/SysCalls/Modules/cellPngDec.h | 16 +- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 71 ++++++-- rpcs3/Emu/SysCalls/Modules/cellResc.h | 42 +---- rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp | 1 + rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 1 + rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 84 +++++++-- rpcs3/Emu/SysCalls/Modules/cellSysutil.h | 23 +++ rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp | 1 + rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 6 +- rpcs3/Emu/System.cpp | 6 +- rpcs3/Emu/System.h | 4 +- rpcs3/Gui/GLGSFrame.cpp | 1 + rpcs3/Gui/MainFrame.cpp | 7 +- rpcs3/emucore.vcxproj | 1 + rpcs3/emucore.vcxproj.filters | 3 + 34 files changed, 395 insertions(+), 503 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/CB_FUNC.h diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index aa59aa2384..727005e651 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Log.h" #include "Thread.h" thread_local NamedThreadBase* g_tls_this_thread = nullptr; @@ -66,7 +67,18 @@ void ThreadBase::Start() SetCurrentNamedThread(this); g_thread_count++; - Task(); + try + { + Task(); + } + catch (const char* e) + { + LOG_ERROR(HLE, "%s: %s", GetThreadName().c_str(), e); + } + catch (const std::string& e) + { + LOG_ERROR(HLE, "%s: %s", GetThreadName().c_str(), e.c_str()); + } m_alive = false; g_thread_count--; @@ -142,7 +154,18 @@ void thread::start(std::function func) SetCurrentNamedThread(&info); g_thread_count++; - func(); + try + { + func(); + } + catch (const char* e) + { + LOG_ERROR(HLE, "%s: %s", name.c_str(), e); + } + catch (const std::string& e) + { + LOG_ERROR(HLE, "%s: %s", name.c_str(), e.c_str()); + } g_thread_count--; }); diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 4d83e2ec67..6866bd22fa 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -1,7 +1,6 @@ #pragma once #include "MemoryBlock.h" -#include "Emu/SysCalls/Callback.h" using std::nullptr_t; diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 24824b382f..a687eab5d4 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -87,6 +87,11 @@ namespace vm return m_addr; } + void set(const AT value) + { + m_addr = value; + } + static _ptr_base make(AT addr) { return (_ptr_base&)addr; @@ -181,6 +186,11 @@ namespace vm return m_addr; } + void set(const AT value) + { + m_addr = value; + } + operator bool() const { return m_addr != 0; @@ -219,6 +229,11 @@ namespace vm return m_addr; } + void set(const AT value) + { + m_addr = value; + } + void* const get_ptr() const { return vm::get_ptr(m_addr); @@ -264,6 +279,11 @@ namespace vm return m_addr; } + void set(const AT value) + { + m_addr = value; + } + const void* const get_ptr() const { return vm::get_ptr(m_addr); @@ -290,124 +310,27 @@ namespace vm _ptr_base& operator = (const _ptr_base& right) = default; }; - - template - class _ptr_base - { - AT m_addr; - - static_assert(!std::is_floating_point::value, "TODO: Unsupported callback result type (floating point)"); - - static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); - - __forceinline RT call_func(bool is_async) const - { - Callback cb; - cb.SetAddr(m_addr); - return (RT)cb.Branch(!is_async); - } - - public: - typedef RT(*type)(); - - __forceinline RT operator()() const - { - return call_func(false); - } - - __forceinline void async() const - { - call_func(true); - } - - AT addr() const - { - return m_addr; - } - - operator bool() const - { - return m_addr != 0; - } - - //typedef typename invert_be_t::type AT2; - - template - operator const _ptr_base() const - { - typename std::remove_const::type addr; addr = m_addr; - return (_ptr_base&)addr; - } - - static _ptr_base make(AT addr) - { - return (_ptr_base&)addr; - } - - operator std::function() const - { - const AT addr = m_addr; - return [addr]() -> RT { return make(addr)(); }; - } - - _ptr_base& operator = (const _ptr_base& right) = default; - }; template class _ptr_base { AT m_addr; - static_assert(!std::is_floating_point::value, "TODO: Unsupported callback result type (floating point)"); - static_assert(!std::is_same::value, "TODO: Unsupported callback result type (vector)"); - - static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); - static_assert(!std::is_reference::value, "Invalid callback result type (reference)"); - - template - struct _func_arg - { - static_assert(!std::is_floating_point::value, "TODO: Unsupported callback argument type (floating point)"); - static_assert(!std::is_same::value, "TODO: Unsupported callback argument type (vector)"); - - static_assert(sizeof(TT) <= 8, "Invalid callback argument type"); - static_assert(!std::is_pointer::value, "Invalid callback argument type (pointer)"); - static_assert(!std::is_reference::value, "Invalid callback argument type (reference)"); - - __forceinline static u64 get_value(const TT& arg) - { - u64 res = 0; - (TT&)res = arg; - return res; - } - }; - - __forceinline RT call_func(bool is_async, T... args) const - { - Callback cb; - cb.SetAddr(m_addr); - cb.Handle(_func_arg::get_value(args)...); - return (RT)cb.Branch(!is_async); - } - public: typedef RT(*type)(T...); - __forceinline RT operator()(T... args) const - { - return call_func(false, args...); - } - - __forceinline void async(T... args) const - { - call_func(true, args...); - } + RT operator()(T... args) const; // defined in Callback.h (CB_FUNC.h) AT addr() const { return m_addr; } + void set(const AT value) + { + m_addr = value; + } + operator bool() const { return m_addr != 0; diff --git a/rpcs3/Emu/RSX/GL/GLProgram.cpp b/rpcs3/Emu/RSX/GL/GLProgram.cpp index 96e32f6be4..e7e7fdaa0a 100644 --- a/rpcs3/Emu/RSX/GL/GLProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLProgram.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" +#include "Emu/Memory/Memory.h" #include "GLProgram.h" #include "GLGSRender.h" diff --git a/rpcs3/Emu/RSX/GSManager.cpp b/rpcs3/Emu/RSX/GSManager.cpp index 17155bbbb3..e4870d13ad 100644 --- a/rpcs3/Emu/RSX/GSManager.cpp +++ b/rpcs3/Emu/RSX/GSManager.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "rpcs3/Ini.h" - +#include "Emu/Memory/Memory.h" #include "sysutil_video.h" #include "GSManager.h" diff --git a/rpcs3/Emu/RSX/GSRender.cpp b/rpcs3/Emu/RSX/GSRender.cpp index acad3443c5..371db32257 100644 --- a/rpcs3/Emu/RSX/GSRender.cpp +++ b/rpcs3/Emu/RSX/GSRender.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GSManager.h" diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index c7d4d0bb8d..6904da2420 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Emu/Memory/Memory.h" #include "RSXThread.h" #include "RSXTexture.h" diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 9958db93a6..861a7f02d1 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -4,6 +4,9 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "RSXThread.h" + +#include "Emu/Cell/PPUThread.h" +#include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/lv2/sys_time.h" #define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.addr()) : args[x].ToLE()) @@ -293,8 +296,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if(m_flip_handler) { - m_flip_handler.Handle(1, 0, 0); - m_flip_handler.Branch(false); + auto cb = m_flip_handler; + Emu.GetCallbackManager().Async([cb]() + { + cb(1); + }); } //Emu.Pause(); @@ -1969,8 +1975,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const case GCM_SET_USER_COMMAND: { const u32 cause = ARGS(0); - m_user_handler.Handle(cause); - m_user_handler.Branch(false); + auto cb = m_user_handler; + Emu.GetCallbackManager().Async([cb, cause]() + { + cb(cause); + }); } break; @@ -2084,22 +2093,12 @@ void RSXThread::Begin(u32 draw_mode) m_draw_mode = draw_mode; m_draw_array_count = 0; m_draw_array_first = ~0; - - if(Emu.GetCallbackManager().m_exit_callback.m_callbacks.size()) - { - //Emu.GetCallbackManager().m_exit_callback.Handle(0x0121, 0); - } } void RSXThread::End() { ExecCMD(); - if(Emu.GetCallbackManager().m_exit_callback.m_callbacks.size()) - { - //Emu.GetCallbackManager().m_exit_callback.Handle(0x0122, 0); - } - m_indexed_array.Reset(); m_fragment_constants.clear(); m_transform_constants.clear(); @@ -2120,7 +2119,7 @@ void RSXThread::Task() OnInitThread(); - m_last_flip_time = get_system_time(); + m_last_flip_time = get_system_time() - 1000000; volatile bool is_vblank_stopped = false; thread vblank("VBlank thread", [&]() @@ -2142,8 +2141,11 @@ void RSXThread::Task() m_vblank_count++; if (m_vblank_handler) { - m_vblank_handler.Handle(1); - m_vblank_handler.Branch(false); + auto cb = m_vblank_handler; + Emu.GetCallbackManager().Async([cb]() + { + cb(1); + }); } continue; } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index d7bad7561b..c928d9c288 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -150,10 +150,10 @@ public: SSemaphore m_sem_flush; SSemaphore m_sem_flip; u64 m_last_flip_time; - Callback m_flip_handler; - Callback m_user_handler; + vm::ptr m_flip_handler; + vm::ptr m_user_handler; u64 m_vblank_count; - Callback m_vblank_handler; + vm::ptr m_vblank_handler; public: // Dither @@ -444,6 +444,9 @@ protected: , m_gcm_current_buffer(0) , m_read_buffer(true) { + m_flip_handler.set(0); + m_vblank_handler.set(0); + m_user_handler.set(0); m_set_depth_test = false; m_set_alpha_test = false; m_set_depth_bounds_test = false; diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h new file mode 100644 index 0000000000..afbc35912b --- /dev/null +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -0,0 +1,34 @@ +#pragma once + +namespace vm +{ + template + struct _func_arg + { + static_assert(!std::is_floating_point::value, "TODO: Unsupported callback argument type (floating point)"); + static_assert(!std::is_same::value, "TODO: Unsupported callback argument type (vector)"); + + static_assert(sizeof(TT) <= 8, "Invalid callback argument type"); + static_assert(!std::is_pointer::value, "Invalid callback argument type (pointer)"); + static_assert(!std::is_reference::value, "Invalid callback argument type (reference)"); + + __forceinline static u64 get_value(const TT& arg) + { + u64 res = 0; + (TT&)res = arg; + return res; + } + }; + + template + RT _ptr_base::operator ()(T... args) const + { + static_assert(!std::is_floating_point::value, "TODO: Unsupported callback result type (floating point)"); + static_assert(!std::is_same::value, "TODO: Unsupported callback result type (vector)"); + + static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); + static_assert(!std::is_reference::value, "Invalid callback result type (reference)"); + + return (RT)GetCurrentPPUThread().FastCall(vm::read32(m_addr), vm::read32(m_addr + 4), _func_arg::get_value(args)...); + } +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index f3af71d9b8..3f8968736d 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -1,152 +1,100 @@ #include "stdafx.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" +#include "ErrorCodes.h" #include "Emu/System.h" +#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" - #include "Callback.h" -Callback::Callback(u32 slot, u64 addr) - : m_addr(addr) - , m_slot(slot) - , a1(0) - , a2(0) - , a3(0) - , a4(0) - , a5(0) - , m_has_data(false) - , m_name("Callback") +void CallbackManager::Register(const std::function& func) { + std::lock_guard lock(m_mutex); + + m_cb_list.push_back(func); } -u32 Callback::GetSlot() const +void CallbackManager::Async(const std::function& func) { - return m_slot; + std::lock_guard lock(m_mutex); + + m_async_list.push_back(func); + m_cb_thread->Notify(); } -u64 Callback::GetAddr() const +bool CallbackManager::Check(s32& result) { - return m_addr; -} + std::function func = nullptr; -void Callback::SetSlot(u32 slot) -{ - m_slot = slot; -} - -void Callback::SetAddr(u64 addr) -{ - m_addr = addr; -} - -bool Callback::HasData() const -{ - return m_has_data; -} - -void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4, u64 _a5) -{ - a1 = _a1; - a2 = _a2; - a3 = _a3; - a4 = _a4; - a5 = _a5; - m_has_data = true; -} - -u64 Callback::Branch(bool wait) -{ - m_has_data = false; - - static std::mutex cb_mutex; - - CPUThread& thr = Emu.GetCallbackThread(); - -again: - - while (thr.IsAlive()) { - if (Emu.IsStopped()) + std::lock_guard lock(m_mutex); + + if (m_cb_list.size()) { - LOG_WARNING(HLE, "Callback::Branch() aborted"); - return 0; + func = m_cb_list[0]; + m_cb_list.erase(m_cb_list.begin()); } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - - std::lock_guard lock(cb_mutex); - - if (thr.IsAlive()) + + if (func) { - goto again; + result = func(); + return true; } - if (Emu.IsStopped()) + else { - LOG_WARNING(HLE, "Callback::Branch() aborted"); - return 0; + return false; } +} - thr.Stop(); - thr.Reset(); +void CallbackManager::Init() +{ + std::lock_guard lock(m_mutex); - thr.SetEntry(m_addr); - thr.SetPrio(1001); - thr.SetStackSize(0x10000); - thr.SetName(m_name); + m_cb_thread = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); - thr.SetArg(0, a1); - thr.SetArg(1, a2); - thr.SetArg(2, a3); - thr.SetArg(3, a4); - thr.Run(); - ((PPUThread&)thr).GPR[7] = a5; + u32 cb_shit = Memory.MainMem.AllocAlign(8); + vm::write32(cb_shit, Emu.m_ppu_thr_stop); + vm::write32(cb_shit + 4, 0); - thr.Exec(); + m_cb_thread->SetEntry(cb_shit); + m_cb_thread->SetPrio(1001); // ??? + m_cb_thread->SetStackSize(0x10000); + m_cb_thread->Run(); - if (!wait) + thread cb_async_thread("CallbackManager::Async() thread", [this]() { - return 0; - } + SetCurrentNamedThread(m_cb_thread); - while (thr.IsAlive()) - { - if (Emu.IsStopped()) + while (!Emu.IsStopped()) { - LOG_WARNING(HLE, "Callback::Branch(true) aborted (end)"); - return 0; + std::function func = nullptr; + { + std::lock_guard lock(m_mutex); + + if (m_async_list.size()) + { + func = m_async_list[0]; + m_async_list.erase(m_async_list.begin()); + } + } + + if (func) + { + func(); + continue; + } + m_cb_thread->WaitForAnySignal(); } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } + }); - return thr.GetExitStatus(); + cb_async_thread.detach(); } -void Callback::SetName(const std::string& name) +void CallbackManager::Clear() { - m_name = name; -} + std::lock_guard lock(m_mutex); -Callback::operator bool() const -{ - return GetAddr() != 0; -} - -Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr) -{ - a2 = userdata; -} - -void Callback2::Handle(u64 status) -{ - Callback::Handle(status, a2, 0); -} - -Callback3::Callback3(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr) -{ - a3 = userdata; -} - -void Callback3::Handle(u64 status, u64 param) -{ - Callback::Handle(status, param, a3); + m_cb_list.clear(); + m_async_list.clear(); } diff --git a/rpcs3/Emu/SysCalls/Callback.h b/rpcs3/Emu/SysCalls/Callback.h index faf3b79e99..6402ca84b6 100644 --- a/rpcs3/Emu/SysCalls/Callback.h +++ b/rpcs3/Emu/SysCalls/Callback.h @@ -1,163 +1,23 @@ #pragma once +#include "CB_FUNC.h" -class Callback +class CPUThread; + +class CallbackManager { -protected: - u64 m_addr; - u32 m_slot; - - bool m_has_data; - - std::string m_name; + std::vector> m_cb_list; + std::vector> m_async_list; + CPUThread* m_cb_thread; + std::mutex m_mutex; public: - u64 a1; - u64 a2; - u64 a3; - u64 a4; - u64 a5; + void Register(const std::function& func); // register callback (called in Check() method) - u32 GetSlot() const; - u64 GetAddr() const; - void SetSlot(u32 slot); - void SetAddr(u64 addr); - bool HasData() const; + void Async(const std::function& func); // register callback for callback thread (called immediately) - Callback(u32 slot = 0, u64 addr = 0); - void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0, u64 a5 = 0); - u64 Branch(bool wait); - void SetName(const std::string& name); + bool Check(s32& result); // call one callback registered by Register() method - operator bool() const; -}; - -struct Callback2 : public Callback -{ - Callback2(u32 slot, u64 addr, u64 userdata); - void Handle(u64 status); -}; - -struct Callback3 : public Callback -{ - Callback3(u32 slot, u64 addr, u64 userdata); - void Handle(u64 status, u64 param); -}; - -struct Callbacks -{ - std::vector m_callbacks; - bool m_in_manager; - - Callbacks() : m_in_manager(false) - { - } - - virtual void Register(u32 slot, u64 addr, u64 userdata) - { - Unregister(slot); - } - - void Unregister(u32 slot) - { - for(u32 i=0; i m_callbacks; - Callbacks3 m_exit_callback; - - void Add(Callbacks& c) - { - if(c.m_in_manager) return; - - c.m_in_manager = true; - m_callbacks.push_back(&c); - } - - void Init() - { - Add(m_exit_callback); - } - - void Clear() - { - for(u32 i=0; im_callbacks.clear(); - m_callbacks[i]->m_in_manager = false; - } - - m_callbacks.clear(); - } + void Init(); + + void Clear(); }; diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp index 1bcb6e7466..3e894fdd29 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ b/rpcs3/Emu/SysCalls/ModuleManager.cpp @@ -58,6 +58,7 @@ extern Module *cellSync2; extern void cellSysmodule_init(); extern Module *cellSysmodule; extern void cellSysutil_init(); +extern void cellSysutil_load(); extern Module *cellSysutil; extern void cellSysutilAp_init(); extern Module *cellSysutilAp; @@ -266,7 +267,7 @@ void ModuleManager::init() cellSync2 = static_cast (&(m_mod_init.back())) + 1; m_mod_init.emplace_back(0x0055, cellSync2_init); cellSysutil = static_cast (&(m_mod_init.back())) + 1; - m_mod_init.emplace_back(0x0015, cellSysutil_init); + m_mod_init.emplace_back(0x0015, cellSysutil_init, cellSysutil_load, nullptr); cellSysutilAp = static_cast (&(m_mod_init.back())) + 1; m_mod_init.emplace_back(0x0039, cellSysutilAp_init); cellSysmodule = static_cast (&(m_mod_init.back())) + 1; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 097106036e..b55bbcec80 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" #include "Utilities/rMsgBox.h" #include "Emu/FS/VFS.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 0ae9f803d7..edcc13f0e6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -456,11 +456,11 @@ int cellGcmSetFlip(vm::ptr ctxt, u32 id) return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } -void cellGcmSetFlipHandler(u32 handler_addr) +void cellGcmSetFlipHandler(vm::ptr handler) { - cellGcmSys->Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr); + cellGcmSys->Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler.addr()); - Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr); + Emu.GetGSManager().GetRender().m_flip_handler = handler; } int cellGcmSetFlipMode(u32 mode) @@ -596,18 +596,18 @@ int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u return CELL_OK; } -void cellGcmSetUserHandler(u32 handler_addr) +void cellGcmSetUserHandler(vm::ptr handler) { - cellGcmSys->Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler_addr); + cellGcmSys->Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler.addr()); - Emu.GetGSManager().GetRender().m_user_handler.SetAddr(handler_addr); + Emu.GetGSManager().GetRender().m_user_handler = handler; } -void cellGcmSetVBlankHandler(u32 handler_addr) +void cellGcmSetVBlankHandler(vm::ptr handler) { - cellGcmSys->Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler_addr); + cellGcmSys->Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler.addr()); - Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr); + Emu.GetGSManager().GetRender().m_vblank_handler = handler; } int cellGcmSetWaitFlip(vm::ptr ctxt) diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 009d91d35a..8df2d3f476 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" #include "Utilities/Log.h" #include "Utilities/rMsgBox.h" @@ -104,6 +105,8 @@ int cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr msgString, vm::ptrWarning("MsgDialog thread aborted"); + return; + } std::this_thread::sleep_for(std::chrono::milliseconds(1)); } @@ -125,7 +133,13 @@ int cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr s32 + { + callback((s32)status, userData); + return CELL_OK; + }); + } CallAfter([]() { diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h index 820d2a7792..9c0b2eeb55 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h @@ -79,7 +79,7 @@ enum CELL_MSGDIALOG_BUTTON_ESCAPE = 3, }; -typedef void(*CellMsgDialogCallback)(int buttonType, u32 userData); +typedef void(*CellMsgDialogCallback)(s32 buttonType, u32 userData); int cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam); int cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr callback, u32 userData, u32 extParam); diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp index 0402966732..35b3d378a3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp @@ -3,6 +3,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "cellSysutil.h" #include "cellNetCtl.h" //void cellNetCtl_init(); @@ -56,7 +57,7 @@ int cellNetCtlNetStartDialogLoadAsync(vm::ptr par cellNetCtl->Warning("cellNetCtlNetStartDialogLoadAsync(param_addr=0x%x)", param.addr()); // TODO: Actually sign into PSN - Emu.GetCallbackManager().m_exit_callback.Handle(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); + sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); return CELL_OK; } @@ -71,7 +72,7 @@ int cellNetCtlNetStartDialogUnloadAsync(vm::ptr { cellNetCtl->Warning("cellNetCtlNetStartDialogUnloadAsync(result_addr=0x%x)", result.addr()); - Emu.GetCallbackManager().m_exit_callback.Handle(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0); + sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 1da9f18ddc..c036052c2a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -365,6 +365,7 @@ s32 cellPngDecCreate(vm::ptr mainHandle, vm::ptrWarning("%s()", __FUNCTION__); + const_cast(*threadInParam).spuThreadEnable = CELL_PNGDEC_SPU_THREAD_DISABLE; // hack return GetCurrentPPUThread().FastCall2(libpngdec + 0x295C, libpngdec_rtoc); #else cellPngDec->Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x)", diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h index 3f0edf4d3a..6bb2d021a4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -28,7 +28,7 @@ enum }; // Consts -enum CellPngDecColorSpace +enum CellPngDecColorSpace : u32 { CELL_PNGDEC_GRAYSCALE = 1, CELL_PNGDEC_RGB = 2, @@ -44,43 +44,43 @@ enum CellPngDecSpuThreadEna : u32 CELL_PNGDEC_SPU_THREAD_ENABLE = 1, }; -enum CellPngDecStreamSrcSel +enum CellPngDecStreamSrcSel : u32 { CELL_PNGDEC_FILE = 0, CELL_PNGDEC_BUFFER = 1, }; -enum CellPngDecInterlaceMode +enum CellPngDecInterlaceMode : u32 { CELL_PNGDEC_NO_INTERLACE = 0, CELL_PNGDEC_ADAM7_INTERLACE = 1, }; -enum CellPngDecOutputMode +enum CellPngDecOutputMode : u32 { CELL_PNGDEC_TOP_TO_BOTTOM = 0, CELL_PNGDEC_BOTTOM_TO_TOP = 1, }; -enum CellPngDecPackFlag +enum CellPngDecPackFlag : u32 { CELL_PNGDEC_1BYTE_PER_NPIXEL = 0, CELL_PNGDEC_1BYTE_PER_1PIXEL = 1, }; -enum CellPngDecAlphaSelect +enum CellPngDecAlphaSelect : u32 { CELL_PNGDEC_STREAM_ALPHA = 0, CELL_PNGDEC_FIX_ALPHA = 1, }; -enum CellPngDecCommand +enum CellPngDecCommand : u32 { CELL_PNGDEC_CONTINUE = 0, CELL_PNGDEC_STOP = 1, }; -enum CellPngDecDecodeStatus +enum CellPngDecDecodeStatus : u32 { CELL_PNGDEC_DEC_STATUS_FINISH = 0, CELL_PNGDEC_DEC_STATUS_STOP = 1, diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index da87d67abe..079e9d82c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -11,6 +11,41 @@ Module *cellResc = nullptr; extern s32 cellVideoOutConfigure(u32 videoOut, vm::ptr config, vm::ptr option, u32 waitForEvent); +extern int cellGcmSetFlipMode(u32 mode); +extern void cellGcmSetFlipHandler(vm::ptr handler); +extern void cellGcmSetVBlankHandler(vm::ptr handler); +extern int cellGcmAddressToOffset(u64 address, vm::ptr> offset); +extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); +extern int cellGcmSetPrepareFlip(vm::ptr ctx, u32 id); +extern int cellGcmSetSecondVFrequency(u32 freq); +extern u32 cellGcmGetLabelAddress(u8 index); +extern u32 cellGcmGetTiledPitchSize(u32 size); + +CCellRescInternal* s_rescInternalInstance = nullptr; + +// Local Functions +int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved); + +// Help Functions +inline bool IsPal() { return s_rescInternalInstance->m_dstMode == CELL_RESC_720x576; } +inline bool IsPal60Hsync() { return (IsPal() && s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_FOR_HSYNC); } +inline bool IsPalDrop() { return (IsPal() && s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_DROP); } +inline bool IsPalInterpolate() { + return (IsPal() && ((s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE) + || (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE_30_DROP) + || (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE_DROP_FLEXIBLE))); +} +inline bool IsNotPalInterpolate() { return !IsPalInterpolate(); } +inline bool IsPalTemporal() { return (IsPal() && s_rescInternalInstance->m_initConfig.palTemporalMode != CELL_RESC_PAL_50); } +inline bool IsNotPalTemporal() { return !IsPalTemporal(); } +inline bool IsNotPal() { return !IsPal(); } +inline bool IsGcmFlip() { + return (IsNotPal() || (IsPal() && (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_50 + || s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_FOR_HSYNC))); +} +inline int GetNumColorBuffers(){ return IsPalInterpolate() ? 6 : (IsPalDrop() ? 3 : 2); } +inline bool IsInterlace() { return s_rescInternalInstance->m_initConfig.interlaceMode == CELL_RESC_INTERLACE_FILTER; } +inline bool IsTextureNR() { return !IsInterlace(); } static const float PICTURE_SIZE = (1.0f), @@ -373,8 +408,8 @@ void InitMembers() s_rescInternalInstance->m_bInitialized = false; s_rescInternalInstance->m_bNewlyAdjustRatio = false; - s_rescInternalInstance->s_applicationVBlankHandler = 0; - s_rescInternalInstance->s_applicationFlipHandler = 0; + s_rescInternalInstance->s_applicationVBlankHandler.set(0); + s_rescInternalInstance->s_applicationFlipHandler.set(0); //E PAL related variables //s_rescInternalInstance->m_intrThread50 = 0; @@ -567,7 +602,7 @@ void cellRescExit() if (IsPalTemporal()) { cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_DISABLE); - cellGcmSetVBlankHandler(0); + cellGcmSetVBlankHandler({}); //GcmSysTypePrefix::cellGcmSetSecondVHandler(NULL); if (IsPalInterpolate()) @@ -631,7 +666,7 @@ int cellRescSetDsts(u32 dstsMode, vm::ptr dsts) return CELL_OK; } -void SetVBlankHandler(u32 handler) +void SetVBlankHandler(vm::ptr handler) { if (!s_rescInternalInstance->m_bInitialized || s_rescInternalInstance->m_dstMode == 0) { @@ -643,12 +678,12 @@ void SetVBlankHandler(u32 handler) if (IsNotPalTemporal()) { cellGcmSetVBlankHandler(handler); - s_rescInternalInstance->s_applicationVBlankHandler = 0; + s_rescInternalInstance->s_applicationVBlankHandler.set(0); } else if (IsPal60Hsync()) { //cellGcmSetSecondVHandler(handler); - s_rescInternalInstance->s_applicationVBlankHandler = 0; + s_rescInternalInstance->s_applicationVBlankHandler.set(0); } else { @@ -657,7 +692,7 @@ void SetVBlankHandler(u32 handler) } -void SetFlipHandler(u32 handler) +void SetFlipHandler(vm::ptr handler) { if (!s_rescInternalInstance->m_bInitialized || s_rescInternalInstance->m_dstMode == 0) { @@ -669,7 +704,7 @@ void SetFlipHandler(u32 handler) if (IsGcmFlip()) { cellGcmSetFlipHandler(handler); - s_rescInternalInstance->s_applicationFlipHandler = 0; + s_rescInternalInstance->s_applicationFlipHandler.set(0); } else { @@ -744,20 +779,20 @@ int cellRescSetDisplayMode(u32 displayMode) cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); //cellGcmSetVBlankHandler(IntrHandler50); //cellGcmSetSecondVHandler(IntrHandler60); - cellGcmSetFlipHandler(0); + cellGcmSetFlipHandler({}); } else if (IsPalDrop()) { //InitLabels(); cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); - cellGcmSetVBlankHandler(0); + cellGcmSetVBlankHandler({}); //cellGcmSetSecondVHandler(IntrHandler60Drop); - cellGcmSetFlipHandler(0); + cellGcmSetFlipHandler({}); } else if (IsPal60Hsync()) { cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); - cellGcmSetVBlankHandler(0); + cellGcmSetVBlankHandler({}); } if (s_rescInternalInstance->s_applicationVBlankHandler) SetVBlankHandler(s_rescInternalInstance->s_applicationVBlankHandler); @@ -1037,11 +1072,11 @@ int cellRescSetBufferAddress(vm::ptr> colorBuffers, vm::ptr> return CELL_OK; } -void cellRescSetFlipHandler(u32 handler_addr) +void cellRescSetFlipHandler(vm::ptr handler) { - cellResc->Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler_addr); + cellResc->Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler.addr()); - Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr); + Emu.GetGSManager().GetRender().m_flip_handler = handler; } void cellRescResetFlipStatus() @@ -1077,11 +1112,11 @@ int cellRescSetRegisterCount() return CELL_OK; } -void cellRescSetVBlankHandler(u32 handler_addr) +void cellRescSetVBlankHandler(vm::ptr handler) { - cellResc->Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler_addr); + cellResc->Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler.addr()); - Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr); + Emu.GetGSManager().GetRender().m_vblank_handler = handler; } u16 FloatToHalf(float val) diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.h b/rpcs3/Emu/SysCalls/Modules/cellResc.h index 9e3d2fa16e..74a7652397 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.h +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.h @@ -137,49 +137,11 @@ struct CCellRescInternal bool m_isDummyFlipped; u8 m_cgParamIndex[RESC_PARAM_NUM]; u64 m_commandIdxCaF, m_rcvdCmdIdx; - u32 s_applicationFlipHandler; - u32 s_applicationVBlankHandler; + vm::ptr s_applicationFlipHandler; + vm::ptr s_applicationVBlankHandler; CCellRescInternal() : m_bInitialized(false) { } }; - - -CCellRescInternal* s_rescInternalInstance = nullptr; - -// Extern Functions -extern int cellGcmSetFlipMode(u32 mode); -extern void cellGcmSetFlipHandler(u32 handler_addr); -extern void cellGcmSetVBlankHandler(u32 handler_addr); -extern int cellGcmAddressToOffset(u64 address, vm::ptr> offset); -extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); -extern int cellGcmSetPrepareFlip(vm::ptr ctx, u32 id); -extern int cellGcmSetSecondVFrequency(u32 freq); -extern u32 cellGcmGetLabelAddress(u8 index); -extern u32 cellGcmGetTiledPitchSize(u32 size); - -// Local Functions -int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved); - -// Help Functions -inline bool IsPal() { return s_rescInternalInstance->m_dstMode == CELL_RESC_720x576; } -inline bool IsPal60Hsync() { return (IsPal() && s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_FOR_HSYNC); } -inline bool IsPalDrop() { return (IsPal() && s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_DROP); } -inline bool IsPalInterpolate() { - return (IsPal() && ((s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE) - || (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE_30_DROP) - || (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE_DROP_FLEXIBLE))); -} -inline bool IsNotPalInterpolate() { return !IsPalInterpolate(); } -inline bool IsPalTemporal() { return (IsPal() && s_rescInternalInstance->m_initConfig.palTemporalMode != CELL_RESC_PAL_50); } -inline bool IsNotPalTemporal() { return !IsPalTemporal(); } -inline bool IsNotPal() { return !IsPal(); } -inline bool IsGcmFlip() { - return (IsNotPal() || (IsPal() && (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_50 - || s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_FOR_HSYNC))); -} -inline int GetNumColorBuffers(){ return IsPalInterpolate() ? 6 : (IsPalDrop() ? 3 : 2); } -inline bool IsInterlace() { return s_rescInternalInstance->m_initConfig.interlaceMode == CELL_RESC_INTERLACE_FILTER; } -inline bool IsTextureNR() { return !IsInterlace(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index a06a9f6975..61dad6c763 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 9c521e9e65..eda13622ec 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/lv2/sys_process.h" #include "Emu/Event.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index e4a7f96cff..e2babf4c71 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -1,9 +1,11 @@ #include "stdafx.h" +#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/DbgCommand.h" +#include "Emu/SysCalls/Callback.h" +#include "Emu/DbgCommand.h" #include "rpcs3/Ini.h" #include "Emu/FS/vfsFile.h" #include "Loader/PSF.h" @@ -303,46 +305,85 @@ int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 as return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT; } -int cellSysutilCheckCallback() +struct sys_callback +{ + vm::ptr func; + vm::ptr arg; + +} g_sys_callback[4]; + +void sysutilSendSystemCommand(u64 status, u64 param) +{ + // TODO: check it and find the source of the return value (not sure that void becomes CELL_OK) + for (auto& cb : g_sys_callback) + { + if (cb.func) + { + Emu.GetCallbackManager().Register([=]() -> s32 + { + cb.func(status, param, cb.arg); + return CELL_OK; + }); + } + } +} + +s32 cellSysutilCheckCallback() { cellSysutil->Log("cellSysutilCheckCallback()"); - Emu.GetCallbackManager().m_exit_callback.Check(); + s32 res; + u32 count = 0; - CPUThread& thr = Emu.GetCallbackThread(); - - while (thr.IsAlive()) + while (Emu.GetCallbackManager().Check(res)) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + count++; + if (Emu.IsStopped()) { cellSysutil->Warning("cellSysutilCheckCallback() aborted"); - break; + return CELL_OK; } + + if (res) + { + return res; + } + } + + if (!count && !g_sys_callback[0].func && !g_sys_callback[1].func && !g_sys_callback[2].func && !g_sys_callback[3].func) + { + LOG_WARNING(TTY, "System warning: no callback registered\n"); } return CELL_OK; } -int cellSysutilRegisterCallback(int slot, u64 func_addr, u64 userdata) +s32 cellSysutilRegisterCallback(s32 slot, vm::ptr func, vm::ptr userdata) { - cellSysutil->Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%llx, userdata=0x%llx)", slot, func_addr, userdata); + cellSysutil->Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%x, userdata=0x%x)", slot, func.addr(), userdata.addr()); - Emu.GetCallbackManager().m_exit_callback.Register(slot, func_addr, userdata); - - SendDbgCommand(DID_REGISTRED_CALLBACK); + if ((u32)slot > 3) + { + return CELL_SYSUTIL_ERROR_VALUE; + } + g_sys_callback[slot].func = func; + g_sys_callback[slot].arg = userdata; return CELL_OK; } -int cellSysutilUnregisterCallback(int slot) +s32 cellSysutilUnregisterCallback(s32 slot) { cellSysutil->Warning("cellSysutilUnregisterCallback(slot=%d)", slot); - Emu.GetCallbackManager().m_exit_callback.Unregister(slot); - - SendDbgCommand(DID_UNREGISTRED_CALLBACK); + if ((u32)slot > 3) + { + return CELL_SYSUTIL_ERROR_VALUE; + } + g_sys_callback[slot].func.set(0); + g_sys_callback[slot].arg.set(0); return CELL_OK; } @@ -887,3 +928,12 @@ void cellSysutil_init() cellSysutil->AddFunc(0xe7951dee, cellGameDataCheckCreate); cellSysutil->AddFunc(0xc9645c41, cellGameDataCheckCreate2); } + +void cellSysutil_load() +{ + for (auto& v : g_sys_callback) + { + v.func.set(0); + v.arg.set(0); + } +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h index 48918d51c7..7b8c4fb8d6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h @@ -59,6 +59,29 @@ enum CELL_SYSUTIL_LANG_ENGLISH_GB = 18, }; +enum +{ + CELL_SYSUTIL_REQUEST_EXITGAME = 0x0101, + CELL_SYSUTIL_DRAWING_BEGIN = 0x0121, + CELL_SYSUTIL_DRAWING_END = 0x0122, + CELL_SYSUTIL_SYSTEM_MENU_OPEN = 0x0131, + CELL_SYSUTIL_SYSTEM_MENU_CLOSE = 0x0132, + CELL_SYSUTIL_BGMPLAYBACK_PLAY = 0x0141, + CELL_SYSUTIL_BGMPLAYBACK_STOP = 0x0142, + + CELL_SYSUTIL_NP_INVITATION_SELECTED = 0x0151, + CELL_SYSUTIL_NP_DATA_MESSAGE_SELECTED = 0x0152, + + CELL_SYSUTIL_SYSCHAT_START = 0x0161, + CELL_SYSUTIL_SYSCHAT_STOP = 0x0162, + CELL_SYSUTIL_SYSCHAT_VOICE_STREAMING_RESUMED = 0x0163, + CELL_SYSUTIL_SYSCHAT_VOICE_STREAMING_PAUSED = 0x0164, +}; + +typedef void(*CellSysutilCallback)(u64 status, u64 param, vm::ptr userdata); + +void sysutilSendSystemCommand(u64 status, u64 param); + enum { CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CIRCLE = 0, diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index 76676966d0..8f56d50067 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" #include "rpcs3/Ini.h" #include "Utilities/rXml.h" diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 28d4407706..d98a276f25 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -2,6 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Callback.h" #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" @@ -198,7 +199,10 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr& GetBreakPoints() { return m_break_points; } std::vector& GetMarkedPoints() { return m_marked_points; } - CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; } EventManager& GetEventManager() { return *m_event_manager; } StaticFuncManager& GetSFuncManager() { return *m_sfunc_manager; } ModuleManager& GetModuleManager() { return *m_module_manager; } diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index 98883da472..f4f1a5f4b7 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -1,4 +1,5 @@ #include "stdafx_gui.h" +#include "Emu/Memory/Memory.h" #include "GLGSFrame.h" #include "Utilities/Timer.h" diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index dca2b82f88..73eb40caef 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -7,6 +7,7 @@ #include "git-version.h" #include "Ini.h" +#include "Emu/Syscalls/Modules/cellSysutil.h" #include "Emu/RSX/sysutil_video.h" #include "Gui/PADManager.h" #include "Gui/VHDDManager.h" @@ -309,12 +310,12 @@ void MainFrame::Stop(wxCommandEvent& WXUNUSED(event)) void MainFrame::SendExit(wxCommandEvent& event) { - Emu.GetCallbackManager().m_exit_callback.Handle(0x0101, 0); + sysutilSendSystemCommand(CELL_SYSUTIL_REQUEST_EXITGAME, 0); } void MainFrame::SendOpenCloseSysMenu(wxCommandEvent& event) { - Emu.GetCallbackManager().m_exit_callback.Handle(m_sys_menu_opened ? 0x0132 : 0x0131, 0); + sysutilSendSystemCommand(m_sys_menu_opened ? CELL_SYSUTIL_SYSTEM_MENU_CLOSE : CELL_SYSUTIL_SYSTEM_MENU_OPEN, 0); m_sys_menu_opened = !m_sys_menu_opened; wxCommandEvent ce; UpdateUI(ce); @@ -744,7 +745,7 @@ void MainFrame::UpdateUI(wxCommandEvent& event) // PS3 Commands wxMenuItem& send_exit = *menubar.FindItem( id_sys_send_exit ); wxMenuItem& send_open_menu = *menubar.FindItem( id_sys_send_open_menu ); - bool enable_commands = !is_stopped && Emu.GetCallbackManager().m_exit_callback.m_callbacks.size(); + bool enable_commands = !is_stopped; send_open_menu.SetItemLabel(wxString::Format("Send %s system menu cmd", (m_sys_menu_opened ? "close" : "open"))); send_open_menu.Enable(enable_commands); send_exit.Enable(enable_commands); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index b8b7237a8a..493972abc2 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -334,6 +334,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index b129a2094e..4b1f50caa3 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1213,5 +1213,8 @@ Emu\SysCalls\Modules + + Emu\SysCalls + \ No newline at end of file