mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 00:40:11 +00:00
Merge branch 'master' of https://github.com/DHrpcs3/rpcs3
This commit is contained in:
commit
4e4dd43646
@ -21,6 +21,15 @@ enum
|
||||
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
|
||||
{
|
||||
MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF,
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "PPCThread.h"
|
||||
#include "Emu/event.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] =
|
||||
{
|
||||
@ -293,7 +296,7 @@ public:
|
||||
};
|
||||
volatile u64 m_indval;
|
||||
};
|
||||
wxCriticalSection m_lock;
|
||||
std::mutex m_lock;
|
||||
|
||||
public:
|
||||
|
||||
@ -311,7 +314,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
if(!m_index)
|
||||
{
|
||||
return false;
|
||||
@ -322,7 +325,7 @@ public:
|
||||
}
|
||||
else
|
||||
{ //lock-free
|
||||
if(!m_index)
|
||||
if ((m_indval & 0xffffffff) == 0)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
@ -337,7 +340,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
if(m_index >= max_count)
|
||||
{
|
||||
return false;
|
||||
@ -347,11 +350,12 @@ public:
|
||||
}
|
||||
else
|
||||
{ //lock-free
|
||||
if(m_index)
|
||||
if (m_indval & 0xffffffff)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
m_indval = ((u64)value << 32) | 1;
|
||||
const u64 new_value = ((u64)value << 32) | 1;
|
||||
m_indval = new_value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -361,7 +365,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
if(m_index >= max_count)
|
||||
m_value[max_count-1] = value; //last message is overwritten
|
||||
else
|
||||
@ -369,7 +373,8 @@ public:
|
||||
}
|
||||
else
|
||||
{ //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)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
if(m_index >= max_count)
|
||||
m_value[max_count-1] |= value; //last message is logically ORed
|
||||
else
|
||||
@ -397,7 +402,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
if(!m_index)
|
||||
res = 0; //result is undefined
|
||||
else
|
||||
@ -422,7 +427,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
return m_index;
|
||||
}
|
||||
else
|
||||
@ -435,7 +440,7 @@ public:
|
||||
{
|
||||
if (max_count > 1 || x86)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_lock);
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
return max_count - m_index;
|
||||
}
|
||||
else
|
||||
@ -470,6 +475,7 @@ public:
|
||||
Channel<1> QueryType;
|
||||
Channel<1> QueryMask;
|
||||
Channel<1> TagStatus;
|
||||
Channel<1> AtomicStat;
|
||||
} Prxy;
|
||||
|
||||
struct
|
||||
@ -519,6 +525,29 @@ public:
|
||||
}
|
||||
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:
|
||||
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);
|
||||
@ -549,6 +578,9 @@ public:
|
||||
case SPU_RdSigNotify2:
|
||||
return SPU.SNR[1].GetCount();
|
||||
|
||||
case MFC_RdAtomicStat:
|
||||
return Prxy.AtomicStat.GetCount();
|
||||
|
||||
default:
|
||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||
break;
|
||||
@ -641,6 +673,10 @@ public:
|
||||
//ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
|
||||
break;
|
||||
|
||||
case MFC_RdAtomicStat:
|
||||
while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) Sleep(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||
break;
|
||||
|
@ -20,7 +20,11 @@ struct VFSManagerEntry
|
||||
char* mount;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
@ -189,40 +189,100 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||
value = "clamp(" + value + ", 0.0, 1.0)";
|
||||
}
|
||||
|
||||
wxString dest;
|
||||
if(d3.dst == 5 || d3.dst == 6)
|
||||
if(set_dst)
|
||||
{
|
||||
int num = d3.dst == 5 ? 0 : 3;
|
||||
|
||||
if(d3.vec_writemask_x)
|
||||
wxString dest;
|
||||
if(d0.cond_update_enable_0)
|
||||
{
|
||||
ConLog.Error("Bad clip mask.");
|
||||
dest = m_parr.AddParam(PARAM_NONE, "float", "rc");
|
||||
}
|
||||
else if(d3.dst == 5 || d3.dst == 6)
|
||||
{
|
||||
int num = d3.dst == 5 ? 0 : 3;
|
||||
|
||||
if(d3.vec_writemask_x)
|
||||
{
|
||||
ConLog.Error("Bad clip mask.");
|
||||
}
|
||||
|
||||
//if(d3.vec_writemask_y) num += 0;
|
||||
if(d3.vec_writemask_z) num += 1;
|
||||
else if(d3.vec_writemask_w) num += 2;
|
||||
|
||||
dest = wxString::Format(GetDST(is_sca), num);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = GetDST(is_sca) + GetMask(is_sca);
|
||||
}
|
||||
|
||||
//if(d3.vec_writemask_y) num += 0;
|
||||
if(d3.vec_writemask_z) num += 1;
|
||||
else if(d3.vec_writemask_w) num += 2;
|
||||
|
||||
dest = wxString::Format(GetDST(is_sca), num);
|
||||
code = cond + dest + " = " + value;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = GetDST(is_sca) + GetMask(is_sca);
|
||||
code = cond + value;
|
||||
}
|
||||
|
||||
code = cond + dest + " = " + 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()
|
||||
@ -233,14 +293,31 @@ wxString GLVertexDecompilerThread::BuildCode()
|
||||
{
|
||||
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 =
|
||||
"#version 330\n"
|
||||
"\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()
|
||||
@ -268,11 +345,11 @@ void GLVertexDecompilerThread::Task()
|
||||
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
|
||||
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
|
||||
//case 0x07: break; // LIT
|
||||
//case 0x08: break; // BRA
|
||||
//case 0x09: break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
||||
//case 0x0a: break; // CAL : works same as BRI
|
||||
//case 0x0b: break; // CLI : works same as BRI
|
||||
//case 0x0c: break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
||||
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false); break; // BRA
|
||||
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false); break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
||||
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false); break; // CAL : works same as BRI
|
||||
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false); break; // CLI : works same as BRI
|
||||
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 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
|
||||
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;)
|
||||
|
||||
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);
|
||||
Emu.Pause();
|
||||
break;
|
||||
@ -314,17 +392,25 @@ void GLVertexDecompilerThread::Task()
|
||||
case 0x16: AddVecCode("sign(" + GetSRC(0) + ")"); break; //SSG
|
||||
|
||||
default:
|
||||
m_body.Add(wxString::Format("//Unknown vp opcode 0x%x", d1.vec_opcode));
|
||||
ConLog.Error("Unknown vp opcode 0x%x", d1.vec_opcode);
|
||||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
|
||||
if(d3.end) break;
|
||||
if(d3.end)
|
||||
{
|
||||
if(i < m_data.GetCount())
|
||||
ConLog.Error("Program end before buffer end.");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_shader = BuildCode();
|
||||
|
||||
main = wxEmptyString;
|
||||
m_body.Clear();
|
||||
m_funcs.RemoveAt(1, m_funcs.GetCount() - 1);
|
||||
}
|
||||
|
||||
GLVertexProgram::GLVertexProgram()
|
||||
|
@ -127,7 +127,17 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||
};
|
||||
} src[3];
|
||||
|
||||
wxString main;
|
||||
struct FuncInfo
|
||||
{
|
||||
u32 offset;
|
||||
wxString name;
|
||||
};
|
||||
|
||||
wxArrayString m_body;
|
||||
|
||||
ArrayF<FuncInfo> m_funcs;
|
||||
|
||||
//wxString main;
|
||||
wxString& m_shader;
|
||||
Array<u32>& m_data;
|
||||
GLParamArray& m_parr;
|
||||
@ -138,6 +148,10 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||
, m_shader(shader)
|
||||
, 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);
|
||||
@ -145,9 +159,11 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||
wxString GetScaMask();
|
||||
wxString GetDST(bool is_sca = false);
|
||||
wxString GetSRC(const u32 n, bool is_sca = false);
|
||||
void AddCode(bool is_sca, wxString code, bool src_mask = true);
|
||||
void AddVecCode(const wxString& code, bool src_mask = true);
|
||||
void AddScaCode(const wxString& code);
|
||||
wxString GetFunc();
|
||||
void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true);
|
||||
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();
|
||||
|
||||
virtual void Task();
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
void Init();
|
||||
void Close();
|
||||
|
||||
bool IsInited() const { return m_render != nullptr; }
|
||||
|
||||
GSInfo& GetInfo() { return m_info; }
|
||||
GSRender& GetRender() { assert(m_render); return *m_render; }
|
||||
|
||||
|
@ -104,6 +104,41 @@ u32 RSXVertexData::GetTypeSize()
|
||||
index = (cmd - a) / m; \
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
tex.SetOffset(tex_addr);
|
||||
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;
|
||||
|
||||
@ -308,10 +350,24 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
{
|
||||
RSXTexture& tex = m_textures[index];
|
||||
|
||||
const u16 height = args[0] & 0xffff;
|
||||
const u16 width = args[0] >> 16;
|
||||
u16 height = args[0] & 0xffff;
|
||||
u16 width = args[0] >> 16;
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
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:
|
||||
{
|
||||
//ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM_LOAD: prog = %d", args[0]);
|
||||
|
||||
m_cur_vertex_prog = &m_vertex_progs[args[0]];
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
ConLog.Warning("NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog == NULL");
|
||||
|
@ -226,7 +226,7 @@ class RSXThread : public ThreadBase
|
||||
{
|
||||
public:
|
||||
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_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
|
||||
{
|
||||
u32 m_port_status;
|
||||
@ -111,6 +129,7 @@ struct Pad
|
||||
u32 m_device_type;
|
||||
|
||||
Array<Button> m_buttons;
|
||||
Array<AnalogStick> m_sticks;
|
||||
|
||||
s16 m_analog_left_x;
|
||||
s16 m_analog_left_y;
|
||||
@ -166,7 +185,7 @@ struct Pad
|
||||
{
|
||||
}
|
||||
|
||||
~Pad() { m_buttons.Clear(); }
|
||||
~Pad() { m_buttons.Clear(); m_sticks.Clear(); }
|
||||
};
|
||||
|
||||
struct PadInfo
|
||||
@ -206,10 +225,29 @@ public:
|
||||
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; }
|
||||
Array<Pad>& GetPads() { return m_pads; }
|
||||
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.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_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));
|
||||
}
|
||||
|
||||
__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>
|
||||
@ -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 -> ()
|
||||
{
|
||||
return (T*)&Memory[this->m_addr];
|
||||
@ -513,8 +531,6 @@ public:
|
||||
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; }
|
||||
@ -530,6 +546,32 @@ public:
|
||||
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()]; }
|
||||
@ -551,6 +593,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
__forceinline T GetValue()
|
||||
{
|
||||
return (be_t<T>&)Memory[this->m_addr];
|
||||
}
|
||||
|
||||
operator const T() const
|
||||
{
|
||||
return (be_t<T>&)Memory[this->m_addr];
|
||||
@ -639,6 +686,123 @@ public:
|
||||
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>
|
||||
class MemoryAllocator
|
||||
{
|
||||
|
@ -9,7 +9,9 @@ Callback::Callback(u32 slot, u64 addr)
|
||||
, a1(0)
|
||||
, a2(0)
|
||||
, a3(0)
|
||||
, a4(0)
|
||||
, m_has_data(false)
|
||||
, m_name("Callback")
|
||||
{
|
||||
}
|
||||
|
||||
@ -38,11 +40,12 @@ bool Callback::HasData() const
|
||||
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;
|
||||
a2 = _a2;
|
||||
a3 = _a3;
|
||||
a4 = _a4;
|
||||
m_has_data = true;
|
||||
}
|
||||
|
||||
@ -55,11 +58,12 @@ void Callback::Branch(bool wait)
|
||||
new_thread.SetEntry(m_addr);
|
||||
new_thread.SetPrio(1001);
|
||||
new_thread.SetStackSize(0x10000);
|
||||
new_thread.SetName("Callback");
|
||||
new_thread.SetName(m_name);
|
||||
|
||||
new_thread.SetArg(0, a1);
|
||||
new_thread.SetArg(1, a2);
|
||||
new_thread.SetArg(2, a3);
|
||||
new_thread.SetArg(3, a4);
|
||||
new_thread.Run();
|
||||
|
||||
new_thread.Exec();
|
||||
@ -68,6 +72,11 @@ void Callback::Branch(bool wait)
|
||||
GetCurrentPPCThread()->Wait(new_thread);
|
||||
}
|
||||
|
||||
void Callback::SetName(const std::string& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
Callback::operator bool() const
|
||||
{
|
||||
return GetAddr() != 0;
|
||||
|
@ -8,10 +8,13 @@ protected:
|
||||
|
||||
bool m_has_data;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
public:
|
||||
u64 a1;
|
||||
u64 a2;
|
||||
u64 a3;
|
||||
u64 a4;
|
||||
|
||||
u32 GetSlot() const;
|
||||
u64 GetAddr() const;
|
||||
@ -20,8 +23,9 @@ public:
|
||||
bool HasData() const;
|
||||
|
||||
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 SetName(const std::string& name);
|
||||
|
||||
operator bool() const;
|
||||
};
|
||||
|
@ -570,6 +570,171 @@ s64 SysCalls::DoFunc(const u32 id)
|
||||
case 0x56776c0d: FUNC_LOG_ERROR("TODO: cellKey2CharGetChar");
|
||||
case 0xabf629c1: FUNC_LOG_ERROR("TODO: cellKey2CharOpen");
|
||||
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 0x05893e7c: FUNC_LOG_ERROR("TODO: cellUserTraceRegister");
|
||||
case 0x6d045c2e: FUNC_LOG_ERROR("TODO: cellUserTraceUnregister");
|
||||
|
@ -19,7 +19,7 @@ static const g_module_list[] =
|
||||
{0x0002, "cellHttpUtil"},
|
||||
{0x0003, "cellSsl"},
|
||||
{0x0004, "cellHttps"},
|
||||
{0x0005, "cellVdec"},
|
||||
{0x0005, "libvdec"},
|
||||
{0x0006, "cellAdec"},
|
||||
{0x0007, "cellDmux"},
|
||||
{0x0008, "cellVpost"},
|
||||
@ -90,7 +90,6 @@ static const g_module_list[] =
|
||||
{0x0050, "cellSpursJq"},
|
||||
{0x0052, "cellPngEnc"},
|
||||
{0x0053, "cellMusicDecode2"},
|
||||
{0x0054, "cellSync"},
|
||||
{0x0055, "cellSync2"},
|
||||
{0x0056, "cellNpUtil"},
|
||||
{0x0057, "cellRudp"},
|
||||
|
@ -4,7 +4,8 @@
|
||||
#include "Emu/Audio/cellAudio.h"
|
||||
|
||||
void cellAudio_init();
|
||||
Module cellAudio(0x0011, cellAudio_init);
|
||||
void cellAudio_unload();
|
||||
Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload);
|
||||
|
||||
enum
|
||||
{
|
||||
@ -81,9 +82,9 @@ struct CellAudioPortConfig
|
||||
|
||||
struct CellAudioConfig //custom structure
|
||||
{
|
||||
bool g_is_audio_initialized;
|
||||
bool g_is_audio_port_open;
|
||||
bool g_is_audio_port_started;
|
||||
bool m_is_audio_initialized;
|
||||
bool m_is_audio_port_open;
|
||||
bool m_is_audio_port_started;
|
||||
};
|
||||
|
||||
CellAudioPortParam* m_param = new CellAudioPortParam;
|
||||
@ -95,55 +96,55 @@ typedef void * CellAANHandle;
|
||||
|
||||
struct CellSSPlayerConfig
|
||||
{
|
||||
u32 channels;
|
||||
u32 outputMode;
|
||||
be_t<u32> channels;
|
||||
be_t<u32> outputMode;
|
||||
};
|
||||
|
||||
struct CellSSPlayerWaveParam
|
||||
{
|
||||
void *addr;
|
||||
int format;
|
||||
u32 samples;
|
||||
u32 loopStartOffset;
|
||||
u32 startOffset;
|
||||
be_t<s32> format;
|
||||
be_t<u32> samples;
|
||||
be_t<u32> loopStartOffset;
|
||||
be_t<u32> startOffset;
|
||||
};
|
||||
|
||||
struct CellSSPlayerCommonParam
|
||||
{
|
||||
u32 loopMode;
|
||||
u32 attackMode;
|
||||
be_t<u32> loopMode;
|
||||
be_t<u32> attackMode;
|
||||
};
|
||||
|
||||
struct CellSurMixerPosition
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
be_t<float> x;
|
||||
be_t<float> y;
|
||||
be_t<float> z;
|
||||
};
|
||||
|
||||
struct CellSSPlayerRuntimeInfo
|
||||
{
|
||||
float level;
|
||||
float speed;
|
||||
be_t<float> level;
|
||||
be_t<float> speed;
|
||||
CellSurMixerPosition position;
|
||||
};
|
||||
|
||||
struct CellSurMixerConfig
|
||||
{
|
||||
s32 priority;
|
||||
u32 chStrips1;
|
||||
u32 chStrips2;
|
||||
u32 chStrips6;
|
||||
u32 chStrips8;
|
||||
be_t<s32> priority;
|
||||
be_t<u32> chStrips1;
|
||||
be_t<u32> chStrips2;
|
||||
be_t<u32> chStrips6;
|
||||
be_t<u32> chStrips8;
|
||||
};
|
||||
|
||||
struct CellSurMixerChStripParam
|
||||
{
|
||||
u32 param;
|
||||
be_t<u32> param;
|
||||
void *attribute;
|
||||
int dBSwitch;
|
||||
float floatVal;
|
||||
int intVal;
|
||||
be_t<s32> dBSwitch;
|
||||
be_t<float> floatVal;
|
||||
be_t<s32> intVal;
|
||||
};
|
||||
|
||||
CellSSPlayerWaveParam current_SSPlayerWaveParam;
|
||||
@ -164,31 +165,31 @@ struct CellSnd3KeyOnParam
|
||||
u8 vel;
|
||||
u8 pan;
|
||||
u8 panEx;
|
||||
s32 addPitch;
|
||||
be_t<s32> addPitch;
|
||||
};
|
||||
|
||||
struct CellSnd3VoiceBitCtx
|
||||
{
|
||||
u32 core; //[CELL_SND3_MAX_CORE], unknown identifier
|
||||
be_t<u32> core; //[CELL_SND3_MAX_CORE], unknown identifier
|
||||
};
|
||||
|
||||
struct CellSnd3RequestQueueCtx
|
||||
{
|
||||
void *frontQueue;
|
||||
u32 frontQueueSize;
|
||||
be_t<u32> frontQueueSize;
|
||||
void *rearQueue;
|
||||
u32 rearQueueSize;
|
||||
be_t<u32> rearQueueSize;
|
||||
};
|
||||
|
||||
//libsynt2 datatypes
|
||||
struct CellSoundSynth2EffectAttr
|
||||
{
|
||||
u16 core;
|
||||
u16 mode;
|
||||
s16 depth_L;
|
||||
s16 depth_R;
|
||||
u16 delay;
|
||||
u16 feedback;
|
||||
be_t<u16> core;
|
||||
be_t<u16> mode;
|
||||
be_t<s16> depth_L;
|
||||
be_t<s16> depth_R;
|
||||
be_t<u16> delay;
|
||||
be_t<u16> feedback;
|
||||
};
|
||||
|
||||
// libaudio Functions
|
||||
@ -196,28 +197,26 @@ struct CellSoundSynth2EffectAttr
|
||||
int cellAudioInit()
|
||||
{
|
||||
cellAudio.Warning("cellAudioInit()");
|
||||
if(m_config->g_is_audio_initialized == true) return CELL_AUDIO_ERROR_ALREADY_INIT;
|
||||
m_config->g_is_audio_initialized = true;
|
||||
if(m_config->m_is_audio_initialized == true) return CELL_AUDIO_ERROR_ALREADY_INIT;
|
||||
m_config->m_is_audio_initialized = true;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioQuit()
|
||||
{
|
||||
cellAudio.Warning("cellAudioQuit()");
|
||||
if (m_config->g_is_audio_initialized == false) return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
m_config->g_is_audio_initialized = false;
|
||||
if (m_config->m_is_audio_initialized == false) return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
m_config->m_is_audio_initialized = false;
|
||||
|
||||
delete m_config;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
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());
|
||||
UNIMPLEMENTED_FUNC(cellAudio);
|
||||
|
||||
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->nBlock = audioParam->nBlock;
|
||||
@ -235,20 +234,22 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfi
|
||||
if(!portConfig.IsGood())
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
};
|
||||
}
|
||||
|
||||
//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;
|
||||
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;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
portConfig->status = CELL_AUDIO_STATUS_READY;
|
||||
portConfig->nChannel = m_param->nChannel;
|
||||
portConfig->nBlock = m_param->nBlock;
|
||||
@ -258,36 +259,41 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfi
|
||||
|
||||
// portAddr - readIndexAddr == 0xFFF0 on ps3
|
||||
Memory.Write64(portConfig->readIndexAddr, 1);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioPortStart(u32 portNum)
|
||||
{
|
||||
cellAudio.Warning("cellAudioPortStart(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_started = true;
|
||||
|
||||
if (m_config->m_is_audio_port_open == true)
|
||||
return CELL_AUDIO_ERROR_PORT_OPEN;
|
||||
|
||||
m_config->m_is_audio_port_started = true;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAudioPortClose(u32 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;
|
||||
}
|
||||
|
||||
int cellAudioPortStop(u32 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;
|
||||
}
|
||||
|
||||
@ -1006,3 +1012,10 @@ void cellAudio_init()
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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(0xbc982946, cellGcmSetDefaultCommandBuffer);
|
||||
cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus);
|
||||
cellGcmSys.AddFunc(0xd0b1d189, cellGcmSetTile);
|
||||
cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo);
|
||||
cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile);
|
||||
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_min; //== 0x0107AC (?????)
|
||||
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<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)
|
||||
@ -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)",
|
||||
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;
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -327,6 +329,9 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||
|
||||
int counts[6] = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
/*if (!pAddr->magic)
|
||||
return 1; /*hack*/
|
||||
|
||||
for (int i = 0; i < pAddr->stream_count; i++)
|
||||
{
|
||||
switch (pAddr->stream_headers[i].type)
|
||||
@ -338,6 +343,7 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||
default:
|
||||
cellPamf.Error("cellPamfReaderGetNumberOfSpecificStreams: unsupported stream type found(0x%x)",
|
||||
pAddr->stream_headers[i].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,7 +362,7 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||
return counts[CELL_PAMF_STREAM_TYPE_ATRAC3PLUS] +
|
||||
counts[CELL_PAMF_STREAM_TYPE_PAMF_LPCM] + counts[CELL_PAMF_STREAM_TYPE_AC3];
|
||||
default:
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,6 +400,9 @@ int cellPamfReaderSetStreamWithTypeAndIndex(mem_ptr_t<CellPamfReader> pSelf, u8
|
||||
|
||||
u32 found = 0;
|
||||
|
||||
/*if (!pAddr->magic)
|
||||
return 0; /*hack*/
|
||||
|
||||
for (int i = 0; i < pAddr->stream_count; i++)
|
||||
{
|
||||
switch (pAddr->stream_headers[i].type)
|
||||
|
@ -1,9 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include <mutex>
|
||||
|
||||
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
|
||||
enum
|
||||
@ -22,73 +25,122 @@ enum
|
||||
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();
|
||||
if (!mutex_addr)
|
||||
cellSync.Log("cellSyncMutexInitialize(mutex=0x%x)", mutex.GetAddr());
|
||||
|
||||
if (!mutex.IsGood())
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
if (mutex.GetAddr() % 4)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int cellSyncMutexLock(mem32_t mutex)
|
||||
int cellSyncMutexTryLock(mem_ptr_t<CellSyncMutex> mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
cellSync.Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr());
|
||||
|
||||
if (!mutex.IsGood())
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
if (mutex.GetAddr() % 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;
|
||||
{ /* global mutex */
|
||||
std::lock_guard<std::mutex> lock(g_SyncMutex);
|
||||
if (mutex->m_order != mutex->m_freed)
|
||||
{
|
||||
return CELL_SYNC_ERROR_BUSY;
|
||||
}
|
||||
mutex->m_order = mutex->m_order + 1;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int cellSyncMutexTryLock(mem32_t mutex)
|
||||
int cellSyncMutexUnlock(mem_ptr_t<CellSyncMutex> mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
//check cellSyncMutexLock
|
||||
if (_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 1 << 24))
|
||||
{
|
||||
return CELL_SYNC_ERROR_BUSY;
|
||||
}
|
||||
_mm_lfence();
|
||||
return CELL_OK;
|
||||
}
|
||||
cellSync.Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr());
|
||||
|
||||
int cellSyncMutexUnlock(mem32_t mutex)
|
||||
{
|
||||
const u32 mutex_addr = mutex.GetAddr();
|
||||
if (!mutex_addr)
|
||||
if (!mutex.IsGood())
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (mutex_addr % 4)
|
||||
if (mutex.GetAddr() % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
//check cellSyncMutexLock
|
||||
_mm_sfence();
|
||||
_InterlockedExchange((volatile long*)Memory.VirtualToRealAddr(mutex_addr), 0);
|
||||
return CELL_OK;
|
||||
|
||||
{ /* global mutex */
|
||||
std::lock_guard<std::mutex> lock(g_SyncMutex);
|
||||
mutex->m_freed = mutex->m_freed + 1;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void cellSync_init()
|
||||
@ -97,4 +149,9 @@ void cellSync_init()
|
||||
cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock);
|
||||
cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock);
|
||||
cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock);
|
||||
}
|
||||
|
||||
void cellSync_unload()
|
||||
{
|
||||
g_SyncMutex.unlock();
|
||||
}
|
@ -106,9 +106,6 @@ enum
|
||||
CELL_SYSUTIL_PAD_RUMBLE_ON = 1,
|
||||
};
|
||||
|
||||
void cellSysutil_init();
|
||||
Module cellSysutil(0x0015, cellSysutil_init);
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
@ -132,6 +129,11 @@ enum CellMsgDialogType
|
||||
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)
|
||||
{
|
||||
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())
|
||||
return CELL_EFAULT;
|
||||
|
||||
memset(buf, 0, bufsize);
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
|
||||
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME");
|
||||
memcpy(buf, "Unknown", 8); //for example
|
||||
break;
|
||||
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME:
|
||||
cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME");
|
||||
memcpy(buf, "Unknown", 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -477,7 +483,7 @@ int cellSysutilUnregisterCallback(int slot)
|
||||
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;
|
||||
|
||||
@ -520,17 +526,16 @@ int cellMsgDialogOpen2(u32 type, char* msgString, u32 callback_addr, u32 userDat
|
||||
break;
|
||||
}
|
||||
|
||||
Callback2 callback(0, callback_addr, userData);
|
||||
callback.Handle(status);
|
||||
callback.Branch(true);
|
||||
if(callback)
|
||||
callback(status, userData);
|
||||
|
||||
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)",
|
||||
errorCode, callback_addr, userData, extParam);
|
||||
errorCode, callback.GetAddr(), userData, extParam);
|
||||
|
||||
std::string errorMessage;
|
||||
switch(errorCode)
|
||||
@ -622,10 +627,8 @@ int cellMsgDialogOpenErrorCode(u32 errorCode, u32 callback_addr, u32 userData, u
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: The following lines produce an infinite loop of cellMsgDialogOpenErrorCode's
|
||||
/*Callback2 callback(0, callback_addr, userData);
|
||||
callback.Handle(status);
|
||||
callback.Branch(true);*/
|
||||
if(callback)
|
||||
callback(status, userData);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -649,7 +652,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||
case CELL_AUDIO_OUT_FS_192KHZ:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
@ -659,7 +662,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
}
|
||||
|
||||
switch(audioOut)
|
||||
@ -668,8 +671,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option)
|
||||
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)
|
||||
@ -690,7 +692,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||
case CELL_AUDIO_OUT_FS_192KHZ:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
}
|
||||
|
||||
switch(ch)
|
||||
@ -700,7 +702,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||
case 8:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
@ -710,7 +712,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE;
|
||||
}
|
||||
|
||||
switch(audioOut)
|
||||
@ -719,8 +721,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3
|
||||
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)
|
||||
@ -831,7 +832,7 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut)
|
||||
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)
|
||||
@ -863,7 +864,7 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control)
|
||||
case CELL_AUDIO_OUT_SECONDARY:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
|
||||
default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
|
||||
}
|
||||
|
||||
switch(control)
|
||||
@ -873,7 +874,7 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control)
|
||||
case CELL_AUDIO_OUT_COPY_CONTROL_COPY_NEVER:
|
||||
break;
|
||||
|
||||
default: CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||
default: return CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
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);
|
||||
u32 entry = LoadSpuImage(f);
|
||||
u32 entry;
|
||||
u32 offset = LoadSpuImage(f, entry);
|
||||
|
||||
img->type = 1;
|
||||
img->type = type;
|
||||
img->entry_point = entry;
|
||||
img->segs_addr = 0x0;
|
||||
img->segs_addr = offset;
|
||||
img->nsegs = 0;
|
||||
|
||||
return CELL_OK;
|
||||
@ -119,15 +120,13 @@ int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
extern u64 g_last_spu_offset;
|
||||
|
||||
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());
|
||||
|
||||
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,
|
||||
img->entry_point - g_last_spu_offset);
|
||||
(u32)img->entry_point);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -3,7 +3,10 @@
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
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)
|
||||
{
|
||||
@ -135,6 +138,80 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
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()
|
||||
{
|
||||
sys_fs.AddFunc(0x718bf5f8, cellFsOpen);
|
||||
@ -155,6 +232,20 @@ void sys_fs_init()
|
||||
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
|
||||
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
|
||||
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
|
||||
|
||||
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)); }
|
||||
};
|
||||
|
||||
#undef ARG
|
||||
|
||||
template<typename TR>
|
||||
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);
|
||||
}
|
||||
|
||||
#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 cellFsTruncate(u32 path_addr, u64 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
|
||||
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
extern Module sys_fs;
|
||||
extern Array<vfsStream*> FDs;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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)",
|
||||
fd, buf_addr, nbytes, nread.GetAddr());
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
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))
|
||||
{
|
||||
@ -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)",
|
||||
fd, buf_addr, nbytes, nwrite.GetAddr());
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
sys_fs.Log("cellFsClose(fd: %d)", fd);
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
sys_fs.Warning("cellFsClose(fd: %d)", fd);
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
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();
|
||||
Emu.GetIdManager().RemoveID(fd);
|
||||
delete FDs[fd];
|
||||
//Emu.GetIdManager().RemoveID(fd);
|
||||
FDs[fd] = nullptr;
|
||||
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)
|
||||
{
|
||||
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
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 =
|
||||
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);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
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);
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -322,9 +343,12 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
||||
int cellFsFtruncate(u32 fd, u64 size)
|
||||
{
|
||||
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
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();
|
||||
|
||||
if (initialSize < size)
|
||||
@ -385,49 +409,3 @@ int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
//fix alignment:
|
||||
addr = (addr + 0x100000) & ~0xfffff;
|
||||
|
||||
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
|
||||
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)
|
||||
{
|
||||
//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;
|
||||
switch(flags)
|
||||
{
|
||||
case SYS_MEMORY_PAGE_SIZE_1M:
|
||||
if(size & 0xfffff) return CELL_EALIGN;
|
||||
addr = Memory.Alloc(size, 0x100000);
|
||||
addr = Memory.Alloc(size + 0x100000, 0x100000);
|
||||
addr = (addr + 0x100000) & ~0xfffff;
|
||||
break;
|
||||
|
||||
case SYS_MEMORY_PAGE_SIZE_64K:
|
||||
if(size & 0xffff) return CELL_EALIGN;
|
||||
addr = Memory.Alloc(size, 0x10000);
|
||||
addr = Memory.Alloc(size + 0x10000, 0x10000);
|
||||
addr = (addr + 0x10000) & ~0xffff;
|
||||
break;
|
||||
|
||||
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.button[CELL_PAD_BTN_OFFSET_DIGITAL1] = re(d1);
|
||||
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_Y] = re(pad.m_analog_right_y);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = re(pad.m_analog_left_x);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = re(pad.m_analog_left_y);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = re(rx);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = re(ry);
|
||||
data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = re(lx);
|
||||
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_LEFT] = re(pad.m_press_left);
|
||||
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 LoadSpuImage(vfsStream& stream, u32& spu_ep)
|
||||
{
|
||||
ELFLoader l(stream);
|
||||
l.LoadInfo();
|
||||
u32 alloc_size = 0xFFFFED - stream.GetSize();
|
||||
g_last_spu_offset = Memory.MainMem.Alloc(alloc_size);
|
||||
l.LoadData(g_last_spu_offset);
|
||||
|
||||
return g_last_spu_offset + l.GetEntry();
|
||||
const u32 alloc_size = 256 * 1024 /*0x1000000 - stream.GetSize()*/;
|
||||
u32 spu_offset = Memory.MainMem.Alloc(alloc_size);
|
||||
l.LoadData(spu_offset);
|
||||
spu_ep = 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
|
||||
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;
|
||||
}
|
||||
|
||||
u32 entry = LoadSpuImage(f);
|
||||
u32 entry;
|
||||
u32 offset = LoadSpuImage(f, entry);
|
||||
|
||||
img->type = 1;
|
||||
img->entry_point = entry;
|
||||
img->segs_addr = 0x0;
|
||||
img->segs_addr = offset;
|
||||
img->nsegs = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
u64 a1 = arg->arg1;
|
||||
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);
|
||||
//copy SPU image:
|
||||
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:
|
||||
new_thread.SetOffset(spu_offset);
|
||||
new_thread.SetEntry(ls_entry);
|
||||
new_thread.SetEntry(spu_ep);
|
||||
new_thread.SetName(name);
|
||||
new_thread.SetArg(0, a1);
|
||||
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;
|
||||
|
||||
ConLog.Write("New SPU Thread:");
|
||||
ConLog.Write("ls_entry = 0x%x", ls_entry);
|
||||
/*ConLog.Write("New SPU Thread:");
|
||||
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("a1 = 0x%x", a1);
|
||||
ConLog.Write("a2 = 0x%x", a2);
|
||||
ConLog.Write("a3 = 0x%x", a3);
|
||||
ConLog.Write("a4 = 0x%x", a4);
|
||||
ConLog.Write("ls_offset = 0x%x", ((SPUThread&)new_thread).dmac.ls_offset);
|
||||
ConLog.SkipLn();
|
||||
ConLog.SkipLn();*/
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
u32 LoadSpuImage(vfsStream& stream);
|
||||
u32 LoadSpuImage(vfsStream& stream, u32& spu_ep);
|
||||
|
||||
enum
|
||||
{
|
||||
@ -9,6 +9,13 @@ enum
|
||||
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
|
||||
{
|
||||
be_t<u32> name_len;
|
||||
@ -35,8 +42,8 @@ struct sys_spu_thread_argument
|
||||
struct sys_spu_image
|
||||
{
|
||||
be_t<u32> type;
|
||||
be_t<u32> entry_point;
|
||||
be_t<u32> segs_addr;
|
||||
be_t<u32> entry_point;
|
||||
be_t<u32> segs_addr; //temporarily used as offset of LS image after elf loading
|
||||
be_t<int> nsegs;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "MemoryViewer.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
|
||||
MemoryViewerPanel::MemoryViewerPanel(wxWindow* parent)
|
||||
: wxFrame(parent, wxID_ANY, "Memory Viewer", wxDefaultPosition, wxSize(700, 450))
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "RSXDebugger.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/GS/sysutil_video.h"
|
||||
#include "Emu/GS/GCM.h"
|
||||
|
||||
@ -16,6 +15,7 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
: wxFrame(parent, wxID_ANY, "RSX Debugger", wxDefaultPosition, wxSize(700, 450))
|
||||
, m_item_count(23)
|
||||
, m_addr(0x0)
|
||||
, m_cur_texture(0)
|
||||
, exit(false)
|
||||
{
|
||||
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);
|
||||
|
||||
// Controls
|
||||
wxStaticBoxSizer& s_controls = *new wxStaticBoxSizer(wxHORIZONTAL, this, "Memory Viewer Options");
|
||||
wxStaticBoxSizer& s_controls = *new wxStaticBoxSizer(wxHORIZONTAL, this, "RSX Debugger Controls");
|
||||
|
||||
// Controls: 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_lightning->InsertColumn(0, "Name", 0, 170);
|
||||
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(1, "Value", 0, 270);
|
||||
|
||||
@ -182,22 +191,24 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
SetSizerAndFit(&s_panel);
|
||||
|
||||
//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(b_goto_get->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RSXDebugger::GoToGet));
|
||||
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_colorB->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
||||
p_buffer_colorC->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(RSXDebugger::OnClickBuffer), NULL, this);
|
||||
p_buffer_colorD->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), nullptr, 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), nullptr, this);
|
||||
//Connect(p_buffer_depth->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_flags->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::SetFlags), 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), nullptr, this);
|
||||
|
||||
m_list_texture->Connect(wxID_ANY, wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(RSXDebugger::OnSelectTexture), nullptr, this);
|
||||
|
||||
//Fill the frame
|
||||
UpdateInformation();
|
||||
@ -205,10 +216,15 @@ RSXDebugger::RSXDebugger(wxWindow* parent)
|
||||
|
||||
void RSXDebugger::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
switch(event.GetKeyCode())
|
||||
if(wxGetActiveWindow() == wxGetTopLevelParent(this))
|
||||
{
|
||||
case WXK_F5: UpdateInformation(); break;
|
||||
switch(event.GetKeyCode())
|
||||
{
|
||||
case WXK_F5: UpdateInformation(); return;
|
||||
}
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event)
|
||||
@ -221,8 +237,34 @@ void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event)
|
||||
|
||||
void RSXDebugger::OnScrollMemory(wxMouseEvent& event)
|
||||
{
|
||||
m_addr -= (event.ControlDown() ? m_item_count : 1) * 4 * (event.GetWheelRotation() / event.GetWheelDelta());
|
||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||
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());
|
||||
}
|
||||
|
||||
UpdateInformation();
|
||||
event.Skip();
|
||||
}
|
||||
@ -233,10 +275,17 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event)
|
||||
const GSRender& render = Emu.GetGSManager().GetRender();
|
||||
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
|
||||
#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_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_tex->GetId())
|
||||
{
|
||||
MemoryViewerPanel::ShowImage(this,
|
||||
render.m_textures[0].m_offset, 0,
|
||||
render.m_textures[0].m_width,
|
||||
render.m_textures[0].m_height, false);
|
||||
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,
|
||||
render.m_textures[m_cur_texture].m_offset, 0,
|
||||
render.m_textures[m_cur_texture].m_width,
|
||||
render.m_textures[m_cur_texture].m_height, false);
|
||||
}
|
||||
|
||||
#undef SHOW_BUFFER
|
||||
@ -275,6 +325,7 @@ void RSXDebugger::GoToPut(wxCommandEvent& event)
|
||||
|
||||
void RSXDebugger::UpdateInformation()
|
||||
{
|
||||
t_addr->SetValue(wxString::Format("%08x", m_addr));
|
||||
GetMemory();
|
||||
GetBuffers();
|
||||
GetFlags();
|
||||
@ -289,26 +340,24 @@ void RSXDebugger::GetMemory()
|
||||
for(u32 i=0; i<m_item_count; i++)
|
||||
m_list_commands->SetItem(i, 2, wxEmptyString);
|
||||
|
||||
u32 ioAddr = RSXReady() ? Emu.GetGSManager().GetRender().m_ioAddress : 0;
|
||||
|
||||
// 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));
|
||||
|
||||
if (Memory.IsGoodAddr(addr))
|
||||
if (ioAddr && Memory.IsGoodAddr(addr))
|
||||
{
|
||||
u32 cmd = Memory.Read32(addr);
|
||||
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, 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);
|
||||
for (u32 j=0; j<count && i+j<m_item_count; j++)
|
||||
{
|
||||
m_list_commands->SetItem(i+j, 2, disasm);
|
||||
}
|
||||
addr += 4 * count;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -327,8 +376,15 @@ void RSXDebugger::GetBuffers()
|
||||
// TODO: Currently it only supports color buffers
|
||||
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);
|
||||
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);
|
||||
|
||||
u32 width = re(buffers[bufferId].width);
|
||||
@ -361,11 +417,15 @@ void RSXDebugger::GetBuffers()
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
u32 width = render.m_textures[0].m_width;
|
||||
u32 height = render.m_textures[0].m_height;
|
||||
u32 width = render.m_textures[m_cur_texture].m_width;
|
||||
u32 height = render.m_textures[m_cur_texture].m_height;
|
||||
unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
|
||||
memcpy(buffer, TexBuffer, width * height * 3);
|
||||
|
||||
@ -421,24 +481,23 @@ void RSXDebugger::GetTexture()
|
||||
if (!RSXReady()) return;
|
||||
const GSRender& render = Emu.GetGSManager().GetRender();
|
||||
m_list_texture->DeleteAllItems();
|
||||
int i=0;
|
||||
|
||||
#define LIST_TEXTURE_ADD(name, value) \
|
||||
m_list_texture->InsertItem(i, name); m_list_texture->SetItem(i, 1, value); i++;
|
||||
for(uint i=0; i<RSXThread::m_textures_count; ++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));
|
||||
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
|
||||
m_list_texture->SetItemBackgroundColour(i, wxColour(m_cur_texture == i ? "Wheat" : "White"));
|
||||
}
|
||||
}
|
||||
|
||||
void RSXDebugger::GetSettings()
|
||||
@ -524,6 +583,15 @@ void RSXDebugger::SetFlags(wxListEvent& event)
|
||||
case 11: render.m_set_poly_offset_point ^= 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();
|
||||
}
|
||||
|
||||
@ -616,117 +684,135 @@ wxString RSXDebugger::ParseGCMEnum(u32 value, u32 type)
|
||||
wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
disasm = wxString::Format("CALL: %08x -> %08x", currentAddr, ioAddr+callAddr);
|
||||
DISASM("CALL: %08x -> %08x", currentAddr, ioAddr+callAddr);
|
||||
}
|
||||
if(cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||
{
|
||||
disasm = "RETURN";
|
||||
}
|
||||
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||
{
|
||||
disasm = "Non Increment cmd";
|
||||
DISASM("RETURN");
|
||||
}
|
||||
|
||||
if(cmd == 0)
|
||||
{
|
||||
disasm = "Null cmd";
|
||||
DISASM("Null cmd");
|
||||
}
|
||||
|
||||
u32 index = 0;
|
||||
mem32_ptr_t args(currentAddr + 4);
|
||||
switch(cmd & 0x3ffff)
|
||||
else if(!(cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL)) && cmd != CELL_GCM_METHOD_FLAG_RETURN)
|
||||
{
|
||||
case 0x3fead:
|
||||
disasm = "???"; break;
|
||||
case NV4097_NO_OPERATION:
|
||||
disasm = "NOP"; break;
|
||||
case NV406E_SET_REFERENCE:
|
||||
disasm = "???"; break;
|
||||
mem32_ptr_t args(currentAddr + 4);
|
||||
|
||||
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
||||
disasm = wxString::Format(" Texture Offset: %08x", args[0]);
|
||||
switch ((args[1] & 0x3) - 1)
|
||||
u32 index = 0;
|
||||
switch(cmd & 0x3ffff)
|
||||
{
|
||||
case CELL_GCM_LOCATION_LOCAL: disasm += " (Local memory);"; break;
|
||||
case CELL_GCM_LOCATION_MAIN: disasm += " (Main memory);"; break;
|
||||
default: disasm += " (Bad location!);"; break;
|
||||
}
|
||||
disasm += wxString::Format(" Cubemap:%s; Dimension:0x%x; Format:0x%x; Mipmap:0x%x",
|
||||
((args[1] >> 2) & 0x1) ? "True" : "False",
|
||||
((args[1] >> 4) & 0xf),
|
||||
((args[1] >> 8) & 0xff),
|
||||
((args[1] >> 16) & 0xffff));
|
||||
break;
|
||||
|
||||
case NV4097_SET_COLOR_MASK:
|
||||
disasm = wxString::Format(" Color mask: True (A:%d, R:%d, G:%d, B:%d)",
|
||||
args[0] & 0x1000000 ? "1" : "0",
|
||||
args[0] & 0x0010000 ? "1" : "0",
|
||||
args[0] & 0x0000100 ? "1" : "0",
|
||||
args[0] & 0x0000001 ? "1" : "0");
|
||||
break;
|
||||
|
||||
case NV4097_SET_ALPHA_TEST_ENABLE:
|
||||
disasm = args[0] ? "Alpha test: Enable" : "Alpha test: Disable";
|
||||
break;
|
||||
|
||||
case NV4097_SET_BLEND_ENABLE:
|
||||
disasm = args[0] ? "Blend: Enable" : "Blend: Disable";
|
||||
break;
|
||||
|
||||
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
|
||||
disasm = args[0] ? "Depth bounds test: Enable" : "Depth bounds test: Disable";
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_COLOR_A:
|
||||
disasm = wxString::Format("Context DMA Color A: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_COLOR_B:
|
||||
disasm = wxString::Format("Context DMA Color B: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_COLOR_C:
|
||||
disasm = wxString::Format("Context DMA Color C: 0x%x", args[0]);
|
||||
if(count > 1)
|
||||
disasm = wxString::Format("Context DMA Color C: 0x%x", args[1]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_ZETA:
|
||||
disasm = wxString::Format("Context DMA Zeta: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_SURFACE_PITCH_C:
|
||||
disasm = wxString::Format("Surface Pitch C: 0x%x; ", args[0]);
|
||||
disasm += wxString::Format("Surface Pitch D: 0x%x; ", args[1]);
|
||||
disasm += wxString::Format("Surface Offset C: 0x%x; ", args[2]);
|
||||
disasm += wxString::Format("Surface Offset D: 0x%x", args[3]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_SURFACE_PITCH_Z:
|
||||
disasm = wxString::Format("Surface Pitch Z: 0x%x; ", args[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0x3fead:
|
||||
DISASM("Flip and change current buffer: %d", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_NO_OPERATION:
|
||||
DISASM("NOP");
|
||||
break;
|
||||
|
||||
case NV406E_SET_REFERENCE:
|
||||
DISASM("Set reference: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
||||
DISASM("Texture Offset[%d]: %08x", index, args[0]);
|
||||
switch ((args[1] & 0x3) - 1)
|
||||
{
|
||||
case CELL_GCM_LOCATION_LOCAL: DISASM("(Local memory);"); break;
|
||||
case CELL_GCM_LOCATION_MAIN: DISASM("(Main memory);"); break;
|
||||
default: DISASM("(Bad location!);"); break;
|
||||
}
|
||||
DISASM(" Cubemap:%s; Dimension:0x%x; Format:0x%x; Mipmap:0x%x",
|
||||
((args[1] >> 2) & 0x1) ? "True" : "False",
|
||||
((args[1] >> 4) & 0xf),
|
||||
((args[1] >> 8) & 0xff),
|
||||
((args[1] >> 16) & 0xffff));
|
||||
break;
|
||||
|
||||
case NV4097_SET_COLOR_MASK:
|
||||
DISASM(" Color mask: True (A:%c, R:%c, G:%c, B:%c)",
|
||||
args[0] & 0x1000000 ? '1' : '0',
|
||||
args[0] & 0x0010000 ? '1' : '0',
|
||||
args[0] & 0x0000100 ? '1' : '0',
|
||||
args[0] & 0x0000001 ? '1' : '0');
|
||||
break;
|
||||
|
||||
case NV4097_SET_ALPHA_TEST_ENABLE:
|
||||
DISASM(args[0] ? "Alpha test: Enable" : "Alpha test: Disable");
|
||||
break;
|
||||
|
||||
case NV4097_SET_BLEND_ENABLE:
|
||||
DISASM(args[0] ? "Blend: Enable" : "Blend: Disable");
|
||||
break;
|
||||
|
||||
case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE:
|
||||
DISASM(args[0] ? "Depth bounds test: Enable" : "Depth bounds test: Disable");
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_COLOR_A:
|
||||
DISASM("Context DMA Color A: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_COLOR_B:
|
||||
DISASM("Context DMA Color B: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_COLOR_C:
|
||||
DISASM("Context DMA Color C: 0x%x", args[0]);
|
||||
if(count > 1)
|
||||
DISASM("0x%x", args[1]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_CONTEXT_DMA_ZETA:
|
||||
DISASM("Context DMA Zeta: 0x%x", args[0]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_SURFACE_PITCH_C:
|
||||
DISASM("Surface Pitch C: 0x%x;", args[0]);
|
||||
DISASM("Surface Pitch D: 0x%x;", args[1]);
|
||||
DISASM("Surface Offset C: 0x%x;", args[2]);
|
||||
DISASM("Surface Offset D: 0x%x", args[3]);
|
||||
break;
|
||||
|
||||
case NV4097_SET_SURFACE_PITCH_Z:
|
||||
DISASM("Surface Pitch Z: 0x%x;", args[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
const GSRender& render = Emu.GetGSManager().GetRender();
|
||||
if (!&render)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return Emu.GetGSManager().IsInited();
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
class RSXDebugger : public wxFrame
|
||||
{
|
||||
AppConnector m_app_connector;
|
||||
|
||||
u32 m_addr;
|
||||
|
||||
u32 m_panel_width;
|
||||
@ -28,6 +30,8 @@ class RSXDebugger : public wxFrame
|
||||
wxPanel* p_buffer_stencil;
|
||||
wxPanel* p_buffer_tex;
|
||||
|
||||
uint m_cur_texture;
|
||||
|
||||
public:
|
||||
bool exit;
|
||||
RSXDebugger(wxWindow* parent);
|
||||
@ -53,7 +57,8 @@ public:
|
||||
virtual void GetSettings();
|
||||
|
||||
virtual void SetFlags(wxListEvent& event);
|
||||
|
||||
virtual void OnSelectTexture(wxListEvent& event);
|
||||
|
||||
wxString ParseGCMEnum(u32 value, u32 type);
|
||||
wxString DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr);
|
||||
|
||||
|
@ -188,7 +188,7 @@ void VFSManagerDialog::OnAdd(wxCommandEvent& event)
|
||||
m_list->SetItemState(i, i == idx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
||||
}
|
||||
|
||||
wxCommandEvent ce;
|
||||
wxCommandEvent ce;
|
||||
OnEntryConfig(ce);
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,8 @@ bool ELF32Loader::LoadShdrInfo()
|
||||
|
||||
if(ehdr.e_shstrndx >= shdr_arr.GetCount())
|
||||
{
|
||||
ConLog.Error("LoadShdr32 error: shstrndx too big!");
|
||||
return false;
|
||||
ConLog.Warning("LoadShdr32 error: shstrndx too big!");
|
||||
return true;
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
ConLog.Error("LoadShdr64 error: shstrndx too big!");
|
||||
return false;
|
||||
ConLog.Warning("LoadShdr64 error: shstrndx too big!");
|
||||
return true;
|
||||
}
|
||||
|
||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "Emu/FS/vfsFileBase.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LOADER_DEBUG
|
||||
//#define LOADER_DEBUG
|
||||
#endif
|
||||
|
||||
enum Elf_Machine
|
||||
|
Loading…
x
Reference in New Issue
Block a user