mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Merge pull request #805 from Nekotekina/master
CallbackManager rewritten
This commit is contained in:
commit
3775d28d24
@ -438,9 +438,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1> be_t operator & (const be_t<T1>& right) const { const T res; res = ToBE() & right.ToBE(); return (be_t&)res; }
|
||||
template<typename T1> be_t operator | (const be_t<T1>& right) const { const T res; res = ToBE() | right.ToBE(); return (be_t&)res; }
|
||||
template<typename T1> be_t operator ^ (const be_t<T1>& right) const { const T res; res = ToBE() ^ right.ToBE(); return (be_t&)res; }
|
||||
template<typename T1> be_t operator & (const be_t<T1>& right) const { const T res = ToBE() & right.ToBE(); return (be_t&)res; }
|
||||
template<typename T1> be_t operator | (const be_t<T1>& right) const { const T res = ToBE() | right.ToBE(); return (be_t&)res; }
|
||||
template<typename T1> be_t operator ^ (const be_t<T1>& right) const { const T res = ToBE() ^ right.ToBE(); return (be_t&)res; }
|
||||
|
||||
template<typename T1> bool operator == (T1 right) const { return (T1)ToLE() == right; }
|
||||
template<typename T1> bool operator != (T1 right) const { return !(*this == right); }
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Log.h"
|
||||
#include "Thread.h"
|
||||
|
||||
thread_local NamedThreadBase* g_tls_this_thread = nullptr;
|
||||
@ -24,10 +25,10 @@ void NamedThreadBase::SetThreadName(const std::string& name)
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void NamedThreadBase::WaitForAnySignal() // wait 1 ms for something
|
||||
void NamedThreadBase::WaitForAnySignal(u64 time) // wait for Notify() signal or sleep
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_signal_mtx);
|
||||
m_signal_cv.wait_for(lock, std::chrono::milliseconds(1));
|
||||
m_signal_cv.wait_for(lock, std::chrono::milliseconds(time));
|
||||
}
|
||||
|
||||
void NamedThreadBase::Notify() // wake up waiting thread or nothing
|
||||
@ -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--;
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
virtual std::string GetThreadName() const;
|
||||
virtual void SetThreadName(const std::string& name);
|
||||
|
||||
void WaitForAnySignal();
|
||||
void WaitForAnySignal(u64 time = 1);
|
||||
|
||||
void Notify();
|
||||
};
|
||||
|
@ -283,11 +283,12 @@ void CPUThread::ExecOnce()
|
||||
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
|
||||
{
|
||||
const u64 addr = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr();
|
||||
if (u == EXCEPTION_ACCESS_VIOLATION && addr < 0x100000000)
|
||||
CPUThread* t = GetCurrentCPUThread();
|
||||
if (u == EXCEPTION_ACCESS_VIOLATION && addr < 0x100000000 && t)
|
||||
{
|
||||
// TODO: allow recovering from a page fault
|
||||
throw fmt::Format("Access violation: addr = 0x%x (last_syscall=0x%llx (%s))",
|
||||
(u32)addr, (u64)GetCurrentCPUThread()->m_last_syscall, SysCalls::GetHLEFuncName((u32)GetCurrentCPUThread()->m_last_syscall).c_str());
|
||||
throw fmt::Format("Access violation: addr = 0x%x (is_alive=%d, last_syscall=0x%llx (%s))",
|
||||
(u32)addr, t->IsAlive() ? 1 : 0, (u64)t->m_last_syscall, SysCalls::GetHLEFuncName((u32)t->m_last_syscall).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -317,7 +318,7 @@ void CPUThread::Task()
|
||||
std::vector<u64> trace;
|
||||
|
||||
#ifdef _WIN32
|
||||
_set_se_translator(_se_translator);
|
||||
auto old_se_translator = _set_se_translator(_se_translator);
|
||||
#else
|
||||
// TODO: linux version
|
||||
#endif
|
||||
@ -370,48 +371,13 @@ void CPUThread::Task()
|
||||
Emu.Pause();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_set_se_translator(old_se_translator);
|
||||
#else
|
||||
// TODO: linux version
|
||||
#endif
|
||||
|
||||
for (auto& v : trace) LOG_NOTICE(PPU, "PC = 0x%llx", v);
|
||||
|
||||
if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str());
|
||||
}
|
||||
|
||||
s64 CPUThread::ExecAsCallback(u64 pc, bool wait, u64 a1, u64 a2, u64 a3, u64 a4) // not multithread-safe
|
||||
{
|
||||
while (m_alive)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(PPU, "ExecAsCallback() aborted");
|
||||
return CELL_ECANCELED; // doesn't mean anything
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
Stop();
|
||||
Reset();
|
||||
|
||||
SetEntry(pc);
|
||||
SetPrio(1001);
|
||||
SetStackSize(0x10000);
|
||||
SetExitStatus(CELL_OK);
|
||||
|
||||
SetArg(0, a1);
|
||||
SetArg(1, a2);
|
||||
SetArg(2, a3);
|
||||
SetArg(3, a4);
|
||||
Run();
|
||||
|
||||
Exec();
|
||||
|
||||
while (wait && m_alive)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
LOG_WARNING(PPU, "ExecAsCallback(wait=%s) aborted", wait ? "true" : "false");
|
||||
return CELL_EABORT; // doesn't mean anything
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
return wait * m_exit_status;
|
||||
}
|
||||
|
@ -242,8 +242,6 @@ public:
|
||||
return pc + 4;
|
||||
}
|
||||
|
||||
s64 ExecAsCallback(u64 pc, bool wait, u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0);
|
||||
|
||||
protected:
|
||||
virtual void DoReset()=0;
|
||||
virtual void DoRun()=0;
|
||||
|
@ -2298,10 +2298,9 @@ private:
|
||||
}
|
||||
void LVEBX(u32 vd, u32 ra, u32 rb)
|
||||
{
|
||||
//const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
|
||||
//CPU.VPR[vd].Clear();
|
||||
//CPU.VPR[vd]._u8[addr & 0xf] = vm::read8(addr);
|
||||
CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
|
||||
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
|
||||
CPU.VPR[vd]._u8[15 - (addr & 0xf)] = vm::read8(addr);
|
||||
// check LVEWX comments
|
||||
}
|
||||
void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
|
||||
{
|
||||
@ -2447,10 +2446,9 @@ private:
|
||||
}
|
||||
void LVEHX(u32 vd, u32 ra, u32 rb)
|
||||
{
|
||||
//const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~1ULL;
|
||||
//CPU.VPR[vd].Clear();
|
||||
//(u16&)CPU.VPR[vd]._u8[addr & 0xf] = vm::read16(addr);
|
||||
CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
|
||||
const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~1ULL;
|
||||
CPU.VPR[vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(addr);
|
||||
// check LVEWX comments
|
||||
}
|
||||
void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
|
||||
{
|
||||
@ -2497,10 +2495,11 @@ private:
|
||||
}
|
||||
void LVEWX(u32 vd, u32 ra, u32 rb)
|
||||
{
|
||||
//const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~3ULL;
|
||||
//CPU.VPR[vd].Clear();
|
||||
//(u32&)CPU.VPR[vd]._u8[addr & 0xf] = vm::read32(addr);
|
||||
CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
|
||||
const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~3ULL;
|
||||
CPU.VPR[vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(addr);
|
||||
// It's not very good idea to implement it using read128(),
|
||||
// because it can theoretically read RawSPU 32-bit MMIO register (read128() will fail)
|
||||
//CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
|
||||
}
|
||||
void MULHD(u32 rd, u32 ra, u32 rb, bool rc)
|
||||
{
|
||||
@ -2964,8 +2963,7 @@ private:
|
||||
}
|
||||
void LFSX(u32 frd, u32 ra, u32 rb)
|
||||
{
|
||||
(u32&)CPU.FPR[frd] = vm::read32(ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]);
|
||||
CPU.FPR[frd] = (float&)CPU.FPR[frd];
|
||||
CPU.FPR[frd] = vm::get_ref<be_t<float>>(ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]).ToLE();
|
||||
}
|
||||
void SRW(u32 ra, u32 rs, u32 rb, bool rc)
|
||||
{
|
||||
|
@ -61,8 +61,8 @@ void PPUThread::AddArgv(const std::string& arg)
|
||||
|
||||
void PPUThread::InitRegs()
|
||||
{
|
||||
const u32 pc = vm::read32(entry);
|
||||
const u32 rtoc = vm::read32(entry + 4);
|
||||
const u32 pc = entry ? vm::read32(entry) : 0;
|
||||
const u32 rtoc = entry ? vm::read32(entry + 4) : 0;
|
||||
|
||||
//ConLog.Write("entry = 0x%x", entry);
|
||||
//ConLog.Write("rtoc = 0x%x", rtoc);
|
||||
@ -222,24 +222,11 @@ u64 PPUThread::GetStackArg(s32 i)
|
||||
return vm::read64(GPR[1] + 0x70 + 0x8 * (i - 9));
|
||||
}
|
||||
|
||||
u64 PPUThread::FastCall(u64 addr, u64 rtoc, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8)
|
||||
{
|
||||
GPR[3] = arg1;
|
||||
GPR[4] = arg2;
|
||||
GPR[5] = arg3;
|
||||
GPR[6] = arg4;
|
||||
GPR[7] = arg5;
|
||||
GPR[8] = arg6;
|
||||
GPR[9] = arg7;
|
||||
GPR[10] = arg8;
|
||||
|
||||
return FastCall2(addr, rtoc);
|
||||
}
|
||||
|
||||
u64 PPUThread::FastCall2(u64 addr, u64 rtoc)
|
||||
{
|
||||
auto old_status = m_status;
|
||||
auto old_PC = PC;
|
||||
auto old_stack = GPR[1]; // only saved and restored (may be wrong)
|
||||
auto old_rtoc = GPR[2];
|
||||
auto old_LR = LR;
|
||||
auto old_thread = GetCurrentNamedThread();
|
||||
@ -254,6 +241,7 @@ u64 PPUThread::FastCall2(u64 addr, u64 rtoc)
|
||||
|
||||
m_status = old_status;
|
||||
PC = old_PC;
|
||||
GPR[1] = old_stack;
|
||||
GPR[2] = old_rtoc;
|
||||
LR = old_LR;
|
||||
SetCurrentNamedThread(old_thread);
|
||||
|
@ -789,11 +789,9 @@ public:
|
||||
virtual void InitRegs();
|
||||
virtual u64 GetFreeStackSize() const;
|
||||
u64 GetStackArg(s32 i);
|
||||
u64 FastCall(u64 addr, u64 rtoc, u64 arg1 = 0, u64 arg2 = 0, u64 arg3 = 0, u64 arg4 = 0, u64 arg5 = 0, u64 arg6 = 0, u64 arg7 = 0, u64 arg8 = 0);
|
||||
u64 FastCall2(u64 addr, u64 rtoc);
|
||||
void FastStop();
|
||||
|
||||
protected:
|
||||
virtual void DoReset() override;
|
||||
virtual void DoRun() override;
|
||||
virtual void DoPause() override;
|
||||
|
@ -288,7 +288,7 @@ public:
|
||||
const XmmLink& XmmGet(s8 reg, s8 target = -1) // get xmm register with specific SPU reg
|
||||
{
|
||||
assert(reg >= 0);
|
||||
XmmLink* res = nullptr;
|
||||
const XmmLink* res = nullptr;
|
||||
if (reg == target)
|
||||
{
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
@ -311,7 +311,7 @@ public:
|
||||
}
|
||||
if (!res)
|
||||
{
|
||||
res = &(XmmLink&)XmmAlloc(target);
|
||||
res = &XmmAlloc(target);
|
||||
/*if (target != res->reg)
|
||||
{
|
||||
c.movdqa(*res->data, cpu_xmm(GPR[reg]));
|
||||
@ -327,7 +327,7 @@ public:
|
||||
c.movdqa(*res->data, cpu_xmm(GPR[reg]));
|
||||
}
|
||||
}
|
||||
res->reg = -1; // ???
|
||||
const_cast<XmmLink*>(res)->reg = -1; // ???
|
||||
LOG4_OPCODE("* cached GPR[%d] not found", reg);
|
||||
}
|
||||
return *res;
|
||||
@ -335,9 +335,9 @@ public:
|
||||
|
||||
const XmmLink& XmmCopy(const XmmLink& from, s8 pref = -1) // XmmAlloc + mov
|
||||
{
|
||||
XmmLink* res = &(XmmLink&)XmmAlloc(pref);
|
||||
const XmmLink* res = &XmmAlloc(pref);
|
||||
c.movdqa(*res->data, *from.data);
|
||||
res->reg = -1; // ???
|
||||
const_cast<XmmLink*>(res)->reg = -1; // ???
|
||||
LOG4_OPCODE("*");
|
||||
return *res;
|
||||
}
|
||||
|
@ -556,12 +556,17 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
|
||||
m_intrtag[2].stat |= 1;
|
||||
if (CPUThread* t = Emu.GetCPU().GetThread(m_intrtag[2].thread))
|
||||
{
|
||||
if (t->GetType() == CPU_THREAD_PPU && !t->IsAlive())
|
||||
if (t->GetType() == CPU_THREAD_PPU)
|
||||
{
|
||||
if (t->IsAlive())
|
||||
{
|
||||
LOG_ERROR(Log::SPU, "%s(%s): interrupt thread was alive", __FUNCTION__, spu_ch_name[ch]);
|
||||
Emu.Pause();
|
||||
return;
|
||||
}
|
||||
PPUThread& ppu = *(PPUThread*)t;
|
||||
ppu.FastStop();
|
||||
ppu.Run();
|
||||
ppu.FastCall(ppu.PC, ppu.GPR[2], ppu.m_interrupt_arg);
|
||||
ppu.GPR[3] = ppu.m_interrupt_arg;
|
||||
ppu.FastCall2(vm::read32(ppu.entry), vm::read32(ppu.entry + 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "MemoryBlock.h"
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
|
||||
using std::nullptr_t;
|
||||
|
||||
@ -116,7 +115,7 @@ public:
|
||||
{
|
||||
for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++)
|
||||
{
|
||||
if (m_pages[i] != 0) return false; // TODO: define page parameters
|
||||
if (!m_pages[i]) return false; // TODO: define page parameters
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
class PPUThread;
|
||||
|
||||
namespace vm
|
||||
{
|
||||
template<typename T, int lvl = 1, typename AT = u32>
|
||||
@ -87,6 +89,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 +188,11 @@ namespace vm
|
||||
return m_addr;
|
||||
}
|
||||
|
||||
void set(const AT value)
|
||||
{
|
||||
m_addr = value;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return m_addr != 0;
|
||||
@ -219,6 +231,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);
|
||||
@ -238,6 +255,13 @@ namespace vm
|
||||
return (_ptr_base<void, 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
template<typename AT2>
|
||||
operator const _ptr_base<const void, 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr; addr = m_addr;
|
||||
return (_ptr_base<const void, 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
static _ptr_base make(AT addr)
|
||||
{
|
||||
return (_ptr_base&)addr;
|
||||
@ -257,6 +281,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);
|
||||
@ -283,119 +312,29 @@ 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_pointer<RT>::value, "Invalid callback result type (pointer)");
|
||||
|
||||
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_pointer<TT>::value, "Invalid callback argument type (pointer)");
|
||||
|
||||
__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...);
|
||||
}
|
||||
RT call(PPUThread& CPU, T... args) const; // call using specified PPU thread context, defined in Callback.h (CB_FUNC.h)
|
||||
|
||||
__forceinline void async(T... args) const
|
||||
{
|
||||
call_func(true, args...);
|
||||
}
|
||||
RT operator()(T... args) const; // call using current PPU thread context, 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,8 @@
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "RSXThread.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 +295,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();
|
||||
@ -1975,8 +1980,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;
|
||||
|
||||
@ -2090,22 +2098,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();
|
||||
@ -2126,7 +2124,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", [&]()
|
||||
@ -2148,8 +2146,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
|
||||
@ -445,6 +445,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;
|
||||
|
158
rpcs3/Emu/SysCalls/CB_FUNC.h
Normal file
158
rpcs3/Emu/SysCalls/CB_FUNC.h
Normal file
@ -0,0 +1,158 @@
|
||||
#pragma once
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
|
||||
namespace cb_detail
|
||||
{
|
||||
enum _func_arg_type
|
||||
{
|
||||
ARG_GENERAL,
|
||||
ARG_FLOAT,
|
||||
ARG_VECTOR,
|
||||
ARG_STACK,
|
||||
};
|
||||
|
||||
template<typename T, _func_arg_type type, int g_count, int f_count, int v_count>
|
||||
struct _func_arg;
|
||||
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct _func_arg<T, ARG_GENERAL, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_GENERAL");
|
||||
|
||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
||||
{
|
||||
(T&)CPU.GPR[g_count + 2] = arg;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct _func_arg<T, ARG_FLOAT, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_FLOAT");
|
||||
|
||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
||||
{
|
||||
CPU.FPR[f_count] = arg;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct _func_arg<T, ARG_VECTOR, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(std::is_same<T, u128>::value, "Invalid callback argument type for ARG_VECTOR");
|
||||
|
||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
||||
{
|
||||
(T&)CPU.VPR[v_count + 1] = arg;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct _func_arg<T, ARG_STACK, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(g_count <= 8, "TODO: Unsupported stack argument type (general)");
|
||||
static_assert(f_count <= 12, "TODO: Unsupported stack argument type (float)");
|
||||
static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)");
|
||||
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_STACK");
|
||||
|
||||
__forceinline static void set_value(PPUThread& CPU, const T arg)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
};
|
||||
|
||||
template<int g_count, int f_count, int v_count>
|
||||
__forceinline static void _bind_func_args(PPUThread& CPU)
|
||||
{
|
||||
// terminator
|
||||
}
|
||||
|
||||
template<int g_count, int f_count, int v_count, typename T1, typename... T>
|
||||
__forceinline static void _bind_func_args(PPUThread& CPU, T1 arg1, T... args)
|
||||
{
|
||||
static_assert(!std::is_pointer<T1>::value, "Invalid callback argument type (pointer)");
|
||||
static_assert(!std::is_reference<T1>::value, "Invalid callback argument type (reference)");
|
||||
const bool is_float = std::is_floating_point<T1>::value;
|
||||
const bool is_vector = std::is_same<T1, u128>::value;
|
||||
const _func_arg_type t = is_float
|
||||
? ((f_count >= 12) ? ARG_STACK : ARG_FLOAT)
|
||||
: (is_vector ? ((v_count >= 12) ? ARG_STACK : ARG_VECTOR) : ((g_count >= 8) ? ARG_STACK : ARG_GENERAL));
|
||||
const int g = g_count + (is_float || is_vector ? 0 : 1);
|
||||
const int f = f_count + (is_float ? 1 : 0);
|
||||
const int v = v_count + (is_vector ? 1 : 0);
|
||||
|
||||
_func_arg<T1, t, g, f, v>::set_value(CPU, arg1);
|
||||
_bind_func_args<g, f, v>(CPU, args...);
|
||||
}
|
||||
|
||||
template<typename RT>
|
||||
struct _func_res
|
||||
{
|
||||
static_assert(sizeof(RT) <= 8, "Invalid callback result type");
|
||||
static_assert(!std::is_pointer<RT>::value, "Invalid callback result type (pointer)");
|
||||
static_assert(!std::is_reference<RT>::value, "Invalid callback result type (reference)");
|
||||
|
||||
__forceinline static RT get_value(const PPUThread& CPU)
|
||||
{
|
||||
if (std::is_floating_point<RT>::value)
|
||||
{
|
||||
return (RT)CPU.FPR[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return (RT&)CPU.GPR[3];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct _func_res<u128>
|
||||
{
|
||||
__forceinline static u128 get_value(const PPUThread& CPU)
|
||||
{
|
||||
return CPU.VPR[2];
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct _func_res<void>
|
||||
{
|
||||
__forceinline static void get_value(const PPUThread& CPU)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RT, typename... T>
|
||||
struct _func_caller
|
||||
{
|
||||
__forceinline static RT call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
|
||||
{
|
||||
_bind_func_args<0, 0, 0>(CPU, args...);
|
||||
CPU.FastCall2(pc, rtoc);
|
||||
return _func_res<RT>::get_value(CPU);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace vm
|
||||
{
|
||||
template<typename AT, typename RT, typename... T>
|
||||
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::call(PPUThread& CPU, T... args) const
|
||||
{
|
||||
const u32 pc = vm::get_ref<be_t<u32>>(m_addr);
|
||||
const u32 rtoc = vm::get_ref<be_t<u32>>(m_addr + 4);
|
||||
|
||||
return cb_detail::_func_caller<RT, T...>::call(CPU, pc, rtoc, args...);
|
||||
}
|
||||
|
||||
template<typename AT, typename RT, typename... T>
|
||||
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::operator ()(T... args) const
|
||||
{
|
||||
return call(GetCurrentPPUThread(), args...);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RT, typename... T>
|
||||
struct cb_caller : public cb_detail::_func_caller<RT, T...>
|
||||
{
|
||||
};
|
@ -1,152 +1,98 @@
|
||||
#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 = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
m_cb_thread->SetName("Callback Thread");
|
||||
m_cb_thread->SetEntry(0);
|
||||
m_cb_thread->SetPrio(1001);
|
||||
m_cb_thread->SetStackSize(0x10000);
|
||||
m_cb_thread->InitStack();
|
||||
m_cb_thread->InitRegs();
|
||||
m_cb_thread->DoRun();
|
||||
|
||||
thr.SetArg(0, a1);
|
||||
thr.SetArg(1, a2);
|
||||
thr.SetArg(2, a3);
|
||||
thr.SetArg(3, a4);
|
||||
thr.Run();
|
||||
((PPUThread&)thr).GPR[7] = a5;
|
||||
|
||||
thr.Exec();
|
||||
|
||||
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,21 @@
|
||||
#pragma once
|
||||
#include "CB_FUNC.h"
|
||||
|
||||
class Callback
|
||||
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;
|
||||
PPUThread* 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();
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ bool LogBase::CheckLogging() const
|
||||
return Ini.HLELogging.GetValue();
|
||||
}
|
||||
|
||||
void LogBase::LogOutput(LogType type, const char* info, const std::string& text)
|
||||
void LogBase::LogOutput(LogType type, const char* info, const std::string& text) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -20,7 +20,7 @@ void LogBase::LogOutput(LogType type, const char* info, const std::string& text)
|
||||
}
|
||||
}
|
||||
|
||||
void LogBase::LogOutput(LogType type, const u32 id, const char* info, const std::string& text)
|
||||
void LogBase::LogOutput(LogType type, const u32 id, const char* info, const std::string& text) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@ -29,4 +29,54 @@ void LogBase::LogOutput(LogType type, const u32 id, const char* info, const std:
|
||||
case LogWarning: LOG_WARNING(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break;
|
||||
case LogError: LOG_ERROR(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hle::error::error(s32 errorCode, const char* errorText)
|
||||
: code(errorCode)
|
||||
, base(nullptr)
|
||||
, text(errorText ? errorText : "")
|
||||
{
|
||||
}
|
||||
|
||||
hle::error::error(s32 errorCode, const LogBase& errorBase, const char* errorText)
|
||||
: code(errorCode)
|
||||
, base(&errorBase)
|
||||
, text(errorText ? errorText : "")
|
||||
{
|
||||
}
|
||||
|
||||
hle::error::error(s32 errorCode, const LogBase* errorBase, const char* errorText)
|
||||
: code(errorCode)
|
||||
, base(errorBase)
|
||||
, text(errorText ? errorText : "")
|
||||
{
|
||||
}
|
||||
|
||||
void hle::error::print(const char* func)
|
||||
{
|
||||
if (!text.empty())
|
||||
{
|
||||
if (base)
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
base->Error("%s(): %s (0x%X)", func, text.c_str(), code);
|
||||
}
|
||||
else
|
||||
{
|
||||
base->Error("%s (0x%X)", text.c_str(), code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
LOG_ERROR(HLE, "%s(): %s (0x%X)", func, text.c_str(), code);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(HLE, "%s (0x%X)", text.c_str(), code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ class LogBase
|
||||
LogError,
|
||||
};
|
||||
|
||||
void LogOutput(LogType type, const char* info, const std::string& text);
|
||||
void LogOutput(LogType type, const u32 id, const char* info, const std::string& text);
|
||||
void LogOutput(LogType type, const char* info, const std::string& text) const;
|
||||
void LogOutput(LogType type, const u32 id, const char* info, const std::string& text) const;
|
||||
|
||||
public:
|
||||
void SetLogging(bool value)
|
||||
@ -29,17 +29,17 @@ public:
|
||||
|
||||
virtual const std::string& GetName() const = 0;
|
||||
|
||||
template<typename... Targs> void Notice(const u32 id, const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Notice(const u32 id, const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogNotice, id, ": ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Notice(const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Notice(const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogNotice, ": ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> __forceinline void Log(const char* fmt, Targs... args)
|
||||
template<typename... Targs> __forceinline void Log(const char* fmt, Targs... args) const
|
||||
{
|
||||
if (CheckLogging())
|
||||
{
|
||||
@ -47,7 +47,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Targs> __forceinline void Log(const u32 id, const char* fmt, Targs... args)
|
||||
template<typename... Targs> __forceinline void Log(const u32 id, const char* fmt, Targs... args) const
|
||||
{
|
||||
if (CheckLogging())
|
||||
{
|
||||
@ -55,43 +55,59 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Targs> void Success(const u32 id, const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Success(const u32 id, const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogSuccess, id, ": ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Success(const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Success(const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogSuccess, ": ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Warning(const u32 id, const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Warning(const u32 id, const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogWarning, id, " warning: ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Warning(const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Warning(const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogWarning, " warning: ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Error(const u32 id, const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Error(const u32 id, const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogError, id, " error: ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Error(const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Error(const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogError, " error: ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Todo(const u32 id, const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Todo(const u32 id, const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogError, id, " TODO: ", fmt::Format(fmt, args...));
|
||||
}
|
||||
|
||||
template<typename... Targs> void Todo(const char* fmt, Targs... args)
|
||||
template<typename... Targs> void Todo(const char* fmt, Targs... args) const
|
||||
{
|
||||
LogOutput(LogError, " TODO: ", fmt::Format(fmt, args...));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
namespace hle
|
||||
{
|
||||
struct error
|
||||
{
|
||||
const s32 code;
|
||||
const LogBase* const base;
|
||||
const std::string text;
|
||||
|
||||
error(s32 errorCode, const char* errorText = nullptr);
|
||||
error(s32 errorCode, const LogBase& base, const char* errorText = nullptr);
|
||||
error(s32 errorCode, const LogBase* base, const char* errorText = nullptr);
|
||||
|
||||
void print(const char* func = nullptr);
|
||||
};
|
||||
}
|
||||
|
@ -62,6 +62,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;
|
||||
@ -274,7 +275,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"
|
||||
|
||||
extern std::mutex g_mutex_avcodec_open2;
|
||||
|
||||
@ -20,7 +21,7 @@ extern "C"
|
||||
//Module cellAdec(0x0006, cellAdec_init);
|
||||
Module *cellAdec = nullptr;
|
||||
|
||||
AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg)
|
||||
AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg)
|
||||
: type(type)
|
||||
, memAddr(addr)
|
||||
, memSize(size)
|
||||
@ -122,7 +123,7 @@ next:
|
||||
buf_size -= adec.reader.size;
|
||||
res += adec.reader.size;
|
||||
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, adec.task.au.auInfo_addr, adec.cbArg);
|
||||
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, adec.task.au.auInfo_addr, adec.cbArg);
|
||||
|
||||
adec.job.Pop(adec.task);
|
||||
|
||||
@ -244,13 +245,18 @@ u32 adecOpen(AudioDecoder* data)
|
||||
{
|
||||
AudioDecoder& adec = *data;
|
||||
|
||||
adec.adecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
u32 adec_id = cellAdec->GetNewId(data);
|
||||
|
||||
adec.id = adec_id;
|
||||
|
||||
adec.adecCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
adec.adecCb->SetName("Audio Decoder[" + std::to_string(adec_id) + "] Callback");
|
||||
adec.adecCb->SetEntry(0);
|
||||
adec.adecCb->SetPrio(1001);
|
||||
adec.adecCb->SetStackSize(0x10000);
|
||||
adec.adecCb->InitStack();
|
||||
adec.adecCb->InitRegs();
|
||||
adec.adecCb->DoRun();
|
||||
|
||||
thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [&]()
|
||||
{
|
||||
@ -304,12 +310,7 @@ u32 adecOpen(AudioDecoder* data)
|
||||
{
|
||||
// TODO: finalize
|
||||
cellAdec->Warning("adecEndSeq:");
|
||||
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
|
||||
cb.Branch(true); // ???*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
|
||||
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
|
||||
|
||||
adec.is_running = false;
|
||||
adec.just_finished = true;
|
||||
@ -446,7 +447,7 @@ u32 adecOpen(AudioDecoder* data)
|
||||
frame.data = nullptr;
|
||||
adec.frames.Push(frame);
|
||||
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
|
||||
break;
|
||||
}*/
|
||||
@ -538,19 +539,11 @@ u32 adecOpen(AudioDecoder* data)
|
||||
adec.frames.Push(frame);
|
||||
frame.data = nullptr; // to prevent destruction
|
||||
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
cb.Branch(false);*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
}
|
||||
}
|
||||
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
|
||||
cb.Branch(false);*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
|
||||
|
||||
adec.cbFunc.call(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -621,7 +614,7 @@ int cellAdecOpen(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResource> res, vm::
|
||||
|
||||
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
|
||||
|
||||
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg));
|
||||
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, vm::ptr<CellAdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -633,7 +626,7 @@ int cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res,
|
||||
|
||||
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
|
||||
|
||||
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg));
|
||||
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, vm::ptr<CellAdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -360,11 +360,11 @@ enum CellAdecMsgType
|
||||
CELL_ADEC_MSG_TYPE_SEQDONE,
|
||||
};
|
||||
|
||||
typedef s32(*CellAdecCbMsg)(u32 handle, CellAdecMsgType msgType, int msgData, u32 cbArg);
|
||||
typedef s32(*CellAdecCbMsg)(u32 handle, CellAdecMsgType msgType, s32 msgData, u32 cbArg);
|
||||
|
||||
struct CellAdecCb
|
||||
{
|
||||
be_t<u32> cbFunc;
|
||||
vm::bptr<CellAdecCbMsg> cbFunc;
|
||||
be_t<u32> cbArg;
|
||||
};
|
||||
|
||||
@ -1108,16 +1108,16 @@ public:
|
||||
const AudioCodecType type;
|
||||
const u32 memAddr;
|
||||
const u32 memSize;
|
||||
const u32 cbFunc;
|
||||
const vm::ptr<CellAdecCbMsg> cbFunc;
|
||||
const u32 cbArg;
|
||||
u32 memBias;
|
||||
|
||||
AdecTask task;
|
||||
u64 last_pts, first_pts;
|
||||
|
||||
CPUThread* adecCb;
|
||||
PPUThread* adecCb;
|
||||
|
||||
AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg);
|
||||
AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg);
|
||||
|
||||
~AudioDecoder();
|
||||
};
|
||||
|
@ -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/CPU/CPUThreadManager.h"
|
||||
#include "cellPamf.h"
|
||||
@ -292,13 +293,18 @@ u32 dmuxOpen(Demuxer* data)
|
||||
{
|
||||
Demuxer& dmux = *data;
|
||||
|
||||
dmux.dmuxCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
u32 dmux_id = cellDmux->GetNewId(data);
|
||||
|
||||
dmux.id = dmux_id;
|
||||
|
||||
dmux.dmuxCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
dmux.dmuxCb->SetName("Demuxer[" + std::to_string(dmux_id) + "] Callback");
|
||||
dmux.dmuxCb->SetEntry(0);
|
||||
dmux.dmuxCb->SetPrio(1001);
|
||||
dmux.dmuxCb->SetStackSize(0x10000);
|
||||
dmux.dmuxCb->InitStack();
|
||||
dmux.dmuxCb->InitRegs();
|
||||
dmux.dmuxCb->DoRun();
|
||||
|
||||
thread t("Demuxer[" + std::to_string(dmux_id) + "] Thread", [&]()
|
||||
{
|
||||
@ -340,11 +346,8 @@ u32 dmuxOpen(Demuxer* data)
|
||||
auto dmuxMsg = vm::ptr<CellDmuxMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
|
||||
dmuxMsg->supplementalInfo = stream.userdata;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(dmux.cbFunc);
|
||||
cb.Handle(dmux.id, dmuxMsg.addr(), dmux.cbArg);
|
||||
cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
|
||||
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, true, dmux.id, dmuxMsg.addr(), dmux.cbArg);
|
||||
dmux.cbFunc.call(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg);
|
||||
|
||||
updates_signaled++;
|
||||
}
|
||||
else switch (code.ToLE())
|
||||
@ -424,11 +427,7 @@ u32 dmuxOpen(Demuxer* data)
|
||||
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -477,11 +476,7 @@ u32 dmuxOpen(Demuxer* data)
|
||||
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
|
||||
}
|
||||
|
||||
if (pes.new_au)
|
||||
@ -589,12 +584,7 @@ u32 dmuxOpen(Demuxer* data)
|
||||
auto dmuxMsg = vm::ptr<CellDmuxMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
|
||||
dmuxMsg->supplementalInfo = stream.userdata;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(dmux.cbFunc);
|
||||
cb.Handle(dmux.id, dmuxMsg.addr(), dmux.cbArg);
|
||||
cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
|
||||
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone,
|
||||
dmux.id, dmuxMsg.addr(), dmux.cbArg);
|
||||
dmux.cbFunc.call(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg);
|
||||
|
||||
updates_signaled++;
|
||||
dmux.is_running = false;
|
||||
@ -675,22 +665,14 @@ u32 dmuxOpen(Demuxer* data)
|
||||
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
|
||||
}
|
||||
|
||||
// callback
|
||||
auto esMsg = vm::ptr<CellDmuxEsMsg>::make(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.addr(), es.cbArg);
|
||||
es.cbFunc.call(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -752,7 +734,7 @@ int cellDmuxOpen(vm::ptr<const CellDmuxType> demuxerType, vm::ptr<const CellDmux
|
||||
|
||||
// TODO: check demuxerResource and demuxerCb arguments
|
||||
|
||||
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource->memAddr, demuxerResource->memSize, demuxerCb->cbMsgFunc, demuxerCb->cbArg_addr));
|
||||
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource->memAddr, demuxerResource->memSize, vm::ptr<CellDmuxCbMsg>::make(demuxerCb->cbMsgFunc.addr()), demuxerCb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -770,7 +752,7 @@ int cellDmuxOpenEx(vm::ptr<const CellDmuxType> demuxerType, vm::ptr<const CellDm
|
||||
|
||||
// TODO: check demuxerResourceEx and demuxerCb arguments
|
||||
|
||||
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResourceEx->memAddr, demuxerResourceEx->memSize, demuxerCb->cbMsgFunc, demuxerCb->cbArg_addr));
|
||||
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResourceEx->memAddr, demuxerResourceEx->memSize, vm::ptr<CellDmuxCbMsg>::make(demuxerCb->cbMsgFunc.addr()), demuxerCb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -788,7 +770,7 @@ int cellDmuxOpen2(vm::ptr<const CellDmuxType2> demuxerType2, vm::ptr<const CellD
|
||||
|
||||
// TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments
|
||||
|
||||
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource2->memAddr, demuxerResource2->memSize, demuxerCb->cbMsgFunc, demuxerCb->cbArg_addr));
|
||||
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource2->memAddr, demuxerResource2->memSize, vm::ptr<CellDmuxCbMsg>::make(demuxerCb->cbMsgFunc.addr()), demuxerCb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -959,7 +941,7 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr<const CellCodecEsFilterId> esFil
|
||||
|
||||
ElementaryStream* es = new ElementaryStream(dmux, esResourceInfo->memAddr, esResourceInfo->memSize,
|
||||
esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2,
|
||||
esCb->cbEsMsgFunc, esCb->cbArg_addr, esSpecificInfo_addr);
|
||||
vm::ptr<CellDmuxCbEsMsg>::make(esCb->cbEsMsgFunc.addr()), esCb->cbArg, esSpecificInfo_addr);
|
||||
|
||||
u32 id = cellDmux->GetNewId(es);
|
||||
es->id = id;
|
||||
|
@ -222,22 +222,20 @@ struct CellDmuxResource2
|
||||
be_t<u32> shit[4];
|
||||
};
|
||||
|
||||
typedef u32(*CellDmuxCbMsg)(u32 demuxerHandle, vm::ptr<CellDmuxMsg> demuxerMsg, u32 cbArg_addr);
|
||||
typedef u32(*CellDmuxCbMsg)(u32 demuxerHandle, vm::ptr<CellDmuxMsg> demuxerMsg, u32 cbArg);
|
||||
|
||||
struct CellDmuxCb
|
||||
{
|
||||
// CellDmuxCbMsg callback
|
||||
be_t<u32> cbMsgFunc;
|
||||
be_t<u32> cbArg_addr;
|
||||
vm::bptr<CellDmuxCbMsg> cbMsgFunc;
|
||||
be_t<u32> cbArg;
|
||||
};
|
||||
|
||||
typedef u32(*CellDmuxCbEsMsg)(u32 demuxerHandle, u32 esHandle, vm::ptr<CellDmuxEsMsg> esMsg, u32 cbArg_addr);
|
||||
typedef u32(*CellDmuxCbEsMsg)(u32 demuxerHandle, u32 esHandle, vm::ptr<CellDmuxEsMsg> esMsg, u32 cbArg);
|
||||
|
||||
struct CellDmuxEsCb
|
||||
{
|
||||
// CellDmuxCbEsMsg callback
|
||||
be_t<u32> cbEsMsgFunc;
|
||||
be_t<u32> cbArg_addr;
|
||||
vm::bptr<CellDmuxCbEsMsg> cbEsMsgFunc;
|
||||
be_t<u32> cbArg;
|
||||
};
|
||||
|
||||
struct CellDmuxAttr
|
||||
@ -413,15 +411,15 @@ public:
|
||||
SQueue<u32, 16> fbSetStream;
|
||||
const u32 memAddr;
|
||||
const u32 memSize;
|
||||
const u32 cbFunc;
|
||||
const vm::ptr<CellDmuxCbMsg> cbFunc;
|
||||
const u32 cbArg;
|
||||
u32 id;
|
||||
volatile bool is_finished;
|
||||
volatile bool is_running;
|
||||
|
||||
CPUThread* dmuxCb;
|
||||
PPUThread* dmuxCb;
|
||||
|
||||
Demuxer(u32 addr, u32 size, u32 func, u32 arg)
|
||||
Demuxer(u32 addr, u32 size, vm::ptr<CellDmuxCbMsg> func, u32 arg)
|
||||
: is_finished(false)
|
||||
, is_running(false)
|
||||
, memAddr(addr)
|
||||
@ -458,11 +456,11 @@ public:
|
||||
const u32 fidMinor;
|
||||
const u32 sup1;
|
||||
const u32 sup2;
|
||||
const u32 cbFunc;
|
||||
const vm::ptr<CellDmuxCbEsMsg> cbFunc;
|
||||
const u32 cbArg;
|
||||
const u32 spec; //addr
|
||||
|
||||
ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, u32 cbFunc, u32 cbArg, u32 spec)
|
||||
ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr<CellDmuxCbEsMsg> cbFunc, u32 cbArg, u32 spec)
|
||||
: dmux(dmux)
|
||||
, memAddr(a128(addr))
|
||||
, memSize(size - (addr - memAddr))
|
||||
|
@ -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,21 +133,20 @@ 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([&m_signal]()
|
||||
CallAfter([]()
|
||||
{
|
||||
MsgDialogDestroy();
|
||||
|
||||
m_signal = false;
|
||||
g_msg_dialog_state = msgDialogNone;
|
||||
});
|
||||
|
||||
while (m_signal)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
g_msg_dialog_state = msgDialogNone;
|
||||
});
|
||||
t.detach();
|
||||
|
||||
|
@ -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();
|
||||
@ -80,7 +81,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;
|
||||
}
|
||||
|
||||
@ -95,7 +96,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;
|
||||
}
|
||||
|
||||
|
174
rpcs3/Emu/SysCalls/Modules/cellPng.h
Normal file
174
rpcs3/Emu/SysCalls/Modules/cellPng.h
Normal file
@ -0,0 +1,174 @@
|
||||
#pragma once
|
||||
|
||||
enum CellPngTxtType
|
||||
{
|
||||
CELL_PNG_TEXT = 0,
|
||||
CELL_PNG_ZTXT = 1,
|
||||
CELL_PNG_ITXT = 2,
|
||||
};
|
||||
|
||||
struct CellPngPLTEentry
|
||||
{
|
||||
u8 red;
|
||||
u8 green;
|
||||
u8 blue;
|
||||
};
|
||||
|
||||
struct CellPngPaletteEntries
|
||||
{
|
||||
be_t<u16> red;
|
||||
be_t<u16> green;
|
||||
be_t<u16> blue;
|
||||
be_t<u16> alpha;
|
||||
be_t<u16> frequency;
|
||||
};
|
||||
|
||||
struct CellPngSPLTentry
|
||||
{
|
||||
vm::bptr<char> paletteName;
|
||||
u8 sampleDepth;
|
||||
vm::bptr<CellPngPaletteEntries> paletteEntries;
|
||||
be_t<u32> paletteEntriesNumber;
|
||||
};
|
||||
|
||||
enum CellPngUnknownLocation
|
||||
{
|
||||
CELL_PNG_BEFORE_PLTE = 1,
|
||||
CELL_PNG_BEFORE_IDAT = 2,
|
||||
CELL_PNG_AFTER_IDAT = 8,
|
||||
};
|
||||
|
||||
struct CellPngTextInfo
|
||||
{
|
||||
be_t<CellPngTxtType> txtType;
|
||||
vm::bptr<char> keyword;
|
||||
vm::bptr<char> text;
|
||||
be_t<u32> textLength;
|
||||
vm::bptr<char> languageTag;
|
||||
vm::bptr<char> translatedKeyword;
|
||||
};
|
||||
|
||||
struct CellPngPLTE
|
||||
{
|
||||
be_t<u32> paletteEntriesNumber;
|
||||
vm::bptr<CellPngPLTEentry> paletteEntries;
|
||||
};
|
||||
|
||||
struct CellPngGAMA
|
||||
{
|
||||
be_t<double> gamma;
|
||||
};
|
||||
|
||||
struct CellPngSRGB
|
||||
{
|
||||
be_t<u32> renderingIntent;
|
||||
};
|
||||
|
||||
struct CellPngICCP
|
||||
{
|
||||
vm::bptr<char> profileName;
|
||||
vm::bptr<char> profile;
|
||||
be_t<u32> profileLength;
|
||||
};
|
||||
|
||||
struct CellPngSBIT
|
||||
{
|
||||
be_t<u32> red;
|
||||
be_t<u32> green;
|
||||
be_t<u32> blue;
|
||||
be_t<u32> gray;
|
||||
be_t<u32> alpha;
|
||||
};
|
||||
|
||||
struct CellPngTRNS
|
||||
{
|
||||
vm::bptr<char> alphaForPaletteIndex;
|
||||
be_t<u32> alphaForPaletteIndexNumber;
|
||||
be_t<u16> red;
|
||||
be_t<u16> green;
|
||||
be_t<u16> blue;
|
||||
be_t<u16> gray;
|
||||
};
|
||||
|
||||
struct CellPngHIST
|
||||
{
|
||||
vm::bptr<u16> histgramEntries;
|
||||
be_t<u32> histgramEntriesNumber;
|
||||
};
|
||||
|
||||
struct CellPngTIME
|
||||
{
|
||||
be_t<u16> year;
|
||||
u8 month;
|
||||
u8 day;
|
||||
u8 hour;
|
||||
u8 minute;
|
||||
u8 second;
|
||||
};
|
||||
|
||||
struct CellPngBKGD
|
||||
{
|
||||
u8 paletteIndex;
|
||||
be_t<u32> red;
|
||||
be_t<u32> green;
|
||||
be_t<u32> blue;
|
||||
be_t<u32> gray;
|
||||
};
|
||||
|
||||
struct CellPngSPLT
|
||||
{
|
||||
vm::bptr<CellPngSPLTentry> sPLTentries;
|
||||
be_t<u32> sPLTentriesNumber;
|
||||
};
|
||||
|
||||
struct CellPngOFFS
|
||||
{
|
||||
be_t<s32> xPosition;
|
||||
be_t<s32> yPosition;
|
||||
be_t<u32> unitSpecifier;
|
||||
};
|
||||
|
||||
struct CellPngPHYS
|
||||
{
|
||||
be_t<u32> xAxis;
|
||||
be_t<u32> yAxis;
|
||||
be_t<u32> unitSpecifier;
|
||||
};
|
||||
|
||||
struct CellPngSCAL
|
||||
{
|
||||
be_t<u32> unitSpecifier;
|
||||
be_t<double> pixelWidth;
|
||||
be_t<double> pixelHeight;
|
||||
};
|
||||
|
||||
struct CellPngCHRM
|
||||
{
|
||||
be_t<double> whitePointX;
|
||||
be_t<double> whitePointY;
|
||||
be_t<double> redX;
|
||||
be_t<double> redY;
|
||||
be_t<double> greenX;
|
||||
be_t<double> greenY;
|
||||
be_t<double> blueX;
|
||||
be_t<double> blueY;
|
||||
};
|
||||
|
||||
struct CellPngPCAL
|
||||
{
|
||||
vm::bptr<char> calibrationName;
|
||||
be_t<s32> x0;
|
||||
be_t<s32> x1;
|
||||
be_t<u32> equationType;
|
||||
be_t<u32> numberOfParameters;
|
||||
vm::bptr<char> unitName;
|
||||
vm::bptr<char, 2> parameter;
|
||||
};
|
||||
|
||||
struct CellPngUnknownChunk
|
||||
{
|
||||
char chunkType[5];
|
||||
vm::bptr<char> chunkData;
|
||||
be_t<u32> length;
|
||||
be_t<CellPngUnknownLocation> location;
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
|
||||
#include "stblib/stb_image.h"
|
||||
@ -11,140 +12,147 @@
|
||||
//Module cellPngDec(0x0018, cellPngDec_init);
|
||||
Module *cellPngDec = nullptr;
|
||||
|
||||
static std::map<u32, CellPngDecMainHandle *> cellPngDecMap;
|
||||
#ifdef PRX_DEBUG
|
||||
#include "prx_libpngdec.h"
|
||||
u32 libpngdec;
|
||||
u32 libpngdec_rtoc;
|
||||
#endif
|
||||
|
||||
CellPngDecMainHandle *getCellPngDecCtx(u32 mainHandle) {
|
||||
if (cellPngDecMap.find(mainHandle) == cellPngDecMap.end())
|
||||
return nullptr;
|
||||
|
||||
return cellPngDecMap[mainHandle];
|
||||
}
|
||||
|
||||
int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||
s32 pngDecCreate(
|
||||
vm::ptr<u32> mainHandle,
|
||||
vm::ptr<const CellPngDecThreadInParam> param,
|
||||
vm::ptr<const CellPngDecExtThreadInParam> ext = {})
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecCreate(mainHandle=0x%x, threadInParam=0x%x, threadOutParam=0x%x)", mainHandle, threadInParam, threadOutParam);
|
||||
CellPngDecMainHandle *ctx = new CellPngDecMainHandle;
|
||||
if (cellPngDecMap.find(mainHandle) != cellPngDecMap.end()) {
|
||||
delete cellPngDecMap[mainHandle];
|
||||
cellPngDecMap.erase(mainHandle);
|
||||
}
|
||||
cellPngDecMap[mainHandle] = ctx;
|
||||
// alloc memory (should probably use param->cbCtrlMallocFunc)
|
||||
auto dec = CellPngDecMainHandle::make(Memory.Alloc(sizeof(PngDecoder), 128));
|
||||
|
||||
ctx->threadInParam = threadInParam;
|
||||
ctx->threadOutParam = threadOutParam;
|
||||
if (!dec)
|
||||
{
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
// initialize decoder
|
||||
dec->malloc = param->cbCtrlMallocFunc;
|
||||
dec->malloc_arg = param->cbCtrlMallocArg;
|
||||
dec->free = param->cbCtrlFreeFunc;
|
||||
dec->free_arg = param->cbCtrlFreeArg;
|
||||
|
||||
if (ext)
|
||||
{
|
||||
}
|
||||
|
||||
// use virtual memory address as a handle
|
||||
*mainHandle = dec.addr();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecDestroy(u32 mainHandle)
|
||||
s32 pngDecDestroy(CellPngDecMainHandle dec)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle);
|
||||
CellPngDecMainHandle *ctx = getCellPngDecCtx(mainHandle);
|
||||
if (!ctx) {
|
||||
cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x): bad handle", mainHandle);
|
||||
return -1;
|
||||
if (!Memory.Free(dec.addr()))
|
||||
{
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
delete ctx;
|
||||
cellPngDecMap.erase(mainHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecOpen(u32 mainHandle, vm::ptr<be_t<u32>> subHandle, vm::ptr<CellPngDecSrc> src, u32 openInfo)
|
||||
s32 pngDecOpen(
|
||||
CellPngDecMainHandle dec,
|
||||
vm::ptr<u32> subHandle,
|
||||
vm::ptr<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> openInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlStrm> cb = {},
|
||||
vm::ptr<const CellPngDecOpnParam> param = {})
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x)",
|
||||
mainHandle, subHandle.addr(), src.addr(), openInfo);
|
||||
// alloc memory (should probably use dec->malloc)
|
||||
auto stream = CellPngDecSubHandle::make(Memory.Alloc(sizeof(PngStream), 128));
|
||||
|
||||
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
||||
current_subHandle->fd = 0;
|
||||
current_subHandle->src = *src;
|
||||
if (!stream)
|
||||
{
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
// initialize stream
|
||||
stream->fd = 0;
|
||||
stream->src = *src;
|
||||
|
||||
switch(src->srcSelect.ToBE())
|
||||
switch (src->srcSelect.ToBE())
|
||||
{
|
||||
case se32(CELL_PNGDEC_BUFFER):
|
||||
current_subHandle->fileSize = src->streamSize.ToLE();
|
||||
stream->fileSize = src->streamSize.ToLE();
|
||||
break;
|
||||
|
||||
case se32(CELL_PNGDEC_FILE):
|
||||
// Get file descriptor
|
||||
vm::var<be_t<u32>> fd;
|
||||
int ret = cellFsOpen(vm::ptr<const char>::make(src->fileName.addr()), 0, fd, vm::ptr<be_t<u32>>::make(0), 0);
|
||||
current_subHandle->fd = fd->ToLE();
|
||||
if(ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE;
|
||||
stream->fd = fd->ToLE();
|
||||
if (ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE;
|
||||
|
||||
// Get size of file
|
||||
vm::var<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||
ret = cellFsFstat(current_subHandle->fd, sb);
|
||||
if(ret != CELL_OK) return ret;
|
||||
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||
ret = cellFsFstat(stream->fd, sb);
|
||||
if (ret != CELL_OK) return ret;
|
||||
stream->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||
break;
|
||||
}
|
||||
|
||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
||||
*subHandle = cellPngDec->GetNewId(current_subHandle);
|
||||
if (cb)
|
||||
{
|
||||
// TODO: callback
|
||||
}
|
||||
|
||||
if (param)
|
||||
{
|
||||
// TODO: param->selectChunk
|
||||
}
|
||||
|
||||
// use virtual memory address as a handle
|
||||
*subHandle = stream.addr();
|
||||
|
||||
// set memory info
|
||||
openInfo->initSpaceAllocated = 4096;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtOpen(u32 mainHandle, vm::ptr<be_t<u32>> subHandle, vm::ptr<CellPngDecSrc> src, u32 openInfo, vm::ptr<CellPngDecCbCtrlStrm> cbCtrlStrm, vm::ptr<CellPngDecOpnParam> opnParam)
|
||||
s32 pngDecClose(CellPngDecSubHandle stream)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x, cbCtrlStrm_addr=0x%x, opnParam=0x%x)",
|
||||
mainHandle, subHandle.addr(), src.addr(), openInfo, cbCtrlStrm.addr(), opnParam.addr());
|
||||
|
||||
cellPngDec->Warning("*** cbCtrlStrm->cbCtrlStrmFunc_addr=0x%x", cbCtrlStrm->cbCtrlStrmFunc.addr());
|
||||
|
||||
vm::var<CellPngDecStrmInfo> streamInfo;
|
||||
vm::var<CellPngDecStrmParam> streamParam;
|
||||
|
||||
int res = cellPngDecOpen(mainHandle, subHandle, src, openInfo);
|
||||
|
||||
if (!res) cbCtrlStrm->cbCtrlStrmFunc(streamInfo, streamParam, cbCtrlStrm->cbCtrlStrmArg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int cellPngDecClose(u32 mainHandle, u32 subHandle)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle);
|
||||
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec->CheckId(subHandle, subHandle_data))
|
||||
cellFsClose(stream->fd);
|
||||
if (!Memory.Free(stream.addr()))
|
||||
{
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
cellPngDec->RemoveId(subHandle);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellPngDecInfo> info)
|
||||
s32 pngReadHeader(
|
||||
CellPngDecSubHandle stream,
|
||||
vm::ptr<CellPngDecInfo> info,
|
||||
vm::ptr<CellPngDecExtInfo> extInfo = {})
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr());
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec->CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
CellPngDecInfo& current_info = stream->info;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
CellPngDecInfo& current_info = subHandle_data->info;
|
||||
if (stream->fileSize < 29)
|
||||
{
|
||||
return CELL_PNGDEC_ERROR_HEADER; // The file is smaller than the length of a PNG header
|
||||
}
|
||||
|
||||
//Check size of file
|
||||
if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header
|
||||
|
||||
//Write the header to buffer
|
||||
vm::var<u8[34]> buffer; // Alloc buffer for PNG header
|
||||
auto buffer_32 = buffer.To<be_t<u32>>();
|
||||
vm::var<be_t<u64>> pos, nread;
|
||||
|
||||
switch(subHandle_data->src.srcSelect.ToBE())
|
||||
switch (stream->src.srcSelect.ToBE())
|
||||
{
|
||||
case se32(CELL_PNGDEC_BUFFER):
|
||||
memmove(buffer.begin(), vm::get_ptr<void>(subHandle_data->src.streamPtr), buffer.size());
|
||||
memmove(buffer.begin(), stream->src.streamPtr.get_ptr(), buffer.size());
|
||||
break;
|
||||
case se32(CELL_PNGDEC_FILE):
|
||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||
cellFsRead(fd, vm::ptr<void>::make(buffer.addr()), buffer.size(), nread);
|
||||
cellFsLseek(stream->fd, 0, CELL_SEEK_SET, pos);
|
||||
cellFsRead(stream->fd, vm::ptr<void>::make(buffer.addr()), buffer.size(), nread);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -152,7 +160,7 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellPngDecInfo>
|
||||
buffer_32[1].ToBE() != se32(0x0D0A1A0A) || // Error: The first 8 bytes are not a valid PNG signature
|
||||
buffer_32[3].ToBE() != se32(0x49484452)) // Error: The PNG file does not start with an IHDR chunk
|
||||
{
|
||||
return CELL_PNGDEC_ERROR_HEADER;
|
||||
return CELL_PNGDEC_ERROR_HEADER;
|
||||
}
|
||||
|
||||
switch (buffer[25])
|
||||
@ -162,50 +170,90 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellPngDecInfo>
|
||||
case 3: current_info.colorSpace = CELL_PNGDEC_PALETTE; current_info.numComponents = 1; break;
|
||||
case 4: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE_ALPHA; current_info.numComponents = 2; break;
|
||||
case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break;
|
||||
default: return CELL_PNGDEC_ERROR_HEADER; // Not supported color type
|
||||
default:
|
||||
cellPngDec->Error("cellPngDecDecodeData: Unsupported color space (%d)", (u32)buffer[25]);
|
||||
return CELL_PNGDEC_ERROR_HEADER;
|
||||
}
|
||||
|
||||
current_info.imageWidth = buffer_32[4];
|
||||
current_info.imageHeight = buffer_32[5];
|
||||
current_info.bitDepth = buffer[24];
|
||||
current_info.interlaceMethod = buffer[28];
|
||||
current_info.imageWidth = buffer_32[4];
|
||||
current_info.imageHeight = buffer_32[5];
|
||||
current_info.bitDepth = buffer[24];
|
||||
current_info.interlaceMethod = (CellPngDecInterlaceMode)buffer[28];
|
||||
current_info.chunkInformation = 0; // Unimplemented
|
||||
|
||||
*info = current_info;
|
||||
|
||||
if (extInfo)
|
||||
{
|
||||
extInfo->reserved = 0;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellPngDecInfo> info, vm::ptr<CellPngDecExtInfo> extInfo)
|
||||
s32 pngDecSetParameter(
|
||||
CellPngDecSubHandle stream,
|
||||
vm::ptr<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> outParam,
|
||||
vm::ptr<const CellPngDecExtInParam> extInParam = {},
|
||||
vm::ptr<CellPngDecExtOutParam> extOutParam = {})
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)",
|
||||
mainHandle, subHandle, info.addr(), extInfo.addr());
|
||||
CellPngDecInfo& current_info = stream->info;
|
||||
CellPngDecOutParam& current_outParam = stream->outParam;
|
||||
|
||||
return cellPngDecReadHeader(mainHandle, subHandle, info);
|
||||
current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents * current_info.bitDepth) / 8;
|
||||
current_outParam.outputWidth = current_info.imageWidth;
|
||||
current_outParam.outputHeight = current_info.imageHeight;
|
||||
current_outParam.outputColorSpace = inParam->outputColorSpace;
|
||||
|
||||
switch ((u32)current_outParam.outputColorSpace)
|
||||
{
|
||||
case CELL_PNGDEC_PALETTE:
|
||||
case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; break;
|
||||
|
||||
case CELL_PNGDEC_GRAYSCALE_ALPHA: current_outParam.outputComponents = 2; break;
|
||||
|
||||
case CELL_PNGDEC_RGB: current_outParam.outputComponents = 3; break;
|
||||
|
||||
case CELL_PNGDEC_RGBA:
|
||||
case CELL_PNGDEC_ARGB: current_outParam.outputComponents = 4; break;
|
||||
|
||||
default:
|
||||
cellPngDec->Error("pngDecSetParameter: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE());
|
||||
return CELL_PNGDEC_ERROR_ARG;
|
||||
}
|
||||
|
||||
current_outParam.outputBitDepth = inParam->outputBitDepth;
|
||||
current_outParam.outputMode = inParam->outputMode;
|
||||
current_outParam.useMemorySpace = 0; // Unimplemented
|
||||
|
||||
*outParam = current_outParam;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam, vm::ptr<CellPngDecDataOutInfo> dataOutInfo)
|
||||
s32 pngDecodeData(
|
||||
CellPngDecSubHandle stream,
|
||||
vm::ptr<u8> data,
|
||||
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp = {},
|
||||
vm::ptr<CellPngDecDispParam> dispParam = {})
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)",
|
||||
mainHandle, subHandle, data.addr(), dataCtrlParam.addr(), dataOutInfo.addr());
|
||||
|
||||
dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP;
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec->CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
const CellPngDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
const u32& fd = stream->fd;
|
||||
const u64& fileSize = stream->fileSize;
|
||||
const CellPngDecOutParam& current_outParam = stream->outParam;
|
||||
|
||||
//Copy the PNG file to a buffer
|
||||
vm::var<unsigned char[]> png((u32)fileSize);
|
||||
vm::var<be_t<u64>> pos, nread;
|
||||
|
||||
switch(subHandle_data->src.srcSelect.ToBE())
|
||||
switch (stream->src.srcSelect.ToBE())
|
||||
{
|
||||
case se32(CELL_PNGDEC_BUFFER):
|
||||
memmove(png.begin(), vm::get_ptr<void>(subHandle_data->src.streamPtr), png.size());
|
||||
memmove(png.begin(), stream->src.streamPtr.get_ptr(), png.size());
|
||||
break;
|
||||
|
||||
case se32(CELL_PNGDEC_FILE):
|
||||
@ -216,18 +264,22 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
|
||||
//Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||
int width, height, actual_components;
|
||||
auto image = std::unique_ptr<unsigned char,decltype(&::free)>
|
||||
(
|
||||
stbi_load_from_memory(png.ptr(), (s32)fileSize, &width, &height, &actual_components, 4),
|
||||
&::free
|
||||
);
|
||||
if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT;
|
||||
auto image = std::unique_ptr<unsigned char, decltype(&::free)>
|
||||
(
|
||||
stbi_load_from_memory(png.ptr(), (s32)fileSize, &width, &height, &actual_components, 4),
|
||||
&::free
|
||||
);
|
||||
if (!image)
|
||||
{
|
||||
cellPngDec->Error("pngDecodeData: stbi_load_from_memory failed");
|
||||
return CELL_PNGDEC_ERROR_STREAM_FORMAT;
|
||||
}
|
||||
|
||||
const bool flip = current_outParam.outputMode == CELL_PNGDEC_BOTTOM_TO_TOP;
|
||||
const int bytesPerLine = (u32)dataCtrlParam->outputBytesPerLine;
|
||||
uint image_size = width * height;
|
||||
|
||||
switch((u32)current_outParam.outputColorSpace)
|
||||
switch ((u32)current_outParam.outputColorSpace)
|
||||
{
|
||||
case CELL_PNGDEC_RGB:
|
||||
case CELL_PNGDEC_RGBA:
|
||||
@ -249,7 +301,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
memcpy(data.get_ptr(), image.get(), image_size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case CELL_PNGDEC_ARGB:
|
||||
{
|
||||
@ -259,7 +311,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
{
|
||||
//TODO: find out if we can't do padding without an extra copy
|
||||
const int linesize = std::min(bytesPerLine, width * nComponents);
|
||||
char *output = (char *) malloc(linesize);
|
||||
char *output = (char *)malloc(linesize);
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
const int dstOffset = i * bytesPerLine;
|
||||
@ -280,7 +332,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
uint* img = (uint*)new char[image_size];
|
||||
uint* source_current = (uint*)&(image.get()[0]);
|
||||
uint* dest_current = img;
|
||||
for (uint i = 0; i < image_size / nComponents; i++)
|
||||
for (uint i = 0; i < image_size / nComponents; i++)
|
||||
{
|
||||
uint val = *source_current;
|
||||
*dest_current = (val >> 24) | (val << 8); // set alpha (A8) as leftmost byte
|
||||
@ -291,15 +343,16 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
delete[] img;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case CELL_PNGDEC_GRAYSCALE:
|
||||
case CELL_PNGDEC_PALETTE:
|
||||
case CELL_PNGDEC_GRAYSCALE_ALPHA:
|
||||
cellPngDec->Error("cellPngDecDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE());
|
||||
break;
|
||||
cellPngDec->Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE());
|
||||
break;
|
||||
|
||||
default:
|
||||
cellPngDec->Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE());
|
||||
return CELL_PNGDEC_ERROR_ARG;
|
||||
}
|
||||
|
||||
@ -308,98 +361,488 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::pt
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPngDecExtDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo, vm::ptr<CellPngDecCbCtrlDisp> cbCtrlDisp, vm::ptr<CellPngDecDispParam> dispParam)
|
||||
s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<CellPngDecThreadOutParam> threadOutParam)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam=0x%x)",
|
||||
mainHandle, subHandle, data.addr(), dataCtrlParam.addr(), dataOutInfo.addr(), cbCtrlDisp.addr(), dispParam.addr());
|
||||
#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)",
|
||||
mainHandle.addr(), threadInParam.addr(), threadOutParam.addr());
|
||||
|
||||
if (cbCtrlDisp) cellPngDec->Warning("*** cbCtrlDisp->cbCtrlDispFunc_addr=0x%x", (u32)cbCtrlDisp->cbCtrlDispFunc_addr);
|
||||
// create decoder
|
||||
if (s32 res = pngDecCreate(mainHandle, threadInParam)) return res;
|
||||
|
||||
return cellPngDecDecodeData(mainHandle, subHandle, data, dataCtrlParam, dataOutInfo);
|
||||
}
|
||||
|
||||
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellPngDecInParam> inParam, vm::ptr<CellPngDecOutParam> outParam)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)",
|
||||
mainHandle, subHandle, inParam.addr(), outParam.addr());
|
||||
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec->CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
CellPngDecInfo& current_info = subHandle_data->info;
|
||||
CellPngDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
|
||||
current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents * current_info.bitDepth) / 8;
|
||||
current_outParam.outputWidth = current_info.imageWidth;
|
||||
current_outParam.outputHeight = current_info.imageHeight;
|
||||
current_outParam.outputColorSpace = inParam->outputColorSpace;
|
||||
|
||||
switch ((u32)current_outParam.outputColorSpace)
|
||||
{
|
||||
case CELL_PNGDEC_PALETTE:
|
||||
case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; break;
|
||||
|
||||
case CELL_PNGDEC_GRAYSCALE_ALPHA: current_outParam.outputComponents = 2; break;
|
||||
|
||||
case CELL_PNGDEC_RGB: current_outParam.outputComponents = 3; break;
|
||||
|
||||
case CELL_PNGDEC_RGBA:
|
||||
case CELL_PNGDEC_ARGB: current_outParam.outputComponents = 4; break;
|
||||
|
||||
default: return CELL_PNGDEC_ERROR_ARG; // Not supported color space
|
||||
}
|
||||
|
||||
current_outParam.outputBitDepth = inParam->outputBitDepth;
|
||||
current_outParam.outputMode = inParam->outputMode;
|
||||
current_outParam.useMemorySpace = 0; // Unimplemented
|
||||
|
||||
*outParam = current_outParam;
|
||||
// set codec version
|
||||
threadOutParam->pngCodecVersion = PNGDEC_CODEC_VERSION;
|
||||
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cellPngDecExtSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellPngDecInParam> inParam, vm::ptr<CellPngDecOutParam> outParam,
|
||||
vm::ptr<CellPngDecExtInParam> extInParam, vm::ptr<CellPngDecExtOutParam> extOutParam)
|
||||
s32 cellPngDecExtCreate(
|
||||
vm::ptr<u32> mainHandle,
|
||||
vm::ptr<const CellPngDecThreadInParam> threadInParam,
|
||||
vm::ptr<CellPngDecThreadOutParam> threadOutParam,
|
||||
vm::ptr<const CellPngDecExtThreadInParam> extThreadInParam,
|
||||
vm::ptr<CellPngDecExtThreadOutParam> extThreadOutParam)
|
||||
{
|
||||
cellPngDec->Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x",
|
||||
mainHandle, subHandle, inParam.addr(), outParam.addr(), extInParam.addr(), extOutParam.addr());
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x296C, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x, extThreadInParam_addr=0x%x, extThreadOutParam_addr=0x%x)",
|
||||
mainHandle.addr(), threadInParam.addr(), threadOutParam.addr(), extThreadInParam.addr(), extThreadOutParam.addr());
|
||||
|
||||
return cellPngDecSetParameter(mainHandle, subHandle, inParam, outParam);
|
||||
// create decoder
|
||||
if (s32 res = pngDecCreate(mainHandle, threadInParam, extThreadInParam)) return res;
|
||||
|
||||
// set codec version
|
||||
threadOutParam->pngCodecVersion = PNGDEC_CODEC_VERSION;
|
||||
|
||||
extThreadOutParam->reserved = 0;
|
||||
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x1E6C, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle.addr());
|
||||
|
||||
// destroy decoder
|
||||
return pngDecDestroy(mainHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecOpen(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
vm::ptr<u32> subHandle,
|
||||
vm::ptr<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> openInfo)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F3C, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr());
|
||||
|
||||
// create stream handle
|
||||
return pngDecOpen(mainHandle, subHandle, src, openInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecExtOpen(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
vm::ptr<u32> subHandle,
|
||||
vm::ptr<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> openInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlStrm> cbCtrlStrm,
|
||||
vm::ptr<const CellPngDecOpnParam> opnParam)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F34, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x, cbCtrlStrm_addr=0x%x, opnParam_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr(), cbCtrlStrm.addr(), opnParam.addr());
|
||||
|
||||
// create stream handle
|
||||
return pngDecOpen(mainHandle, subHandle, src, openInfo, cbCtrlStrm, opnParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x066C, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle.addr(), subHandle.addr());
|
||||
|
||||
return pngDecClose(subHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngDecInfo> info)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A3C, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), info.addr());
|
||||
|
||||
return pngReadHeader(subHandle, info);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecExtReadHeader(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<CellPngDecInfo> info,
|
||||
vm::ptr<CellPngDecExtInfo> extInfo)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A34, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), info.addr(), extInfo.addr());
|
||||
|
||||
return pngReadHeader(subHandle, info, extInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecSetParameter(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> outParam)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x33F4, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr());
|
||||
|
||||
return pngDecSetParameter(subHandle, inParam, outParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecExtSetParameter(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> outParam,
|
||||
vm::ptr<const CellPngDecExtInParam> extInParam,
|
||||
vm::ptr<CellPngDecExtOutParam> extOutParam)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x33EC, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x",
|
||||
mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr(), extInParam.addr(), extOutParam.addr());
|
||||
|
||||
return pngDecSetParameter(subHandle, inParam, outParam, extInParam, extOutParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecDecodeData(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<u8> data,
|
||||
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D40, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr());
|
||||
|
||||
return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecExtDecodeData(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<u8> data,
|
||||
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp,
|
||||
vm::ptr<CellPngDecDispParam> dispParam)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D38, libpngdec_rtoc);
|
||||
#else
|
||||
cellPngDec->Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam_addr=0x%x)",
|
||||
mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr(), cbCtrlDisp.addr(), dispParam.addr());
|
||||
|
||||
return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo, cbCtrlDisp, dispParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetUnknownChunks(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<vm::bptr<CellPngUnknownChunk>> unknownChunk,
|
||||
vm::ptr<u32> unknownChunkNumber)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x03EC, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPCAL> pcal)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x0730, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngCHRM> chrm)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x0894, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSCAL> scal)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x09EC, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPHYS> phys)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x0B14, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngOFFS> offs)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x0C58, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSPLT> splt)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x0D9C, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngBKGD> bkgd)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x0ED0, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngTIME> time)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x1024, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngHIST> hist)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x116C, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngTRNS> trns)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x12A4, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSBIT> sbit)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x1420, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngICCP> iccp)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x1574, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSRGB> srgb)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x16B4, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngGAMA> gama)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x17CC, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPLTE> plte)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x18E4, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
s32 cellPngDecGetTextChunk(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<u32> textInfoNum,
|
||||
vm::ptr<vm::bptr<CellPngTextInfo>> textInfo)
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
cellPngDec->Warning("%s()", __FUNCTION__);
|
||||
return GetCurrentPPUThread().FastCall2(libpngdec + 0x19FC, libpngdec_rtoc);
|
||||
#else
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
return CELL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cellPngDec_init()
|
||||
{
|
||||
cellPngDec->AddFunc(0x157d30c5, cellPngDecCreate);
|
||||
cellPngDec->AddFunc(0x820dae1a, cellPngDecDestroy);
|
||||
cellPngDec->AddFunc(0xd2bc5bfd, cellPngDecOpen);
|
||||
cellPngDec->AddFunc(0x5b3d1ff1, cellPngDecClose);
|
||||
cellPngDec->AddFunc(0x9ccdcc95, cellPngDecReadHeader);
|
||||
cellPngDec->AddFunc(0x2310f155, cellPngDecDecodeData);
|
||||
cellPngDec->AddFunc(0xe97c9bd4, cellPngDecSetParameter);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetUnknownChunks);
|
||||
REG_FUNC(cellPngDec, cellPngDecClose);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetpCAL);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetcHRM);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetsCAL);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetpHYs);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetoFFs);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetsPLT);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetbKGD);
|
||||
REG_FUNC(cellPngDec, cellPngDecGettIME);
|
||||
REG_FUNC(cellPngDec, cellPngDecGethIST);
|
||||
REG_FUNC(cellPngDec, cellPngDecGettRNS);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetsBIT);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetiCCP);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetsRGB);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetgAMA);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetPLTE);
|
||||
REG_FUNC(cellPngDec, cellPngDecGetTextChunk);
|
||||
REG_FUNC(cellPngDec, cellPngDecDestroy);
|
||||
REG_FUNC(cellPngDec, cellPngDecCreate);
|
||||
REG_FUNC(cellPngDec, cellPngDecExtCreate);
|
||||
REG_FUNC(cellPngDec, cellPngDecExtSetParameter);
|
||||
REG_FUNC(cellPngDec, cellPngDecSetParameter);
|
||||
REG_FUNC(cellPngDec, cellPngDecExtReadHeader);
|
||||
REG_FUNC(cellPngDec, cellPngDecReadHeader);
|
||||
REG_FUNC(cellPngDec, cellPngDecExtOpen);
|
||||
REG_FUNC(cellPngDec, cellPngDecOpen);
|
||||
REG_FUNC(cellPngDec, cellPngDecExtDecodeData);
|
||||
REG_FUNC(cellPngDec, cellPngDecDecodeData);
|
||||
|
||||
cellPngDec->AddFunc(0x0c515302, cellPngDecExtOpen);
|
||||
cellPngDec->AddFunc(0x8b33f863, cellPngDecExtReadHeader);
|
||||
cellPngDec->AddFunc(0x726fc1d0, cellPngDecExtDecodeData);
|
||||
cellPngDec->AddFunc(0x9e9d7d42, cellPngDecExtSetParameter);
|
||||
#ifdef PRX_DEBUG
|
||||
CallAfter([]()
|
||||
{
|
||||
libpngdec = (u32)Memory.PRXMem.AllocAlign(sizeof(libpngdec_data), 4096);
|
||||
memcpy(vm::get_ptr<void>(libpngdec), libpngdec_data, sizeof(libpngdec_data));
|
||||
libpngdec_rtoc = libpngdec + 0x49710;
|
||||
|
||||
/*cellPngDec->AddFunc(0x48436b2d, cellPngDecExtCreate);
|
||||
cellPngDec->AddFunc(0x7585a275, cellPngDecGetbKGD);
|
||||
cellPngDec->AddFunc(0x7a062d26, cellPngDecGetcHRM);
|
||||
cellPngDec->AddFunc(0xb153629c, cellPngDecGetgAMA);
|
||||
cellPngDec->AddFunc(0xb905ebb7, cellPngDecGethIST);
|
||||
cellPngDec->AddFunc(0xf44b6c30, cellPngDecGetiCCP);
|
||||
cellPngDec->AddFunc(0x27c921b5, cellPngDecGetoFFs);
|
||||
cellPngDec->AddFunc(0xb4fe75e1, cellPngDecGetpCAL);
|
||||
cellPngDec->AddFunc(0x3d50016a, cellPngDecGetpHYs);
|
||||
cellPngDec->AddFunc(0x30cb334a, cellPngDecGetsBIT);
|
||||
cellPngDec->AddFunc(0xc41e1198, cellPngDecGetsCAL);
|
||||
cellPngDec->AddFunc(0xa5cdf57e, cellPngDecGetsPLT);
|
||||
cellPngDec->AddFunc(0xe4416e82, cellPngDecGetsRGB);
|
||||
cellPngDec->AddFunc(0x35a6846c, cellPngDecGettIME);
|
||||
cellPngDec->AddFunc(0xb96fb26e, cellPngDecGettRNS);
|
||||
cellPngDec->AddFunc(0xe163977f, cellPngDecGetPLTE);
|
||||
cellPngDec->AddFunc(0x609ec7d5, cellPngDecUnknownChunks);
|
||||
cellPngDec->AddFunc(0xb40ca175, cellPngDecGetTextChunk);*/
|
||||
extern Module* sysPrxForUser;
|
||||
extern Module* cellSpurs;
|
||||
extern Module* sys_fs;
|
||||
|
||||
FIX_IMPORT(sysPrxForUser, _sys_snprintf , libpngdec + 0x1E6D0);
|
||||
FIX_IMPORT(sysPrxForUser, _sys_strlen , libpngdec + 0x1E6F0);
|
||||
fix_import(sysPrxForUser, 0x3EF17F8C , libpngdec + 0x1E710);
|
||||
FIX_IMPORT(sysPrxForUser, _sys_memset , libpngdec + 0x1E730);
|
||||
FIX_IMPORT(sysPrxForUser, _sys_memcpy , libpngdec + 0x1E750);
|
||||
FIX_IMPORT(sysPrxForUser, _sys_strcpy , libpngdec + 0x1E770);
|
||||
FIX_IMPORT(sysPrxForUser, _sys_strncpy , libpngdec + 0x1E790);
|
||||
FIX_IMPORT(sysPrxForUser, _sys_memcmp , libpngdec + 0x1E7B0);
|
||||
FIX_IMPORT(cellSpurs, cellSpursQueueDetachLv2EventQueue , libpngdec + 0x1E7D0);
|
||||
FIX_IMPORT(cellSpurs, cellSpursAttributeSetNamePrefix , libpngdec + 0x1E7F0);
|
||||
FIX_IMPORT(cellSpurs, _cellSpursQueueInitialize , libpngdec + 0x1E810);
|
||||
FIX_IMPORT(cellSpurs, _cellSpursTasksetAttributeInitialize, libpngdec + 0x1E830);
|
||||
FIX_IMPORT(cellSpurs, cellSpursTasksetAttributeSetName , libpngdec + 0x1E850);
|
||||
FIX_IMPORT(cellSpurs, cellSpursTaskGetReadOnlyAreaPattern , libpngdec + 0x1E870);
|
||||
FIX_IMPORT(cellSpurs, cellSpursTaskGetContextSaveAreaSize , libpngdec + 0x1E890);
|
||||
FIX_IMPORT(cellSpurs, cellSpursQueuePopBody , libpngdec + 0x1E8B0);
|
||||
FIX_IMPORT(cellSpurs, cellSpursQueuePushBody , libpngdec + 0x1E8D0);
|
||||
FIX_IMPORT(cellSpurs, _cellSpursAttributeInitialize , libpngdec + 0x1E8F0);
|
||||
FIX_IMPORT(cellSpurs, cellSpursJoinTaskset , libpngdec + 0x1E910);
|
||||
FIX_IMPORT(cellSpurs, cellSpursShutdownTaskset , libpngdec + 0x1E930);
|
||||
FIX_IMPORT(cellSpurs, cellSpursInitializeWithAttribute , libpngdec + 0x1E950);
|
||||
FIX_IMPORT(cellSpurs, cellSpursCreateTask , libpngdec + 0x1E970);
|
||||
FIX_IMPORT(cellSpurs, cellSpursCreateTasksetWithAttribute , libpngdec + 0x1E990);
|
||||
FIX_IMPORT(cellSpurs, cellSpursFinalize , libpngdec + 0x1E9B0);
|
||||
FIX_IMPORT(cellSpurs, cellSpursQueueAttachLv2EventQueue , libpngdec + 0x1E9D0);
|
||||
FIX_IMPORT(sys_fs, cellFsClose , libpngdec + 0x1E9F0);
|
||||
FIX_IMPORT(sys_fs, cellFsRead , libpngdec + 0x1EA10);
|
||||
FIX_IMPORT(sys_fs, cellFsOpen , libpngdec + 0x1EA30);
|
||||
FIX_IMPORT(sys_fs, cellFsLseek , libpngdec + 0x1EA50);
|
||||
|
||||
fix_relocs(cellPngDec, libpngdec, 0x41C30, 0x47AB0, 0x40A00);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
@ -1,6 +1,18 @@
|
||||
#pragma once
|
||||
#include "cellPng.h"
|
||||
|
||||
//Return Codes
|
||||
enum : u32
|
||||
{
|
||||
PNGDEC_CODEC_VERSION = 0x00420000,
|
||||
};
|
||||
|
||||
struct PngDecoder;
|
||||
struct PngStream;
|
||||
|
||||
typedef vm::ptr<PngDecoder> CellPngDecMainHandle;
|
||||
typedef vm::ptr<PngStream> CellPngDecSubHandle;
|
||||
|
||||
// Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_PNGDEC_ERROR_HEADER = 0x80611201,
|
||||
@ -15,7 +27,8 @@ enum
|
||||
CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a,
|
||||
};
|
||||
|
||||
enum CellPngDecColorSpace
|
||||
// Consts
|
||||
enum CellPngDecColorSpace : u32
|
||||
{
|
||||
CELL_PNGDEC_GRAYSCALE = 1,
|
||||
CELL_PNGDEC_RGB = 2,
|
||||
@ -25,43 +38,101 @@ enum CellPngDecColorSpace
|
||||
CELL_PNGDEC_ARGB = 20,
|
||||
};
|
||||
|
||||
enum CellPngDecDecodeStatus
|
||||
enum CellPngDecSpuThreadEna : u32
|
||||
{
|
||||
CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
CELL_PNGDEC_SPU_THREAD_DISABLE = 0,
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
// Structs
|
||||
struct CellPngDecDataOutInfo
|
||||
enum CellPngDecPackFlag : u32
|
||||
{
|
||||
be_t<u32> chunkInformation;
|
||||
be_t<u32> numText;
|
||||
be_t<u32> numUnknownChunk;
|
||||
be_t<u32> status;
|
||||
CELL_PNGDEC_1BYTE_PER_NPIXEL = 0,
|
||||
CELL_PNGDEC_1BYTE_PER_1PIXEL = 1,
|
||||
};
|
||||
|
||||
struct CellPngDecDataCtrlParam
|
||||
enum CellPngDecAlphaSelect : u32
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
CELL_PNGDEC_STREAM_ALPHA = 0,
|
||||
CELL_PNGDEC_FIX_ALPHA = 1,
|
||||
};
|
||||
|
||||
enum CellPngDecCommand : u32
|
||||
{
|
||||
CELL_PNGDEC_CONTINUE = 0,
|
||||
CELL_PNGDEC_STOP = 1,
|
||||
};
|
||||
|
||||
enum CellPngDecDecodeStatus : u32
|
||||
{
|
||||
CELL_PNGDEC_DEC_STATUS_FINISH = 0,
|
||||
CELL_PNGDEC_DEC_STATUS_STOP = 1,
|
||||
};
|
||||
|
||||
// Callbacks
|
||||
typedef vm::ptr<void>(*CellPngDecCbControlMalloc)(u32 size, vm::ptr<void> cbCtrlMallocArg);
|
||||
typedef s32(*CellPngDecCbControlFree)(vm::ptr<void> ptr, vm::ptr<void> cbCtrlFreeArg);
|
||||
|
||||
// Structs
|
||||
struct CellPngDecThreadInParam
|
||||
{
|
||||
be_t<CellPngDecSpuThreadEna> spuThreadEnable;
|
||||
be_t<u32> ppuThreadPriority;
|
||||
be_t<u32> spuThreadPriority;
|
||||
vm::bptr<CellPngDecCbControlMalloc> cbCtrlMallocFunc;
|
||||
vm::bptr<void> cbCtrlMallocArg;
|
||||
vm::bptr<CellPngDecCbControlFree> cbCtrlFreeFunc;
|
||||
vm::bptr<void> cbCtrlFreeArg;
|
||||
};
|
||||
|
||||
struct CellPngDecExtThreadInParam
|
||||
{
|
||||
be_t<u32> spurs_addr; // it could be vm::bptr<CellSpurs>, but nobody will use SPURS in HLE implementation
|
||||
u8 priority[8];
|
||||
be_t<u32> maxContention;
|
||||
};
|
||||
|
||||
struct CellPngDecThreadOutParam
|
||||
{
|
||||
be_t<u32> pngCodecVersion;
|
||||
};
|
||||
|
||||
struct CellPngDecExtThreadOutParam
|
||||
{
|
||||
be_t<u32> reserved;
|
||||
};
|
||||
|
||||
struct CellPngDecSrc
|
||||
{
|
||||
be_t<CellPngDecStreamSrcSel> srcSelect;
|
||||
vm::bptr<const char> fileName;
|
||||
be_t<s64> fileOffset;
|
||||
be_t<u32> fileSize;
|
||||
vm::bptr<void> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<CellPngDecSpuThreadEna> spuThreadEnable;
|
||||
};
|
||||
|
||||
struct CellPngDecOpnInfo
|
||||
{
|
||||
be_t<u32> initSpaceAllocated;
|
||||
};
|
||||
|
||||
struct CellPngDecInfo
|
||||
@ -69,31 +140,20 @@ struct CellPngDecInfo
|
||||
be_t<u32> imageWidth;
|
||||
be_t<u32> imageHeight;
|
||||
be_t<u32> numComponents;
|
||||
be_t<u32> colorSpace; // CellPngDecColorSpace
|
||||
be_t<CellPngDecColorSpace> colorSpace;
|
||||
be_t<u32> bitDepth;
|
||||
be_t<u32> interlaceMethod; // CellPngDecInterlaceMode
|
||||
be_t<CellPngDecInterlaceMode> interlaceMethod;
|
||||
be_t<u32> chunkInformation;
|
||||
};
|
||||
|
||||
struct CellPngDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect; // CellPngDecStreamSrcSel
|
||||
vm::bptr<const char> fileName;
|
||||
be_t<s64> fileOffset;
|
||||
be_t<u32> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable; // CellPngDecSpuThreadEna
|
||||
};
|
||||
|
||||
struct CellPngDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||
vm::bptr<volatile CellPngDecCommand> commandPtr;
|
||||
be_t<CellPngDecOutputMode> outputMode;
|
||||
be_t<CellPngDecColorSpace> outputColorSpace;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputPackFlag; // CellPngDecPackFlag
|
||||
be_t<u32> outputAlphaSelect; // CellPngDecAlphaSelect
|
||||
be_t<CellPngDecPackFlag> outputPackFlag;
|
||||
be_t<CellPngDecAlphaSelect> outputAlphaSelect;
|
||||
be_t<u32> outputColorAlpha;
|
||||
};
|
||||
|
||||
@ -104,11 +164,114 @@ struct CellPngDecOutParam
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||
be_t<CellPngDecOutputMode> outputMode;
|
||||
be_t<CellPngDecColorSpace> outputColorSpace;
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellPngDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellPngDecDataOutInfo
|
||||
{
|
||||
be_t<u32> chunkInformation;
|
||||
be_t<u32> numText;
|
||||
be_t<u32> numUnknownChunk;
|
||||
be_t<CellPngDecDecodeStatus> status;
|
||||
};
|
||||
|
||||
// Functions
|
||||
s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<CellPngDecThreadOutParam> threadOutParam);
|
||||
|
||||
s32 cellPngDecExtCreate(
|
||||
vm::ptr<u32> mainHandle,
|
||||
vm::ptr<const CellPngDecThreadInParam> threadInParam,
|
||||
vm::ptr<CellPngDecThreadOutParam> threadOutParam,
|
||||
vm::ptr<const CellPngDecExtThreadInParam> extThreadInParam,
|
||||
vm::ptr<CellPngDecExtThreadOutParam> extThreadOutParam);
|
||||
|
||||
s32 cellPngDecOpen(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
vm::ptr<u32> subHandle,
|
||||
vm::ptr<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> openInfo);
|
||||
|
||||
s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngDecInfo> info);
|
||||
|
||||
s32 cellPngDecSetParameter(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> outParam);
|
||||
|
||||
s32 cellPngDecDecodeData(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<u8> data,
|
||||
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo);
|
||||
|
||||
s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle);
|
||||
|
||||
s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle);
|
||||
|
||||
s32 cellPngDecGetTextChunk(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<u32> textInfoNum,
|
||||
vm::ptr<vm::bptr<CellPngTextInfo>> textInfo);
|
||||
|
||||
s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPLTE> plte);
|
||||
|
||||
s32 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngGAMA> gama);
|
||||
|
||||
s32 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSRGB> srgb);
|
||||
|
||||
s32 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngICCP> iccp);
|
||||
|
||||
s32 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSBIT> sbit);
|
||||
|
||||
s32 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngTRNS> trns);
|
||||
|
||||
s32 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngHIST> hist);
|
||||
|
||||
s32 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngTIME> time);
|
||||
|
||||
s32 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngBKGD> bkgd);
|
||||
|
||||
s32 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSPLT> splt);
|
||||
|
||||
s32 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngOFFS> offs);
|
||||
|
||||
s32 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPHYS> phys);
|
||||
|
||||
s32 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngSCAL> scal);
|
||||
|
||||
s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngCHRM> chrm);
|
||||
|
||||
s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr<CellPngPCAL> pcal);
|
||||
|
||||
s32 cellPngDecGetUnknownChunks(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<vm::bptr<CellPngUnknownChunk>> unknownChunk,
|
||||
vm::ptr<u32> unknownChunkNumber);
|
||||
|
||||
|
||||
enum CellPngDecBufferMode
|
||||
{
|
||||
CELL_PNGDEC_LINE_MODE = 1,
|
||||
};
|
||||
|
||||
enum CellPngDecSpuMode
|
||||
{
|
||||
CELL_PNGDEC_RECEIVE_EVENT = 0,
|
||||
CELL_PNGDEC_TRYRECEIVE_EVENT = 1,
|
||||
};
|
||||
|
||||
// Structs
|
||||
struct CellPngDecStrmInfo
|
||||
{
|
||||
be_t<u32> decodedStrmSize;
|
||||
@ -116,25 +279,49 @@ struct CellPngDecStrmInfo
|
||||
|
||||
struct CellPngDecStrmParam
|
||||
{
|
||||
be_t<u32> strmPtr;
|
||||
vm::bptr<void> strmPtr;
|
||||
be_t<u32> strmSize;
|
||||
};
|
||||
|
||||
struct CellPngDecCbCtrlStrm
|
||||
{
|
||||
vm::bptr<void(*)(vm::ptr<CellPngDecStrmInfo> strmInfo, vm::ptr<CellPngDecStrmParam> strmParam, u32 cbCtrlStrmArg)> cbCtrlStrmFunc;
|
||||
be_t<u32> cbCtrlStrmArg;
|
||||
};
|
||||
typedef s32(*CellPngDecCbControlStream)(
|
||||
vm::ptr<CellPngDecStrmInfo> strmInfo,
|
||||
vm::ptr<CellPngDecStrmParam> strmParam,
|
||||
vm::ptr<void> cbCtrlStrmArg
|
||||
);
|
||||
|
||||
struct CellPngDecCbCtrlDisp
|
||||
struct CellPngDecDispInfo
|
||||
{
|
||||
be_t<u32> cbCtrlDispFunc_addr;
|
||||
be_t<u32> cbCtrlDispArg;
|
||||
be_t<u64> outputFrameWidthByte;
|
||||
be_t<u32> outputFrameHeight;
|
||||
be_t<u64> outputStartXByte;
|
||||
be_t<u32> outputStartY;
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> nextOutputStartY;
|
||||
be_t<u32> scanPassCount;
|
||||
vm::bptr<void> outputImage;
|
||||
};
|
||||
|
||||
struct CellPngDecDispParam
|
||||
{
|
||||
be_t<u32> nextOutputImage_addr;
|
||||
vm::bptr<void> nextOutputImage;
|
||||
};
|
||||
|
||||
// Callback
|
||||
typedef s32(*CellPngDecCbControlDisp)(vm::ptr<CellPngDecDispInfo> dispInfo, vm::ptr<CellPngDecDispParam> dispParam, vm::ptr<void> cbCtrlDispArg);
|
||||
|
||||
// Structs
|
||||
struct CellPngDecOpnParam
|
||||
{
|
||||
be_t<u32> selectChunk;
|
||||
};
|
||||
|
||||
struct CellPngDecCbCtrlStrm
|
||||
{
|
||||
vm::bptr<CellPngDecCbControlStream> cbCtrlStrmFunc;
|
||||
be_t<vm::ptr<void>> cbCtrlStrmArg;
|
||||
};
|
||||
|
||||
struct CellPngDecExtInfo
|
||||
@ -144,9 +331,9 @@ struct CellPngDecExtInfo
|
||||
|
||||
struct CellPngDecExtInParam
|
||||
{
|
||||
be_t<u32> bufferMode; // CellPngDecBufferMode
|
||||
be_t<CellPngDecBufferMode> bufferMode;
|
||||
be_t<u32> outputCounts;
|
||||
be_t<u32> spuMode; // CellPngDecSpuMode
|
||||
be_t<CellPngDecSpuMode> spuMode;
|
||||
};
|
||||
|
||||
struct CellPngDecExtOutParam
|
||||
@ -155,25 +342,64 @@ struct CellPngDecExtOutParam
|
||||
be_t<u32> outputHeight;
|
||||
};
|
||||
|
||||
struct CellPngDecOpnParam
|
||||
struct CellPngDecCbCtrlDisp
|
||||
{
|
||||
be_t<u32> selectChunk;
|
||||
vm::bptr<CellPngDecCbControlDisp> cbCtrlDispFunc;
|
||||
be_t<vm::ptr<void>> cbCtrlDispArg;
|
||||
};
|
||||
|
||||
// Functions
|
||||
s32 cellPngDecExtOpen(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
vm::ptr<u32> subHandle,
|
||||
vm::ptr<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> openInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlStrm> cbCtrlStrm,
|
||||
vm::ptr<const CellPngDecOpnParam> opnParam);
|
||||
|
||||
s32 cellPngDecExtReadHeader(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<CellPngDecInfo> info,
|
||||
vm::ptr<CellPngDecExtInfo> extInfo);
|
||||
|
||||
s32 cellPngDecExtSetParameter(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> outParam,
|
||||
vm::ptr<const CellPngDecExtInParam> extInParam,
|
||||
vm::ptr<CellPngDecExtOutParam> extOutParam);
|
||||
|
||||
s32 cellPngDecExtDecodeData(
|
||||
CellPngDecMainHandle mainHandle,
|
||||
CellPngDecSubHandle subHandle,
|
||||
vm::ptr<u8> data,
|
||||
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp,
|
||||
vm::ptr<CellPngDecDispParam> dispParam);
|
||||
|
||||
// Custom structs
|
||||
struct CellPngDecSubHandle
|
||||
struct PngDecoder
|
||||
{
|
||||
be_t<u32> fd;
|
||||
be_t<u64> fileSize;
|
||||
vm::ptr<CellPngDecCbControlMalloc> malloc;
|
||||
vm::ptr<void> malloc_arg;
|
||||
vm::ptr<CellPngDecCbControlFree> free;
|
||||
vm::ptr<void> free_arg;
|
||||
};
|
||||
|
||||
struct PngStream
|
||||
{
|
||||
CellPngDecMainHandle dec;
|
||||
|
||||
// old data:
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellPngDecInfo info;
|
||||
CellPngDecOutParam outParam;
|
||||
CellPngDecSrc src;
|
||||
};
|
||||
|
||||
struct CellPngDecMainHandle
|
||||
{
|
||||
be_t<u32> mainHandle;
|
||||
be_t<u32> threadInParam;
|
||||
be_t<u32> threadOutParam;
|
||||
};
|
||||
CellPngDecStrmInfo streamInfo;
|
||||
CellPngDecStrmParam streamParam;
|
||||
};
|
@ -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;
|
||||
@ -568,7 +603,7 @@ void cellRescExit()
|
||||
if (IsPalTemporal())
|
||||
{
|
||||
cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_DISABLE);
|
||||
cellGcmSetVBlankHandler(0);
|
||||
cellGcmSetVBlankHandler({});
|
||||
//GcmSysTypePrefix::cellGcmSetSecondVHandler(NULL);
|
||||
|
||||
if (IsPalInterpolate())
|
||||
@ -632,7 +667,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)
|
||||
{
|
||||
@ -644,12 +679,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
|
||||
{
|
||||
@ -658,7 +693,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)
|
||||
{
|
||||
@ -670,7 +705,7 @@ void SetFlipHandler(u32 handler)
|
||||
if (IsGcmFlip())
|
||||
{
|
||||
cellGcmSetFlipHandler(handler);
|
||||
s_rescInternalInstance->s_applicationFlipHandler = 0;
|
||||
s_rescInternalInstance->s_applicationFlipHandler.set(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -745,20 +780,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);
|
||||
@ -1038,11 +1073,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()
|
||||
@ -1078,11 +1113,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"
|
||||
@ -14,7 +15,7 @@ Module *cellSync = nullptr;
|
||||
#ifdef PRX_DEBUG
|
||||
#include "prx_libsre.h"
|
||||
u32 libsre;
|
||||
u32 libsre_rtoc;
|
||||
u32 libsre_rtoc;
|
||||
#endif
|
||||
|
||||
s32 syncMutexInitialize(vm::ptr<CellSyncMutex> mutex)
|
||||
@ -1080,7 +1081,8 @@ void syncLFQueueInit(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 siz
|
||||
s32 syncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr<void> eaSignal)
|
||||
{
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
return GetCurrentPPUThread().FastCall(libsre + 0x205C, libsre_rtoc, queue.addr(), buffer_addr, size, depth, direction, eaSignal_addr);
|
||||
return cb_caller<s32, vm::ptr<CellSyncLFQueue>, vm::ptr<u8>, u32, u32, CellSyncQueueDirection, vm::ptr<void>>::call(GetCurrentPPUThread(), libsre + 0x205C, libsre_rtoc,
|
||||
queue, buffer, size, depth, direction, eaSignal);
|
||||
#else
|
||||
|
||||
if (!queue)
|
||||
@ -1525,7 +1527,8 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
|
||||
if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY))
|
||||
{
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
res = GetCurrentPPUThread().FastCall(libsre + 0x24B0, libsre_rtoc, queue.addr(), position_v.addr(), isBlocking, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>::call(GetCurrentPPUThread(), libsre + 0x24B0, libsre_rtoc,
|
||||
queue, position_v.addr(), isBlocking, 0);
|
||||
position = position_v->ToLE();
|
||||
#else
|
||||
res = syncLFQueueGetPushPointer(queue, position, isBlocking, 0);
|
||||
@ -1534,7 +1537,8 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
|
||||
else
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
res = (s32)GetCurrentPPUThread().FastCall(libsre + 0x3050, libsre_rtoc, queue.addr(), position_v.addr(), isBlocking, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>::call(GetCurrentPPUThread(), libsre + 0x3050, libsre_rtoc,
|
||||
queue, position_v.addr(), isBlocking, 0);
|
||||
position = position_v->ToLE();
|
||||
#else
|
||||
res = syncLFQueueGetPushPointer2(queue, position, isBlocking, 0);
|
||||
@ -1569,7 +1573,8 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
|
||||
if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY))
|
||||
{
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
res = GetCurrentPPUThread().FastCall(libsre + 0x26C0, libsre_rtoc, queue.addr(), position, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, s32, u64>::call(GetCurrentPPUThread(), libsre + 0x26C0, libsre_rtoc,
|
||||
queue, position, 0);
|
||||
#else
|
||||
res = syncLFQueueCompletePushPointer(queue, position, nullptr);
|
||||
#endif
|
||||
@ -1577,7 +1582,8 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
|
||||
else
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
res = (s32)GetCurrentPPUThread().FastCall(libsre + 0x355C, libsre_rtoc, queue.addr(), position, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, s32, u64>::call(GetCurrentPPUThread(), libsre + 0x355C, libsre_rtoc,
|
||||
queue, position, 0);
|
||||
#else
|
||||
res = syncLFQueueCompletePushPointer2(queue, position, nullptr);
|
||||
#endif
|
||||
@ -1916,7 +1922,8 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
|
||||
if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY))
|
||||
{
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
res = GetCurrentPPUThread().FastCall(libsre + 0x2A90, libsre_rtoc, queue.addr(), position_v.addr(), isBlocking, 0, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x2A90, libsre_rtoc,
|
||||
queue, position_v.addr(), isBlocking, 0, 0);
|
||||
position = position_v->ToLE();
|
||||
#else
|
||||
res = syncLFQueueGetPopPointer(queue, position, isBlocking, 0, 0);
|
||||
@ -1925,7 +1932,8 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
|
||||
else
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
res = (s32)GetCurrentPPUThread().FastCall(libsre + 0x39AC, libsre_rtoc, queue.addr(), position_v.addr(), isBlocking, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, u32, u32, u64>::call(GetCurrentPPUThread(), libsre + 0x39AC, libsre_rtoc,
|
||||
queue, position_v.addr(), isBlocking, 0);
|
||||
position = position_v->ToLE();
|
||||
#else
|
||||
res = syncLFQueueGetPopPointer2(queue, position, isBlocking, 0);
|
||||
@ -1957,7 +1965,8 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
|
||||
if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY))
|
||||
{
|
||||
#ifdef PRX_DEBUG_XXX
|
||||
res = GetCurrentPPUThread().FastCall(libsre + 0x2CA8, libsre_rtoc, queue.addr(), position, 0, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, s32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x2CA8, libsre_rtoc,
|
||||
queue, position, 0, 0);
|
||||
#else
|
||||
res = syncLFQueueCompletePopPointer(queue, position, nullptr, 0);
|
||||
#endif
|
||||
@ -1965,7 +1974,8 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
|
||||
else
|
||||
{
|
||||
#ifdef PRX_DEBUG
|
||||
res = (s32)GetCurrentPPUThread().FastCall(libsre + 0x3EB8, libsre_rtoc, queue.addr(), position, 0, 0);
|
||||
res = cb_caller<s32, vm::ptr<CellSyncLFQueue>, s32, u64, u64>::call(GetCurrentPPUThread(), libsre + 0x3EB8, libsre_rtoc,
|
||||
queue, position, 0, 0);
|
||||
#else
|
||||
res = syncLFQueueCompletePopPointer2(queue, position, nullptr, 0);
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -889,3 +930,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"
|
||||
|
||||
std::mutex g_mutex_avcodec_open2;
|
||||
|
||||
@ -20,7 +21,7 @@ extern "C"
|
||||
//Module cellVdec(0x0005, cellVdec_init);
|
||||
Module *cellVdec = nullptr;
|
||||
|
||||
VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg)
|
||||
VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg)
|
||||
: type(type)
|
||||
, profile(profile)
|
||||
, memAddr(addr)
|
||||
@ -122,11 +123,7 @@ next:
|
||||
buf_size -= vdec.reader.size;
|
||||
res += vdec.reader.size;
|
||||
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(false);*/
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
|
||||
vdec.job.Pop(vdec.task);
|
||||
|
||||
@ -183,13 +180,18 @@ u32 vdecOpen(VideoDecoder* data)
|
||||
{
|
||||
VideoDecoder& vdec = *data;
|
||||
|
||||
vdec.vdecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
u32 vdec_id = cellVdec->GetNewId(data);
|
||||
|
||||
vdec.id = vdec_id;
|
||||
|
||||
vdec.vdecCb = (PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
vdec.vdecCb->SetName("Video Decoder[" + std::to_string(vdec_id) + "] Callback");
|
||||
vdec.vdecCb->SetEntry(0);
|
||||
vdec.vdecCb->SetPrio(1001);
|
||||
vdec.vdecCb->SetStackSize(0x10000);
|
||||
vdec.vdecCb->InitStack();
|
||||
vdec.vdecCb->InitRegs();
|
||||
vdec.vdecCb->DoRun();
|
||||
|
||||
thread t("Video Decoder[" + std::to_string(vdec_id) + "] Thread", [&]()
|
||||
{
|
||||
@ -240,11 +242,7 @@ u32 vdecOpen(VideoDecoder* data)
|
||||
// TODO: finalize
|
||||
cellVdec->Warning("vdecEndSeq:");
|
||||
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(true); // ???*/
|
||||
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
|
||||
|
||||
vdec.is_running = false;
|
||||
vdec.just_finished = true;
|
||||
@ -439,19 +437,11 @@ u32 vdecOpen(VideoDecoder* data)
|
||||
vdec.frames.Push(frame); // !!!!!!!!
|
||||
frame.data = nullptr; // to prevent destruction
|
||||
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(false);*/
|
||||
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
|
||||
}
|
||||
}
|
||||
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(false);*/
|
||||
vdec.cbFunc.call(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -501,7 +491,7 @@ int cellVdecOpen(vm::ptr<const CellVdecType> type, vm::ptr<const CellVdecResourc
|
||||
cellVdec->Warning("cellVdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)",
|
||||
type.addr(), res.addr(), cb.addr(), handle.addr());
|
||||
|
||||
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg));
|
||||
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, vm::ptr<CellVdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -511,7 +501,7 @@ int cellVdecOpenEx(vm::ptr<const CellVdecTypeEx> type, vm::ptr<const CellVdecRes
|
||||
cellVdec->Warning("cellVdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)",
|
||||
type.addr(), res.addr(), cb.addr(), handle.addr());
|
||||
|
||||
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg));
|
||||
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, vm::ptr<CellVdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -167,12 +167,12 @@ struct CellVdecPicFormat
|
||||
u8 alpha;
|
||||
};
|
||||
|
||||
typedef void(*CellVdecCbMsg)(u32 handle_addr, CellVdecMsgType msgType, int msgData, u32 cbArg_addr);
|
||||
typedef u32(*CellVdecCbMsg)(u32 handle, CellVdecMsgType msgType, s32 msgData, u32 cbArg);
|
||||
|
||||
// Callback Function Information
|
||||
struct CellVdecCb
|
||||
{
|
||||
be_t<u32> cbFunc;
|
||||
vm::bptr<CellVdecCbMsg> cbFunc;
|
||||
be_t<u32> cbArg;
|
||||
};
|
||||
|
||||
@ -717,7 +717,7 @@ public:
|
||||
const u32 profile;
|
||||
const u32 memAddr;
|
||||
const u32 memSize;
|
||||
const u32 cbFunc;
|
||||
const vm::ptr<CellVdecCbMsg> cbFunc;
|
||||
const u32 cbArg;
|
||||
u32 memBias;
|
||||
|
||||
@ -725,9 +725,9 @@ public:
|
||||
u64 last_pts, first_pts, first_dts;
|
||||
AVRational rfr, afr;
|
||||
|
||||
CPUThread* vdecCb;
|
||||
PPUThread* vdecCb;
|
||||
|
||||
VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg);
|
||||
VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, vm::ptr<CellVdecCbMsg> func, u32 arg);
|
||||
|
||||
~VideoDecoder();
|
||||
};
|
||||
|
@ -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/CPU/CPUThreadManager.h"
|
||||
#include "Emu/Audio/cellAudio.h"
|
||||
@ -14,8 +15,8 @@ Module *libmixer = nullptr;
|
||||
CellSurMixerConfig surMixer;
|
||||
|
||||
#define SUR_PORT (7)
|
||||
u32 surMixerCb;
|
||||
u32 surMixerCbArg;
|
||||
vm::ptr<CellSurMixerNotifyCallbackFunction> surMixerCb;
|
||||
vm::ptr<void> surMixerCbArg;
|
||||
std::mutex mixer_mutex;
|
||||
float mixdata[8*256];
|
||||
u64 mixcount;
|
||||
@ -323,15 +324,20 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
|
||||
(u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8);
|
||||
|
||||
mixcount = 0;
|
||||
surMixerCb = 0;
|
||||
surMixerCb.set(0);
|
||||
|
||||
thread t("Surmixer Thread", []()
|
||||
{
|
||||
AudioPortConfig& port = m_config.m_ports[SUR_PORT];
|
||||
|
||||
CPUThread* mixerCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
mixerCb->SetName("Surmixer Callback");
|
||||
PPUThread& cb_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
cb_thread.SetName("Surmixer Callback Thread");
|
||||
cb_thread.SetEntry(0);
|
||||
cb_thread.SetPrio(1001);
|
||||
cb_thread.SetStackSize(0x10000);
|
||||
cb_thread.InitStack();
|
||||
cb_thread.InitRegs();
|
||||
cb_thread.DoRun();
|
||||
|
||||
while (port.m_is_audio_port_opened)
|
||||
{
|
||||
@ -352,7 +358,10 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
|
||||
//u64 stamp0 = get_system_time();
|
||||
|
||||
memset(mixdata, 0, sizeof(mixdata));
|
||||
if (surMixerCb) mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256);
|
||||
if (surMixerCb)
|
||||
{
|
||||
surMixerCb.call(cb_thread, surMixerCbArg, mixcount, 256);
|
||||
}
|
||||
|
||||
//u64 stamp1 = get_system_time();
|
||||
|
||||
@ -456,7 +465,8 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> config)
|
||||
ssp.clear();
|
||||
}
|
||||
|
||||
Emu.GetCPU().RemoveThread(mixerCb->GetId());
|
||||
Emu.GetCPU().RemoveThread(cb_thread.GetId());
|
||||
surMixerCb.set(0);
|
||||
});
|
||||
t.detach();
|
||||
|
||||
@ -477,19 +487,31 @@ int cellSurMixerChStripGetAANPortNo(vm::ptr<be_t<u32>> port, u32 type, u32 index
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSurMixerSetNotifyCallback(u32 func, u32 arg)
|
||||
int cellSurMixerSetNotifyCallback(vm::ptr<CellSurMixerNotifyCallbackFunction> func, vm::ptr<void> arg)
|
||||
{
|
||||
libmixer->Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x) (surMixerCb=0x%x)", func, arg, surMixerCb);
|
||||
libmixer->Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func.addr(), arg.addr());
|
||||
|
||||
if (surMixerCb)
|
||||
{
|
||||
libmixer->Error("cellSurMixerSetNotifyCallback: surMixerCb already set (addr=0x%x)", surMixerCb.addr());
|
||||
}
|
||||
surMixerCb = func;
|
||||
surMixerCbArg = arg;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSurMixerRemoveNotifyCallback(u32 func)
|
||||
int cellSurMixerRemoveNotifyCallback(vm::ptr<CellSurMixerNotifyCallbackFunction> func)
|
||||
{
|
||||
libmixer->Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x) (surMixerCb=0x%x)", func, surMixerCb);
|
||||
surMixerCb = 0;
|
||||
surMixerCbArg = 0;
|
||||
libmixer->Warning("cellSurMixerRemoveNotifyCallback(func_addr=0x%x)", func.addr());
|
||||
|
||||
if (surMixerCb.addr() != func.addr())
|
||||
{
|
||||
libmixer->Error("cellSurMixerRemoveNotifyCallback: surMixerCb had different value (addr=0x%x)", surMixerCb.addr());
|
||||
}
|
||||
else
|
||||
{
|
||||
surMixerCb.set(0);
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ enum
|
||||
CELL_SSPLAYER_STATE_ON = 0x20,
|
||||
};
|
||||
|
||||
typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples);
|
||||
typedef s32(*CellSurMixerNotifyCallbackFunction)(vm::ptr<void> arg, u32 counter, u32 samples);
|
||||
|
||||
struct CellSSPlayerConfig
|
||||
{
|
||||
@ -180,4 +180,4 @@ struct SSPlayer
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
};
|
||||
};
|
||||
|
@ -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"
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
#include "Emu/SysCalls/Callback.h"
|
||||
|
||||
#include "Emu/FS/vfsFile.h"
|
||||
#include "Emu/FS/vfsStreamMemory.h"
|
||||
@ -235,14 +237,21 @@ vm::ptr<char> _sys_strncpy(vm::ptr<char> dest, vm::ptr<const char> source, u32 l
|
||||
return dest;
|
||||
}
|
||||
|
||||
u32 spu_printf_agcb;
|
||||
u32 spu_printf_dgcb;
|
||||
u32 spu_printf_atcb;
|
||||
u32 spu_printf_dtcb;
|
||||
typedef s32(*spu_printf_cb_t)(u32 arg);
|
||||
|
||||
s32 _sys_spu_printf_initialize(u32 agcb, u32 dgcb, u32 atcb, u32 dtcb)
|
||||
vm::ptr<spu_printf_cb_t> spu_printf_agcb;
|
||||
vm::ptr<spu_printf_cb_t> spu_printf_dgcb;
|
||||
vm::ptr<spu_printf_cb_t> spu_printf_atcb;
|
||||
vm::ptr<spu_printf_cb_t> spu_printf_dtcb;
|
||||
|
||||
s32 _sys_spu_printf_initialize(
|
||||
vm::ptr<spu_printf_cb_t> agcb,
|
||||
vm::ptr<spu_printf_cb_t> dgcb,
|
||||
vm::ptr<spu_printf_cb_t> atcb,
|
||||
vm::ptr<spu_printf_cb_t> dtcb)
|
||||
{
|
||||
sysPrxForUser->Warning("_sys_spu_printf_initialize(agcb=0x%x, dgcb=0x%x, atcb=0x%x, dtcb=0x%x)", agcb, dgcb, atcb, dtcb);
|
||||
sysPrxForUser->Warning("_sys_spu_printf_initialize(agcb_addr=0x%x, dgcb_addr=0x%x, atcb_addr=0x%x, dtcb_addr=0x%x)",
|
||||
agcb.addr(), dgcb.addr(), atcb.addr(), dtcb.addr());
|
||||
|
||||
// prx: register some callbacks
|
||||
spu_printf_agcb = agcb;
|
||||
@ -256,10 +265,10 @@ s32 _sys_spu_printf_finalize()
|
||||
{
|
||||
sysPrxForUser->Warning("_sys_spu_printf_finalize()");
|
||||
|
||||
spu_printf_agcb = 0;
|
||||
spu_printf_dgcb = 0;
|
||||
spu_printf_atcb = 0;
|
||||
spu_printf_dtcb = 0;
|
||||
spu_printf_agcb.set(0);
|
||||
spu_printf_dgcb.set(0);
|
||||
spu_printf_atcb.set(0);
|
||||
spu_printf_dtcb.set(0);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -272,7 +281,7 @@ s64 _sys_spu_printf_attach_group(u32 arg)
|
||||
return CELL_ESTAT;
|
||||
}
|
||||
|
||||
return GetCurrentPPUThread().FastCall(vm::read32(spu_printf_agcb), vm::read32(spu_printf_agcb + 4), arg);
|
||||
return spu_printf_agcb(arg);
|
||||
}
|
||||
|
||||
s64 _sys_spu_printf_detach_group(u32 arg)
|
||||
@ -284,7 +293,7 @@ s64 _sys_spu_printf_detach_group(u32 arg)
|
||||
return CELL_ESTAT;
|
||||
}
|
||||
|
||||
return GetCurrentPPUThread().FastCall(vm::read32(spu_printf_dgcb), vm::read32(spu_printf_dgcb + 4), arg);
|
||||
return spu_printf_dgcb(arg);
|
||||
}
|
||||
|
||||
s64 _sys_spu_printf_attach_thread(u32 arg)
|
||||
@ -296,7 +305,7 @@ s64 _sys_spu_printf_attach_thread(u32 arg)
|
||||
return CELL_ESTAT;
|
||||
}
|
||||
|
||||
return GetCurrentPPUThread().FastCall(vm::read32(spu_printf_atcb), vm::read32(spu_printf_atcb + 4), arg);
|
||||
return spu_printf_atcb(arg);
|
||||
}
|
||||
|
||||
s64 _sys_spu_printf_detach_thread(u32 arg)
|
||||
@ -308,7 +317,20 @@ s64 _sys_spu_printf_detach_thread(u32 arg)
|
||||
return CELL_ESTAT;
|
||||
}
|
||||
|
||||
return GetCurrentPPUThread().FastCall(vm::read32(spu_printf_dtcb), vm::read32(spu_printf_dtcb + 4), arg);
|
||||
return spu_printf_dtcb(arg);
|
||||
}
|
||||
|
||||
s32 _sys_snprintf(vm::ptr<char> dst, u32 count, vm::ptr<const char> fmt, u32 a1, u32 a2) // va_args...
|
||||
{
|
||||
sysPrxForUser->Todo("_sys_snprintf(dst_addr=0x%x, count=%d, fmt_addr=0x%x['%s'], ...)", dst.addr(), count, fmt.addr(), fmt.get_ptr());
|
||||
|
||||
if (std::string(fmt.get_ptr()) == "%s_%08x")
|
||||
{
|
||||
return snprintf(dst.get_ptr(), count, fmt.get_ptr(), vm::get_ptr<char>(a1), a2);
|
||||
}
|
||||
|
||||
Emu.Pause();
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 _sys_printf(vm::ptr<const char> fmt)
|
||||
@ -317,6 +339,7 @@ s32 _sys_printf(vm::ptr<const char> fmt)
|
||||
|
||||
// probably, assertion failed
|
||||
sysPrxForUser->Warning("_sys_printf: \n%s", fmt.get_ptr());
|
||||
Emu.Pause();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -412,7 +435,6 @@ void sysPrxForUser_init()
|
||||
REG_FUNC(sysPrxForUser, _sys_strncat);
|
||||
REG_FUNC(sysPrxForUser, _sys_strcpy);
|
||||
REG_FUNC(sysPrxForUser, _sys_strncpy);
|
||||
sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown
|
||||
|
||||
REG_FUNC(sysPrxForUser, _sys_spu_printf_initialize);
|
||||
REG_FUNC(sysPrxForUser, _sys_spu_printf_finalize);
|
||||
@ -421,13 +443,16 @@ void sysPrxForUser_init()
|
||||
REG_FUNC(sysPrxForUser, _sys_spu_printf_attach_thread);
|
||||
REG_FUNC(sysPrxForUser, _sys_spu_printf_detach_thread);
|
||||
|
||||
REG_FUNC(sysPrxForUser, _sys_snprintf);
|
||||
|
||||
REG_FUNC(sysPrxForUser, _sys_printf);
|
||||
sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown
|
||||
}
|
||||
|
||||
void sysPrxForUser_load()
|
||||
{
|
||||
spu_printf_agcb = 0;
|
||||
spu_printf_dgcb = 0;
|
||||
spu_printf_atcb = 0;
|
||||
spu_printf_dtcb = 0;
|
||||
spu_printf_agcb.set(0);
|
||||
spu_printf_dgcb.set(0);
|
||||
spu_printf_atcb.set(0);
|
||||
spu_printf_dtcb.set(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 "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++;
|
||||
|
@ -24,7 +24,7 @@ namespace detail
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_GENERAL, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(sizeof(T) <= 8, "Wrong argument type for ARG_GENERAL");
|
||||
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_GENERAL");
|
||||
|
||||
static __forceinline T func(PPUThread& CPU)
|
||||
{
|
||||
@ -35,7 +35,7 @@ namespace detail
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_FLOAT, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(sizeof(T) <= 8, "Wrong argument type for ARG_FLOAT");
|
||||
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT");
|
||||
|
||||
static __forceinline T func(PPUThread& CPU)
|
||||
{
|
||||
@ -46,7 +46,7 @@ namespace detail
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_VECTOR, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(std::is_same<T, u128>::value, "Wrong argument type for ARG_VECTOR");
|
||||
static_assert(std::is_same<T, u128>::value, "Invalid function argument type for ARG_VECTOR");
|
||||
|
||||
static __forceinline T func(PPUThread& CPU)
|
||||
{
|
||||
@ -57,11 +57,14 @@ namespace detail
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
struct bind_arg<T, ARG_STACK, g_count, f_count, v_count>
|
||||
{
|
||||
static_assert(sizeof(T) <= 8 && v_count <= 12, "Wrong argument type for ARG_STACK");
|
||||
static_assert(f_count <= 12, "TODO: Unsupported stack argument type (float)");
|
||||
static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)");
|
||||
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_STACK");
|
||||
|
||||
static __forceinline T func(PPUThread& CPU)
|
||||
{
|
||||
const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0));
|
||||
// TODO: check stack argument displacement
|
||||
const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0) + std::max(v_count - 12, 0));
|
||||
return (T&)res;
|
||||
}
|
||||
};
|
||||
@ -69,18 +72,19 @@ namespace detail
|
||||
template<typename T>
|
||||
struct bind_result
|
||||
{
|
||||
static_assert(!std::is_pointer<T>::value, "Invalid function result type: pointer");
|
||||
static_assert(sizeof(T) <= 8, "Invalid function result type");
|
||||
static_assert(!std::is_pointer<T>::value, "Invalid function result type (pointer)");
|
||||
static_assert(!std::is_reference<T>::value, "Invalid function result type (reference)");
|
||||
|
||||
static __forceinline void func(PPUThread& CPU, T value)
|
||||
static __forceinline void func(PPUThread& CPU, T result)
|
||||
{
|
||||
if (std::is_floating_point<T>::value)
|
||||
{
|
||||
CPU.FPR[1] = (double)value;
|
||||
CPU.FPR[1] = (double)result;
|
||||
}
|
||||
else
|
||||
{
|
||||
(T&)CPU.GPR[3] = value;
|
||||
(T&)CPU.GPR[3] = result;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -88,9 +92,9 @@ namespace detail
|
||||
template<>
|
||||
struct bind_result<u128>
|
||||
{
|
||||
static __forceinline void func(PPUThread& CPU, u128 value)
|
||||
static __forceinline void func(PPUThread& CPU, u128 result)
|
||||
{
|
||||
CPU.VPR[2] = value;
|
||||
CPU.VPR[2] = result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -122,13 +126,15 @@ namespace detail
|
||||
template<int g_count, int f_count, int v_count>
|
||||
static __forceinline std::tuple<> iterate(PPUThread& CPU)
|
||||
{
|
||||
// terminator
|
||||
return std::tuple<>();
|
||||
}
|
||||
|
||||
template<int g_count, int f_count, int v_count, typename T, typename... A>
|
||||
static __forceinline std::tuple<T, A...> iterate(PPUThread& CPU)
|
||||
{
|
||||
static_assert(!std::is_pointer<T>::value, "Invalid function argument type: pointer");
|
||||
static_assert(!std::is_pointer<T>::value, "Invalid function argument type (pointer)");
|
||||
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
|
||||
// TODO: check calculations
|
||||
const bool is_float = std::is_floating_point<T>::value;
|
||||
const bool is_vector = std::is_same<T, u128>::value;
|
||||
@ -138,6 +144,7 @@ namespace detail
|
||||
const int g = g_count + (is_float || is_vector ? 0 : 1);
|
||||
const int f = f_count + (is_float ? 1 : 0);
|
||||
const int v = v_count + (is_vector ? 1 : 0);
|
||||
|
||||
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::func(CPU)), iterate<g, f, v, A...>(CPU));
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
|
||||
default: sys_ppu_thread.Error("sys_ppu_thread_create(): unknown flags value (0x%llx)", flags); return CELL_EPERM;
|
||||
}
|
||||
|
||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
PPUThread& new_thread = *(PPUThread*)&Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
*thread_id = new_thread.GetId();
|
||||
new_thread.SetEntry(entry);
|
||||
@ -193,6 +193,12 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
|
||||
new_thread.Run();
|
||||
new_thread.Exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
new_thread.InitStack();
|
||||
new_thread.InitRegs();
|
||||
new_thread.DoRun();
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -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);
|
||||
@ -764,7 +765,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" />
|
||||
@ -378,6 +379,7 @@
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPad.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPamf.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPng.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellPngDec.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellSail.h" />
|
||||
<ClInclude Include="Emu\SysCalls\Modules\cellResc.h" />
|
||||
|
@ -1210,5 +1210,11 @@
|
||||
<ClInclude Include="define_new_memleakdetect.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<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