mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 15:31:26 +12:00
Merge branch 'master' of https://github.com/DHrpcs3/rpcs3
This commit is contained in:
commit
4e4dd43646
36 changed files with 1375 additions and 447 deletions
|
@ -21,6 +21,15 @@ enum
|
||||||
MFC_MASK_CMD = 0xffff,
|
MFC_MASK_CMD = 0xffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Atomic Status Update
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MFC_PUTLLC_SUCCESS = 0,
|
||||||
|
MFC_PUTLLC_FAILURE = 1, //reservation was lost
|
||||||
|
MFC_PUTLLUC_SUCCESS = 2,
|
||||||
|
MFC_GETLLAR_SUCCESS = 4,
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF,
|
MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF,
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#include "PPCThread.h"
|
#include "PPCThread.h"
|
||||||
#include "Emu/event.h"
|
#include "Emu/event.h"
|
||||||
#include "MFC.h"
|
#include "MFC.h"
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
extern std::mutex g_SyncMutex; //can provide compatability for CellSyncMutex through SPU<>PPU and SPU<>SPU
|
||||||
|
|
||||||
static const char* spu_reg_name[128] =
|
static const char* spu_reg_name[128] =
|
||||||
{
|
{
|
||||||
|
@ -293,7 +296,7 @@ public:
|
||||||
};
|
};
|
||||||
volatile u64 m_indval;
|
volatile u64 m_indval;
|
||||||
};
|
};
|
||||||
wxCriticalSection m_lock;
|
std::mutex m_lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -311,7 +314,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
if(!m_index)
|
if(!m_index)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -322,7 +325,7 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //lock-free
|
{ //lock-free
|
||||||
if(!m_index)
|
if ((m_indval & 0xffffffff) == 0)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -337,7 +340,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
if(m_index >= max_count)
|
if(m_index >= max_count)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -347,11 +350,12 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //lock-free
|
{ //lock-free
|
||||||
if(m_index)
|
if (m_indval & 0xffffffff)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_indval = ((u64)value << 32) | 1;
|
const u64 new_value = ((u64)value << 32) | 1;
|
||||||
|
m_indval = new_value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,7 +365,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
if(m_index >= max_count)
|
if(m_index >= max_count)
|
||||||
m_value[max_count-1] = value; //last message is overwritten
|
m_value[max_count-1] = value; //last message is overwritten
|
||||||
else
|
else
|
||||||
|
@ -369,7 +373,8 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //lock-free
|
{ //lock-free
|
||||||
m_indval = ((u64)value << 32) | 1;
|
const u64 new_value = ((u64)value << 32) | 1;
|
||||||
|
m_indval = new_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +382,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
if(m_index >= max_count)
|
if(m_index >= max_count)
|
||||||
m_value[max_count-1] |= value; //last message is logically ORed
|
m_value[max_count-1] |= value; //last message is logically ORed
|
||||||
else
|
else
|
||||||
|
@ -397,7 +402,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
if(!m_index)
|
if(!m_index)
|
||||||
res = 0; //result is undefined
|
res = 0; //result is undefined
|
||||||
else
|
else
|
||||||
|
@ -422,7 +427,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
return m_index;
|
return m_index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -435,7 +440,7 @@ public:
|
||||||
{
|
{
|
||||||
if (max_count > 1 || x86)
|
if (max_count > 1 || x86)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_lock);
|
std::lock_guard<std::mutex> lock(m_lock);
|
||||||
return max_count - m_index;
|
return max_count - m_index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -470,6 +475,7 @@ public:
|
||||||
Channel<1> QueryType;
|
Channel<1> QueryType;
|
||||||
Channel<1> QueryMask;
|
Channel<1> QueryMask;
|
||||||
Channel<1> TagStatus;
|
Channel<1> TagStatus;
|
||||||
|
Channel<1> AtomicStat;
|
||||||
} Prxy;
|
} Prxy;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -519,6 +525,29 @@ public:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MFC_GETLLAR_CMD:
|
||||||
|
case MFC_PUTLLC_CMD:
|
||||||
|
case MFC_PUTLLUC_CMD:
|
||||||
|
{
|
||||||
|
if (op == MFC_GETLLAR_CMD)
|
||||||
|
{
|
||||||
|
g_SyncMutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConLog.Warning("DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x",
|
||||||
|
op == MFC_GETLLAR_CMD ? "GETLLAR" : op == MFC_PUTLLC_CMD ? "PUTLLC" : "PUTLLUC",
|
||||||
|
lsa, ea, tag, size, cmd);
|
||||||
|
|
||||||
|
dmac.ProcessCmd(op == MFC_GETLLAR_CMD ? MFC_GET_CMD : MFC_PUT_CMD, tag, lsa, ea, 128);
|
||||||
|
Prxy.AtomicStat.PushUncond(op == MFC_GETLLAR_CMD ? MFC_GETLLAR_SUCCESS : op == MFC_PUTLLC_CMD ? MFC_PUTLLC_SUCCESS : MFC_PUTLLUC_SUCCESS);
|
||||||
|
|
||||||
|
if (op == MFC_PUTLLC_CMD || op == MFC_PUTLLUC_CMD)
|
||||||
|
{
|
||||||
|
g_SyncMutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)",
|
ConLog.Error("Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)",
|
||||||
op, cmd, lsa, ea, tag, size);
|
op, cmd, lsa, ea, tag, size);
|
||||||
|
@ -549,6 +578,9 @@ public:
|
||||||
case SPU_RdSigNotify2:
|
case SPU_RdSigNotify2:
|
||||||
return SPU.SNR[1].GetCount();
|
return SPU.SNR[1].GetCount();
|
||||||
|
|
||||||
|
case MFC_RdAtomicStat:
|
||||||
|
return Prxy.AtomicStat.GetCount();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
@ -641,6 +673,10 @@ public:
|
||||||
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MFC_RdAtomicStat:
|
||||||
|
while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,7 +20,11 @@ struct VFSManagerEntry
|
||||||
char* mount;
|
char* mount;
|
||||||
vfsDeviceType device;
|
vfsDeviceType device;
|
||||||
|
|
||||||
VFSManagerEntry() : device(vfsDevice_LocalFile)
|
VFSManagerEntry()
|
||||||
|
: device(vfsDevice_LocalFile)
|
||||||
|
, device_path("")
|
||||||
|
, path("")
|
||||||
|
, mount("")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -151,7 +151,7 @@ wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask)
|
void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst)
|
||||||
{
|
{
|
||||||
if(d0.cond == 0) return;
|
if(d0.cond == 0) return;
|
||||||
enum
|
enum
|
||||||
|
@ -179,7 +179,7 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||||
}
|
}
|
||||||
|
|
||||||
//ConLog.Error("cond! %d (%d %s %d %d)", d0.cond, d0.dst_tmp, cond, d1.input_src, d1.const_src);
|
//ConLog.Error("cond! %d (%d %s %d %d)", d0.cond, d0.dst_tmp, cond, d1.input_src, d1.const_src);
|
||||||
cond = wxString::Format("if(tmp%d.x %s 0) ", d0.dst_tmp, cond.mb_str());
|
cond = wxString::Format("if(rc %s 0) ", cond.mb_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString value = src_mask ? code + GetMask(is_sca) : code;
|
wxString value = src_mask ? code + GetMask(is_sca) : code;
|
||||||
|
@ -189,8 +189,14 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||||
value = "clamp(" + value + ", 0.0, 1.0)";
|
value = "clamp(" + value + ", 0.0, 1.0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(set_dst)
|
||||||
|
{
|
||||||
wxString dest;
|
wxString dest;
|
||||||
if(d3.dst == 5 || d3.dst == 6)
|
if(d0.cond_update_enable_0)
|
||||||
|
{
|
||||||
|
dest = m_parr.AddParam(PARAM_NONE, "float", "rc");
|
||||||
|
}
|
||||||
|
else if(d3.dst == 5 || d3.dst == 6)
|
||||||
{
|
{
|
||||||
int num = d3.dst == 5 ? 0 : 3;
|
int num = d3.dst == 5 ? 0 : 3;
|
||||||
|
|
||||||
|
@ -211,18 +217,72 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||||
}
|
}
|
||||||
|
|
||||||
code = cond + dest + " = " + value;
|
code = cond + dest + " = " + value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code = cond + value;
|
||||||
|
}
|
||||||
|
|
||||||
main += "\t" + code + ";\n";
|
m_body.Add(code + wxString::Format(";//%d %d %d %d", d0.cond_reg_sel_1, d0.cond_test_enable, d0.cond_update_enable_0, d0.cond_update_enable_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask)
|
wxString GLVertexDecompilerThread::GetFunc()
|
||||||
{
|
{
|
||||||
AddCode(false, code, src_mask);
|
u32 offset = (d2.iaddrh << 3) | d3.iaddrl;
|
||||||
|
wxString name = wxString::Format("func%u", offset);
|
||||||
|
|
||||||
|
for(uint i=0; i<m_funcs.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(m_funcs[i].name.Cmp(name) == 0)
|
||||||
|
return name + "()";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint idx = m_funcs.Add(new FuncInfo());
|
||||||
|
m_funcs[idx].offset = offset;
|
||||||
|
m_funcs[idx].name = name;
|
||||||
|
|
||||||
|
return name + "()";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::AddScaCode(const wxString& code)
|
void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask, bool set_dst)
|
||||||
{
|
{
|
||||||
AddCode(true, code, false);
|
AddCode(false, code, src_mask, set_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst)
|
||||||
|
{
|
||||||
|
AddCode(true, code, false, set_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString GLVertexDecompilerThread::BuildFuncBody(const FuncInfo& func)
|
||||||
|
{
|
||||||
|
wxString result;
|
||||||
|
|
||||||
|
for(uint i=func.offset; i<m_body.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(i != func.offset)
|
||||||
|
{
|
||||||
|
uint call_func = -1;
|
||||||
|
for(uint j=0; j<m_funcs.GetCount(); ++j)
|
||||||
|
{
|
||||||
|
if(m_funcs[j].offset == i)
|
||||||
|
{
|
||||||
|
call_func = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(call_func != -1)
|
||||||
|
{
|
||||||
|
result += '\t' + m_funcs[call_func].name + "();\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result += '\t' + m_body[i] + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GLVertexDecompilerThread::BuildCode()
|
wxString GLVertexDecompilerThread::BuildCode()
|
||||||
|
@ -234,13 +294,30 @@ wxString GLVertexDecompilerThread::BuildCode()
|
||||||
p += m_parr.params[i].Format();
|
p += m_parr.params[i].Format();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString fp = wxEmptyString;
|
||||||
|
|
||||||
|
for(int i=m_funcs.GetCount() - 1; i>=0; --i)
|
||||||
|
{
|
||||||
|
fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString f = wxEmptyString;
|
||||||
|
|
||||||
|
f += wxString::Format("void %s()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n%s}\n", m_funcs[0].name.mb_str(), BuildFuncBody(m_funcs[0]).mb_str());
|
||||||
|
|
||||||
|
for(uint i=1; i<m_funcs.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
f += wxString::Format("\nvoid %s()\n{\n%s}\n", m_funcs[i].name.mb_str(), BuildFuncBody(m_funcs[i]).mb_str());
|
||||||
|
}
|
||||||
|
|
||||||
static const wxString& prot =
|
static const wxString& prot =
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
"\n"
|
"\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
"void main()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n%s}\n";
|
"%s\n"
|
||||||
|
"%s";
|
||||||
|
|
||||||
return wxString::Format(prot, p.mb_str(), main.mb_str());
|
return wxString::Format(prot, p.mb_str(), fp.mb_str(), f.mb_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::Task()
|
void GLVertexDecompilerThread::Task()
|
||||||
|
@ -268,11 +345,11 @@ void GLVertexDecompilerThread::Task()
|
||||||
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
|
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
|
||||||
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
|
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
|
||||||
//case 0x07: break; // LIT
|
//case 0x07: break; // LIT
|
||||||
//case 0x08: break; // BRA
|
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false); break; // BRA
|
||||||
//case 0x09: break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false); break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
||||||
//case 0x0a: break; // CAL : works same as BRI
|
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false); break; // CAL : works same as BRI
|
||||||
//case 0x0b: break; // CLI : works same as BRI
|
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false); break; // CLI : works same as BRI
|
||||||
//case 0x0c: break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
case 0x0c: AddScaCode("return", false); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
||||||
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
|
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
|
||||||
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
|
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
|
||||||
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
|
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
|
||||||
|
@ -283,6 +360,7 @@ void GLVertexDecompilerThread::Task()
|
||||||
//case 0x14: break; // POP : works differently (POP o[1].x;)
|
//case 0x14: break; // POP : works differently (POP o[1].x;)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
m_body.Add(wxString::Format("//Unknown vp sca_opcode 0x%x", d1.sca_opcode));
|
||||||
ConLog.Error("Unknown vp sca_opcode 0x%x", d1.sca_opcode);
|
ConLog.Error("Unknown vp sca_opcode 0x%x", d1.sca_opcode);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
|
@ -314,17 +392,25 @@ void GLVertexDecompilerThread::Task()
|
||||||
case 0x16: AddVecCode("sign(" + GetSRC(0) + ")"); break; //SSG
|
case 0x16: AddVecCode("sign(" + GetSRC(0) + ")"); break; //SSG
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
m_body.Add(wxString::Format("//Unknown vp opcode 0x%x", d1.vec_opcode));
|
||||||
ConLog.Error("Unknown vp opcode 0x%x", d1.vec_opcode);
|
ConLog.Error("Unknown vp opcode 0x%x", d1.vec_opcode);
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(d3.end) break;
|
if(d3.end)
|
||||||
|
{
|
||||||
|
if(i < m_data.GetCount())
|
||||||
|
ConLog.Error("Program end before buffer end.");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shader = BuildCode();
|
m_shader = BuildCode();
|
||||||
|
|
||||||
main = wxEmptyString;
|
m_body.Clear();
|
||||||
|
m_funcs.RemoveAt(1, m_funcs.GetCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVertexProgram::GLVertexProgram()
|
GLVertexProgram::GLVertexProgram()
|
||||||
|
|
|
@ -127,7 +127,17 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||||
};
|
};
|
||||||
} src[3];
|
} src[3];
|
||||||
|
|
||||||
wxString main;
|
struct FuncInfo
|
||||||
|
{
|
||||||
|
u32 offset;
|
||||||
|
wxString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
wxArrayString m_body;
|
||||||
|
|
||||||
|
ArrayF<FuncInfo> m_funcs;
|
||||||
|
|
||||||
|
//wxString main;
|
||||||
wxString& m_shader;
|
wxString& m_shader;
|
||||||
Array<u32>& m_data;
|
Array<u32>& m_data;
|
||||||
GLParamArray& m_parr;
|
GLParamArray& m_parr;
|
||||||
|
@ -138,6 +148,10 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||||
, m_shader(shader)
|
, m_shader(shader)
|
||||||
, m_parr(parr)
|
, m_parr(parr)
|
||||||
{
|
{
|
||||||
|
m_funcs.Add(new FuncInfo());
|
||||||
|
m_funcs[0].offset = 0;
|
||||||
|
m_funcs[0].name = "main";
|
||||||
|
//m_cur_func->body = "\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GetMask(bool is_sca);
|
wxString GetMask(bool is_sca);
|
||||||
|
@ -145,9 +159,11 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||||
wxString GetScaMask();
|
wxString GetScaMask();
|
||||||
wxString GetDST(bool is_sca = false);
|
wxString GetDST(bool is_sca = false);
|
||||||
wxString GetSRC(const u32 n, bool is_sca = false);
|
wxString GetSRC(const u32 n, bool is_sca = false);
|
||||||
void AddCode(bool is_sca, wxString code, bool src_mask = true);
|
wxString GetFunc();
|
||||||
void AddVecCode(const wxString& code, bool src_mask = true);
|
void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true);
|
||||||
void AddScaCode(const wxString& code);
|
void AddVecCode(const wxString& code, bool src_mask = true, bool set_dst = true);
|
||||||
|
void AddScaCode(const wxString& code, bool set_dst = true);
|
||||||
|
wxString BuildFuncBody(const FuncInfo& func);
|
||||||
wxString BuildCode();
|
wxString BuildCode();
|
||||||
|
|
||||||
virtual void Task();
|
virtual void Task();
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
bool IsInited() const { return m_render != nullptr; }
|
||||||
|
|
||||||
GSInfo& GetInfo() { return m_info; }
|
GSInfo& GetInfo() { return m_info; }
|
||||||
GSRender& GetRender() { assert(m_render); return *m_render; }
|
GSRender& GetRender() { assert(m_render); return *m_render; }
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,41 @@ u32 RSXVertexData::GetTypeSize()
|
||||||
index = (cmd - a) / m; \
|
index = (cmd - a) / m; \
|
||||||
case a \
|
case a \
|
||||||
|
|
||||||
|
#define case_32(a, m) \
|
||||||
|
case a + m: \
|
||||||
|
case a + m * 2: \
|
||||||
|
case a + m * 3: \
|
||||||
|
case a + m * 4: \
|
||||||
|
case a + m * 5: \
|
||||||
|
case a + m * 6: \
|
||||||
|
case a + m * 7: \
|
||||||
|
case a + m * 8: \
|
||||||
|
case a + m * 9: \
|
||||||
|
case a + m * 10: \
|
||||||
|
case a + m * 11: \
|
||||||
|
case a + m * 12: \
|
||||||
|
case a + m * 13: \
|
||||||
|
case a + m * 14: \
|
||||||
|
case a + m * 15: \
|
||||||
|
case a + m * 16: \
|
||||||
|
case a + m * 17: \
|
||||||
|
case a + m * 18: \
|
||||||
|
case a + m * 19: \
|
||||||
|
case a + m * 20: \
|
||||||
|
case a + m * 21: \
|
||||||
|
case a + m * 22: \
|
||||||
|
case a + m * 23: \
|
||||||
|
case a + m * 24: \
|
||||||
|
case a + m * 25: \
|
||||||
|
case a + m * 26: \
|
||||||
|
case a + m * 27: \
|
||||||
|
case a + m * 28: \
|
||||||
|
case a + m * 29: \
|
||||||
|
case a + m * 30: \
|
||||||
|
case a + m * 31: \
|
||||||
|
index = (cmd - a) / m; \
|
||||||
|
case a \
|
||||||
|
|
||||||
void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count)
|
void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u32 count)
|
||||||
{
|
{
|
||||||
#if CMD_DEBUG
|
#if CMD_DEBUG
|
||||||
|
@ -170,6 +205,13 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||||
//ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location);
|
//ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location);
|
||||||
tex.SetOffset(tex_addr);
|
tex.SetOffset(tex_addr);
|
||||||
tex.SetFormat(cubemap, dimension, format, mipmap);
|
tex.SetFormat(cubemap, dimension, format, mipmap);
|
||||||
|
|
||||||
|
if(!tex.m_width || !tex.m_height)
|
||||||
|
{
|
||||||
|
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr);
|
||||||
|
if(!tex.m_width) tex.m_width = re(buffers[m_gcm_current_buffer].width);
|
||||||
|
if(!tex.m_height) tex.m_height = re(buffers[m_gcm_current_buffer].height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -308,10 +350,24 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||||
{
|
{
|
||||||
RSXTexture& tex = m_textures[index];
|
RSXTexture& tex = m_textures[index];
|
||||||
|
|
||||||
const u16 height = args[0] & 0xffff;
|
u16 height = args[0] & 0xffff;
|
||||||
const u16 width = args[0] >> 16;
|
u16 width = args[0] >> 16;
|
||||||
CMD_LOG("width=%d, height=%d", width, height);
|
CMD_LOG("width=%d, height=%d", width, height);
|
||||||
|
|
||||||
|
if(!width || !height)
|
||||||
|
{
|
||||||
|
ConLog.Warning("Bad texture rect: %dx%d (%dx%d)", width, height, tex.m_width, tex.m_height);
|
||||||
|
for(int i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
ConLog.Warning("*** 0x%x", args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!width) width = tex.m_width;
|
||||||
|
if(!height) height = tex.m_height;
|
||||||
|
}
|
||||||
tex.SetRect(width, height);
|
tex.SetRect(width, height);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -665,6 +721,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||||
|
|
||||||
case NV4097_SET_TRANSFORM_PROGRAM_LOAD:
|
case NV4097_SET_TRANSFORM_PROGRAM_LOAD:
|
||||||
{
|
{
|
||||||
|
//ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM_LOAD: prog = %d", args[0]);
|
||||||
|
|
||||||
m_cur_vertex_prog = &m_vertex_progs[args[0]];
|
m_cur_vertex_prog = &m_vertex_progs[args[0]];
|
||||||
m_cur_vertex_prog->data.Clear();
|
m_cur_vertex_prog->data.Clear();
|
||||||
|
|
||||||
|
@ -677,8 +735,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_TRANSFORM_PROGRAM:
|
case_32(NV4097_SET_TRANSFORM_PROGRAM, 4):
|
||||||
{
|
{
|
||||||
|
//ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count);
|
||||||
|
|
||||||
if(!m_cur_vertex_prog)
|
if(!m_cur_vertex_prog)
|
||||||
{
|
{
|
||||||
ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog == NULL");
|
ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog == NULL");
|
||||||
|
|
|
@ -226,7 +226,7 @@ class RSXThread : public ThreadBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const uint m_textures_count = 16;
|
static const uint m_textures_count = 16;
|
||||||
static const uint m_vertex_count = 16;
|
static const uint m_vertex_count = 32;
|
||||||
static const uint m_fragment_count = 16;
|
static const uint m_fragment_count = 16;
|
||||||
static const uint m_tiles_count = 15;
|
static const uint m_tiles_count = 15;
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,24 @@ struct Button
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AnalogStick
|
||||||
|
{
|
||||||
|
u32 m_offset;
|
||||||
|
u32 m_keyCodeMin;
|
||||||
|
u32 m_keyCodeMax;
|
||||||
|
bool m_min_pressed;
|
||||||
|
bool m_max_pressed;
|
||||||
|
|
||||||
|
AnalogStick(u32 offset, u32 keyCodeMin, u32 keyCodeMax)
|
||||||
|
: m_min_pressed(false)
|
||||||
|
, m_max_pressed(false)
|
||||||
|
, m_offset(offset)
|
||||||
|
, m_keyCodeMin(keyCodeMin)
|
||||||
|
, m_keyCodeMax(keyCodeMax)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Pad
|
struct Pad
|
||||||
{
|
{
|
||||||
u32 m_port_status;
|
u32 m_port_status;
|
||||||
|
@ -111,6 +129,7 @@ struct Pad
|
||||||
u32 m_device_type;
|
u32 m_device_type;
|
||||||
|
|
||||||
Array<Button> m_buttons;
|
Array<Button> m_buttons;
|
||||||
|
Array<AnalogStick> m_sticks;
|
||||||
|
|
||||||
s16 m_analog_left_x;
|
s16 m_analog_left_x;
|
||||||
s16 m_analog_left_y;
|
s16 m_analog_left_y;
|
||||||
|
@ -166,7 +185,7 @@ struct Pad
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~Pad() { m_buttons.Clear(); }
|
~Pad() { m_buttons.Clear(); m_sticks.Clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PadInfo
|
struct PadInfo
|
||||||
|
@ -206,10 +225,29 @@ public:
|
||||||
button.m_pressed = pressed;
|
button.m_pressed = pressed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(u32 s = 0; s < GetSticks(p).GetCount(); s++)
|
||||||
|
{
|
||||||
|
AnalogStick& stick = GetSticks(p).Get(s);
|
||||||
|
if (stick.m_keyCodeMax != code && stick.m_keyCodeMin != code) continue;
|
||||||
|
|
||||||
|
GetPads()[p].m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||||
|
|
||||||
|
if (stick.m_keyCodeMax == code)
|
||||||
|
{
|
||||||
|
stick.m_min_pressed = false; //!!! need fix !!!
|
||||||
|
stick.m_max_pressed = pressed;
|
||||||
|
}
|
||||||
|
if (stick.m_keyCodeMin == code)
|
||||||
|
{
|
||||||
|
stick.m_max_pressed = false; //!!!
|
||||||
|
stick.m_min_pressed = pressed;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PadInfo& GetInfo() { return m_info; }
|
PadInfo& GetInfo() { return m_info; }
|
||||||
Array<Pad>& GetPads() { return m_pads; }
|
Array<Pad>& GetPads() { return m_pads; }
|
||||||
Array<Button>& GetButtons(const u32 pad) { return GetPads()[pad].m_buttons; }
|
Array<Button>& GetButtons(const u32 pad) { return GetPads()[pad].m_buttons; }
|
||||||
|
Array<AnalogStick>& GetSticks(const u32 pad) { return GetPads()[pad].m_sticks; }
|
||||||
};
|
};
|
|
@ -56,5 +56,10 @@ public:
|
||||||
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, static_cast<char>(Ini.PadHandlerL1.GetValue()), CELL_PAD_CTRL_L1));
|
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, static_cast<char>(Ini.PadHandlerL1.GetValue()), CELL_PAD_CTRL_L1));
|
||||||
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, static_cast<char>(Ini.PadHandlerR2.GetValue()), CELL_PAD_CTRL_R2));
|
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, static_cast<char>(Ini.PadHandlerR2.GetValue()), CELL_PAD_CTRL_R2));
|
||||||
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, static_cast<char>(Ini.PadHandlerL2.GetValue()), CELL_PAD_CTRL_L2));
|
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, static_cast<char>(Ini.PadHandlerL2.GetValue()), CELL_PAD_CTRL_L2));
|
||||||
|
|
||||||
|
m_pads[0].m_sticks.Move(new AnalogStick(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X, WXK_LEFT, WXK_RIGHT));
|
||||||
|
m_pads[0].m_sticks.Move(new AnalogStick(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, WXK_UP, WXK_DOWN));
|
||||||
|
m_pads[0].m_sticks.Move(new AnalogStick(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, WXK_HOME, WXK_END));
|
||||||
|
m_pads[0].m_sticks.Move(new AnalogStick(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, WXK_PAGEUP, WXK_PAGEDOWN));
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -419,12 +419,27 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetAddr() const { return m_addr; }
|
__forceinline u32 GetAddr() const { return m_addr; }
|
||||||
|
|
||||||
bool IsGood() const
|
__forceinline bool IsGood() const
|
||||||
{
|
{
|
||||||
return Memory.IsGoodAddr(m_addr, sizeof(T));
|
return Memory.IsGoodAddr(m_addr, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline operator u32() const
|
||||||
|
{
|
||||||
|
return m_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline bool operator != (nullptr_t) const
|
||||||
|
{
|
||||||
|
return m_addr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline bool operator == (nullptr_t) const
|
||||||
|
{
|
||||||
|
return m_addr == 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -435,6 +450,9 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename NT> operator mem_ptr_t<NT>&() { return (mem_ptr_t<NT>&)*this; }
|
||||||
|
template<typename NT> operator const mem_ptr_t<NT>&() const { return (const mem_ptr_t<NT>&)*this; }
|
||||||
|
|
||||||
T* operator -> ()
|
T* operator -> ()
|
||||||
{
|
{
|
||||||
return (T*)&Memory[this->m_addr];
|
return (T*)&Memory[this->m_addr];
|
||||||
|
@ -513,8 +531,6 @@ public:
|
||||||
return (const T&)Memory[this->m_addr + sizeof(T) * index];
|
return (const T&)Memory[this->m_addr + sizeof(T) * index];
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const { return this->m_addr == 0; }
|
|
||||||
|
|
||||||
bool operator == (mem_ptr_t right) const { return this->m_addr == right.m_addr; }
|
bool operator == (mem_ptr_t right) const { return this->m_addr == right.m_addr; }
|
||||||
bool operator != (mem_ptr_t right) const { return this->m_addr != right.m_addr; }
|
bool operator != (mem_ptr_t right) const { return this->m_addr != right.m_addr; }
|
||||||
bool operator > (mem_ptr_t right) const { return this->m_addr > right.m_addr; }
|
bool operator > (mem_ptr_t right) const { return this->m_addr > right.m_addr; }
|
||||||
|
@ -530,6 +546,32 @@ public:
|
||||||
bool operator <= (T* right) const { return (T*)&Memory[this->m_addr] <= right; }
|
bool operator <= (T* right) const { return (T*)&Memory[this->m_addr] <= right; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class mem_ptr_t<void> : public mem_base_t<u8>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mem_ptr_t(u32 addr) : mem_base_t<u8>(addr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename NT> operator mem_ptr_t<NT>&() { return (mem_ptr_t<NT>&)*this; }
|
||||||
|
template<typename NT> operator const mem_ptr_t<NT>&() const { return (const mem_ptr_t<NT>&)*this; }
|
||||||
|
|
||||||
|
bool operator == (mem_ptr_t right) const { return this->m_addr == right.m_addr; }
|
||||||
|
bool operator != (mem_ptr_t right) const { return this->m_addr != right.m_addr; }
|
||||||
|
bool operator > (mem_ptr_t right) const { return this->m_addr > right.m_addr; }
|
||||||
|
bool operator < (mem_ptr_t right) const { return this->m_addr < right.m_addr; }
|
||||||
|
bool operator >= (mem_ptr_t right) const { return this->m_addr >= right.m_addr; }
|
||||||
|
bool operator <= (mem_ptr_t right) const { return this->m_addr <= right.m_addr; }
|
||||||
|
|
||||||
|
bool operator == (void* right) const { return (void*)&Memory[this->m_addr] == right; }
|
||||||
|
bool operator != (void* right) const { return (void*)&Memory[this->m_addr] != right; }
|
||||||
|
bool operator > (void* right) const { return (void*)&Memory[this->m_addr] > right; }
|
||||||
|
bool operator < (void* right) const { return (void*)&Memory[this->m_addr] < right; }
|
||||||
|
bool operator >= (void* right) const { return (void*)&Memory[this->m_addr] >= right; }
|
||||||
|
bool operator <= (void* right) const { return (void*)&Memory[this->m_addr] <= right; }
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T> static bool operator == (T* left, mem_ptr_t<T> right) { return left == (T*)&Memory[right.GetAddr()]; }
|
template<typename T> static bool operator == (T* left, mem_ptr_t<T> right) { return left == (T*)&Memory[right.GetAddr()]; }
|
||||||
template<typename T> static bool operator != (T* left, mem_ptr_t<T> right) { return left != (T*)&Memory[right.GetAddr()]; }
|
template<typename T> static bool operator != (T* left, mem_ptr_t<T> right) { return left != (T*)&Memory[right.GetAddr()]; }
|
||||||
template<typename T> static bool operator > (T* left, mem_ptr_t<T> right) { return left > (T*)&Memory[right.GetAddr()]; }
|
template<typename T> static bool operator > (T* left, mem_ptr_t<T> right) { return left > (T*)&Memory[right.GetAddr()]; }
|
||||||
|
@ -551,6 +593,11 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline T GetValue()
|
||||||
|
{
|
||||||
|
return (be_t<T>&)Memory[this->m_addr];
|
||||||
|
}
|
||||||
|
|
||||||
operator const T() const
|
operator const T() const
|
||||||
{
|
{
|
||||||
return (be_t<T>&)Memory[this->m_addr];
|
return (be_t<T>&)Memory[this->m_addr];
|
||||||
|
@ -639,6 +686,123 @@ public:
|
||||||
void SetAddr(const u64 addr) { m_addr = addr; }
|
void SetAddr(const u64 addr) { m_addr = addr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T> class mem_func_ptr_t;
|
||||||
|
|
||||||
|
template<typename RT>
|
||||||
|
class mem_func_ptr_t<RT (*)()> : public mem_base_t<u64>
|
||||||
|
{
|
||||||
|
__forceinline void call_func(bool is_async)
|
||||||
|
{
|
||||||
|
Callback cb;
|
||||||
|
cb.SetAddr(m_addr);
|
||||||
|
cb.Branch(!is_async);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
__forceinline void operator()()
|
||||||
|
{
|
||||||
|
call_func(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void async()
|
||||||
|
{
|
||||||
|
call_func(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename RT, typename T1>
|
||||||
|
class mem_func_ptr_t<RT (*)(T1)> : public mem_base_t<u64>
|
||||||
|
{
|
||||||
|
__forceinline void call_func(bool is_async, T1 a1)
|
||||||
|
{
|
||||||
|
Callback cb;
|
||||||
|
cb.SetAddr(m_addr);
|
||||||
|
cb.Handle(a1);
|
||||||
|
cb.Branch(!is_async);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
__forceinline void operator()(T1 a1)
|
||||||
|
{
|
||||||
|
call_func(false, a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void async(T1 a1)
|
||||||
|
{
|
||||||
|
call_func(true, a1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename RT, typename T1, typename T2>
|
||||||
|
class mem_func_ptr_t<RT (*)(T1, T2)> : public mem_base_t<u64>
|
||||||
|
{
|
||||||
|
__forceinline void call_func(bool is_async, T1 a1, T2 a2)
|
||||||
|
{
|
||||||
|
Callback cb;
|
||||||
|
cb.SetAddr(m_addr);
|
||||||
|
cb.Handle(a1, a2);
|
||||||
|
cb.Branch(!is_async);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
__forceinline void operator()(T1 a1, T2 a2)
|
||||||
|
{
|
||||||
|
call_func(false, a1, a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void async(T1 a1, T2 a2)
|
||||||
|
{
|
||||||
|
call_func(true, a1, a2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename RT, typename T1, typename T2, typename T3>
|
||||||
|
class mem_func_ptr_t<RT (*)(T1, T2, T3)> : public mem_base_t<u64>
|
||||||
|
{
|
||||||
|
__forceinline void call_func(bool is_async, T1 a1, T2 a2, T3 a3)
|
||||||
|
{
|
||||||
|
Callback cb;
|
||||||
|
cb.SetAddr(m_addr);
|
||||||
|
cb.Handle(a1, a2, a3);
|
||||||
|
cb.Branch(!is_async);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
__forceinline void operator()(T1 a1, T2 a2, T3 a3)
|
||||||
|
{
|
||||||
|
call_func(false, a1, a2, a3);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void async(T1 a1, T2 a2, T3 a3)
|
||||||
|
{
|
||||||
|
call_func(true, a1, a2, a3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename RT, typename T1, typename T2, typename T3, typename T4>
|
||||||
|
class mem_func_ptr_t<RT (*)(T1, T2, T3, T4)> : public mem_base_t<u64>
|
||||||
|
{
|
||||||
|
__forceinline void call_func(bool is_async, T1 a1, T2 a2, T3 a3, T4 a4)
|
||||||
|
{
|
||||||
|
Callback cb;
|
||||||
|
cb.SetAddr(m_addr);
|
||||||
|
cb.Handle(a1, a2, a3, a4);
|
||||||
|
cb.Branch(!is_async);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
__forceinline void operator()(T1 a1, T2 a2, T3 a3, T4 a4)
|
||||||
|
{
|
||||||
|
call_func(false, a1, a2, a3, a4);
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void async(T1 a1, T2 a2, T3 a3, T4 a4)
|
||||||
|
{
|
||||||
|
call_func(true, a1, a2, a3, a4);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class MemoryAllocator
|
class MemoryAllocator
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,9 @@ Callback::Callback(u32 slot, u64 addr)
|
||||||
, a1(0)
|
, a1(0)
|
||||||
, a2(0)
|
, a2(0)
|
||||||
, a3(0)
|
, a3(0)
|
||||||
|
, a4(0)
|
||||||
, m_has_data(false)
|
, m_has_data(false)
|
||||||
|
, m_name("Callback")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +40,12 @@ bool Callback::HasData() const
|
||||||
return m_has_data;
|
return m_has_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Callback::Handle(u64 _a1, u64 _a2, u64 _a3)
|
void Callback::Handle(u64 _a1, u64 _a2, u64 _a3, u64 _a4)
|
||||||
{
|
{
|
||||||
a1 = _a1;
|
a1 = _a1;
|
||||||
a2 = _a2;
|
a2 = _a2;
|
||||||
a3 = _a3;
|
a3 = _a3;
|
||||||
|
a4 = _a4;
|
||||||
m_has_data = true;
|
m_has_data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +58,12 @@ void Callback::Branch(bool wait)
|
||||||
new_thread.SetEntry(m_addr);
|
new_thread.SetEntry(m_addr);
|
||||||
new_thread.SetPrio(1001);
|
new_thread.SetPrio(1001);
|
||||||
new_thread.SetStackSize(0x10000);
|
new_thread.SetStackSize(0x10000);
|
||||||
new_thread.SetName("Callback");
|
new_thread.SetName(m_name);
|
||||||
|
|
||||||
new_thread.SetArg(0, a1);
|
new_thread.SetArg(0, a1);
|
||||||
new_thread.SetArg(1, a2);
|
new_thread.SetArg(1, a2);
|
||||||
new_thread.SetArg(2, a3);
|
new_thread.SetArg(2, a3);
|
||||||
|
new_thread.SetArg(3, a4);
|
||||||
new_thread.Run();
|
new_thread.Run();
|
||||||
|
|
||||||
new_thread.Exec();
|
new_thread.Exec();
|
||||||
|
@ -68,6 +72,11 @@ void Callback::Branch(bool wait)
|
||||||
GetCurrentPPCThread()->Wait(new_thread);
|
GetCurrentPPCThread()->Wait(new_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Callback::SetName(const std::string& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
Callback::operator bool() const
|
Callback::operator bool() const
|
||||||
{
|
{
|
||||||
return GetAddr() != 0;
|
return GetAddr() != 0;
|
||||||
|
|
|
@ -8,10 +8,13 @@ protected:
|
||||||
|
|
||||||
bool m_has_data;
|
bool m_has_data;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
u64 a1;
|
u64 a1;
|
||||||
u64 a2;
|
u64 a2;
|
||||||
u64 a3;
|
u64 a3;
|
||||||
|
u64 a4;
|
||||||
|
|
||||||
u32 GetSlot() const;
|
u32 GetSlot() const;
|
||||||
u64 GetAddr() const;
|
u64 GetAddr() const;
|
||||||
|
@ -20,8 +23,9 @@ public:
|
||||||
bool HasData() const;
|
bool HasData() const;
|
||||||
|
|
||||||
Callback(u32 slot = 0, u64 addr = 0);
|
Callback(u32 slot = 0, u64 addr = 0);
|
||||||
void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0);
|
void Handle(u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0);
|
||||||
void Branch(bool wait);
|
void Branch(bool wait);
|
||||||
|
void SetName(const std::string& name);
|
||||||
|
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -570,6 +570,171 @@ s64 SysCalls::DoFunc(const u32 id)
|
||||||
case 0x56776c0d: FUNC_LOG_ERROR("TODO: cellKey2CharGetChar");
|
case 0x56776c0d: FUNC_LOG_ERROR("TODO: cellKey2CharGetChar");
|
||||||
case 0xabf629c1: FUNC_LOG_ERROR("TODO: cellKey2CharOpen");
|
case 0xabf629c1: FUNC_LOG_ERROR("TODO: cellKey2CharOpen");
|
||||||
case 0xbfc03768: FUNC_LOG_ERROR("TODO: cellKey2CharSetMode");
|
case 0xbfc03768: FUNC_LOG_ERROR("TODO: cellKey2CharSetMode");
|
||||||
|
case 0x005200e6: FUNC_LOG_ERROR("TODO: UCS2toEUCJP");
|
||||||
|
case 0x01b0cbf4: FUNC_LOG_ERROR("TODO: l10n_convert");
|
||||||
|
case 0x0356038c: FUNC_LOG_ERROR("TODO: UCS2toUTF32");
|
||||||
|
case 0x05028763: FUNC_LOG_ERROR("TODO: jis2kuten");
|
||||||
|
case 0x058addc8: FUNC_LOG_ERROR("TODO: UTF8toGB18030");
|
||||||
|
case 0x060ee3b2: FUNC_LOG_ERROR("TODO: JISstoUTF8s");
|
||||||
|
case 0x07168a83: FUNC_LOG_ERROR("TODO: SjisZen2Han");
|
||||||
|
case 0x0bc386c8: FUNC_LOG_ERROR("TODO: ToSjisLower");
|
||||||
|
case 0x0bedf77d: FUNC_LOG_ERROR("TODO: UCS2toGB18030");
|
||||||
|
case 0x0bf867e2: FUNC_LOG_ERROR("TODO: HZstoUCS2s");
|
||||||
|
case 0x0ce278fd: FUNC_LOG_ERROR("TODO: UCS2stoHZs");
|
||||||
|
case 0x0d90a48d: FUNC_LOG_ERROR("TODO: UCS2stoSJISs");
|
||||||
|
case 0x0f624540: FUNC_LOG_ERROR("TODO: kuten2eucjp");
|
||||||
|
case 0x14ee3649: FUNC_LOG_ERROR("TODO: sjis2jis");
|
||||||
|
case 0x14f504b8: FUNC_LOG_ERROR("TODO: EUCKRstoUCS2s");
|
||||||
|
case 0x16eaf5f1: FUNC_LOG_ERROR("TODO: UHCstoEUCKRs");
|
||||||
|
case 0x1758053c: FUNC_LOG_ERROR("TODO: jis2sjis");
|
||||||
|
case 0x1906ce6b: FUNC_LOG_ERROR("TODO: jstrnchk");
|
||||||
|
case 0x1ac0d23d: FUNC_LOG_ERROR("TODO: L10nConvert");
|
||||||
|
case 0x1ae2acee: FUNC_LOG_ERROR("TODO: EUCCNstoUTF8s");
|
||||||
|
case 0x1cb1138f: FUNC_LOG_ERROR("TODO: GBKstoUCS2s");
|
||||||
|
case 0x1da42d70: FUNC_LOG_ERROR("TODO: eucjphan2zen");
|
||||||
|
case 0x1ec712e0: FUNC_LOG_ERROR("TODO: ToSjisHira");
|
||||||
|
case 0x1fb50183: FUNC_LOG_ERROR("TODO: GBKtoUCS2");
|
||||||
|
case 0x21948c03: FUNC_LOG_ERROR("TODO: eucjp2jis");
|
||||||
|
case 0x21aa3045: FUNC_LOG_ERROR("TODO: UTF32stoUTF8s");
|
||||||
|
case 0x24fd32a9: FUNC_LOG_ERROR("TODO: sjishan2zen");
|
||||||
|
case 0x256b6861: FUNC_LOG_ERROR("TODO: UCS2toSBCS");
|
||||||
|
case 0x262a5ae2: FUNC_LOG_ERROR("TODO: UTF8stoGBKs");
|
||||||
|
case 0x28724522: FUNC_LOG_ERROR("TODO: UTF8toUCS2");
|
||||||
|
case 0x2ad091c6: FUNC_LOG_ERROR("TODO: UCS2stoUTF8s");
|
||||||
|
case 0x2b84030c: FUNC_LOG_ERROR("TODO: EUCKRstoUTF8s");
|
||||||
|
case 0x2efa7294: FUNC_LOG_ERROR("TODO: UTF16stoUTF32s");
|
||||||
|
case 0x2f9eb543: FUNC_LOG_ERROR("TODO: UTF8toEUCKR");
|
||||||
|
case 0x317ab7c2: FUNC_LOG_ERROR("TODO: UTF16toUTF8");
|
||||||
|
case 0x32689828: FUNC_LOG_ERROR("TODO: ARIBstoUTF8s");
|
||||||
|
case 0x33435818: FUNC_LOG_ERROR("TODO: SJISstoUTF8s");
|
||||||
|
case 0x33f8b35c: FUNC_LOG_ERROR("TODO: sjiszen2han");
|
||||||
|
case 0x3968f176: FUNC_LOG_ERROR("TODO: ToEucJpLower");
|
||||||
|
case 0x398a3dee: FUNC_LOG_ERROR("TODO: MSJIStoUTF8");
|
||||||
|
case 0x3a20bc34: FUNC_LOG_ERROR("TODO: UCS2stoMSJISs");
|
||||||
|
case 0x3dabd5a7: FUNC_LOG_ERROR("TODO: EUCJPtoUTF8");
|
||||||
|
case 0x3df65b64: FUNC_LOG_ERROR("TODO: eucjp2sjis");
|
||||||
|
case 0x408a622b: FUNC_LOG_ERROR("TODO: ToEucJpHira");
|
||||||
|
case 0x41b4a5ae: FUNC_LOG_ERROR("TODO: UHCstoUCS2s");
|
||||||
|
case 0x41ccf033: FUNC_LOG_ERROR("TODO: ToEucJpKata");
|
||||||
|
case 0x42838145: FUNC_LOG_ERROR("TODO: HZstoUTF8s");
|
||||||
|
case 0x4931b44e: FUNC_LOG_ERROR("TODO: UTF8toMSJIS");
|
||||||
|
case 0x4b3bbacb: FUNC_LOG_ERROR("TODO: BIG5toUTF8");
|
||||||
|
case 0x511d386b: FUNC_LOG_ERROR("TODO: EUCJPstoSJISs");
|
||||||
|
case 0x52b7883f: FUNC_LOG_ERROR("TODO: UTF8stoBIG5s");
|
||||||
|
case 0x53558b6b: FUNC_LOG_ERROR("TODO: UTF16stoUCS2s");
|
||||||
|
case 0x53764725: FUNC_LOG_ERROR("TODO: UCS2stoGB18030s");
|
||||||
|
case 0x53c71ac2: FUNC_LOG_ERROR("TODO: EUCJPtoSJIS");
|
||||||
|
case 0x54f59807: FUNC_LOG_ERROR("TODO: EUCJPtoUCS2");
|
||||||
|
case 0x55f6921c: FUNC_LOG_ERROR("TODO: UCS2stoGBKs");
|
||||||
|
case 0x58246762: FUNC_LOG_ERROR("TODO: EUCKRtoUHC");
|
||||||
|
case 0x596df41c: FUNC_LOG_ERROR("TODO: UCS2toSJIS");
|
||||||
|
case 0x5a4ab223: FUNC_LOG_ERROR("TODO: MSJISstoUTF8s");
|
||||||
|
case 0x5ac783dc: FUNC_LOG_ERROR("TODO: EUCJPstoUTF8s");
|
||||||
|
case 0x5b684dfb: FUNC_LOG_ERROR("TODO: UCS2toBIG5");
|
||||||
|
case 0x5cd29270: FUNC_LOG_ERROR("TODO: UTF8stoEUCKRs");
|
||||||
|
case 0x5e1d9330: FUNC_LOG_ERROR("TODO: UHCstoUTF8s");
|
||||||
|
case 0x60ffa0ec: FUNC_LOG_ERROR("TODO: GB18030stoUCS2s");
|
||||||
|
case 0x6122e000: FUNC_LOG_ERROR("TODO: SJIStoUTF8");
|
||||||
|
case 0x6169f205: FUNC_LOG_ERROR("TODO: JISstoSJISs");
|
||||||
|
case 0x61fb9442: FUNC_LOG_ERROR("TODO: UTF8toUTF16");
|
||||||
|
case 0x62b36bcf: FUNC_LOG_ERROR("TODO: UTF8stoMSJISs");
|
||||||
|
case 0x63219199: FUNC_LOG_ERROR("TODO: EUCKRtoUTF8");
|
||||||
|
case 0x638c2fc1: FUNC_LOG_ERROR("TODO: SjisHan2Zen");
|
||||||
|
case 0x64a10ec8: FUNC_LOG_ERROR("TODO: UCS2toUTF16");
|
||||||
|
case 0x65444204: FUNC_LOG_ERROR("TODO: UCS2toMSJIS");
|
||||||
|
case 0x6621a82c: FUNC_LOG_ERROR("TODO: sjis2kuten");
|
||||||
|
case 0x6a6f25d1: FUNC_LOG_ERROR("TODO: UCS2toUHC");
|
||||||
|
case 0x6c62d879: FUNC_LOG_ERROR("TODO: UTF32toUCS2");
|
||||||
|
case 0x6de4b508: FUNC_LOG_ERROR("TODO: ToSjisUpper");
|
||||||
|
case 0x6e0705c4: FUNC_LOG_ERROR("TODO: UTF8toEUCJP");
|
||||||
|
case 0x6e5906fd: FUNC_LOG_ERROR("TODO: UCS2stoEUCJPs");
|
||||||
|
case 0x6fc530b3: FUNC_LOG_ERROR("TODO: UTF16toUCS2");
|
||||||
|
case 0x714a9b4a: FUNC_LOG_ERROR("TODO: UCS2stoUTF16s");
|
||||||
|
case 0x71804d64: FUNC_LOG_ERROR("TODO: UCS2stoEUCCNs");
|
||||||
|
case 0x72632e53: FUNC_LOG_ERROR("TODO: SBCSstoUTF8s");
|
||||||
|
case 0x73f2cd21: FUNC_LOG_ERROR("TODO: SJISstoJISs");
|
||||||
|
case 0x74496718: FUNC_LOG_ERROR("TODO: SBCStoUTF8");
|
||||||
|
case 0x74871fe0: FUNC_LOG_ERROR("TODO: UTF8toUTF32");
|
||||||
|
case 0x750c363d: FUNC_LOG_ERROR("TODO: jstrchk");
|
||||||
|
case 0x7c5bde1c: FUNC_LOG_ERROR("TODO: UHCtoEUCKR");
|
||||||
|
case 0x7c912bda: FUNC_LOG_ERROR("TODO: kuten2jis");
|
||||||
|
case 0x7d07a1c2: FUNC_LOG_ERROR("TODO: UTF8toEUCCN");
|
||||||
|
case 0x8171c1cc: FUNC_LOG_ERROR("TODO: EUCCNtoUTF8");
|
||||||
|
case 0x82d5ecdf: FUNC_LOG_ERROR("TODO: EucJpZen2Han");
|
||||||
|
case 0x8555fe15: FUNC_LOG_ERROR("TODO: UTF32stoUTF16s");
|
||||||
|
case 0x860fc741: FUNC_LOG_ERROR("TODO: GBKtoUTF8");
|
||||||
|
case 0x867f7b8b: FUNC_LOG_ERROR("TODO: ToEucJpUpper");
|
||||||
|
case 0x88f8340b: FUNC_LOG_ERROR("TODO: UCS2stoJISs");
|
||||||
|
case 0x89236c86: FUNC_LOG_ERROR("TODO: UTF8stoGB18030s");
|
||||||
|
case 0x8a56f148: FUNC_LOG_ERROR("TODO: EUCKRstoUHCs");
|
||||||
|
case 0x8ccdba38: FUNC_LOG_ERROR("TODO: UTF8stoUTF32s");
|
||||||
|
case 0x8f472054: FUNC_LOG_ERROR("TODO: UTF8stoEUCCNs");
|
||||||
|
case 0x90e9b5d2: FUNC_LOG_ERROR("TODO: EUCJPstoUCS2s");
|
||||||
|
case 0x91a99765: FUNC_LOG_ERROR("TODO: UHCtoUCS2");
|
||||||
|
case 0x931ff25a: FUNC_LOG_ERROR("TODO: L10nConvertStr");
|
||||||
|
case 0x949bb14c: FUNC_LOG_ERROR("TODO: GBKstoUTF8s");
|
||||||
|
case 0x9557ac9b: FUNC_LOG_ERROR("TODO: UTF8toUHC");
|
||||||
|
case 0x9768b6d3: FUNC_LOG_ERROR("TODO: UTF32toUTF8");
|
||||||
|
case 0x9874020d: FUNC_LOG_ERROR("TODO: sjis2eucjp");
|
||||||
|
case 0x9a0e7d23: FUNC_LOG_ERROR("TODO: UCS2toEUCCN");
|
||||||
|
case 0x9a13d6b8: FUNC_LOG_ERROR("TODO: UTF8stoUHCs");
|
||||||
|
case 0x9a72059d: FUNC_LOG_ERROR("TODO: EUCKRtoUCS2");
|
||||||
|
case 0x9b1210c6: FUNC_LOG_ERROR("TODO: UTF32toUTF16");
|
||||||
|
case 0x9cd8135b: FUNC_LOG_ERROR("TODO: EUCCNstoUCS2s");
|
||||||
|
case 0x9ce52809: FUNC_LOG_ERROR("TODO: SBCSstoUCS2s");
|
||||||
|
case 0x9cf1ab77: FUNC_LOG_ERROR("TODO: UTF8stoJISs");
|
||||||
|
case 0x9d14dc46: FUNC_LOG_ERROR("TODO: ToSjisKata");
|
||||||
|
case 0x9dcde367: FUNC_LOG_ERROR("TODO: jis2eucjp");
|
||||||
|
case 0x9ec52258: FUNC_LOG_ERROR("TODO: BIG5toUCS2");
|
||||||
|
case 0xa0d463c0: FUNC_LOG_ERROR("TODO: UCS2toGBK");
|
||||||
|
case 0xa19fb9de: FUNC_LOG_ERROR("TODO: UTF16toUTF32");
|
||||||
|
case 0xa298cad2: FUNC_LOG_ERROR("TODO: l10n_convert_str");
|
||||||
|
case 0xa34fa0eb: FUNC_LOG_ERROR("TODO: EUCJPstoJISs");
|
||||||
|
case 0xa5146299: FUNC_LOG_ERROR("TODO: UTF8stoARIBs");
|
||||||
|
case 0xa609f3e9: FUNC_LOG_ERROR("TODO: JISstoEUCJPs");
|
||||||
|
case 0xa60ff5c9: FUNC_LOG_ERROR("TODO: EucJpHan2Zen");
|
||||||
|
case 0xa963619c: FUNC_LOG_ERROR("TODO: isEucJpKigou");
|
||||||
|
case 0xa9a76fb8: FUNC_LOG_ERROR("TODO: UCS2toUTF8");
|
||||||
|
case 0xaf18d499: FUNC_LOG_ERROR("TODO: GB18030toUCS2");
|
||||||
|
case 0xb3361be6: FUNC_LOG_ERROR("TODO: UHCtoUTF8");
|
||||||
|
case 0xb6e45343: FUNC_LOG_ERROR("TODO: MSJIStoUCS2");
|
||||||
|
case 0xb7cef4a6: FUNC_LOG_ERROR("TODO: UTF8toGBK");
|
||||||
|
case 0xb7e08f7a: FUNC_LOG_ERROR("TODO: kuten2sjis");
|
||||||
|
case 0xb9cf473d: FUNC_LOG_ERROR("TODO: UTF8toSBCS");
|
||||||
|
case 0xbdd44ee3: FUNC_LOG_ERROR("TODO: SJIStoUCS2");
|
||||||
|
case 0xbe42e661: FUNC_LOG_ERROR("TODO: eucjpzen2han");
|
||||||
|
case 0xbe8d5485: FUNC_LOG_ERROR("TODO: UCS2stoARIBs");
|
||||||
|
case 0xbefe3869: FUNC_LOG_ERROR("TODO: isSjisKigou");
|
||||||
|
case 0xc62b758d: FUNC_LOG_ERROR("TODO: UTF8stoEUCJPs");
|
||||||
|
case 0xc7bdcb4c: FUNC_LOG_ERROR("TODO: UCS2toEUCKR");
|
||||||
|
case 0xc944fa56: FUNC_LOG_ERROR("TODO: SBCStoUCS2");
|
||||||
|
case 0xc9b78f58: FUNC_LOG_ERROR("TODO: MSJISstoUCS2s");
|
||||||
|
case 0xcc1633cc: FUNC_LOG_ERROR("TODO: l10n_get_converter");
|
||||||
|
case 0xd02ef83d: FUNC_LOG_ERROR("TODO: GB18030stoUTF8s");
|
||||||
|
case 0xd8721e2c: FUNC_LOG_ERROR("TODO: SJISstoEUCJPs");
|
||||||
|
case 0xd8cb24cb: FUNC_LOG_ERROR("TODO: UTF32stoUCS2s");
|
||||||
|
case 0xd990858b: FUNC_LOG_ERROR("TODO: BIG5stoUTF8s");
|
||||||
|
case 0xd9fb1224: FUNC_LOG_ERROR("TODO: EUCCNtoUCS2");
|
||||||
|
case 0xda67b37f: FUNC_LOG_ERROR("TODO: UTF8stoSBCSs");
|
||||||
|
case 0xdc54886c: FUNC_LOG_ERROR("TODO: UCS2stoEUCKRs");
|
||||||
|
case 0xdd5ebdeb: FUNC_LOG_ERROR("TODO: UTF8stoSJISs");
|
||||||
|
case 0xdefa1c17: FUNC_LOG_ERROR("TODO: UTF8stoHZs");
|
||||||
|
case 0xe2eabb32: FUNC_LOG_ERROR("TODO: eucjp2kuten");
|
||||||
|
case 0xe6d9e234: FUNC_LOG_ERROR("TODO: UTF8toBIG5");
|
||||||
|
case 0xe6f5711b: FUNC_LOG_ERROR("TODO: UTF16stoUTF8s");
|
||||||
|
case 0xe956dc64: FUNC_LOG_ERROR("TODO: JISstoUCS2s");
|
||||||
|
case 0xeabc3d00: FUNC_LOG_ERROR("TODO: GB18030toUTF8");
|
||||||
|
case 0xeb3dc670: FUNC_LOG_ERROR("TODO: UTF8toSJIS");
|
||||||
|
case 0xeb41cc68: FUNC_LOG_ERROR("TODO: ARIBstoUCS2s");
|
||||||
|
case 0xeb685b83: FUNC_LOG_ERROR("TODO: UCS2stoUTF32s");
|
||||||
|
case 0xebae29c0: FUNC_LOG_ERROR("TODO: UCS2stoSBCSs");
|
||||||
|
case 0xee6c6a39: FUNC_LOG_ERROR("TODO: UCS2stoBIG5s");
|
||||||
|
case 0xf1dcfa71: FUNC_LOG_ERROR("TODO: UCS2stoUHCs");
|
||||||
|
case 0xf439728e: FUNC_LOG_ERROR("TODO: SJIStoEUCJP");
|
||||||
|
case 0xf7681b9a: FUNC_LOG_ERROR("TODO: UTF8stoUTF16s");
|
||||||
|
case 0xf9b1896d: FUNC_LOG_ERROR("TODO: SJISstoUCS2s");
|
||||||
|
case 0xfa4a675a: FUNC_LOG_ERROR("TODO: BIG5stoUCS2s");
|
||||||
|
case 0xfdbf6ac5: FUNC_LOG_ERROR("TODO: UTF8stoUCS2s");
|
||||||
case 0x0252efcc: FUNC_LOG_ERROR("TODO: cellUserTraceInit");
|
case 0x0252efcc: FUNC_LOG_ERROR("TODO: cellUserTraceInit");
|
||||||
case 0x05893e7c: FUNC_LOG_ERROR("TODO: cellUserTraceRegister");
|
case 0x05893e7c: FUNC_LOG_ERROR("TODO: cellUserTraceRegister");
|
||||||
case 0x6d045c2e: FUNC_LOG_ERROR("TODO: cellUserTraceUnregister");
|
case 0x6d045c2e: FUNC_LOG_ERROR("TODO: cellUserTraceUnregister");
|
||||||
|
|
|
@ -19,7 +19,7 @@ static const g_module_list[] =
|
||||||
{0x0002, "cellHttpUtil"},
|
{0x0002, "cellHttpUtil"},
|
||||||
{0x0003, "cellSsl"},
|
{0x0003, "cellSsl"},
|
||||||
{0x0004, "cellHttps"},
|
{0x0004, "cellHttps"},
|
||||||
{0x0005, "cellVdec"},
|
{0x0005, "libvdec"},
|
||||||
{0x0006, "cellAdec"},
|
{0x0006, "cellAdec"},
|
||||||
{0x0007, "cellDmux"},
|
{0x0007, "cellDmux"},
|
||||||
{0x0008, "cellVpost"},
|
{0x0008, "cellVpost"},
|
||||||
|
@ -90,7 +90,6 @@ static const g_module_list[] =
|
||||||
{0x0050, "cellSpursJq"},
|
{0x0050, "cellSpursJq"},
|
||||||
{0x0052, "cellPngEnc"},
|
{0x0052, "cellPngEnc"},
|
||||||
{0x0053, "cellMusicDecode2"},
|
{0x0053, "cellMusicDecode2"},
|
||||||
{0x0054, "cellSync"},
|
|
||||||
{0x0055, "cellSync2"},
|
{0x0055, "cellSync2"},
|
||||||
{0x0056, "cellNpUtil"},
|
{0x0056, "cellNpUtil"},
|
||||||
{0x0057, "cellRudp"},
|
{0x0057, "cellRudp"},
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "Emu/Audio/cellAudio.h"
|
#include "Emu/Audio/cellAudio.h"
|
||||||
|
|
||||||
void cellAudio_init();
|
void cellAudio_init();
|
||||||
Module cellAudio(0x0011, cellAudio_init);
|
void cellAudio_unload();
|
||||||
|
Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -81,9 +82,9 @@ struct CellAudioPortConfig
|
||||||
|
|
||||||
struct CellAudioConfig //custom structure
|
struct CellAudioConfig //custom structure
|
||||||
{
|
{
|
||||||
bool g_is_audio_initialized;
|
bool m_is_audio_initialized;
|
||||||
bool g_is_audio_port_open;
|
bool m_is_audio_port_open;
|
||||||
bool g_is_audio_port_started;
|
bool m_is_audio_port_started;
|
||||||
};
|
};
|
||||||
|
|
||||||
CellAudioPortParam* m_param = new CellAudioPortParam;
|
CellAudioPortParam* m_param = new CellAudioPortParam;
|
||||||
|
@ -95,55 +96,55 @@ typedef void * CellAANHandle;
|
||||||
|
|
||||||
struct CellSSPlayerConfig
|
struct CellSSPlayerConfig
|
||||||
{
|
{
|
||||||
u32 channels;
|
be_t<u32> channels;
|
||||||
u32 outputMode;
|
be_t<u32> outputMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSSPlayerWaveParam
|
struct CellSSPlayerWaveParam
|
||||||
{
|
{
|
||||||
void *addr;
|
void *addr;
|
||||||
int format;
|
be_t<s32> format;
|
||||||
u32 samples;
|
be_t<u32> samples;
|
||||||
u32 loopStartOffset;
|
be_t<u32> loopStartOffset;
|
||||||
u32 startOffset;
|
be_t<u32> startOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSSPlayerCommonParam
|
struct CellSSPlayerCommonParam
|
||||||
{
|
{
|
||||||
u32 loopMode;
|
be_t<u32> loopMode;
|
||||||
u32 attackMode;
|
be_t<u32> attackMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSurMixerPosition
|
struct CellSurMixerPosition
|
||||||
{
|
{
|
||||||
float x;
|
be_t<float> x;
|
||||||
float y;
|
be_t<float> y;
|
||||||
float z;
|
be_t<float> z;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSSPlayerRuntimeInfo
|
struct CellSSPlayerRuntimeInfo
|
||||||
{
|
{
|
||||||
float level;
|
be_t<float> level;
|
||||||
float speed;
|
be_t<float> speed;
|
||||||
CellSurMixerPosition position;
|
CellSurMixerPosition position;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSurMixerConfig
|
struct CellSurMixerConfig
|
||||||
{
|
{
|
||||||
s32 priority;
|
be_t<s32> priority;
|
||||||
u32 chStrips1;
|
be_t<u32> chStrips1;
|
||||||
u32 chStrips2;
|
be_t<u32> chStrips2;
|
||||||
u32 chStrips6;
|
be_t<u32> chStrips6;
|
||||||
u32 chStrips8;
|
be_t<u32> chStrips8;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSurMixerChStripParam
|
struct CellSurMixerChStripParam
|
||||||
{
|
{
|
||||||
u32 param;
|
be_t<u32> param;
|
||||||
void *attribute;
|
void *attribute;
|
||||||
int dBSwitch;
|
be_t<s32> dBSwitch;
|
||||||
float floatVal;
|
be_t<float> floatVal;
|
||||||
int intVal;
|
be_t<s32> intVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
CellSSPlayerWaveParam current_SSPlayerWaveParam;
|
CellSSPlayerWaveParam current_SSPlayerWaveParam;
|
||||||
|
@ -164,31 +165,31 @@ struct CellSnd3KeyOnParam
|
||||||
u8 vel;
|
u8 vel;
|
||||||
u8 pan;
|
u8 pan;
|
||||||
u8 panEx;
|
u8 panEx;
|
||||||
s32 addPitch;
|
be_t<s32> addPitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSnd3VoiceBitCtx
|
struct CellSnd3VoiceBitCtx
|
||||||
{
|
{
|
||||||
u32 core; //[CELL_SND3_MAX_CORE], unknown identifier
|
be_t<u32> core; //[CELL_SND3_MAX_CORE], unknown identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSnd3RequestQueueCtx
|
struct CellSnd3RequestQueueCtx
|
||||||
{
|
{
|
||||||
void *frontQueue;
|
void *frontQueue;
|
||||||
u32 frontQueueSize;
|
be_t<u32> frontQueueSize;
|
||||||
void *rearQueue;
|
void *rearQueue;
|
||||||
u32 rearQueueSize;
|
be_t<u32> rearQueueSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
//libsynt2 datatypes
|
//libsynt2 datatypes
|
||||||
struct CellSoundSynth2EffectAttr
|
struct CellSoundSynth2EffectAttr
|
||||||
{
|
{
|
||||||
u16 core;
|
be_t<u16> core;
|
||||||
u16 mode;
|
be_t<u16> mode;
|
||||||
s16 depth_L;
|
be_t<s16> depth_L;
|
||||||
s16 depth_R;
|
be_t<s16> depth_R;
|
||||||
u16 delay;
|
be_t<u16> delay;
|
||||||
u16 feedback;
|
be_t<u16> feedback;
|
||||||
};
|
};
|
||||||
|
|
||||||
// libaudio Functions
|
// libaudio Functions
|
||||||
|
@ -196,28 +197,26 @@ struct CellSoundSynth2EffectAttr
|
||||||
int cellAudioInit()
|
int cellAudioInit()
|
||||||
{
|
{
|
||||||
cellAudio.Warning("cellAudioInit()");
|
cellAudio.Warning("cellAudioInit()");
|
||||||
if(m_config->g_is_audio_initialized == true) return CELL_AUDIO_ERROR_ALREADY_INIT;
|
if(m_config->m_is_audio_initialized == true) return CELL_AUDIO_ERROR_ALREADY_INIT;
|
||||||
m_config->g_is_audio_initialized = true;
|
m_config->m_is_audio_initialized = true;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioQuit()
|
int cellAudioQuit()
|
||||||
{
|
{
|
||||||
cellAudio.Warning("cellAudioQuit()");
|
cellAudio.Warning("cellAudioQuit()");
|
||||||
if (m_config->g_is_audio_initialized == false) return CELL_AUDIO_ERROR_NOT_INIT;
|
if (m_config->m_is_audio_initialized == false) return CELL_AUDIO_ERROR_NOT_INIT;
|
||||||
m_config->g_is_audio_initialized = false;
|
m_config->m_is_audio_initialized = false;
|
||||||
|
|
||||||
delete m_config;
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioPortOpen(mem_ptr_t<CellAudioPortParam> audioParam, mem32_t portNum)
|
int cellAudioPortOpen(mem_ptr_t<CellAudioPortParam> audioParam, mem32_t portNum)
|
||||||
{
|
{
|
||||||
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x,portNum_addr=0x%x)",audioParam.GetAddr(),portNum.GetAddr());
|
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x,portNum_addr=0x%x)",audioParam.GetAddr(),portNum.GetAddr());
|
||||||
UNIMPLEMENTED_FUNC(cellAudio);
|
|
||||||
|
|
||||||
if(!audioParam.IsGood() || !portNum.IsGood()) return CELL_AUDIO_ERROR_PORT_OPEN;
|
if(!audioParam.IsGood() || !portNum.IsGood()) return CELL_AUDIO_ERROR_PORT_OPEN;
|
||||||
m_config->g_is_audio_port_open = true;
|
m_config->m_is_audio_port_open = true;
|
||||||
|
|
||||||
m_param->nChannel = audioParam->nChannel;
|
m_param->nChannel = audioParam->nChannel;
|
||||||
m_param->nBlock = audioParam->nBlock;
|
m_param->nBlock = audioParam->nBlock;
|
||||||
|
@ -235,20 +234,22 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfi
|
||||||
if(!portConfig.IsGood())
|
if(!portConfig.IsGood())
|
||||||
{
|
{
|
||||||
return CELL_AUDIO_ERROR_PARAM;
|
return CELL_AUDIO_ERROR_PARAM;
|
||||||
};
|
}
|
||||||
|
|
||||||
//if(portNum > 7) return CELL_AUDIO_ERROR_PORT_FULL;
|
//if(portNum > 7) return CELL_AUDIO_ERROR_PORT_FULL;
|
||||||
|
|
||||||
if(m_config->g_is_audio_port_open == false)
|
if(m_config->m_is_audio_port_open == false)
|
||||||
{
|
{
|
||||||
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
|
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
};
|
}
|
||||||
|
|
||||||
if(m_config->g_is_audio_port_started == true)
|
if(m_config->m_is_audio_port_started == true)
|
||||||
|
{
|
||||||
portConfig->status = CELL_AUDIO_STATUS_RUN;
|
portConfig->status = CELL_AUDIO_STATUS_RUN;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
portConfig->status = CELL_AUDIO_STATUS_READY;
|
portConfig->status = CELL_AUDIO_STATUS_READY;
|
||||||
portConfig->nChannel = m_param->nChannel;
|
portConfig->nChannel = m_param->nChannel;
|
||||||
portConfig->nBlock = m_param->nBlock;
|
portConfig->nBlock = m_param->nBlock;
|
||||||
|
@ -258,6 +259,8 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfi
|
||||||
|
|
||||||
// portAddr - readIndexAddr == 0xFFF0 on ps3
|
// portAddr - readIndexAddr == 0xFFF0 on ps3
|
||||||
Memory.Write64(portConfig->readIndexAddr, 1);
|
Memory.Write64(portConfig->readIndexAddr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,29 +268,32 @@ int cellAudioPortStart(u32 portNum)
|
||||||
{
|
{
|
||||||
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)",portNum);
|
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)",portNum);
|
||||||
|
|
||||||
if (m_config->g_is_audio_port_open == false) return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
if (m_config->m_is_audio_port_open == true)
|
||||||
m_config->g_is_audio_port_started = true;
|
return CELL_AUDIO_ERROR_PORT_OPEN;
|
||||||
|
|
||||||
|
m_config->m_is_audio_port_started = true;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioPortClose(u32 portNum)
|
int cellAudioPortClose(u32 portNum)
|
||||||
{
|
{
|
||||||
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)",portNum);
|
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)",portNum);
|
||||||
if (m_config->g_is_audio_port_open == false) return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
|
||||||
m_config->g_is_audio_port_open = false;
|
|
||||||
|
|
||||||
UNIMPLEMENTED_FUNC(cellAudio);
|
if (m_config->m_is_audio_port_open == false)
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||||
|
|
||||||
|
m_config->m_is_audio_port_open = false;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioPortStop(u32 portNum)
|
int cellAudioPortStop(u32 portNum)
|
||||||
{
|
{
|
||||||
cellAudio.Warning("cellAudioPortStop(portNum=0x%x)",portNum);
|
cellAudio.Warning("cellAudioPortStop(portNum=0x%x)",portNum);
|
||||||
if (m_config->g_is_audio_port_started == false) return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
|
||||||
m_config->g_is_audio_port_started = false;
|
|
||||||
|
|
||||||
UNIMPLEMENTED_FUNC(cellAudio);
|
if (m_config->m_is_audio_port_started == false)
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||||
|
|
||||||
|
m_config->m_is_audio_port_started = false;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,3 +1012,10 @@ void cellAudio_init()
|
||||||
|
|
||||||
//TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions
|
//TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cellAudio_unload()
|
||||||
|
{
|
||||||
|
m_config->m_is_audio_initialized = false;
|
||||||
|
m_config->m_is_audio_port_open = false;
|
||||||
|
m_config->m_is_audio_port_started = false;
|
||||||
|
}
|
|
@ -415,6 +415,44 @@ void cellGcmSetFlipStatus()
|
||||||
Emu.GetGSManager().GetRender().m_flip_status = 0;
|
Emu.GetGSManager().GetRender().m_flip_status = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank)
|
||||||
|
{
|
||||||
|
cellGcmSys.Warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||||
|
index, location, offset, size, pitch, comp, base, bank);
|
||||||
|
//copied form cellGcmSetTileInfo
|
||||||
|
if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4)
|
||||||
|
{
|
||||||
|
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(offset & 0xffff || size & 0xffff || pitch & 0xf)
|
||||||
|
{
|
||||||
|
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
|
||||||
|
{
|
||||||
|
return CELL_GCM_ERROR_INVALID_ENUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(comp)
|
||||||
|
{
|
||||||
|
cellGcmSys.Error("cellGcmSetTileInfo: bad comp! (%d)", comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& tile = Emu.GetGSManager().GetRender().m_tiles[index];
|
||||||
|
tile.m_location = location;
|
||||||
|
tile.m_offset = offset;
|
||||||
|
tile.m_size = size;
|
||||||
|
tile.m_pitch = pitch;
|
||||||
|
tile.m_comp = comp;
|
||||||
|
tile.m_base = base;
|
||||||
|
tile.m_bank = bank;
|
||||||
|
Memory.WriteData(Emu.GetGSManager().GetRender().m_tiles_addr + sizeof(CellGcmTileInfo) * index, tile.Pack());
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank)
|
int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank)
|
||||||
{
|
{
|
||||||
cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||||
|
@ -720,6 +758,7 @@ void cellGcmSys_init()
|
||||||
cellGcmSys.AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId);
|
cellGcmSys.AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId);
|
||||||
cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer);
|
cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer);
|
||||||
cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus);
|
cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus);
|
||||||
|
cellGcmSys.AddFunc(0xd0b1d189, cellGcmSetTile);
|
||||||
cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo);
|
cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo);
|
||||||
cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile);
|
cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile);
|
||||||
cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip);
|
cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip);
|
||||||
|
|
|
@ -186,7 +186,8 @@ struct PamfHeader
|
||||||
be_t<u32> mux_rate_max; //== 0x01D470 (400 bps per unit, == 48000000 bps)
|
be_t<u32> mux_rate_max; //== 0x01D470 (400 bps per unit, == 48000000 bps)
|
||||||
be_t<u32> mux_rate_min; //== 0x0107AC (?????)
|
be_t<u32> mux_rate_min; //== 0x0107AC (?????)
|
||||||
u16 reserved2; // ?????
|
u16 reserved2; // ?????
|
||||||
be_t<u16> stream_count; //total stream count
|
u8 reserved3;
|
||||||
|
u8 stream_count; //total stream count (reduced to 1 byte)
|
||||||
be_t<u16> unk1; //== 1 (?????)
|
be_t<u16> unk1; //== 1 (?????)
|
||||||
be_t<u32> table_data_size; //== table_size - 0x20 == 0x14 + (0x30 * total_stream_num) (?????)
|
be_t<u32> table_data_size; //== table_size - 0x20 == 0x14 + (0x30 * total_stream_num) (?????)
|
||||||
//TODO: check relative offset of stream structs (could be from 0x0c to 0x14, currently 0x14)
|
//TODO: check relative offset of stream structs (could be from 0x0c to 0x14, currently 0x14)
|
||||||
|
@ -245,7 +246,8 @@ int cellPamfGetStreamOffsetAndSize(mem_ptr_t<PamfHeader> pAddr, u64 fileSize, me
|
||||||
cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)",
|
cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)",
|
||||||
pAddr.GetAddr(), fileSize, pOffset.GetAddr(), pSize.GetAddr());
|
pAddr.GetAddr(), fileSize, pOffset.GetAddr(), pSize.GetAddr());
|
||||||
|
|
||||||
pOffset = (u64)pAddr->data_offset << 11;
|
const u64 size = (u64)pAddr->data_offset << 11;
|
||||||
|
pOffset = size;
|
||||||
pSize = (u64)pAddr->data_size << 11;
|
pSize = (u64)pAddr->data_size << 11;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -327,6 +329,9 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||||
|
|
||||||
int counts[6] = {0, 0, 0, 0, 0, 0};
|
int counts[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
/*if (!pAddr->magic)
|
||||||
|
return 1; /*hack*/
|
||||||
|
|
||||||
for (int i = 0; i < pAddr->stream_count; i++)
|
for (int i = 0; i < pAddr->stream_count; i++)
|
||||||
{
|
{
|
||||||
switch (pAddr->stream_headers[i].type)
|
switch (pAddr->stream_headers[i].type)
|
||||||
|
@ -338,6 +343,7 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||||
default:
|
default:
|
||||||
cellPamf.Error("cellPamfReaderGetNumberOfSpecificStreams: unsupported stream type found(0x%x)",
|
cellPamf.Error("cellPamfReaderGetNumberOfSpecificStreams: unsupported stream type found(0x%x)",
|
||||||
pAddr->stream_headers[i].type);
|
pAddr->stream_headers[i].type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +400,9 @@ int cellPamfReaderSetStreamWithTypeAndIndex(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||||
|
|
||||||
u32 found = 0;
|
u32 found = 0;
|
||||||
|
|
||||||
|
/*if (!pAddr->magic)
|
||||||
|
return 0; /*hack*/
|
||||||
|
|
||||||
for (int i = 0; i < pAddr->stream_count; i++)
|
for (int i = 0; i < pAddr->stream_count; i++)
|
||||||
{
|
{
|
||||||
switch (pAddr->stream_headers[i].type)
|
switch (pAddr->stream_headers[i].type)
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
#include "Emu/SysCalls/SC_FUNC.h"
|
#include "Emu/SysCalls/SC_FUNC.h"
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
void cellSync_init();
|
void cellSync_init();
|
||||||
Module cellSync(0x0054, cellSync_init);
|
void cellSync_unload();
|
||||||
|
Module cellSync("cellSync", cellSync_init, nullptr, cellSync_unload);
|
||||||
|
std::mutex g_SyncMutex;
|
||||||
|
|
||||||
// Return Codes
|
// Return Codes
|
||||||
enum
|
enum
|
||||||
|
@ -22,73 +25,122 @@ enum
|
||||||
CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114,
|
CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114,
|
||||||
};
|
};
|
||||||
|
|
||||||
int cellSyncMutexInitialize(mem32_t mutex)
|
#pragma pack(push, 1)
|
||||||
|
struct CellSyncMutex {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
be_t<u16> m_freed;
|
||||||
|
be_t<u16> m_order;
|
||||||
|
};
|
||||||
|
volatile u32 m_data;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
(???) Initialize: set zeros
|
||||||
|
(???) Lock: increase m_order and wait until m_freed == old m_order
|
||||||
|
(???) Unlock: increase m_freed
|
||||||
|
(???) TryLock: ?????
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
int cellSyncMutexInitialize(mem_ptr_t<CellSyncMutex> mutex)
|
||||||
{
|
{
|
||||||
const u32 mutex_addr = mutex.GetAddr();
|
cellSync.Log("cellSyncMutexInitialize(mutex=0x%x)", mutex.GetAddr());
|
||||||
if (!mutex_addr)
|
|
||||||
|
if (!mutex.IsGood())
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (mutex_addr % 4)
|
if (mutex.GetAddr() % 4)
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
mutex = 0;
|
|
||||||
|
{ // global mutex
|
||||||
|
std::lock_guard<std::mutex> lock(g_SyncMutex); //???
|
||||||
|
mutex->m_data = 0;
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cellSyncMutexLock(mem_ptr_t<CellSyncMutex> mutex)
|
||||||
|
{
|
||||||
|
cellSync.Log("cellSyncMutexLock(mutex=0x%x)", mutex.GetAddr());
|
||||||
|
|
||||||
|
if (!mutex.IsGood())
|
||||||
|
{
|
||||||
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
if (mutex.GetAddr() % 4)
|
||||||
|
{
|
||||||
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
be_t<u16> old_order;
|
||||||
|
{ // global mutex
|
||||||
|
std::lock_guard<std::mutex> lock(g_SyncMutex);
|
||||||
|
old_order = mutex->m_order;
|
||||||
|
mutex->m_order = mutex->m_order + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
while (*(u16*)&old_order != *(u16*)&mutex->m_freed)
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
if (++counter >= 5000)
|
||||||
|
{
|
||||||
|
Emu.Pause();
|
||||||
|
cellSync.Error("cellSyncMutexLock(mutex=0x%x, old_order=%d, order=%d, freed=%d): TIMEOUT",
|
||||||
|
mutex.GetAddr(), (u16)old_order, (u16)mutex->m_order, (u16)mutex->m_freed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//while (_InterlockedExchange((volatile long*)&mutex->m_data, 1)) Sleep(1);
|
||||||
|
_mm_mfence();
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSyncMutexLock(mem32_t mutex)
|
int cellSyncMutexTryLock(mem_ptr_t<CellSyncMutex> mutex)
|
||||||
{
|
{
|
||||||
const u32 mutex_addr = mutex.GetAddr();
|
cellSync.Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr());
|
||||||
if (!mutex_addr)
|
|
||||||
{
|
|
||||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
|
||||||
}
|
|
||||||
if (mutex_addr % 4)
|
|
||||||
{
|
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
|
||||||
}
|
|
||||||
while (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24));
|
|
||||||
//need to check how does SPU work with these mutexes, also obtainment order is not guaranteed
|
|
||||||
_mm_lfence();
|
|
||||||
return CELL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cellSyncMutexTryLock(mem32_t mutex)
|
if (!mutex.IsGood())
|
||||||
{
|
|
||||||
const u32 mutex_addr = mutex.GetAddr();
|
|
||||||
if (!mutex_addr)
|
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (mutex_addr % 4)
|
if (mutex.GetAddr() % 4)
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
//check cellSyncMutexLock
|
{ /* global mutex */
|
||||||
if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24))
|
std::lock_guard<std::mutex> lock(g_SyncMutex);
|
||||||
|
if (mutex->m_order != mutex->m_freed)
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_BUSY;
|
return CELL_SYNC_ERROR_BUSY;
|
||||||
}
|
}
|
||||||
_mm_lfence();
|
mutex->m_order = mutex->m_order + 1;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSyncMutexUnlock(mem32_t mutex)
|
int cellSyncMutexUnlock(mem_ptr_t<CellSyncMutex> mutex)
|
||||||
{
|
{
|
||||||
const u32 mutex_addr = mutex.GetAddr();
|
cellSync.Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr());
|
||||||
if (!mutex_addr)
|
|
||||||
|
if (!mutex.IsGood())
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (mutex_addr % 4)
|
if (mutex.GetAddr() % 4)
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
//check cellSyncMutexLock
|
|
||||||
_mm_sfence();
|
{ /* global mutex */
|
||||||
_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0);
|
std::lock_guard<std::mutex> lock(g_SyncMutex);
|
||||||
|
mutex->m_freed = mutex->m_freed + 1;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cellSync_init()
|
void cellSync_init()
|
||||||
|
@ -98,3 +150,8 @@ void cellSync_init()
|
||||||
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
|
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
|
||||||
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
|
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cellSync_unload()
|
||||||
|
{
|
||||||
|
g_SyncMutex.unlock();
|
||||||
|
}
|
|
@ -106,9 +106,6 @@ enum
|
||||||
CELL_SYSUTIL_PAD_RUMBLE_ON = 1,
|
CELL_SYSUTIL_PAD_RUMBLE_ON = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void cellSysutil_init();
|
|
||||||
Module cellSysutil(0x0015, cellSysutil_init);
|
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -132,6 +129,11 @@ enum CellMsgDialogType
|
||||||
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
|
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*CellMsgDialogCallback)(int buttonType, mem_ptr_t<void> userData);
|
||||||
|
|
||||||
|
void cellSysutil_init();
|
||||||
|
Module cellSysutil(0x0015, cellSysutil_init);
|
||||||
|
|
||||||
int cellSysutilGetSystemParamInt(int id, mem32_t value)
|
int cellSysutilGetSystemParamInt(int id, mem32_t value)
|
||||||
{
|
{
|
||||||
cellSysutil.Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.GetAddr());
|
cellSysutil.Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.GetAddr());
|
||||||
|
@ -232,14 +234,18 @@ int cellSysutilGetSystemParamString(s32 id, mem_list_ptr_t<u8> buf, u32 bufsize)
|
||||||
if (!buf.IsGood())
|
if (!buf.IsGood())
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
|
|
||||||
|
memset(buf, 0, bufsize);
|
||||||
|
|
||||||
switch(id)
|
switch(id)
|
||||||
{
|
{
|
||||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
|
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
|
||||||
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME");
|
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME");
|
||||||
|
memcpy(buf, "Unknown", 8); //for example
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME:
|
case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME:
|
||||||
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME");
|
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME");
|
||||||
|
memcpy(buf, "Unknown", 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -477,7 +483,7 @@ int cellSysutilUnregisterCallback(int slot)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellMsgDialogOpen2(u32 type, char* msgString, u32 callback_addr, u32 userData, u32 extParam)
|
int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||||
{
|
{
|
||||||
long style = 0;
|
long style = 0;
|
||||||
|
|
||||||
|
@ -520,17 +526,16 @@ int cellMsgDialogOpen2(u32 type, char* msgString, u32 callback_addr, u32 userDat
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback2 callback(0, callback_addr, userData);
|
if(callback)
|
||||||
callback.Handle(status);
|
callback(status, userData);
|
||||||
callback.Branch(true);
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellMsgDialogOpenErrorCode(u32 errorCode, u32 callback_addr, u32 userData, u32 extParam)
|
int cellMsgDialogOpenErrorCode(u32 errorCode, mem_func_ptr_t<CellMsgDialogCallback> callback, mem_ptr_t<void> userData, u32 extParam)
|
||||||
{
|
{
|
||||||
cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=%d, extParam=%d)",
|
cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=%d, extParam=%d)",
|
||||||
errorCode, callback_addr, userData, extParam);
|
errorCode, callback.GetAddr(), userData, extParam);
|
||||||
|
|
||||||
std::string errorMessage;
|
std::string errorMessage;
|
||||||
switch(errorCode)
|
switch(errorCode)
|
||||||
|
@ -622,10 +627,8 @@ int cellMsgDialogOpenErrorCode(u32 errorCode, u32 callback_addr, u32 userData, u
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: The following lines produce an infinite loop of cellMsgDialogOpenErrorCode's
|
if(callback)
|
||||||
/*Callback2 callback(0, callback_addr, userData);
|
callback(status, userData);
|
||||||
callback.Handle(status);
|
|
||||||
callback.Branch(true);*/
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -649,7 +652,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||||
case CELL_AUDIO_OUT_FS_192KHZ:
|
case CELL_AUDIO_OUT_FS_192KHZ:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
|
@ -659,7 +662,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(audioOut)
|
switch(audioOut)
|
||||||
|
@ -668,8 +671,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||||
case CELL_AUDIO_OUT_SECONDARY: return 0;
|
case CELL_AUDIO_OUT_SECONDARY: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u32 option)
|
int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u32 option)
|
||||||
|
@ -690,7 +692,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||||
case CELL_AUDIO_OUT_FS_192KHZ:
|
case CELL_AUDIO_OUT_FS_192KHZ:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(ch)
|
switch(ch)
|
||||||
|
@ -700,7 +702,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||||
case 8:
|
case 8:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
|
@ -710,7 +712,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(audioOut)
|
switch(audioOut)
|
||||||
|
@ -719,8 +721,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||||
case CELL_AUDIO_OUT_SECONDARY: return 0;
|
case CELL_AUDIO_OUT_SECONDARY: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, u32 state_addr)
|
int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, u32 state_addr)
|
||||||
|
@ -831,7 +832,7 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut)
|
||||||
case CELL_AUDIO_OUT_SECONDARY: return 0;
|
case CELL_AUDIO_OUT_SECONDARY: return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
|
return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, mem_ptr_t<CellAudioOutDeviceInfo> info)
|
int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, mem_ptr_t<CellAudioOutDeviceInfo> info)
|
||||||
|
@ -863,7 +864,7 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control)
|
||||||
case CELL_AUDIO_OUT_SECONDARY:
|
case CELL_AUDIO_OUT_SECONDARY:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
|
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(control)
|
switch(control)
|
||||||
|
@ -873,7 +874,7 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control)
|
||||||
case CELL_AUDIO_OUT_COPY_CONTROL_COPY_NEVER:
|
case CELL_AUDIO_OUT_COPY_CONTROL_COPY_NEVER:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER;
|
default: return CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CELL_AUDIO_OUT_SUCCEEDED;
|
return CELL_AUDIO_OUT_SUCCEEDED;
|
||||||
|
|
|
@ -81,11 +81,12 @@ int sys_spu_image_import(mem_ptr_t<sys_spu_image> img, u32 src, u32 type)
|
||||||
}
|
}
|
||||||
|
|
||||||
vfsStreamMemory f(src);
|
vfsStreamMemory f(src);
|
||||||
u32 entry = LoadSpuImage(f);
|
u32 entry;
|
||||||
|
u32 offset = LoadSpuImage(f, entry);
|
||||||
|
|
||||||
img->type = 1;
|
img->type = type;
|
||||||
img->entry_point = entry;
|
img->entry_point = entry;
|
||||||
img->segs_addr = 0x0;
|
img->segs_addr = offset;
|
||||||
img->nsegs = 0;
|
img->nsegs = 0;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -119,15 +120,13 @@ int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern u64 g_last_spu_offset;
|
|
||||||
|
|
||||||
int sys_raw_spu_image_load(int id, mem_ptr_t<sys_spu_image> img)
|
int sys_raw_spu_image_load(int id, mem_ptr_t<sys_spu_image> img)
|
||||||
{
|
{
|
||||||
sysPrxForUser.Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.GetAddr());
|
sysPrxForUser.Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.GetAddr());
|
||||||
|
|
||||||
memcpy(Memory + RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, Memory + g_last_spu_offset, 256 * 1024);
|
memcpy(Memory + RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, Memory + (u32)img->segs_addr, 256 * 1024);
|
||||||
Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs,
|
Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs,
|
||||||
img->entry_point - g_last_spu_offset);
|
(u32)img->entry_point);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
#include "Emu/SysCalls/SC_FUNC.h"
|
#include "Emu/SysCalls/SC_FUNC.h"
|
||||||
|
|
||||||
void sys_fs_init();
|
void sys_fs_init();
|
||||||
Module sys_fs(0x000e, sys_fs_init);
|
void sys_fs_unload();
|
||||||
|
Module sys_fs(0x000e, sys_fs_init, nullptr, sys_fs_unload);
|
||||||
|
std::atomic<u32> g_FsAioReadID = 0;
|
||||||
|
Array<vfsStream*> FDs;
|
||||||
|
|
||||||
bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp)
|
bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp)
|
||||||
{
|
{
|
||||||
|
@ -135,6 +138,80 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*)(u32 xaio_addr, u32 error, int xid, u64 size)> func)
|
||||||
|
{
|
||||||
|
vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd];
|
||||||
|
const wxString path = orig_file.GetPath().AfterFirst('/');
|
||||||
|
|
||||||
|
u64 nbytes = (u64)aio->size;
|
||||||
|
const u32 buf_addr = (u32)aio->buf_addr;
|
||||||
|
|
||||||
|
u64 res;
|
||||||
|
u32 error;
|
||||||
|
|
||||||
|
if(Memory.IsGoodAddr(buf_addr))
|
||||||
|
{
|
||||||
|
//open the file again (to prevent access conflicts roughly)
|
||||||
|
vfsLocalFile file(path, vfsRead);
|
||||||
|
if(!Memory.IsGoodAddr(buf_addr, nbytes))
|
||||||
|
{
|
||||||
|
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
|
||||||
|
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Seek((u64)aio->offset);
|
||||||
|
res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||||
|
error = CELL_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = 0;
|
||||||
|
error = CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//start callback thread
|
||||||
|
//if(func)
|
||||||
|
//func.async(aio.GetAddr(), error, xid, res);
|
||||||
|
|
||||||
|
ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=%d, res=%d, xid=%d [%s])",
|
||||||
|
fd, (u64)aio->offset, buf_addr, (u64)aio->size, res, xid, path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void (*)(u32 xaio_addr, u32 error, int xid, u64 size)> func)
|
||||||
|
{
|
||||||
|
sys_fs.Warning("cellFsAioRead(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.GetAddr(), aio_id.GetAddr(), func.GetAddr());
|
||||||
|
//ID id;
|
||||||
|
u32 fd = (u32)aio->fd;
|
||||||
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsFileBase& orig_file = *(vfsFileBase*)id.m_data;
|
||||||
|
vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd];
|
||||||
|
|
||||||
|
//get a unique id for the callback
|
||||||
|
const u32 xid = g_FsAioReadID++;
|
||||||
|
aio_id = xid;
|
||||||
|
|
||||||
|
//std::thread t(fsAioRead, fd, aio, xid, func);
|
||||||
|
//t.detach();
|
||||||
|
//read data immediately (actually it should be read in special thread):
|
||||||
|
fsAioRead(fd, aio, xid, func);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cellFsAioInit(mem8_ptr_t mount_point)
|
||||||
|
{
|
||||||
|
sys_fs.Warning("cellFsAioInit(mount_point_addr=0x%x)", mount_point.GetAddr());
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cellFsAioFinish(mem8_ptr_t mount_point)
|
||||||
|
{
|
||||||
|
sys_fs.Warning("cellFsAioFinish(mount_point_addr=0x%x)", mount_point.GetAddr());
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void sys_fs_init()
|
void sys_fs_init()
|
||||||
{
|
{
|
||||||
sys_fs.AddFunc(0x718bf5f8, cellFsOpen);
|
sys_fs.AddFunc(0x718bf5f8, cellFsOpen);
|
||||||
|
@ -155,6 +232,20 @@ void sys_fs_init()
|
||||||
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
|
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
|
||||||
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
|
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
|
||||||
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
|
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
|
||||||
|
|
||||||
sys_fs.AddFunc(0xc1c507e7, cellFsAioRead);
|
sys_fs.AddFunc(0xc1c507e7, cellFsAioRead);
|
||||||
|
sys_fs.AddFunc(0xdb869f20, cellFsAioInit);
|
||||||
|
sys_fs.AddFunc(0x9f951810, cellFsAioFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_fs_unload()
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < FDs.GetCount(); i++)
|
||||||
|
{
|
||||||
|
if (FDs[i])
|
||||||
|
{
|
||||||
|
FDs[i]->Close();
|
||||||
|
delete FDs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FDs.Clear();
|
||||||
}
|
}
|
|
@ -302,6 +302,8 @@ public:
|
||||||
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12)); }
|
virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef ARG
|
||||||
|
|
||||||
template<typename TR>
|
template<typename TR>
|
||||||
func_caller* bind_func(TR (*call)())
|
func_caller* bind_func(TR (*call)())
|
||||||
{
|
{
|
||||||
|
@ -379,5 +381,3 @@ func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
|
||||||
{
|
{
|
||||||
return new binder_func_12<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(call);
|
return new binder_func_12<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ARG(n)
|
|
||||||
|
|
|
@ -225,7 +225,6 @@ extern int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos);
|
||||||
extern int cellFsFtruncate(u32 fd, u64 size);
|
extern int cellFsFtruncate(u32 fd, u64 size);
|
||||||
extern int cellFsTruncate(u32 path_addr, u64 size);
|
extern int cellFsTruncate(u32 path_addr, u64 size);
|
||||||
extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size);
|
extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size);
|
||||||
extern int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t id, u32 func_addr);
|
|
||||||
|
|
||||||
//cellVideo
|
//cellVideo
|
||||||
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
|
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
|
||||||
extern Module sys_fs;
|
extern Module sys_fs;
|
||||||
|
extern Array<vfsStream*> FDs;
|
||||||
|
|
||||||
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||||
{
|
{
|
||||||
|
@ -94,7 +95,9 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = sys_fs.GetNewId(stream, flags);
|
fd = FDs.AddCpy(stream);
|
||||||
|
//fd = sys_fs.GetNewId(stream, flags);
|
||||||
|
ConLog.Warning("*** cellFsOpen(path: %s): fd=%d", path.mb_str(), fd.GetValue());
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -103,9 +106,12 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
||||||
{
|
{
|
||||||
sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
|
sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
|
||||||
fd, buf_addr, nbytes, nread.GetAddr());
|
fd, buf_addr, nbytes, nread.GetAddr());
|
||||||
ID id;
|
//ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||||
|
|
||||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
||||||
{
|
{
|
||||||
|
@ -125,9 +131,13 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||||
{
|
{
|
||||||
sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
|
sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
|
||||||
fd, buf_addr, nbytes, nwrite.GetAddr());
|
fd, buf_addr, nbytes, nwrite.GetAddr());
|
||||||
ID id;
|
//ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||||
|
|
||||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
||||||
{
|
{
|
||||||
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
|
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
|
||||||
|
@ -144,12 +154,17 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||||
|
|
||||||
int cellFsClose(u32 fd)
|
int cellFsClose(u32 fd)
|
||||||
{
|
{
|
||||||
sys_fs.Log("cellFsClose(fd: %d)", fd);
|
sys_fs.Warning("cellFsClose(fd: %d)", fd);
|
||||||
ID id;
|
//ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||||
file.Close();
|
file.Close();
|
||||||
Emu.GetIdManager().RemoveID(fd);
|
delete FDs[fd];
|
||||||
|
//Emu.GetIdManager().RemoveID(fd);
|
||||||
|
FDs[fd] = nullptr;
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,9 +246,12 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
|
||||||
int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb)
|
int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb)
|
||||||
{
|
{
|
||||||
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
||||||
ID id;
|
//ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||||
|
|
||||||
sb->st_mode =
|
sb->st_mode =
|
||||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
||||||
|
@ -312,9 +330,12 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
||||||
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
|
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
ID id;
|
//ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||||
pos = file.Seek(offset, seek_mode);
|
pos = file.Seek(offset, seek_mode);
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -322,9 +343,12 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
||||||
int cellFsFtruncate(u32 fd, u64 size)
|
int cellFsFtruncate(u32 fd, u64 size)
|
||||||
{
|
{
|
||||||
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
|
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
|
||||||
ID id;
|
//ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||||
|
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||||
|
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||||
u64 initialSize = file.GetSize();
|
u64 initialSize = file.GetSize();
|
||||||
|
|
||||||
if (initialSize < size)
|
if (initialSize < size)
|
||||||
|
@ -385,49 +409,3 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::atomic<u32> g_FsAioReadID = 0;
|
|
||||||
|
|
||||||
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, u32 func_addr)
|
|
||||||
{
|
|
||||||
sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x, id_addr: 0x%x, func_addr: 0x%x)", aio.GetAddr(), aio_id.GetAddr(), func_addr);
|
|
||||||
|
|
||||||
ID id;
|
|
||||||
u32 fd = (u32)aio->fd;
|
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
|
||||||
vfsFileBase& orig_file = *(vfsFileBase*)id.m_data;
|
|
||||||
//open the file again (to prevent access conflicts roughly)
|
|
||||||
vfsStream file = *Emu.GetVFS().Open(orig_file.GetPath(), vfsRead);
|
|
||||||
|
|
||||||
u64 nbytes = (u64)aio->size;
|
|
||||||
const u32 buf_addr = (u32)aio->buf_addr;
|
|
||||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
|
||||||
{
|
|
||||||
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
|
|
||||||
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
|
||||||
}
|
|
||||||
|
|
||||||
//read data immediately (actually it should be read in special thread)
|
|
||||||
file.Seek((u64)aio->offset);
|
|
||||||
const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
|
||||||
file.Close();
|
|
||||||
|
|
||||||
//get a unique id for the callback
|
|
||||||
const u32 xid = g_FsAioReadID++;
|
|
||||||
aio_id = xid;
|
|
||||||
|
|
||||||
//TODO: init the callback
|
|
||||||
/*CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
|
||||||
new_thread.SetEntry(func_addr);
|
|
||||||
new_thread.SetPrio(1001);
|
|
||||||
new_thread.SetStackSize(0x10000);
|
|
||||||
new_thread.SetName("FsAioReadCallback");
|
|
||||||
new_thread.SetArg(0, aio.GetAddr()); //xaio
|
|
||||||
new_thread.SetArg(1, CELL_OK); //error code
|
|
||||||
new_thread.SetArg(2, xid); //xid (unique id)
|
|
||||||
new_thread.SetArg(3, res); //size (bytes read)
|
|
||||||
new_thread.Run();
|
|
||||||
new_thread.Exec();*/
|
|
||||||
|
|
||||||
return CELL_OK;
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,20 +6,26 @@ SysCallBase sc_mem("memory");
|
||||||
|
|
||||||
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
|
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
|
||||||
{
|
{
|
||||||
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
|
sc_mem.Warning("(HACK!) sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
|
||||||
|
|
||||||
if(!Memory.IsGoodAddr(cid_addr, 4))
|
if(!Memory.IsGoodAddr(cid_addr, 4))
|
||||||
{
|
{
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 addr = Memory.Alloc(yield_size, 1);
|
yield_size &= ~0xfffff; //round down to 1 MB granularity
|
||||||
|
|
||||||
|
//alignment hack (Memory.Alloc does not support alignment yet): alloc size is increased
|
||||||
|
u64 addr = Memory.Alloc(yield_size + 0x100000, 0x100000); //1 MB alignment (???)
|
||||||
|
|
||||||
if(!addr)
|
if(!addr)
|
||||||
{
|
{
|
||||||
return CELL_ENOMEM;
|
return CELL_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fix alignment:
|
||||||
|
addr = (addr + 0x100000) & ~0xfffff;
|
||||||
|
|
||||||
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
|
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -43,18 +49,20 @@ int sys_memory_container_destroy(u32 cid)
|
||||||
int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
|
int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
|
||||||
{
|
{
|
||||||
//0x30000100;
|
//0x30000100;
|
||||||
sc_mem.Log("sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags);
|
sc_mem.Warning("(HACK!) sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags);
|
||||||
u32 addr;
|
u32 addr;
|
||||||
switch(flags)
|
switch(flags)
|
||||||
{
|
{
|
||||||
case SYS_MEMORY_PAGE_SIZE_1M:
|
case SYS_MEMORY_PAGE_SIZE_1M:
|
||||||
if(size & 0xfffff) return CELL_EALIGN;
|
if(size & 0xfffff) return CELL_EALIGN;
|
||||||
addr = Memory.Alloc(size, 0x100000);
|
addr = Memory.Alloc(size + 0x100000, 0x100000);
|
||||||
|
addr = (addr + 0x100000) & ~0xfffff;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_MEMORY_PAGE_SIZE_64K:
|
case SYS_MEMORY_PAGE_SIZE_64K:
|
||||||
if(size & 0xffff) return CELL_EALIGN;
|
if(size & 0xffff) return CELL_EALIGN;
|
||||||
addr = Memory.Alloc(size, 0x10000);
|
addr = Memory.Alloc(size + 0x10000, 0x10000);
|
||||||
|
addr = (addr + 0x10000) & ~0xffff;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: return CELL_EINVAL;
|
default: return CELL_EINVAL;
|
||||||
|
|
|
@ -107,13 +107,36 @@ int cellPadGetData(u32 port_no, u32 data_addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 lx = 128;
|
||||||
|
u16 ly = 128;
|
||||||
|
u16 rx = 128;
|
||||||
|
u16 ry = 128;
|
||||||
|
const Array<AnalogStick>& sticks = pads[port_no].m_sticks;
|
||||||
|
for (u32 s = 0; s < sticks.GetCount(); s++)
|
||||||
|
{
|
||||||
|
u16* res;
|
||||||
|
switch (sticks[s].m_offset)
|
||||||
|
{
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: res = &lx; break;
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: res = &ly; break;
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: res = ℞ break;
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: res = &ry; break;
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sticks[s].m_max_pressed && !sticks[s].m_min_pressed)
|
||||||
|
*res = 255;
|
||||||
|
if (sticks[s].m_min_pressed && !sticks[s].m_max_pressed)
|
||||||
|
*res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
data.len = re(len);
|
data.len = re(len);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_DIGITAL1] = re(d1);
|
data.button[CELL_PAD_BTN_OFFSET_DIGITAL1] = re(d1);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] = re(d2);
|
data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] = re(d2);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = re(pad.m_analog_right_x);
|
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = re(rx);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = re(pad.m_analog_right_y);
|
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = re(ry);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = re(pad.m_analog_left_x);
|
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = re(lx);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = re(pad.m_analog_left_y);
|
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = re(ly);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = re(pad.m_press_right);
|
data.button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = re(pad.m_press_right);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = re(pad.m_press_left);
|
data.button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = re(pad.m_press_left);
|
||||||
data.button[CELL_PAD_BTN_OFFSET_PRESS_UP] = re(pad.m_press_up);
|
data.button[CELL_PAD_BTN_OFFSET_PRESS_UP] = re(pad.m_press_up);
|
||||||
|
|
|
@ -23,18 +23,33 @@ struct SpuGroupInfo
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
u64 g_last_spu_offset = 0;
|
u32 LoadSpuImage(vfsStream& stream, u32& spu_ep)
|
||||||
|
|
||||||
u32 LoadSpuImage(vfsStream& stream)
|
|
||||||
{
|
{
|
||||||
ELFLoader l(stream);
|
ELFLoader l(stream);
|
||||||
l.LoadInfo();
|
l.LoadInfo();
|
||||||
u32 alloc_size = 0xFFFFED - stream.GetSize();
|
const u32 alloc_size = 256 * 1024 /*0x1000000 - stream.GetSize()*/;
|
||||||
g_last_spu_offset = Memory.MainMem.Alloc(alloc_size);
|
u32 spu_offset = Memory.MainMem.Alloc(alloc_size);
|
||||||
l.LoadData(g_last_spu_offset);
|
l.LoadData(spu_offset);
|
||||||
|
spu_ep = l.GetEntry();
|
||||||
return g_last_spu_offset + l.GetEntry();
|
return spu_offset;
|
||||||
}
|
}
|
||||||
|
/*u64 g_last_spu_offset = 0;
|
||||||
|
static const u64 g_spu_alloc_size = 0x1000000;
|
||||||
|
|
||||||
|
u32 LoadSpuImage(vfsStream& stream, u64 address)
|
||||||
|
{
|
||||||
|
ELFLoader l(stream);
|
||||||
|
l.LoadInfo();
|
||||||
|
l.LoadData(address);
|
||||||
|
|
||||||
|
return address + l.GetEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 LoadSpuImage(vfsStream& stream)
|
||||||
|
{
|
||||||
|
g_last_spu_offset = Memory.MainMem.Alloc(g_spu_alloc_size);
|
||||||
|
return LoadSpuImage(stream, g_last_spu_offset);
|
||||||
|
}*/
|
||||||
|
|
||||||
//156
|
//156
|
||||||
int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr)
|
int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr)
|
||||||
|
@ -54,11 +69,12 @@ int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr)
|
||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 entry = LoadSpuImage(f);
|
u32 entry;
|
||||||
|
u32 offset = LoadSpuImage(f, entry);
|
||||||
|
|
||||||
img->type = 1;
|
img->type = 1;
|
||||||
img->entry_point = entry;
|
img->entry_point = entry;
|
||||||
img->segs_addr = 0x0;
|
img->segs_addr = offset;
|
||||||
img->nsegs = 0;
|
img->nsegs = 0;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -97,7 +113,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ls_entry = img->entry_point - g_last_spu_offset;
|
u32 spu_ep = (u32)img->entry_point;
|
||||||
std::string name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str();
|
std::string name = Memory.ReadString(attr->name_addr, attr->name_len).mb_str();
|
||||||
u64 a1 = arg->arg1;
|
u64 a1 = arg->arg1;
|
||||||
u64 a2 = arg->arg2;
|
u64 a2 = arg->arg2;
|
||||||
|
@ -107,10 +123,10 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU);
|
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU);
|
||||||
//copy SPU image:
|
//copy SPU image:
|
||||||
u32 spu_offset = Memory.MainMem.Alloc(256 * 1024);
|
u32 spu_offset = Memory.MainMem.Alloc(256 * 1024);
|
||||||
memcpy(Memory + spu_offset, Memory + g_last_spu_offset, 256 * 1024);
|
memcpy(Memory + spu_offset, Memory + (u32)img->segs_addr, 256 * 1024);
|
||||||
//initialize from new place:
|
//initialize from new place:
|
||||||
new_thread.SetOffset(spu_offset);
|
new_thread.SetOffset(spu_offset);
|
||||||
new_thread.SetEntry(ls_entry);
|
new_thread.SetEntry(spu_ep);
|
||||||
new_thread.SetName(name);
|
new_thread.SetName(name);
|
||||||
new_thread.SetArg(0, a1);
|
new_thread.SetArg(0, a1);
|
||||||
new_thread.SetArg(1, a2);
|
new_thread.SetArg(1, a2);
|
||||||
|
@ -122,15 +138,16 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||||
|
|
||||||
group_info.threads[spu_num] = &new_thread;
|
group_info.threads[spu_num] = &new_thread;
|
||||||
|
|
||||||
ConLog.Write("New SPU Thread:");
|
/*ConLog.Write("New SPU Thread:");
|
||||||
ConLog.Write("ls_entry = 0x%x", ls_entry);
|
ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr);
|
||||||
|
ConLog.Write("entry_point = 0x%x", spu_ep);
|
||||||
ConLog.Write("name = %s", name.c_str());
|
ConLog.Write("name = %s", name.c_str());
|
||||||
ConLog.Write("a1 = 0x%x", a1);
|
ConLog.Write("a1 = 0x%x", a1);
|
||||||
ConLog.Write("a2 = 0x%x", a2);
|
ConLog.Write("a2 = 0x%x", a2);
|
||||||
ConLog.Write("a3 = 0x%x", a3);
|
ConLog.Write("a3 = 0x%x", a3);
|
||||||
ConLog.Write("a4 = 0x%x", a4);
|
ConLog.Write("a4 = 0x%x", a4);
|
||||||
ConLog.Write("ls_offset = 0x%x", ((SPUThread&)new_thread).dmac.ls_offset);
|
ConLog.Write("ls_offset = 0x%x", ((SPUThread&)new_thread).dmac.ls_offset);
|
||||||
ConLog.SkipLn();
|
ConLog.SkipLn();*/
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
u32 LoadSpuImage(vfsStream& stream);
|
u32 LoadSpuImage(vfsStream& stream, u32& spu_ep);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,13 @@ enum
|
||||||
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SYS_SPU_SEGMENT_TYPE_COPY = 0x0001,
|
||||||
|
SYS_SPU_SEGMENT_TYPE_FILL = 0x0002,
|
||||||
|
SYS_SPU_SEGMENT_TYPE_INFO = 0x0004,
|
||||||
|
};
|
||||||
|
|
||||||
struct sys_spu_thread_group_attribute
|
struct sys_spu_thread_group_attribute
|
||||||
{
|
{
|
||||||
be_t<u32> name_len;
|
be_t<u32> name_len;
|
||||||
|
@ -36,7 +43,7 @@ struct sys_spu_image
|
||||||
{
|
{
|
||||||
be_t<u32> type;
|
be_t<u32> type;
|
||||||
be_t<u32> entry_point;
|
be_t<u32> entry_point;
|
||||||
be_t<u32> segs_addr;
|
be_t<u32> segs_addr; //temporarily used as offset of LS image after elf loading
|
||||||
be_t<int> nsegs;
|
be_t<int> nsegs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "MemoryViewer.h"
|
#include "MemoryViewer.h"
|
||||||
#include "Emu/Memory/Memory.h"
|
|
||||||
|
|
||||||
MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent)
|
MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent)
|
||||||
: wxFrame(parent, wxID_ANY, "Memory Viewer", wxDefaultPosition, wxSize(700, 450))
|
: wxFrame(parent, wxID_ANY, "Memory Viewer", wxDefaultPosition, wxSize(700, 450))
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "RSXDebugger.h"
|
#include "RSXDebugger.h"
|
||||||
#include "Emu/Memory/Memory.h"
|
|
||||||
#include "Emu/GS/sysutil_video.h"
|
#include "Emu/GS/sysutil_video.h"
|
||||||
#include "Emu/GS/GCM.h"
|
#include "Emu/GS/GCM.h"
|
||||||
|
|
||||||
|
@ -16,6 +15,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||||
: wxFrame(parent, wxID_ANY, "RSX Debugger", wxDefaultPosition, wxSize(700, 450))
|
: wxFrame(parent, wxID_ANY, "RSX Debugger", wxDefaultPosition, wxSize(700, 450))
|
||||||
, m_item_count(23)
|
, m_item_count(23)
|
||||||
, m_addr(0x0)
|
, m_addr(0x0)
|
||||||
|
, m_cur_texture(0)
|
||||||
, exit(false)
|
, exit(false)
|
||||||
{
|
{
|
||||||
this->SetBackgroundColour(wxColour(240,240,240)); //This fix the ugly background color under Windows
|
this->SetBackgroundColour(wxColour(240,240,240)); //This fix the ugly background color under Windows
|
||||||
|
@ -25,7 +25,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||||
wxBoxSizer& s_tools = *new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer& s_tools = *new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
wxStaticBoxSizer& s_controls = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Memory Viewer Options");
|
wxStaticBoxSizer& s_controls = *new wxStaticBoxSizer(wxHORIZONTAL, this, "RSX Debugger Controls");
|
||||||
|
|
||||||
// Controls: Address
|
// Controls: Address
|
||||||
wxStaticBoxSizer& s_controls_addr = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Address:");
|
wxStaticBoxSizer& s_controls_addr = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Address:");
|
||||||
|
@ -101,8 +101,17 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||||
m_list_flags->InsertColumn(1, "Value", 0, 270);
|
m_list_flags->InsertColumn(1, "Value", 0, 270);
|
||||||
m_list_lightning->InsertColumn(0, "Name", 0, 170);
|
m_list_lightning->InsertColumn(0, "Name", 0, 170);
|
||||||
m_list_lightning->InsertColumn(1, "Value", 0, 270);
|
m_list_lightning->InsertColumn(1, "Value", 0, 270);
|
||||||
m_list_texture->InsertColumn(0, "Name", 0, 170);
|
|
||||||
m_list_texture->InsertColumn(1, "Value", 0, 270);
|
m_list_texture->InsertColumn(0, "Index");
|
||||||
|
m_list_texture->InsertColumn(1, "Address");
|
||||||
|
m_list_texture->InsertColumn(2, "Cubemap");
|
||||||
|
m_list_texture->InsertColumn(3, "Dimension");
|
||||||
|
m_list_texture->InsertColumn(4, "Enabled");
|
||||||
|
m_list_texture->InsertColumn(5, "Format");
|
||||||
|
m_list_texture->InsertColumn(6, "Mipmap");
|
||||||
|
m_list_texture->InsertColumn(7, "Pitch");
|
||||||
|
m_list_texture->InsertColumn(8, "Size");
|
||||||
|
|
||||||
m_list_settings->InsertColumn(0, "Name", 0, 170);
|
m_list_settings->InsertColumn(0, "Name", 0, 170);
|
||||||
m_list_settings->InsertColumn(1, "Value", 0, 270);
|
m_list_settings->InsertColumn(1, "Value", 0, 270);
|
||||||
|
|
||||||
|
@ -182,22 +191,24 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||||
SetSizerAndFit(&s_panel);
|
SetSizerAndFit(&s_panel);
|
||||||
|
|
||||||
//Events
|
//Events
|
||||||
Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(RSXDebugger::OnKeyDown), NULL, this);
|
m_app_connector.Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(RSXDebugger::OnKeyDown), nullptr, this);
|
||||||
Connect(t_addr->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(RSXDebugger::OnChangeToolsAddr));
|
Connect(t_addr->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(RSXDebugger::OnChangeToolsAddr));
|
||||||
|
|
||||||
Connect(b_goto_get->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToGet));
|
Connect(b_goto_get->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToGet));
|
||||||
Connect(b_goto_put->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToPut));
|
Connect(b_goto_put->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToPut));
|
||||||
|
|
||||||
p_buffer_colorA->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
p_buffer_colorA->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), nullptr, this);
|
||||||
p_buffer_colorB->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
p_buffer_colorB->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), nullptr, this);
|
||||||
p_buffer_colorC->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
p_buffer_colorC->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), nullptr, this);
|
||||||
p_buffer_colorD->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
p_buffer_colorD->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), nullptr, this);
|
||||||
//Connect(p_buffer_depth->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::OnClickBuffer));
|
//Connect(p_buffer_depth->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::OnClickBuffer));
|
||||||
//Connect(p_buffer_stencil->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::OnClickBuffer));
|
//Connect(p_buffer_stencil->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::OnClickBuffer));
|
||||||
p_buffer_tex->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
p_buffer_tex->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), nullptr, this);
|
||||||
|
|
||||||
m_list_commands->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(RSXDebugger::OnScrollMemory), NULL, this);
|
m_list_commands->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(RSXDebugger::OnScrollMemory), nullptr, this);
|
||||||
m_list_flags->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::SetFlags), NULL, this);
|
m_list_flags->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::SetFlags), nullptr, this);
|
||||||
|
|
||||||
|
m_list_texture->Connect(wxID_ANY, wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::OnSelectTexture), nullptr, this);
|
||||||
|
|
||||||
//Fill the frame
|
//Fill the frame
|
||||||
UpdateInformation();
|
UpdateInformation();
|
||||||
|
@ -205,10 +216,15 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||||
|
|
||||||
void RSXDebugger::OnKeyDown(wxKeyEvent& event)
|
void RSXDebugger::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
|
if(wxGetActiveWindow() == wxGetTopLevelParent(this))
|
||||||
|
{
|
||||||
switch(event.GetKeyCode())
|
switch(event.GetKeyCode())
|
||||||
{
|
{
|
||||||
case WXK_F5: UpdateInformation(); break;
|
case WXK_F5: UpdateInformation(); return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event)
|
void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event)
|
||||||
|
@ -221,8 +237,34 @@ void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event)
|
||||||
|
|
||||||
void RSXDebugger::OnScrollMemory(wxMouseEvent& event)
|
void RSXDebugger::OnScrollMemory(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
|
if(Memory.IsGoodAddr(m_addr))
|
||||||
|
{
|
||||||
|
int items = event.ControlDown() ? m_item_count : 1;
|
||||||
|
|
||||||
|
for(int i=0; i<items; ++i)
|
||||||
|
{
|
||||||
|
u32 offset;
|
||||||
|
if(Memory.IsGoodAddr(m_addr))
|
||||||
|
{
|
||||||
|
u32 cmd = Memory.Read32(m_addr);
|
||||||
|
u32 count = (cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL))
|
||||||
|
|| cmd == CELL_GCM_METHOD_FLAG_RETURN ? 0 : (cmd >> 18) & 0x7ff;
|
||||||
|
|
||||||
|
offset = 1 + count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_addr -= 4 * offset * (event.GetWheelRotation() / event.GetWheelDelta());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
m_addr -= (event.ControlDown() ? m_item_count : 1) * 4 * (event.GetWheelRotation() / event.GetWheelDelta());
|
m_addr -= (event.ControlDown() ? m_item_count : 1) * 4 * (event.GetWheelRotation() / event.GetWheelDelta());
|
||||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
}
|
||||||
|
|
||||||
UpdateInformation();
|
UpdateInformation();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
@ -233,10 +275,17 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event)
|
||||||
const GSRender& render = Emu.GetGSManager().GetRender();
|
const GSRender& render = Emu.GetGSManager().GetRender();
|
||||||
const mem_ptr_t<gcmBuffer> buffers = render.m_gcm_buffers_addr;
|
const mem_ptr_t<gcmBuffer> buffers = render.m_gcm_buffers_addr;
|
||||||
|
|
||||||
|
if(!buffers.IsGood())
|
||||||
|
return;
|
||||||
|
|
||||||
// TODO: Is there any better way to choose the color buffers
|
// TODO: Is there any better way to choose the color buffers
|
||||||
#define SHOW_BUFFER(id) \
|
#define SHOW_BUFFER(id) \
|
||||||
MemoryViewerPanel::ShowImage(this, render.m_local_mem_addr + re(buffers[id].offset), \
|
{ \
|
||||||
3, re(buffers[id].width), re(buffers[id].height), true);
|
u32 addr = render.m_local_mem_addr + re(buffers[id].offset); \
|
||||||
|
if(Memory.IsGoodAddr(addr) && buffers[id].width && buffers[id].height) \
|
||||||
|
MemoryViewerPanel::ShowImage(this, addr, 3, re(buffers[id].width), re(buffers[id].height), true); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
|
||||||
if (event.GetId() == p_buffer_colorA->GetId()) SHOW_BUFFER(0);
|
if (event.GetId() == p_buffer_colorA->GetId()) SHOW_BUFFER(0);
|
||||||
if (event.GetId() == p_buffer_colorB->GetId()) SHOW_BUFFER(1);
|
if (event.GetId() == p_buffer_colorB->GetId()) SHOW_BUFFER(1);
|
||||||
|
@ -244,10 +293,11 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event)
|
||||||
if (event.GetId() == p_buffer_colorD->GetId()) SHOW_BUFFER(3);
|
if (event.GetId() == p_buffer_colorD->GetId()) SHOW_BUFFER(3);
|
||||||
if (event.GetId() == p_buffer_tex->GetId())
|
if (event.GetId() == p_buffer_tex->GetId())
|
||||||
{
|
{
|
||||||
|
if(Memory.IsGoodAddr(render.m_textures[m_cur_texture].m_offset) && render.m_textures[m_cur_texture].m_width && render.m_textures[m_cur_texture].m_height)
|
||||||
MemoryViewerPanel::ShowImage(this,
|
MemoryViewerPanel::ShowImage(this,
|
||||||
render.m_textures[0].m_offset, 0,
|
render.m_textures[m_cur_texture].m_offset, 0,
|
||||||
render.m_textures[0].m_width,
|
render.m_textures[m_cur_texture].m_width,
|
||||||
render.m_textures[0].m_height, false);
|
render.m_textures[m_cur_texture].m_height, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SHOW_BUFFER
|
#undef SHOW_BUFFER
|
||||||
|
@ -275,6 +325,7 @@ void RSXDebugger::GoToPut(wxCommandEvent& event)
|
||||||
|
|
||||||
void RSXDebugger::UpdateInformation()
|
void RSXDebugger::UpdateInformation()
|
||||||
{
|
{
|
||||||
|
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||||
GetMemory();
|
GetMemory();
|
||||||
GetBuffers();
|
GetBuffers();
|
||||||
GetFlags();
|
GetFlags();
|
||||||
|
@ -289,26 +340,24 @@ void RSXDebugger::GetMemory()
|
||||||
for(u32 i=0; i<m_item_count; i++)
|
for(u32 i=0; i<m_item_count; i++)
|
||||||
m_list_commands->SetItem(i, 2, wxEmptyString);
|
m_list_commands->SetItem(i, 2, wxEmptyString);
|
||||||
|
|
||||||
|
u32 ioAddr = RSXReady() ? Emu.GetGSManager().GetRender().m_ioAddress : 0;
|
||||||
|
|
||||||
// Write information
|
// Write information
|
||||||
for(u32 i=0; i<m_item_count; i++)
|
for(u32 i=0, addr = m_addr; i<m_item_count; i++, addr += 4)
|
||||||
{
|
{
|
||||||
u32 addr = m_addr + 4*i;
|
|
||||||
m_list_commands->SetItem(i, 0, wxString::Format("%08x", addr));
|
m_list_commands->SetItem(i, 0, wxString::Format("%08x", addr));
|
||||||
|
|
||||||
if (Memory.IsGoodAddr(addr))
|
if (ioAddr && Memory.IsGoodAddr(addr))
|
||||||
{
|
{
|
||||||
u32 cmd = Memory.Read32(addr);
|
u32 cmd = Memory.Read32(addr);
|
||||||
u32 count = (cmd >> 18) & 0x7ff;
|
u32 count = (cmd >> 18) & 0x7ff;
|
||||||
u32 ioAddr = Emu.GetGSManager().GetRender().m_ioAddress;
|
|
||||||
m_list_commands->SetItem(i, 1, wxString::Format("%08x", cmd));
|
m_list_commands->SetItem(i, 1, wxString::Format("%08x", cmd));
|
||||||
m_list_commands->SetItem(i, 3, wxString::Format("%d", count));
|
m_list_commands->SetItem(i, 3, wxString::Format("%d", count));
|
||||||
if (count > 0)
|
m_list_commands->SetItem(i, 2, DisAsmCommand(cmd, count, addr, ioAddr));
|
||||||
|
|
||||||
|
if(!(cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL)) && cmd != CELL_GCM_METHOD_FLAG_RETURN)
|
||||||
{
|
{
|
||||||
wxString disasm = DisAsmCommand(cmd, count, addr, ioAddr);
|
addr += 4 * count;
|
||||||
for (u32 j=0; j<count && i+j<m_item_count; j++)
|
|
||||||
{
|
|
||||||
m_list_commands->SetItem(i+j, 2, disasm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -327,8 +376,15 @@ void RSXDebugger::GetBuffers()
|
||||||
// TODO: Currently it only supports color buffers
|
// TODO: Currently it only supports color buffers
|
||||||
for (u32 bufferId=0; bufferId < render.m_gcm_buffers_count; bufferId++)
|
for (u32 bufferId=0; bufferId < render.m_gcm_buffers_count; bufferId++)
|
||||||
{
|
{
|
||||||
|
if(!Memory.IsGoodAddr(render.m_gcm_buffers_addr))
|
||||||
|
continue;
|
||||||
|
|
||||||
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(render.m_gcm_buffers_addr);
|
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(render.m_gcm_buffers_addr);
|
||||||
u32 RSXbuffer_addr = render.m_local_mem_addr + re(buffers[bufferId].offset);
|
u32 RSXbuffer_addr = render.m_local_mem_addr + re(buffers[bufferId].offset);
|
||||||
|
|
||||||
|
if(!Memory.IsGoodAddr(RSXbuffer_addr))
|
||||||
|
continue;
|
||||||
|
|
||||||
unsigned char* RSXbuffer = (unsigned char*)Memory.VirtualToRealAddr(RSXbuffer_addr);
|
unsigned char* RSXbuffer = (unsigned char*)Memory.VirtualToRealAddr(RSXbuffer_addr);
|
||||||
|
|
||||||
u32 width = re(buffers[bufferId].width);
|
u32 width = re(buffers[bufferId].width);
|
||||||
|
@ -361,11 +417,15 @@ void RSXDebugger::GetBuffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Texture
|
// Draw Texture
|
||||||
u32 TexBuffer_addr = render.m_textures[0].m_offset;
|
u32 TexBuffer_addr = render.m_textures[m_cur_texture].m_offset;
|
||||||
|
|
||||||
|
if(!Memory.IsGoodAddr(TexBuffer_addr))
|
||||||
|
return;
|
||||||
|
|
||||||
unsigned char* TexBuffer = (unsigned char*)Memory.VirtualToRealAddr(TexBuffer_addr);
|
unsigned char* TexBuffer = (unsigned char*)Memory.VirtualToRealAddr(TexBuffer_addr);
|
||||||
|
|
||||||
u32 width = render.m_textures[0].m_width;
|
u32 width = render.m_textures[m_cur_texture].m_width;
|
||||||
u32 height = render.m_textures[0].m_height;
|
u32 height = render.m_textures[m_cur_texture].m_height;
|
||||||
unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
|
unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
|
||||||
memcpy(buffer, TexBuffer, width * height * 3);
|
memcpy(buffer, TexBuffer, width * height * 3);
|
||||||
|
|
||||||
|
@ -421,24 +481,23 @@ void RSXDebugger::GetTexture()
|
||||||
if (!RSXReady()) return;
|
if (!RSXReady()) return;
|
||||||
const GSRender& render = Emu.GetGSManager().GetRender();
|
const GSRender& render = Emu.GetGSManager().GetRender();
|
||||||
m_list_texture->DeleteAllItems();
|
m_list_texture->DeleteAllItems();
|
||||||
int i=0;
|
|
||||||
|
|
||||||
#define LIST_TEXTURE_ADD(name, value) \
|
for(uint i=0; i<RSXThread::m_textures_count; ++i)
|
||||||
m_list_texture->InsertItem(i, name); m_list_texture->SetItem(i, 1, value); i++;
|
{
|
||||||
|
m_list_texture->InsertItem(i, wxString::Format("%d", i));
|
||||||
|
m_list_texture->SetItem(i, 1, wxString::Format("0x%x", render.m_textures[i].m_offset));
|
||||||
|
m_list_texture->SetItem(i, 2, render.m_textures[i].m_cubemap ? "True" : "False");
|
||||||
|
m_list_texture->SetItem(i, 3, wxString::Format("%dD", render.m_textures[i].m_dimension));
|
||||||
|
m_list_texture->SetItem(i, 4, render.m_textures[i].m_enabled ? "True" : "False");
|
||||||
|
m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.m_textures[i].m_format));
|
||||||
|
m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].m_mipmap));
|
||||||
|
m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.m_textures[i].m_pitch));
|
||||||
|
m_list_texture->SetItem(i, 8, wxString::Format("%dx%d",
|
||||||
|
render.m_textures[i].m_width,
|
||||||
|
render.m_textures[i].m_height));
|
||||||
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Address:", wxString::Format("0x%x", render.m_textures[0].m_offset));
|
m_list_texture->SetItemBackgroundColour(i, wxColour(m_cur_texture == i ? "Wheat" : "White"));
|
||||||
LIST_TEXTURE_ADD("Texture #0 Cubemap:", render.m_textures[0].m_cubemap ? "True" : "False");
|
}
|
||||||
LIST_TEXTURE_ADD("Texture #0 Depth:", wxString::Format("0x%x", render.m_textures[0].m_depth));
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Dimension:", wxString::Format("0x%x", render.m_textures[0].m_dimension));
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Enabled:", render.m_textures[0].m_enabled ? "True" : "False");
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Format:", wxString::Format("0x%x", render.m_textures[0].m_format));
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Mipmap:", wxString::Format("0x%x", render.m_textures[0].m_mipmap));
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Pitch:", wxString::Format("0x%x", render.m_textures[0].m_pitch));
|
|
||||||
LIST_TEXTURE_ADD("Texture #0 Size:", wxString::Format("%d x %d",
|
|
||||||
render.m_textures[0].m_width,
|
|
||||||
render.m_textures[0].m_height));
|
|
||||||
|
|
||||||
#undef LIST_TEXTURE_ADD
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSXDebugger::GetSettings()
|
void RSXDebugger::GetSettings()
|
||||||
|
@ -524,6 +583,15 @@ void RSXDebugger::SetFlags(wxListEvent& event)
|
||||||
case 11: render.m_set_poly_offset_point ^= true; break;
|
case 11: render.m_set_poly_offset_point ^= true; break;
|
||||||
case 12: render.m_set_stencil_test ^= true; break;
|
case 12: render.m_set_stencil_test ^= true; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateInformation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSXDebugger::OnSelectTexture(wxListEvent& event)
|
||||||
|
{
|
||||||
|
if(event.GetIndex() >= 0)
|
||||||
|
m_cur_texture = event.GetIndex();
|
||||||
|
|
||||||
UpdateInformation();
|
UpdateInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,49 +684,55 @@ wxString RSXDebugger::ParseGCMEnum(u32 value, u32 type)
|
||||||
wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr)
|
wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr)
|
||||||
{
|
{
|
||||||
wxString disasm = wxEmptyString;
|
wxString disasm = wxEmptyString;
|
||||||
|
|
||||||
|
#define DISASM(string, ...) if(disasm.IsEmpty()) disasm = wxString::Format((string), ##__VA_ARGS__); else disasm += (wxString(' ') + wxString::Format((string), ##__VA_ARGS__))
|
||||||
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||||
{
|
{
|
||||||
u32 jumpAddr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT);
|
u32 jumpAddr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT);
|
||||||
disasm = wxString::Format("JUMP: %08x -> %08x", currentAddr, ioAddr+jumpAddr);
|
DISASM("JUMP: %08x -> %08x", currentAddr, ioAddr+jumpAddr);
|
||||||
}
|
}
|
||||||
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
|
else if(cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||||
{
|
{
|
||||||
u32 callAddr = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
|
u32 callAddr = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
|
||||||
disasm = wxString::Format("CALL: %08x -> %08x", currentAddr, ioAddr+callAddr);
|
DISASM("CALL: %08x -> %08x", currentAddr, ioAddr+callAddr);
|
||||||
}
|
}
|
||||||
if(cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
if(cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||||
{
|
{
|
||||||
disasm = "RETURN";
|
DISASM("RETURN");
|
||||||
}
|
|
||||||
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
|
||||||
{
|
|
||||||
disasm = "Non Increment cmd";
|
|
||||||
}
|
|
||||||
if(cmd == 0)
|
|
||||||
{
|
|
||||||
disasm = "Null cmd";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 index = 0;
|
if(cmd == 0)
|
||||||
|
{
|
||||||
|
DISASM("Null cmd");
|
||||||
|
}
|
||||||
|
else if(!(cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL)) && cmd != CELL_GCM_METHOD_FLAG_RETURN)
|
||||||
|
{
|
||||||
mem32_ptr_t args(currentAddr + 4);
|
mem32_ptr_t args(currentAddr + 4);
|
||||||
|
|
||||||
|
u32 index = 0;
|
||||||
switch(cmd & 0x3ffff)
|
switch(cmd & 0x3ffff)
|
||||||
{
|
{
|
||||||
case 0x3fead:
|
case 0x3fead:
|
||||||
disasm = "???"; break;
|
DISASM("Flip and change current buffer: %d", args[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
case NV4097_NO_OPERATION:
|
case NV4097_NO_OPERATION:
|
||||||
disasm = "NOP"; break;
|
DISASM("NOP");
|
||||||
|
break;
|
||||||
|
|
||||||
case NV406E_SET_REFERENCE:
|
case NV406E_SET_REFERENCE:
|
||||||
disasm = "???"; break;
|
DISASM("Set reference: 0x%x", args[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
||||||
disasm = wxString::Format(" Texture Offset: %08x", args[0]);
|
DISASM("Texture Offset[%d]: %08x", index, args[0]);
|
||||||
switch ((args[1] & 0x3) - 1)
|
switch ((args[1] & 0x3) - 1)
|
||||||
{
|
{
|
||||||
case CELL_GCM_LOCATION_LOCAL: disasm += " (Local memory);"; break;
|
case CELL_GCM_LOCATION_LOCAL: DISASM("(Local memory);"); break;
|
||||||
case CELL_GCM_LOCATION_MAIN: disasm += " (Main memory);"; break;
|
case CELL_GCM_LOCATION_MAIN: DISASM("(Main memory);"); break;
|
||||||
default: disasm += " (Bad location!);"; break;
|
default: DISASM("(Bad location!);"); break;
|
||||||
}
|
}
|
||||||
disasm += wxString::Format(" Cubemap:%s; Dimension:0x%x; Format:0x%x; Mipmap:0x%x",
|
DISASM(" Cubemap:%s; Dimension:0x%x; Format:0x%x; Mipmap:0x%x",
|
||||||
((args[1] >> 2) & 0x1) ? "True" : "False",
|
((args[1] >> 2) & 0x1) ? "True" : "False",
|
||||||
((args[1] >> 4) & 0xf),
|
((args[1] >> 4) & 0xf),
|
||||||
((args[1] >> 8) & 0xff),
|
((args[1] >> 8) & 0xff),
|
||||||
|
@ -666,67 +740,79 @@ wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_COLOR_MASK:
|
case NV4097_SET_COLOR_MASK:
|
||||||
disasm = wxString::Format(" Color mask: True (A:%d, R:%d, G:%d, B:%d)",
|
DISASM(" Color mask: True (A:%c, R:%c, G:%c, B:%c)",
|
||||||
args[0] & 0x1000000 ? "1" : "0",
|
args[0] & 0x1000000 ? '1' : '0',
|
||||||
args[0] & 0x0010000 ? "1" : "0",
|
args[0] & 0x0010000 ? '1' : '0',
|
||||||
args[0] & 0x0000100 ? "1" : "0",
|
args[0] & 0x0000100 ? '1' : '0',
|
||||||
args[0] & 0x0000001 ? "1" : "0");
|
args[0] & 0x0000001 ? '1' : '0');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_ALPHA_TEST_ENABLE:
|
case NV4097_SET_ALPHA_TEST_ENABLE:
|
||||||
disasm = args[0] ? "Alpha test: Enable" : "Alpha test: Disable";
|
DISASM(args[0] ? "Alpha test: Enable" : "Alpha test: Disable");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_BLEND_ENABLE:
|
case NV4097_SET_BLEND_ENABLE:
|
||||||
disasm = args[0] ? "Blend: Enable" : "Blend: Disable";
|
DISASM(args[0] ? "Blend: Enable" : "Blend: Disable");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
|
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
|
||||||
disasm = args[0] ? "Depth bounds test: Enable" : "Depth bounds test: Disable";
|
DISASM(args[0] ? "Depth bounds test: Enable" : "Depth bounds test: Disable");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_CONTEXT_DMA_COLOR_A:
|
case NV4097_SET_CONTEXT_DMA_COLOR_A:
|
||||||
disasm = wxString::Format("Context DMA Color A: 0x%x", args[0]);
|
DISASM("Context DMA Color A: 0x%x", args[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_CONTEXT_DMA_COLOR_B:
|
case NV4097_SET_CONTEXT_DMA_COLOR_B:
|
||||||
disasm = wxString::Format("Context DMA Color B: 0x%x", args[0]);
|
DISASM("Context DMA Color B: 0x%x", args[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_CONTEXT_DMA_COLOR_C:
|
case NV4097_SET_CONTEXT_DMA_COLOR_C:
|
||||||
disasm = wxString::Format("Context DMA Color C: 0x%x", args[0]);
|
DISASM("Context DMA Color C: 0x%x", args[0]);
|
||||||
if(count > 1)
|
if(count > 1)
|
||||||
disasm = wxString::Format("Context DMA Color C: 0x%x", args[1]);
|
DISASM("0x%x", args[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_CONTEXT_DMA_ZETA:
|
case NV4097_SET_CONTEXT_DMA_ZETA:
|
||||||
disasm = wxString::Format("Context DMA Zeta: 0x%x", args[0]);
|
DISASM("Context DMA Zeta: 0x%x", args[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_SURFACE_PITCH_C:
|
case NV4097_SET_SURFACE_PITCH_C:
|
||||||
disasm = wxString::Format("Surface Pitch C: 0x%x; ", args[0]);
|
DISASM("Surface Pitch C: 0x%x;", args[0]);
|
||||||
disasm += wxString::Format("Surface Pitch D: 0x%x; ", args[1]);
|
DISASM("Surface Pitch D: 0x%x;", args[1]);
|
||||||
disasm += wxString::Format("Surface Offset C: 0x%x; ", args[2]);
|
DISASM("Surface Offset C: 0x%x;", args[2]);
|
||||||
disasm += wxString::Format("Surface Offset D: 0x%x", args[3]);
|
DISASM("Surface Offset D: 0x%x", args[3]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_SURFACE_PITCH_Z:
|
case NV4097_SET_SURFACE_PITCH_Z:
|
||||||
disasm = wxString::Format("Surface Pitch Z: 0x%x; ", args[0]);
|
DISASM("Surface Pitch Z: 0x%x;", args[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||||
|
{
|
||||||
|
DISASM("Non Increment cmd");
|
||||||
|
}
|
||||||
|
|
||||||
|
DISASM("[0x%08x(", cmd);
|
||||||
|
|
||||||
|
for(uint i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
if(i != 0) disasm += ", ";
|
||||||
|
disasm += wxString::Format("0x%x", args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
disasm += ")]";
|
||||||
|
}
|
||||||
|
#undef DISASM
|
||||||
|
|
||||||
return disasm;
|
return disasm;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RSXDebugger::RSXReady()
|
bool RSXDebugger::RSXReady()
|
||||||
{
|
{
|
||||||
// TODO: This is a *very* ugly way of checking if m_render was initialized. It throws an error while debugging in VS
|
return Emu.GetGSManager().IsInited();
|
||||||
const GSRender& render = Emu.GetGSManager().GetRender();
|
|
||||||
if (!&render)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
class RSXDebugger : public wxFrame
|
class RSXDebugger : public wxFrame
|
||||||
{
|
{
|
||||||
|
AppConnector m_app_connector;
|
||||||
|
|
||||||
u32 m_addr;
|
u32 m_addr;
|
||||||
|
|
||||||
u32 m_panel_width;
|
u32 m_panel_width;
|
||||||
|
@ -28,6 +30,8 @@ class RSXDebugger : public wxFrame
|
||||||
wxPanel* p_buffer_stencil;
|
wxPanel* p_buffer_stencil;
|
||||||
wxPanel* p_buffer_tex;
|
wxPanel* p_buffer_tex;
|
||||||
|
|
||||||
|
uint m_cur_texture;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool exit;
|
bool exit;
|
||||||
RSXDebugger(wxWindow* parent);
|
RSXDebugger(wxWindow* parent);
|
||||||
|
@ -53,6 +57,7 @@ public:
|
||||||
virtual void GetSettings();
|
virtual void GetSettings();
|
||||||
|
|
||||||
virtual void SetFlags(wxListEvent& event);
|
virtual void SetFlags(wxListEvent& event);
|
||||||
|
virtual void OnSelectTexture(wxListEvent& event);
|
||||||
|
|
||||||
wxString ParseGCMEnum(u32 value, u32 type);
|
wxString ParseGCMEnum(u32 value, u32 type);
|
||||||
wxString DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr);
|
wxString DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr);
|
||||||
|
|
|
@ -119,8 +119,8 @@ bool ELF32Loader::LoadShdrInfo()
|
||||||
|
|
||||||
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
||||||
{
|
{
|
||||||
ConLog.Error("LoadShdr32 error: shstrndx too big!");
|
ConLog.Warning("LoadShdr32 error: shstrndx too big!");
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||||
|
|
|
@ -169,8 +169,8 @@ bool ELF64Loader::LoadShdrInfo(s64 offset)
|
||||||
|
|
||||||
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
||||||
{
|
{
|
||||||
ConLog.Error("LoadShdr64 error: shstrndx too big!");
|
ConLog.Warning("LoadShdr64 error: shstrndx too big!");
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "Emu/FS/vfsFileBase.h"
|
#include "Emu/FS/vfsFileBase.h"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define LOADER_DEBUG
|
//#define LOADER_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum Elf_Machine
|
enum Elf_Machine
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue