1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

CallbackManager rewritten

This commit is contained in:
Nekotekina 2014-09-11 23:18:19 +04:00
parent 3b71721a33
commit cd39256361
34 changed files with 395 additions and 503 deletions

View File

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

View File

@ -1,7 +1,6 @@
#pragma once
#include "MemoryBlock.h"
#include "Emu/SysCalls/Callback.h"
using std::nullptr_t;

View File

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

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "Utilities/Log.h"
#include "Emu/Memory/Memory.h"
#include "GLProgram.h"
#include "GLGSRender.h"

View File

@ -1,6 +1,6 @@
#include "stdafx.h"
#include "rpcs3/Ini.h"
#include "Emu/Memory/Memory.h"
#include "sysutil_video.h"
#include "GSManager.h"

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "GSManager.h"

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "RSXThread.h"
#include "RSXTexture.h"

View File

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

View File

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

View 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)...);
}
}

View File

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

View File

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

View File

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

View File

@ -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"

View File

@ -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)

View File

@ -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([]()
{

View File

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

View File

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

View File

@ -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)",

View File

@ -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,

View File

@ -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)

View File

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

View File

@ -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"

View File

@ -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"

View File

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

View File

@ -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,

View File

@ -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"

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
#include "stdafx_gui.h"
#include "Emu/Memory/Memory.h"
#include "GLGSFrame.h"
#include "Utilities/Timer.h"

View File

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

View File

@ -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" />

View File

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