mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
CallbackManager rewritten
This commit is contained in:
parent
3b71721a33
commit
cd39256361
@ -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<void()> 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--;
|
||||
});
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "MemoryBlock.h"
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
|
||||
using std::nullptr_t;
|
||||
|
||||
|
@ -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<void>(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<const void>(m_addr);
|
||||
@ -290,124 +310,27 @@ namespace vm
|
||||
|
||||
_ptr_base& operator = (const _ptr_base& right) = default;
|
||||
};
|
||||
|
||||
template<typename RT, typename AT>
|
||||
class _ptr_base<RT(*)(), 1, AT>
|
||||
{
|
||||
AT m_addr;
|
||||
|
||||
static_assert(!std::is_floating_point<RT>::value, "TODO: Unsupported callback result type (floating point)");
|
||||
|
||||
static_assert(!std::is_pointer<RT>::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<AT>::type AT2;
|
||||
|
||||
template<typename AT2>
|
||||
operator const _ptr_base<RT(*)(), 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr; addr = m_addr;
|
||||
return (_ptr_base<RT(*)(), 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
static _ptr_base make(AT addr)
|
||||
{
|
||||
return (_ptr_base&)addr;
|
||||
}
|
||||
|
||||
operator std::function<RT()>() const
|
||||
{
|
||||
const AT addr = m_addr;
|
||||
return [addr]() -> RT { return make(addr)(); };
|
||||
}
|
||||
|
||||
_ptr_base& operator = (const _ptr_base& right) = default;
|
||||
};
|
||||
|
||||
template<typename AT, typename RT, typename ...T>
|
||||
class _ptr_base<RT(*)(T...), 1, AT>
|
||||
{
|
||||
AT m_addr;
|
||||
|
||||
static_assert(!std::is_floating_point<RT>::value, "TODO: Unsupported callback result type (floating point)");
|
||||
static_assert(!std::is_same<RT, u128>::value, "TODO: Unsupported callback result type (vector)");
|
||||
|
||||
static_assert(!std::is_pointer<RT>::value, "Invalid callback result type (pointer)");
|
||||
static_assert(!std::is_reference<RT>::value, "Invalid callback result type (reference)");
|
||||
|
||||
template<typename TT>
|
||||
struct _func_arg
|
||||
{
|
||||
static_assert(!std::is_floating_point<TT>::value, "TODO: Unsupported callback argument type (floating point)");
|
||||
static_assert(!std::is_same<TT, u128>::value, "TODO: Unsupported callback argument type (vector)");
|
||||
|
||||
static_assert(sizeof(TT) <= 8, "Invalid callback argument type");
|
||||
static_assert(!std::is_pointer<TT>::value, "Invalid callback argument type (pointer)");
|
||||
static_assert(!std::is_reference<TT>::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<T>::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;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "GLProgram.h"
|
||||
#include "GLGSRender.h"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "rpcs3/Ini.h"
|
||||
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "sysutil_video.h"
|
||||
|
||||
#include "GSManager.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "GSManager.h"
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "RSXThread.h"
|
||||
#include "RSXTexture.h"
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<void(*)(const u32)> m_flip_handler;
|
||||
vm::ptr<void(*)(const u32)> m_user_handler;
|
||||
u64 m_vblank_count;
|
||||
Callback m_vblank_handler;
|
||||
vm::ptr<void(*)(const u32)> 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;
|
||||
|
34
rpcs3/Emu/SysCalls/CB_FUNC.h
Normal file
34
rpcs3/Emu/SysCalls/CB_FUNC.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
namespace vm
|
||||
{
|
||||
template<typename TT>
|
||||
struct _func_arg
|
||||
{
|
||||
static_assert(!std::is_floating_point<TT>::value, "TODO: Unsupported callback argument type (floating point)");
|
||||
static_assert(!std::is_same<TT, u128>::value, "TODO: Unsupported callback argument type (vector)");
|
||||
|
||||
static_assert(sizeof(TT) <= 8, "Invalid callback argument type");
|
||||
static_assert(!std::is_pointer<TT>::value, "Invalid callback argument type (pointer)");
|
||||
static_assert(!std::is_reference<TT>::value, "Invalid callback argument type (reference)");
|
||||
|
||||
__forceinline static u64 get_value(const TT& arg)
|
||||
{
|
||||
u64 res = 0;
|
||||
(TT&)res = arg;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename AT, typename RT, typename... T>
|
||||
RT _ptr_base<RT(*)(T...), 1, AT>::operator ()(T... args) const
|
||||
{
|
||||
static_assert(!std::is_floating_point<RT>::value, "TODO: Unsupported callback result type (floating point)");
|
||||
static_assert(!std::is_same<RT, u128>::value, "TODO: Unsupported callback result type (vector)");
|
||||
|
||||
static_assert(!std::is_pointer<RT>::value, "Invalid callback result type (pointer)");
|
||||
static_assert(!std::is_reference<RT>::value, "Invalid callback result type (reference)");
|
||||
|
||||
return (RT)GetCurrentPPUThread().FastCall(vm::read32(m_addr), vm::read32(m_addr + 4), _func_arg<T>::get_value(args)...);
|
||||
}
|
||||
}
|
@ -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<s32()>& func)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_cb_list.push_back(func);
|
||||
}
|
||||
|
||||
u32 Callback::GetSlot() const
|
||||
void CallbackManager::Async(const std::function<void()>& func)
|
||||
{
|
||||
return m_slot;
|
||||
std::lock_guard<std::mutex> 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<s32()> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<void()> func = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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();
|
||||
}
|
||||
|
@ -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<std::function<s32()>> m_cb_list;
|
||||
std::vector<std::function<void()>> 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<s32()>& 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<void()>& 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<Callback> 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.size(); ++i)
|
||||
{
|
||||
if(m_callbacks[i].GetSlot() == slot)
|
||||
{
|
||||
m_callbacks.erase(m_callbacks.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Handle(u64 status, u64 param = 0)=0;
|
||||
|
||||
bool Check()
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
for(u32 i=0; i<m_callbacks.size(); ++i)
|
||||
{
|
||||
if(m_callbacks[i].HasData())
|
||||
{
|
||||
handled = true;
|
||||
m_callbacks[i].Branch(true);
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
|
||||
struct Callbacks2 : public Callbacks
|
||||
{
|
||||
Callbacks2() : Callbacks()
|
||||
{
|
||||
}
|
||||
|
||||
void Register(u32 slot, u64 addr, u64 userdata)
|
||||
{
|
||||
Callbacks::Register(slot, addr, userdata);
|
||||
Callback2 callback(slot, addr, userdata);
|
||||
m_callbacks.push_back(callback);
|
||||
}
|
||||
|
||||
void Handle(u64 a1, u64 a2)
|
||||
{
|
||||
for(u32 i=0; i<m_callbacks.size(); ++i)
|
||||
{
|
||||
((Callback2&)m_callbacks[i]).Handle(a1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Callbacks3 : public Callbacks
|
||||
{
|
||||
Callbacks3() : Callbacks()
|
||||
{
|
||||
}
|
||||
|
||||
void Register(u32 slot, u64 addr, u64 userdata)
|
||||
{
|
||||
Callbacks::Register(slot, addr, userdata);
|
||||
Callback3 callback(slot, addr, userdata);
|
||||
m_callbacks.push_back(callback);
|
||||
}
|
||||
|
||||
void Handle(u64 a1, u64 a2)
|
||||
{
|
||||
for(u32 i=0; i<m_callbacks.size(); ++i)
|
||||
{
|
||||
((Callback3&)m_callbacks[i]).Handle(a1, a2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct CallbackManager
|
||||
{
|
||||
std::vector<Callbacks *> 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; i<m_callbacks.size(); ++i)
|
||||
{
|
||||
m_callbacks[i]->m_callbacks.clear();
|
||||
m_callbacks[i]->m_in_manager = false;
|
||||
}
|
||||
|
||||
m_callbacks.clear();
|
||||
}
|
||||
void Init();
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
@ -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 <Module*>(&(m_mod_init.back())) + 1;
|
||||
m_mod_init.emplace_back(0x0055, cellSync2_init);
|
||||
cellSysutil = static_cast <Module*>(&(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 <Module*>(&(m_mod_init.back())) + 1;
|
||||
m_mod_init.emplace_back(0x0039, cellSysutilAp_init);
|
||||
cellSysmodule = static_cast <Module*>(&(m_mod_init.back())) + 1;
|
||||
|
@ -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"
|
||||
|
@ -456,11 +456,11 @@ int cellGcmSetFlip(vm::ptr<CellGcmContextData> ctxt, u32 id)
|
||||
return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK;
|
||||
}
|
||||
|
||||
void cellGcmSetFlipHandler(u32 handler_addr)
|
||||
void cellGcmSetFlipHandler(vm::ptr<void(*)(const u32)> 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<void(*)(const u32)> 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<void(*)(const u32)> 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<CellGcmContextData> ctxt)
|
||||
|
@ -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<const char> msgString, vm::ptr<CellMsgD
|
||||
volatile bool m_signal = false;
|
||||
CallAfter([type, msg, &status, &m_signal]()
|
||||
{
|
||||
if (Emu.IsStopped()) return;
|
||||
|
||||
MsgDialogCreate(type, msg.c_str(), status);
|
||||
|
||||
m_signal = true;
|
||||
@ -111,6 +114,11 @@ int cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
|
||||
|
||||
while (!m_signal)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
cellSysutil->Warning("MsgDialog thread aborted");
|
||||
return;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
@ -125,7 +133,13 @@ int cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
|
||||
}
|
||||
|
||||
if (callback && (g_msg_dialog_state != msgDialogAbort))
|
||||
callback.async((s32)status, userData); // TODO: this callback should be registered
|
||||
{
|
||||
Emu.GetCallbackManager().Register([callback, status, userData]() -> s32
|
||||
{
|
||||
callback((s32)status, userData);
|
||||
return CELL_OK;
|
||||
});
|
||||
}
|
||||
|
||||
CallAfter([]()
|
||||
{
|
||||
|
@ -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<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
|
||||
int cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
|
||||
|
@ -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<CellNetCtlNetStartDialogParam> 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<CellNetCtlNetStartDialogResult>
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -365,6 +365,7 @@ s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInPa
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
const_cast<CellPngDecThreadInParam&>(*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)",
|
||||
|
@ -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,
|
||||
|
@ -11,6 +11,41 @@
|
||||
Module *cellResc = nullptr;
|
||||
|
||||
extern s32 cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> option, u32 waitForEvent);
|
||||
extern int cellGcmSetFlipMode(u32 mode);
|
||||
extern void cellGcmSetFlipHandler(vm::ptr<void(*)(const u32)> handler);
|
||||
extern void cellGcmSetVBlankHandler(vm::ptr<void(*)(const u32)> handler);
|
||||
extern int cellGcmAddressToOffset(u64 address, vm::ptr<be_t<u32>> offset);
|
||||
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
|
||||
extern int cellGcmSetPrepareFlip(vm::ptr<CellGcmContextData> 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<CellRescDsts> dsts)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void SetVBlankHandler(u32 handler)
|
||||
void SetVBlankHandler(vm::ptr<void(*)(const u32)> 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<void(*)(const u32)> 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<be_t<u32>> colorBuffers, vm::ptr<be_t<u32>>
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void cellRescSetFlipHandler(u32 handler_addr)
|
||||
void cellRescSetFlipHandler(vm::ptr<void(*)(const u32)> 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<void(*)(const u32)> 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)
|
||||
|
@ -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<void(*)(const u32)> s_applicationFlipHandler;
|
||||
vm::ptr<void(*)(const u32)> 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<be_t<u32>> offset);
|
||||
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
|
||||
extern int cellGcmSetPrepareFlip(vm::ptr<CellGcmContextData> 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(); }
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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<CellSysutilCallback> func;
|
||||
vm::ptr<void> 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<CellSysutilCallback> func, vm::ptr<void> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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<void> userdata);
|
||||
|
||||
void sysutilSendSystemCommand(u64 status, u64 param);
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CIRCLE = 0,
|
||||
|
@ -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"
|
||||
|
@ -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<CellFsAio> aio, int xid, vm::ptr<void (*)(vm::ptr
|
||||
|
||||
if (func) // start callback thread
|
||||
{
|
||||
func.async(aio, error, xid, res);
|
||||
Emu.GetCallbackManager().Async([func, aio, error, xid, res]()
|
||||
{
|
||||
func(aio, error, xid, res);
|
||||
});
|
||||
}
|
||||
|
||||
g_FsAioReadCur++;
|
||||
|
@ -43,7 +43,6 @@ Emulator::Emulator()
|
||||
: m_status(Stopped)
|
||||
, m_mode(DisAsm)
|
||||
, m_rsx_callback(0)
|
||||
, m_ppu_callback_thr(0)
|
||||
, m_thread_manager(new CPUThreadManager())
|
||||
, m_pad_manager(new PadManager())
|
||||
, m_keyboard_manager(new KeyboardManager())
|
||||
@ -336,8 +335,6 @@ void Emulator::Load()
|
||||
|
||||
case MACHINE_PPC64:
|
||||
{
|
||||
m_ppu_callback_thr = &GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
thread.SetEntry(l.GetEntry());
|
||||
Memory.StackMem.AllocAlign(0x1000);
|
||||
thread.InitStack();
|
||||
@ -375,6 +372,8 @@ void Emulator::Load()
|
||||
break;
|
||||
}
|
||||
|
||||
m_status = Ready;
|
||||
|
||||
GetGSManager().Init();
|
||||
GetCallbackManager().Init();
|
||||
GetAudioManager().Init();
|
||||
@ -382,7 +381,6 @@ void Emulator::Load()
|
||||
|
||||
thread.Run();
|
||||
|
||||
m_status = Ready;
|
||||
SendDbgCommand(DID_READY_EMU);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ class MouseManager;
|
||||
class IdManager;
|
||||
class GSManager;
|
||||
class AudioManager;
|
||||
struct CallbackManager;
|
||||
class CallbackManager;
|
||||
class CPUThread;
|
||||
class EventManager;
|
||||
class ModuleManager;
|
||||
@ -96,7 +96,6 @@ class Emulator
|
||||
GSManager* m_gs_manager;
|
||||
AudioManager* m_audio_manager;
|
||||
CallbackManager* m_callback_manager;
|
||||
CPUThread* m_ppu_callback_thr;
|
||||
EventManager* m_event_manager;
|
||||
StaticFuncManager* m_sfunc_manager;
|
||||
ModuleManager* m_module_manager;
|
||||
@ -131,7 +130,6 @@ public:
|
||||
VFS& GetVFS() { return *m_vfs; }
|
||||
std::vector<u64>& GetBreakPoints() { return m_break_points; }
|
||||
std::vector<u64>& 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; }
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx_gui.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "GLGSFrame.h"
|
||||
#include "Utilities/Timer.h"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -334,6 +334,7 @@
|
||||
<ClInclude Include="Emu\Memory\vm_ref.h" />
|
||||
<ClInclude Include="Emu\Memory\vm_var.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Callback.h" />
|
||||
<ClInclude Include="Emu\SysCalls\CB_FUNC.h" />
|
||||
<ClInclude Include="Emu\SysCalls\ErrorCodes.h" />
|
||||
<ClInclude Include="Emu\SysCalls\LogBase.h" />
|
||||
<ClInclude Include="Emu\SysCalls\lv2\lv2Fs.h" />
|
||||
|
@ -1213,5 +1213,8 @@
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPng.h">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\SysCalls\CB_FUNC.h">
|
||||
<Filter>Emu\SysCalls</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user