mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 14:01:25 +12:00
Conflicts fixed
This commit is contained in:
commit
be2d606193
51 changed files with 1850 additions and 657 deletions
|
@ -137,23 +137,42 @@ std::vector<std::string> fmt::split(const std::string& source, std::initializer_
|
||||||
|
|
||||||
std::string fmt::merge(std::vector<std::string> source, const std::string& separator)
|
std::string fmt::merge(std::vector<std::string> source, const std::string& separator)
|
||||||
{
|
{
|
||||||
std::string result;
|
if (!source.size())
|
||||||
|
|
||||||
for (auto &s : source)
|
|
||||||
{
|
{
|
||||||
result += s + separator;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
std::string result;
|
||||||
|
|
||||||
|
for (int i = 0; i < source.size() - 1; ++i)
|
||||||
|
{
|
||||||
|
result += source[i] + separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result + source[source.size() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fmt::merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator)
|
std::string fmt::merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator)
|
||||||
{
|
{
|
||||||
|
if (!sources.size())
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
for (auto &v : sources)
|
for (auto &v : sources)
|
||||||
{
|
{
|
||||||
result += fmt::merge(v, separator);
|
if (first)
|
||||||
|
{
|
||||||
|
result = fmt::merge(v, separator);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += separator + fmt::merge(v, separator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
2
asmjit
2
asmjit
|
@ -1 +1 @@
|
||||||
Subproject commit 1318c9aff7137b30aec7dee2ababb2b313ae0f06
|
Subproject commit 48da90ded775fa2ba0fd3f15522890ad631ad6de
|
2
ffmpeg
2
ffmpeg
|
@ -1 +1 @@
|
||||||
Subproject commit 352fdfbbfa6d7b26142f00b43d7e1802a03c68a8
|
Subproject commit 79a2d7a9f780ad27d1622010cb1cb8396c3701e9
|
|
@ -43,13 +43,13 @@ bool CheckHeader(rFile& pkg_f, PKGHeader* m_header)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_header->pkg_size != pkg_f.Length()) {
|
if (m_header->pkg_size != pkg_f.Length()) {
|
||||||
LOG_ERROR(LOADER, "PKG: File size mismatch.");
|
LOG_WARNING(LOADER, "PKG: File size mismatch.");
|
||||||
return false;
|
//return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_header->data_size + m_header->data_offset + 0x60 != pkg_f.Length()) {
|
if (m_header->data_size + m_header->data_offset + 0x60 != pkg_f.Length()) {
|
||||||
LOG_ERROR(LOADER, "PKG: Data size mismatch.");
|
LOG_WARNING(LOADER, "PKG: Data size mismatch.");
|
||||||
return false;
|
//return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -82,6 +82,8 @@ struct AudioPortConfig
|
||||||
u64 attr;
|
u64 attr;
|
||||||
u64 tag;
|
u64 tag;
|
||||||
u64 counter; // copy of global counter
|
u64 counter; // copy of global counter
|
||||||
|
u32 addr;
|
||||||
|
u32 read_index_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AudioConfig //custom structure
|
struct AudioConfig //custom structure
|
||||||
|
|
|
@ -25,7 +25,7 @@ SPURecompilerCore::SPURecompilerCore(SPUThread& cpu)
|
||||||
memset(entry, 0, sizeof(entry));
|
memset(entry, 0, sizeof(entry));
|
||||||
X86CpuInfo inf;
|
X86CpuInfo inf;
|
||||||
X86CpuUtil::detect(&inf);
|
X86CpuUtil::detect(&inf);
|
||||||
if (!inf.hasFeature(kX86CpuFeatureSse41))
|
if (!inf.hasFeature(kX86CpuFeatureSSE4_1))
|
||||||
{
|
{
|
||||||
LOG_ERROR(SPU, "SPU JIT requires SSE4.1 instruction set support");
|
LOG_ERROR(SPU, "SPU JIT requires SSE4.1 instruction set support");
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
|
|
|
@ -32,21 +32,12 @@ std::string simplify_path(const std::string& path, bool is_dir)
|
||||||
{
|
{
|
||||||
std::vector<std::string> path_blocks = simplify_path_blocks(path);
|
std::vector<std::string> path_blocks = simplify_path_blocks(path);
|
||||||
|
|
||||||
std::string result;
|
|
||||||
|
|
||||||
if (path_blocks.empty())
|
if (path_blocks.empty())
|
||||||
return result;
|
return "";
|
||||||
|
|
||||||
if (is_dir)
|
std::string result = fmt::merge(path_blocks, "/");
|
||||||
{
|
|
||||||
result = fmt::merge(path_blocks, "/");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = fmt::merge(std::vector<std::string>(path_blocks.begin(), path_blocks.end() - 1), "/") + path_blocks[path_blocks.size() - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return is_dir ? result + "/" : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VFS::~VFS()
|
VFS::~VFS()
|
||||||
|
|
|
@ -75,7 +75,12 @@ bool vfsLocalFile::Create(const std::string& path)
|
||||||
if(m != '/' && m != '\\' && !rExists(path)) // ???
|
if(m != '/' && m != '\\' && !rExists(path)) // ???
|
||||||
{
|
{
|
||||||
rFile f;
|
rFile f;
|
||||||
return f.Create(path);
|
if (!f.Create(path)) {
|
||||||
|
LOG_NOTICE(HLE, "vfsLocalFile::Create: couldn't create file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -29,19 +29,31 @@ void GLFragmentDecompilerThread::SetDst(std::string code, bool append_mask)
|
||||||
code = "clamp(" + code + ", 0.0, 1.0)";
|
code = "clamp(" + code + ", 0.0, 1.0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dest;
|
code += (append_mask ? "$m" : "");
|
||||||
|
|
||||||
|
if (dst.no_dest)
|
||||||
|
{
|
||||||
|
if (dst.set_cond)
|
||||||
|
{
|
||||||
|
AddCode("$ifcond " + m_parr.AddParam(PARAM_NONE, "vec4", "cc" + std::to_string(src0.cond_mod_reg_index)) + "$m = " + code + ";");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddCode("$ifcond " + code + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string dest = AddReg(dst.dest_reg, dst.fp16) + "$m";
|
||||||
|
|
||||||
|
AddCodeCond(Format(dest), code);
|
||||||
|
//AddCode("$ifcond " + dest + code + (append_mask ? "$m;" : ";"));
|
||||||
|
|
||||||
if (dst.set_cond)
|
if (dst.set_cond)
|
||||||
{
|
{
|
||||||
dest += m_parr.AddParam(PARAM_NONE, "vec4", "cc" + std::to_string(src0.cond_mod_reg_index)) + "$m = ";
|
AddCode(m_parr.AddParam(PARAM_NONE, "vec4", "cc" + std::to_string(src0.cond_mod_reg_index)) + "$m = " + dest + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dst.no_dest)
|
|
||||||
{
|
|
||||||
dest += AddReg(dst.dest_reg, dst.fp16) + "$m = ";
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCode("$ifcond " + dest + code + (append_mask ? "$m;" : ";"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLFragmentDecompilerThread::AddCode(const std::string& code)
|
void GLFragmentDecompilerThread::AddCode(const std::string& code)
|
||||||
|
@ -68,7 +80,7 @@ std::string GLFragmentDecompilerThread::GetMask()
|
||||||
|
|
||||||
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
|
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
|
||||||
{
|
{
|
||||||
return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0, 0.0, 0.0, 0.0)");
|
return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
|
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
|
||||||
|
@ -179,6 +191,74 @@ std::string GLFragmentDecompilerThread::GetCond()
|
||||||
return "any(" + cond + "(" + AddCond() + swizzle + ", vec4(0.0)))";
|
return "any(" + cond + "(" + AddCond() + swizzle + ", vec4(0.0)))";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLFragmentDecompilerThread::AddCodeCond(const std::string& dst, const std::string& src)
|
||||||
|
{
|
||||||
|
if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
AddCode(dst + " = " + src + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
AddCode("//" + dst + " = " + src + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||||
|
|
||||||
|
std::string swizzle, cond;
|
||||||
|
swizzle += f[src0.cond_swizzle_x];
|
||||||
|
swizzle += f[src0.cond_swizzle_y];
|
||||||
|
swizzle += f[src0.cond_swizzle_z];
|
||||||
|
swizzle += f[src0.cond_swizzle_w];
|
||||||
|
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||||
|
|
||||||
|
if (src0.exec_if_gr && src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
cond = "greaterThanEqual";
|
||||||
|
}
|
||||||
|
else if (src0.exec_if_lt && src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
cond = "lessThanEqual";
|
||||||
|
}
|
||||||
|
else if (src0.exec_if_gr && src0.exec_if_lt)
|
||||||
|
{
|
||||||
|
cond = "notEqual";
|
||||||
|
}
|
||||||
|
else if (src0.exec_if_gr)
|
||||||
|
{
|
||||||
|
cond = "greaterThan";
|
||||||
|
}
|
||||||
|
else if (src0.exec_if_lt)
|
||||||
|
{
|
||||||
|
cond = "lessThan";
|
||||||
|
}
|
||||||
|
else //if(src0.exec_if_eq)
|
||||||
|
{
|
||||||
|
cond = "equal";
|
||||||
|
}
|
||||||
|
|
||||||
|
cond = cond + "(" + AddCond() + swizzle + ", vec4(0.0))";
|
||||||
|
|
||||||
|
ShaderVar dst_var(dst);
|
||||||
|
dst_var.symplify();
|
||||||
|
|
||||||
|
//const char *c_mask = f;
|
||||||
|
|
||||||
|
if (dst_var.swizzles[0].length() == 1)
|
||||||
|
{
|
||||||
|
AddCode("if (" + cond + ".x) " + dst + " = vec4(" + src + ").x;");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dst_var.swizzles[0].length(); ++i)
|
||||||
|
{
|
||||||
|
AddCode("if (" + cond + "." + f[i] + ") " + dst + "." + f[i] + " = " + src + "." + f[i] + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> std::string GLFragmentDecompilerThread::GetSRC(T src)
|
template<typename T> std::string GLFragmentDecompilerThread::GetSRC(T src)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
@ -251,10 +331,9 @@ std::string GLFragmentDecompilerThread::BuildCode()
|
||||||
const std::pair<std::string, std::string> table[] =
|
const std::pair<std::string, std::string> table[] =
|
||||||
{
|
{
|
||||||
{ "ocol0", m_ctrl & 0x40 ? "r0" : "h0" },
|
{ "ocol0", m_ctrl & 0x40 ? "r0" : "h0" },
|
||||||
{ "ocol1", m_ctrl & 0x40 ? "r2" : "h2" },
|
{ "ocol1", m_ctrl & 0x40 ? "r2" : "h4" },
|
||||||
{ "ocol2", m_ctrl & 0x40 ? "r3" : "h4" },
|
{ "ocol2", m_ctrl & 0x40 ? "r3" : "h6" },
|
||||||
{ "ocol3", m_ctrl & 0x40 ? "r4" : "h6" },
|
{ "ocol3", m_ctrl & 0x40 ? "r4" : "h8" },
|
||||||
{ "ocol4", m_ctrl & 0x40 ? "r5" : "h8" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(table) / sizeof(*table); ++i)
|
for (int i = 0; i < sizeof(table) / sizeof(*table); ++i)
|
||||||
|
@ -263,7 +342,7 @@ std::string GLFragmentDecompilerThread::BuildCode()
|
||||||
AddCode(m_parr.AddParam(PARAM_OUT, "vec4", table[i].first, i) + " = " + table[i].second + ";");
|
AddCode(m_parr.AddParam(PARAM_OUT, "vec4", table[i].first, i) + " = " + table[i].second + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ctrl & 0xe) main += "\tgl_FragDepth = r1.z;\n";
|
if (m_ctrl & 0xe) main += m_ctrl & 0x40 ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h2.z;\n";
|
||||||
|
|
||||||
std::string p;
|
std::string p;
|
||||||
|
|
||||||
|
@ -285,6 +364,15 @@ void GLFragmentDecompilerThread::Task()
|
||||||
m_loop_count = 0;
|
m_loop_count = 0;
|
||||||
m_code_level = 1;
|
m_code_level = 1;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FORCE_NONE,
|
||||||
|
FORCE_SCT,
|
||||||
|
FORCE_SCB,
|
||||||
|
};
|
||||||
|
|
||||||
|
int forced_unit = FORCE_NONE;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
for (auto finded = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size);
|
for (auto finded = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size);
|
||||||
|
@ -318,111 +406,116 @@ void GLFragmentDecompilerThread::Task()
|
||||||
|
|
||||||
const u32 opcode = dst.opcode | (src1.opcode_is_branch << 6);
|
const u32 opcode = dst.opcode | (src1.opcode_is_branch << 6);
|
||||||
|
|
||||||
|
auto SCT = [&]()
|
||||||
|
{
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case RSX_FP_OPCODE_NOP: break;
|
|
||||||
case RSX_FP_OPCODE_MOV: SetDst("$0"); break;
|
|
||||||
case RSX_FP_OPCODE_MUL: SetDst("($0 * $1)"); break;
|
|
||||||
case RSX_FP_OPCODE_ADD: SetDst("($0 + $1)"); break;
|
case RSX_FP_OPCODE_ADD: SetDst("($0 + $1)"); break;
|
||||||
case RSX_FP_OPCODE_MAD: SetDst("($0 * $1 + $2)"); break;
|
|
||||||
case RSX_FP_OPCODE_DP3: SetDst("vec4(dot($0.xyz, $1.xyz))"); break;
|
|
||||||
case RSX_FP_OPCODE_DP4: SetDst("vec4(dot($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_DST: SetDst("vec4(distance($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_MIN: SetDst("min($0, $1)"); break;
|
|
||||||
case RSX_FP_OPCODE_MAX: SetDst("max($0, $1)"); break;
|
|
||||||
case RSX_FP_OPCODE_SLT: SetDst("vec4(lessThan($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_SGE: SetDst("vec4(greaterThanEqual($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_SLE: SetDst("vec4(lessThanEqual($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_SGT: SetDst("vec4(greaterThan($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_SNE: SetDst("vec4(notEqual($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_SEQ: SetDst("vec4(equal($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_FRC: SetDst("fract($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_FLR: SetDst("floor($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_KIL: SetDst("discard", false); break;
|
|
||||||
case RSX_FP_OPCODE_PK4:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode PK4");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_UP4:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode UP4");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_DDX: SetDst("dFdx($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_DDY: SetDst("dFdy($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_TEX: SetDst("texture($t, $0.xy)"); break;
|
|
||||||
case RSX_FP_OPCODE_TXP:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TXP");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_TXD:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TXD");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_RCP: SetDst("(1 / $0)"); break;
|
|
||||||
case RSX_FP_OPCODE_RSQ: SetDst("inversesqrt(abs($0))"); break;
|
|
||||||
case RSX_FP_OPCODE_EX2: SetDst("exp2($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_LG2: SetDst("log2($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_LIT: SetDst("vec4(1.0, $0.x, ($0.x > 0 ? exp2($0.w * log2($0.y)) : 0.0), 1.0)"); break;
|
|
||||||
case RSX_FP_OPCODE_LRP: SetDst("($0 * ($1 - $2) + $2)"); break;
|
|
||||||
case RSX_FP_OPCODE_STR: SetDst("vec4(equal($0, vec4(1.0)))"); break;
|
|
||||||
case RSX_FP_OPCODE_SFL: SetDst("vec4(equal($0, vec4(0.0)))"); break;
|
|
||||||
case RSX_FP_OPCODE_COS: SetDst("cos($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_SIN: SetDst("sin($0)"); break;
|
|
||||||
case RSX_FP_OPCODE_PK2:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode PK2");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_UP2:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode UP2");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_POW: SetDst("pow($0, $1)"); break;
|
|
||||||
case RSX_FP_OPCODE_PKB:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode PKB");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_UPB:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode UPB");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_PK16:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode PK16");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_UP16:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode UP16");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_BEM:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode BEM");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_PKG:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode PKG");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_UPG:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode UPG");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_DP2A: SetDst("($0.x * $1.x + $0.y * $1.y + $2.x)"); break;
|
|
||||||
case RSX_FP_OPCODE_TXL: break;
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TXL");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_TXB: break;
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TXB");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_TEXBEM:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TEXBEM");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_TXPBEM:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TXPBEM");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_BEMLUM:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode BEMLUM");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_REFL: SetDst("($0 - 2.0 * $1 * dot($0, $1))"); break;
|
|
||||||
case RSX_FP_OPCODE_TIMESWTEX:
|
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode TIMESWTEX");
|
|
||||||
break;
|
|
||||||
case RSX_FP_OPCODE_DP2: SetDst("vec4(dot($0.xy, $1.xy))"); break;
|
|
||||||
case RSX_FP_OPCODE_NRM: SetDst("normalize($0.xyz)"); break;
|
|
||||||
case RSX_FP_OPCODE_DIV: SetDst("($0 / $1)"); break;
|
case RSX_FP_OPCODE_DIV: SetDst("($0 / $1)"); break;
|
||||||
case RSX_FP_OPCODE_DIVSQ: SetDst("($0 / sqrt($1))"); break;
|
case RSX_FP_OPCODE_DIVSQ: SetDst("($0 / sqrt($1))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP2: SetDst("vec4(dot($0.xy, $1.xy))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP3: SetDst("vec4(dot($0.xyz, $1.xyz))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP4: SetDst("vec4(dot($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP2A: SetDst("vec4($0.x * $1.x + $0.y * $1.y + $2.x)"); break;
|
||||||
|
case RSX_FP_OPCODE_MAD: SetDst("($0 * $1 + $2)"); break;
|
||||||
|
case RSX_FP_OPCODE_MAX: SetDst("max($0, $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_MIN: SetDst("min($0, $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_MOV: SetDst("$0"); break;
|
||||||
|
case RSX_FP_OPCODE_MUL: SetDst("($0 * $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_RCP: SetDst("1 / $0"); break;
|
||||||
|
case RSX_FP_OPCODE_RSQ: SetDst("inversesqrt(abs($0))"); break;
|
||||||
|
case RSX_FP_OPCODE_SEQ: SetDst("vec4(equal($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SFL: SetDst("vec4(0.0)"); break;
|
||||||
|
case RSX_FP_OPCODE_SGE: SetDst("vec4(greaterThanEqual($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SGT: SetDst("vec4(greaterThan($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SLE: SetDst("vec4(lessThanEqual($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SLT: SetDst("vec4(lessThan($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SNE: SetDst("vec4(notEqual($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_STR: SetDst("vec4(1.0)"); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto SCB = [&]()
|
||||||
|
{
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
|
case RSX_FP_OPCODE_ADD: SetDst("($0 + $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_COS: SetDst("cos($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_DP2: SetDst("vec4(dot($0.xy, $1.xy))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP3: SetDst("vec4(dot($0.xyz, $1.xyz))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP4: SetDst("vec4(dot($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_DP2A: SetDst("vec4($0.x * $1.x + $0.y * $1.y + $2.x)"); break;
|
||||||
|
case RSX_FP_OPCODE_DST: SetDst("vec4(distance($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_EX2: SetDst("exp2($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_FLR: SetDst("floor($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_FRC: SetDst("fract($0)"); break;
|
||||||
case RSX_FP_OPCODE_LIF: SetDst("vec4(1.0, $0.y, ($0.y > 0 ? pow(2.0, $0.w) : 0.0), 1.0)"); break;
|
case RSX_FP_OPCODE_LIF: SetDst("vec4(1.0, $0.y, ($0.y > 0 ? pow(2.0, $0.w) : 0.0), 1.0)"); break;
|
||||||
case RSX_FP_OPCODE_FENCT: break;
|
case RSX_FP_OPCODE_LG2: SetDst("log2($0)"); break;
|
||||||
case RSX_FP_OPCODE_FENCB: break;
|
case RSX_FP_OPCODE_MAD: SetDst("($0 * $1 + $2)"); break;
|
||||||
|
case RSX_FP_OPCODE_MAX: SetDst("max($0, $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_MIN: SetDst("min($0, $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_MOV: SetDst("$0"); break;
|
||||||
|
case RSX_FP_OPCODE_MUL: SetDst("($0 * $1)"); break;
|
||||||
|
case RSX_FP_OPCODE_PK2: LOG_ERROR(RSX, "Unimplemented SCB instruction: PK2"); break;
|
||||||
|
case RSX_FP_OPCODE_PK4: LOG_ERROR(RSX, "Unimplemented SCB instruction: PK4"); break;
|
||||||
|
case RSX_FP_OPCODE_PK16: LOG_ERROR(RSX, "Unimplemented SCB instruction: PK16"); break;
|
||||||
|
case RSX_FP_OPCODE_PKB: LOG_ERROR(RSX, "Unimplemented SCB instruction: PKB"); break;
|
||||||
|
case RSX_FP_OPCODE_PKG: LOG_ERROR(RSX, "Unimplemented SCB instruction: PKG"); break;
|
||||||
|
case RSX_FP_OPCODE_SEQ: SetDst("vec4(equal($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SFL: SetDst("vec4(0.0)"); break;
|
||||||
|
case RSX_FP_OPCODE_SGE: SetDst("vec4(greaterThanEqual($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SGT: SetDst("vec4(greaterThan($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SIN: SetDst("sin($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_SLE: SetDst("vec4(lessThanEqual($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SLT: SetDst("vec4(lessThan($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_SNE: SetDst("vec4(notEqual($0, $1))"); break;
|
||||||
|
case RSX_FP_OPCODE_STR: SetDst("vec4(1.0)"); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto TEX_SRB = [&]()
|
||||||
|
{
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
|
case RSX_FP_OPCODE_DDX: SetDst("dFdx($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_DDY: SetDst("dFdy($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_NRM: SetDst("normalize($0)"); break;
|
||||||
|
case RSX_FP_OPCODE_TEX: SetDst("texture($t, $0.xy)"); break;
|
||||||
|
case RSX_FP_OPCODE_TXP: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXP"); break;
|
||||||
|
case RSX_FP_OPCODE_TXD: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXD"); break;
|
||||||
|
case RSX_FP_OPCODE_TXB: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXB"); break;
|
||||||
|
case RSX_FP_OPCODE_TXL: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXL"); break;
|
||||||
|
case RSX_FP_OPCODE_UP2: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UP2"); break;
|
||||||
|
case RSX_FP_OPCODE_UP4: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UP4"); break;
|
||||||
|
case RSX_FP_OPCODE_UP16: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UP16"); break;
|
||||||
|
case RSX_FP_OPCODE_UPB: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UPB"); break;
|
||||||
|
case RSX_FP_OPCODE_UPG: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UPG"); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto SIP = [&]()
|
||||||
|
{
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
case RSX_FP_OPCODE_BRK: SetDst("break"); break;
|
case RSX_FP_OPCODE_BRK: SetDst("break"); break;
|
||||||
case RSX_FP_OPCODE_CAL:
|
case RSX_FP_OPCODE_CAL: LOG_ERROR(RSX, "Unimplemented SIP instruction: CAL"); break;
|
||||||
LOG_ERROR(RSX, "Unimplemented fp_opcode CAL");
|
case RSX_FP_OPCODE_FENCT: forced_unit = FORCE_SCT; break;
|
||||||
break;
|
case RSX_FP_OPCODE_FENCB: forced_unit = FORCE_SCB; break;
|
||||||
case RSX_FP_OPCODE_IFE:
|
case RSX_FP_OPCODE_IFE:
|
||||||
AddCode("if($cond)");
|
AddCode("if($cond)");
|
||||||
m_else_offsets.push_back(src1.else_offset << 2);
|
m_else_offsets.push_back(src1.else_offset << 2);
|
||||||
|
@ -430,7 +523,6 @@ void GLFragmentDecompilerThread::Task()
|
||||||
AddCode("{");
|
AddCode("{");
|
||||||
m_code_level++;
|
m_code_level++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RSX_FP_OPCODE_LOOP:
|
case RSX_FP_OPCODE_LOOP:
|
||||||
if (!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt)
|
if (!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt)
|
||||||
{
|
{
|
||||||
|
@ -463,13 +555,40 @@ void GLFragmentDecompilerThread::Task()
|
||||||
m_code_level++;
|
m_code_level++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RSX_FP_OPCODE_RET:
|
case RSX_FP_OPCODE_RET: SetDst("return"); break;
|
||||||
SetDst("return");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(RSX, "Unknown fp opcode 0x%x (inst %d)", opcode, m_size / (4 * 4));
|
return false;
|
||||||
Emu.Pause();
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
|
case RSX_FP_OPCODE_NOP: break;
|
||||||
|
case RSX_FP_OPCODE_KIL: SetDst("discard", false); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (forced_unit == FORCE_NONE)
|
||||||
|
{
|
||||||
|
if (SIP()) break;
|
||||||
|
if (SCT()) break;
|
||||||
|
if (TEX_SRB()) break;
|
||||||
|
if (SCB()) break;
|
||||||
|
}
|
||||||
|
else if (forced_unit == FORCE_SCT)
|
||||||
|
{
|
||||||
|
forced_unit = FORCE_NONE;
|
||||||
|
if (SCT()) break;
|
||||||
|
}
|
||||||
|
else if (forced_unit == FORCE_SCB)
|
||||||
|
{
|
||||||
|
forced_unit = FORCE_NONE;
|
||||||
|
if (SCB()) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERROR(RSX, "Unknown/illegal instruction: 0x%x (forced unit %d)", opcode, forced_unit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ struct GLFragmentDecompilerThread : public ThreadBase
|
||||||
std::string AddTex();
|
std::string AddTex();
|
||||||
std::string Format(const std::string& code);
|
std::string Format(const std::string& code);
|
||||||
|
|
||||||
|
void AddCodeCond(const std::string& dst, const std::string& src);
|
||||||
std::string GetCond();
|
std::string GetCond();
|
||||||
template<typename T> std::string GetSRC(T src);
|
template<typename T> std::string GetSRC(T src);
|
||||||
std::string BuildCode();
|
std::string BuildCode();
|
||||||
|
|
|
@ -425,7 +425,7 @@ void GLTexture::Init(RSXTexture& tex)
|
||||||
|
|
||||||
free(unswizzledPixels);
|
free(unswizzledPixels);
|
||||||
}
|
}
|
||||||
break; break;
|
break;
|
||||||
|
|
||||||
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN):
|
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN):
|
||||||
{
|
{
|
||||||
|
@ -450,7 +450,7 @@ void GLTexture::Init(RSXTexture& tex)
|
||||||
|
|
||||||
free(unswizzledPixels);
|
free(unswizzledPixels);
|
||||||
}
|
}
|
||||||
break; break;
|
break;
|
||||||
|
|
||||||
default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format,
|
default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format,
|
||||||
(is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40);
|
(is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40);
|
||||||
|
@ -984,7 +984,7 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
|
||||||
LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type);
|
LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 && !m_vertex_data[i].addr)
|
if(!m_vertex_data[i].addr)
|
||||||
{
|
{
|
||||||
switch(m_vertex_data[i].type)
|
switch(m_vertex_data[i].type)
|
||||||
{
|
{
|
||||||
|
@ -1647,6 +1647,21 @@ void GLGSRender::InitDrawBuffers()
|
||||||
LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target);
|
LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_read_buffer)
|
||||||
|
{
|
||||||
|
u32 format = GL_BGRA;
|
||||||
|
CellGcmDisplayInfo* buffers = vm::get_ptr<CellGcmDisplayInfo>(m_gcm_buffers_addr);
|
||||||
|
u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||||
|
|
||||||
|
if (Memory.IsGoodAddr(addr))
|
||||||
|
{
|
||||||
|
u32 width = buffers[m_gcm_current_buffer].width;
|
||||||
|
u32 height = buffers[m_gcm_current_buffer].height;
|
||||||
|
|
||||||
|
glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, vm::get_ptr(addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::ExecCMD(u32 cmd)
|
void GLGSRender::ExecCMD(u32 cmd)
|
||||||
|
@ -1721,24 +1736,6 @@ void GLGSRender::ExecCMD()
|
||||||
checkForGlError("glColorMask");
|
checkForGlError("glColorMask");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_indexed_array.m_count && !m_draw_array_count)
|
|
||||||
{
|
|
||||||
u32 min_vertex_size = ~0;
|
|
||||||
for(auto &i : m_vertex_data)
|
|
||||||
{
|
|
||||||
if (!i.size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u32 vertex_size = i.data.size() / (i.size * i.GetTypeSize());
|
|
||||||
|
|
||||||
if (min_vertex_size > vertex_size)
|
|
||||||
min_vertex_size = vertex_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_draw_array_count = min_vertex_size;
|
|
||||||
m_draw_array_first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Enable(m_set_depth_test, GL_DEPTH_TEST);
|
Enable(m_set_depth_test, GL_DEPTH_TEST);
|
||||||
Enable(m_set_alpha_test, GL_ALPHA_TEST);
|
Enable(m_set_alpha_test, GL_ALPHA_TEST);
|
||||||
Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT);
|
Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT);
|
||||||
|
@ -1995,6 +1992,20 @@ void GLGSRender::ExecCMD()
|
||||||
checkForGlError(fmt::Format("m_gl_textures[%d].Init", i));
|
checkForGlError(fmt::Format("m_gl_textures[%d].Init", i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < m_textures_count; ++i)
|
||||||
|
{
|
||||||
|
if (!m_vertex_textures[i].IsEnabled()) continue;
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + m_textures_count + i);
|
||||||
|
checkForGlError("glActiveTexture");
|
||||||
|
m_gl_vertex_textures[i].Create();
|
||||||
|
m_gl_vertex_textures[i].Bind();
|
||||||
|
checkForGlError(fmt::Format("m_gl_vertex_textures[%d].Bind", i));
|
||||||
|
m_program.SetTex(i);
|
||||||
|
m_gl_vertex_textures[i].Init(m_vertex_textures[i]);
|
||||||
|
checkForGlError(fmt::Format("m_gl_vertex_textures[%d].Init", i));
|
||||||
|
}
|
||||||
|
|
||||||
m_vao.Bind();
|
m_vao.Bind();
|
||||||
if(m_indexed_array.m_count)
|
if(m_indexed_array.m_count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,6 +148,7 @@ private:
|
||||||
GLVertexProgram m_vertex_prog;
|
GLVertexProgram m_vertex_prog;
|
||||||
|
|
||||||
GLTexture m_gl_textures[m_textures_count];
|
GLTexture m_gl_textures[m_textures_count];
|
||||||
|
GLTexture m_gl_vertex_textures[m_textures_count];
|
||||||
|
|
||||||
GLvao m_vao;
|
GLvao m_vao;
|
||||||
GLvbo m_vbo;
|
GLvbo m_vbo;
|
||||||
|
|
|
@ -98,6 +98,13 @@ void GLProgram::SetTex(u32 index)
|
||||||
checkForGlError(fmt::Format("SetTex(%u - %d - %d)", id, index, loc));
|
checkForGlError(fmt::Format("SetTex(%u - %d - %d)", id, index, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLProgram::SetVTex(u32 index)
|
||||||
|
{
|
||||||
|
int loc = GetLocation(fmt::Format("vtex%u", index));
|
||||||
|
glProgramUniform1i(id, loc, index);
|
||||||
|
checkForGlError(fmt::Format("SetVTex(%u - %d - %d)", id, index, loc));
|
||||||
|
}
|
||||||
|
|
||||||
void GLProgram::Delete()
|
void GLProgram::Delete()
|
||||||
{
|
{
|
||||||
if(!IsCreated()) return;
|
if(!IsCreated()) return;
|
||||||
|
|
|
@ -24,5 +24,6 @@ public:
|
||||||
void Use();
|
void Use();
|
||||||
void UnUse();
|
void UnUse();
|
||||||
void SetTex(u32 index);
|
void SetTex(u32 index);
|
||||||
|
void SetVTex(u32 index);
|
||||||
void Delete();
|
void Delete();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "OpenGL.h"
|
#include "OpenGL.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
enum GLParamFlag
|
enum GLParamFlag
|
||||||
{
|
{
|
||||||
|
@ -139,3 +140,90 @@ struct GLParamArray
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ShaderVar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> swizzles;
|
||||||
|
|
||||||
|
ShaderVar() = default;
|
||||||
|
ShaderVar(const std::string& var)
|
||||||
|
{
|
||||||
|
auto var_blocks = fmt::split(var, { "." });
|
||||||
|
|
||||||
|
if (var_blocks.size() == 0)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = var_blocks[0];
|
||||||
|
|
||||||
|
if (var_blocks.size() == 1)
|
||||||
|
{
|
||||||
|
swizzles.push_back("xyzw");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
swizzles = std::vector<std::string>(var_blocks.begin() + 1, var_blocks.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_vector_size() const
|
||||||
|
{
|
||||||
|
return swizzles[swizzles.size() - 1].length();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderVar& symplify()
|
||||||
|
{
|
||||||
|
std::unordered_map<char, char> swizzle;
|
||||||
|
|
||||||
|
static std::unordered_map<int, char> pos_to_swizzle =
|
||||||
|
{
|
||||||
|
{ 0, 'x' },
|
||||||
|
{ 1, 'y' },
|
||||||
|
{ 2, 'z' },
|
||||||
|
{ 3, 'w' }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &i : pos_to_swizzle)
|
||||||
|
{
|
||||||
|
swizzle[i.second] = swizzles[0].length() > i.first ? swizzles[0][i.first] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < swizzles.size(); ++i)
|
||||||
|
{
|
||||||
|
std::unordered_map<char, char> new_swizzle;
|
||||||
|
|
||||||
|
for (auto &sw : pos_to_swizzle)
|
||||||
|
{
|
||||||
|
new_swizzle[sw.second] = swizzle[swizzles[i].length() <= sw.first ? '\0' : swizzles[i][sw.first]];
|
||||||
|
}
|
||||||
|
|
||||||
|
swizzle = new_swizzle;
|
||||||
|
}
|
||||||
|
|
||||||
|
swizzles.clear();
|
||||||
|
std::string new_swizzle;
|
||||||
|
|
||||||
|
for (auto &i : pos_to_swizzle)
|
||||||
|
{
|
||||||
|
if (swizzle[i.second] != '\0')
|
||||||
|
new_swizzle += swizzle[i.second];
|
||||||
|
}
|
||||||
|
|
||||||
|
swizzles.push_back(new_swizzle);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get() const
|
||||||
|
{
|
||||||
|
if (swizzles.size() == 1 && swizzles[0] == "xyzw")
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name + "." + fmt::merge({ swizzles }, ".");
|
||||||
|
}
|
||||||
|
};
|
|
@ -140,7 +140,7 @@ void GLVertexDecompilerThread::SetDST(bool is_sca, std::string value)
|
||||||
|
|
||||||
if (is_sca && d0.vec_result)
|
if (is_sca && d0.vec_result)
|
||||||
{
|
{
|
||||||
value = "vec4(" + value + ")" + mask;
|
//value = "vec4(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d0.staturate)
|
if (d0.staturate)
|
||||||
|
@ -152,22 +152,20 @@ void GLVertexDecompilerThread::SetDST(bool is_sca, std::string value)
|
||||||
|
|
||||||
if (d0.cond_update_enable_0 && d0.cond_update_enable_1)
|
if (d0.cond_update_enable_0 && d0.cond_update_enable_1)
|
||||||
{
|
{
|
||||||
dest += m_parr.AddParam(PARAM_NONE, "vec4", "cc" + std::to_string(d0.cond_reg_sel_1), "vec4(0.0)") + mask + " = ";
|
dest = m_parr.AddParam(PARAM_NONE, "vec4", "cc" + std::to_string(d0.cond_reg_sel_1), "vec4(0.0)") + mask;
|
||||||
}
|
}
|
||||||
|
else if (d3.dst != 0x1f || (is_sca ? d3.sca_dst_tmp != 0x3f : d0.dst_tmp != 0x3f))
|
||||||
if (d3.dst != 0x1f || (is_sca ? d3.sca_dst_tmp != 0x3f : d0.dst_tmp != 0x3f))
|
|
||||||
{
|
{
|
||||||
dest += GetDST(is_sca) + mask + " = ";
|
dest = GetDST(is_sca) + mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string code;
|
//std::string code;
|
||||||
|
//if (d0.cond_test_enable)
|
||||||
|
// code += "$ifcond ";
|
||||||
|
//code += dest + value;
|
||||||
|
//AddCode(code + ";");
|
||||||
|
|
||||||
if (d0.cond_test_enable)
|
AddCodeCond(Format(dest), value);
|
||||||
code += "$ifcond ";
|
|
||||||
|
|
||||||
code += dest + value;
|
|
||||||
|
|
||||||
AddCode(code + ";");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLVertexDecompilerThread::GetFunc()
|
std::string GLVertexDecompilerThread::GetFunc()
|
||||||
|
@ -188,6 +186,11 @@ std::string GLVertexDecompilerThread::GetFunc()
|
||||||
return name + "()";
|
return name + "()";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GLVertexDecompilerThread::GetTex()
|
||||||
|
{
|
||||||
|
return m_parr.AddParam(PARAM_UNIFORM, "sampler2D", std::string("vtex") + std::to_string(/*?.tex_num*/0));
|
||||||
|
}
|
||||||
|
|
||||||
std::string GLVertexDecompilerThread::Format(const std::string& code)
|
std::string GLVertexDecompilerThread::Format(const std::string& code)
|
||||||
{
|
{
|
||||||
const std::pair<std::string, std::function<std::string()>> repl_list[] =
|
const std::pair<std::string, std::function<std::string()>> repl_list[] =
|
||||||
|
@ -200,6 +203,8 @@ std::string GLVertexDecompilerThread::Format(const std::string& code)
|
||||||
{ "$am", std::bind(std::mem_fn(&GLVertexDecompilerThread::AddAddrMask), this) },
|
{ "$am", std::bind(std::mem_fn(&GLVertexDecompilerThread::AddAddrMask), this) },
|
||||||
{ "$a", std::bind(std::mem_fn(&GLVertexDecompilerThread::AddAddrReg), this) },
|
{ "$a", std::bind(std::mem_fn(&GLVertexDecompilerThread::AddAddrReg), this) },
|
||||||
|
|
||||||
|
{ "$t", std::bind(std::mem_fn(&GLVertexDecompilerThread::GetTex), this) },
|
||||||
|
|
||||||
{ "$fa", [this]()->std::string { return std::to_string(GetAddr()); } },
|
{ "$fa", [this]()->std::string { return std::to_string(GetAddr()); } },
|
||||||
{ "$f()", std::bind(std::mem_fn(&GLVertexDecompilerThread::GetFunc), this) },
|
{ "$f()", std::bind(std::mem_fn(&GLVertexDecompilerThread::GetFunc), this) },
|
||||||
{ "$ifcond ", [this]() -> std::string
|
{ "$ifcond ", [this]() -> std::string
|
||||||
|
@ -252,6 +257,70 @@ std::string GLVertexDecompilerThread::GetCond()
|
||||||
return fmt::Format("any(%s(cc%d%s, vec4(0.0)%s))", cond_string_table[d0.cond], d0.cond_reg_sel_1, swizzle.c_str(), swizzle.c_str());
|
return fmt::Format("any(%s(cc%d%s, vec4(0.0)%s))", cond_string_table[d0.cond], d0.cond_reg_sel_1, swizzle.c_str(), swizzle.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLVertexDecompilerThread::AddCodeCond(const std::string& dst, const std::string& src)
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
lt = 0x1,
|
||||||
|
eq = 0x2,
|
||||||
|
gt = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (!d0.cond_test_enable || d0.cond == (lt | gt | eq))
|
||||||
|
{
|
||||||
|
AddCode(dst + " = " + src + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d0.cond == 0)
|
||||||
|
{
|
||||||
|
AddCode("//" + dst + " = " + src + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* cond_string_table[(lt | gt | eq) + 1] =
|
||||||
|
{
|
||||||
|
"error",
|
||||||
|
"lessThan",
|
||||||
|
"equal",
|
||||||
|
"lessThanEqual",
|
||||||
|
"greaterThan",
|
||||||
|
"notEqual",
|
||||||
|
"greaterThanEqual",
|
||||||
|
"error"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||||
|
|
||||||
|
std::string swizzle;
|
||||||
|
swizzle += f[d0.mask_x];
|
||||||
|
swizzle += f[d0.mask_y];
|
||||||
|
swizzle += f[d0.mask_z];
|
||||||
|
swizzle += f[d0.mask_w];
|
||||||
|
|
||||||
|
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||||
|
|
||||||
|
std::string cond = fmt::Format("%s(cc%d%s, vec4(0.0))", cond_string_table[d0.cond], d0.cond_reg_sel_1, swizzle.c_str());
|
||||||
|
|
||||||
|
ShaderVar dst_var(dst);
|
||||||
|
dst_var.symplify();
|
||||||
|
|
||||||
|
//const char *c_mask = f;
|
||||||
|
|
||||||
|
if (dst_var.swizzles[0].length() == 1)
|
||||||
|
{
|
||||||
|
AddCode("if (" + cond + ".x) " + dst + " = vec4(" + src + ").x;");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dst_var.swizzles[0].length(); ++i)
|
||||||
|
{
|
||||||
|
AddCode("if (" + cond + "." + f[i] + ") " + dst + "." + f[i] + " = " + src + "." + f[i] + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string GLVertexDecompilerThread::AddAddrMask()
|
std::string GLVertexDecompilerThread::AddAddrMask()
|
||||||
{
|
{
|
||||||
|
@ -554,7 +623,7 @@ void GLVertexDecompilerThread::Task()
|
||||||
case RSX_SCA_OPCODE_RSQ: SetDSTSca("inversesqrt(abs($s))"); break;
|
case RSX_SCA_OPCODE_RSQ: SetDSTSca("inversesqrt(abs($s))"); break;
|
||||||
case RSX_SCA_OPCODE_EXP: SetDSTSca("exp($s)"); break;
|
case RSX_SCA_OPCODE_EXP: SetDSTSca("exp($s)"); break;
|
||||||
case RSX_SCA_OPCODE_LOG: SetDSTSca("log($s)"); break;
|
case RSX_SCA_OPCODE_LOG: SetDSTSca("log($s)"); break;
|
||||||
case RSX_SCA_OPCODE_LIT: SetDSTSca("vec4(1.0, $s.x, ($s.x > 0 ? exp2($s.w * log2($s.y)) : 0.0), 1.0)"); break;
|
case RSX_SCA_OPCODE_LIT: SetDSTSca("vec4(1.0, $s.x, ($s.x > 0.0 ? exp($s.w * log2($s.y)) : 0.0), 1.0)"); break;
|
||||||
case RSX_SCA_OPCODE_BRA:
|
case RSX_SCA_OPCODE_BRA:
|
||||||
{
|
{
|
||||||
AddCode("$if ($cond)");
|
AddCode("$if ($cond)");
|
||||||
|
@ -662,6 +731,7 @@ void GLVertexDecompilerThread::Task()
|
||||||
case RSX_VEC_OPCODE_SNE: SetDSTVec("vec4(notEqual($0, $1))"); break;
|
case RSX_VEC_OPCODE_SNE: SetDSTVec("vec4(notEqual($0, $1))"); break;
|
||||||
case RSX_VEC_OPCODE_STR: SetDSTVec("vec4(equal($0, vec4(1.0)))"); break;
|
case RSX_VEC_OPCODE_STR: SetDSTVec("vec4(equal($0, vec4(1.0)))"); break;
|
||||||
case RSX_VEC_OPCODE_SSG: SetDSTVec("sign($0)"); break;
|
case RSX_VEC_OPCODE_SSG: SetDSTVec("sign($0)"); break;
|
||||||
|
case RSX_VEC_OPCODE_TEX: SetDSTVec("texture($t, $0.xy)"); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
AddCode(fmt::Format("//Unknown vp opcode 0x%x", fmt::by_value(d1.vec_opcode)));
|
AddCode(fmt::Format("//Unknown vp opcode 0x%x", fmt::by_value(d1.vec_opcode)));
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum vec_opcode
|
||||||
RSX_VEC_OPCODE_SNE = 0x14,
|
RSX_VEC_OPCODE_SNE = 0x14,
|
||||||
RSX_VEC_OPCODE_STR = 0x15,
|
RSX_VEC_OPCODE_STR = 0x15,
|
||||||
RSX_VEC_OPCODE_SSG = 0x16,
|
RSX_VEC_OPCODE_SSG = 0x16,
|
||||||
|
RSX_VEC_OPCODE_TEX = 0x19,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLVertexDecompilerThread : public ThreadBase
|
struct GLVertexDecompilerThread : public ThreadBase
|
||||||
|
@ -237,12 +238,14 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||||
std::string GetDST(bool is_sca = false);
|
std::string GetDST(bool is_sca = false);
|
||||||
std::string GetSRC(const u32 n);
|
std::string GetSRC(const u32 n);
|
||||||
std::string GetFunc();
|
std::string GetFunc();
|
||||||
|
std::string GetTex();
|
||||||
std::string GetCond();
|
std::string GetCond();
|
||||||
std::string AddAddrMask();
|
std::string AddAddrMask();
|
||||||
std::string AddAddrReg();
|
std::string AddAddrReg();
|
||||||
u32 GetAddr();
|
u32 GetAddr();
|
||||||
std::string Format(const std::string& code);
|
std::string Format(const std::string& code);
|
||||||
|
|
||||||
|
void AddCodeCond(const std::string& dst, const std::string& src);
|
||||||
void AddCode(const std::string& code);
|
void AddCode(const std::string& code);
|
||||||
void SetDST(bool is_sca, std::string value);
|
void SetDST(bool is_sca, std::string value);
|
||||||
void SetDSTVec(const std::string& code);
|
void SetDSTVec(const std::string& code);
|
||||||
|
|
|
@ -210,3 +210,206 @@ void RSXTexture::SetControl3(u16 depth, u32 pitch)
|
||||||
m_depth = depth;
|
m_depth = depth;
|
||||||
m_pitch = pitch;
|
m_pitch = pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RSXVertexTexture::RSXVertexTexture() : RSXTexture()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RSXVertexTexture::RSXVertexTexture(u8 index) : RSXTexture(index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSXVertexTexture::Init()
|
||||||
|
{
|
||||||
|
// Offset
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 32)] = 0;
|
||||||
|
|
||||||
|
// Format
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] = 0;
|
||||||
|
|
||||||
|
// Address
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] =
|
||||||
|
((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) |
|
||||||
|
((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28));
|
||||||
|
|
||||||
|
// Control0
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] =
|
||||||
|
(((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31);
|
||||||
|
|
||||||
|
// Control1
|
||||||
|
//methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 32)] = 0xE4;
|
||||||
|
|
||||||
|
// Filter
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] =
|
||||||
|
((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24)
|
||||||
|
| ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31));
|
||||||
|
|
||||||
|
// Image Rect
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 32)] = (/*height*/1) | ((/*width*/1) << 16);
|
||||||
|
|
||||||
|
// Border Color
|
||||||
|
methodRegisters[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 32)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 RSXVertexTexture::GetOffset() const
|
||||||
|
{
|
||||||
|
return methodRegisters[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 32)];
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetLocation() const
|
||||||
|
{
|
||||||
|
return (methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] & 0x3) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::isCubemap() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 2) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetBorderType() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 3) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetDimension() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 4) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetFormat() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 RSXVertexTexture::GetMipmap() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 32)] >> 16) & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetWrapS() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)]) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetWrapT() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 8) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetWrapR() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 16) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetUnsignedRemap() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 12) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetZfunc() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 28) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetGamma() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 20) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetAnisoBias() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 4) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetSignedRemap() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 32)] >> 24) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::IsEnabled() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 31) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 RSXVertexTexture::GetMinLOD() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 19) & 0xfff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 RSXVertexTexture::GetMaxLOD() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 7) & 0xfff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetMaxAniso() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 4) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::IsAlphaKillEnabled() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 32)] >> 2) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 RSXVertexTexture::GetRemap() const
|
||||||
|
{
|
||||||
|
return 0 | (1 << 2) | (2 << 4) | (3 << 6);//(methodRegisters[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 32)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 RSXVertexTexture::GetBias() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)]) & 0x1fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetMinFilter() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 16) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetMagFilter() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 24) & 0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 RSXVertexTexture::GetConvolutionFilter() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 13) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::isASigned() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 28) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::isRSigned() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 29) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::isGSigned() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 30) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSXVertexTexture::isBSigned() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 32)] >> 31) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 RSXVertexTexture::GetWidth() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 32)] >> 16) & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 RSXVertexTexture::GetHeight() const
|
||||||
|
{
|
||||||
|
return ((methodRegisters[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 32)]) & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 RSXVertexTexture::GetBorderColor() const
|
||||||
|
{
|
||||||
|
return methodRegisters[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 32)];
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
class RSXTexture
|
class RSXTexture
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
u8 m_index;
|
u8 m_index;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -11,6 +12,64 @@ public:
|
||||||
public:
|
public:
|
||||||
RSXTexture();
|
RSXTexture();
|
||||||
RSXTexture(u8 index);
|
RSXTexture(u8 index);
|
||||||
|
virtual void Init();
|
||||||
|
|
||||||
|
// Offset
|
||||||
|
virtual u32 GetOffset() const;
|
||||||
|
|
||||||
|
// Format
|
||||||
|
virtual u8 GetLocation() const;
|
||||||
|
virtual bool isCubemap() const;
|
||||||
|
virtual u8 GetBorderType() const;
|
||||||
|
virtual u8 GetDimension() const;
|
||||||
|
virtual u8 GetFormat() const;
|
||||||
|
virtual u16 GetMipmap() const;
|
||||||
|
|
||||||
|
// Address
|
||||||
|
virtual u8 GetWrapS() const;
|
||||||
|
virtual u8 GetWrapT() const;
|
||||||
|
virtual u8 GetWrapR() const;
|
||||||
|
virtual u8 GetUnsignedRemap() const;
|
||||||
|
virtual u8 GetZfunc() const;
|
||||||
|
virtual u8 GetGamma() const;
|
||||||
|
virtual u8 GetAnisoBias() const;
|
||||||
|
virtual u8 GetSignedRemap() const;
|
||||||
|
|
||||||
|
// Control0
|
||||||
|
virtual bool IsEnabled() const;
|
||||||
|
virtual u16 GetMinLOD() const;
|
||||||
|
virtual u16 GetMaxLOD() const;
|
||||||
|
virtual u8 GetMaxAniso() const;
|
||||||
|
virtual bool IsAlphaKillEnabled() const;
|
||||||
|
|
||||||
|
// Control1
|
||||||
|
virtual u32 GetRemap() const;
|
||||||
|
|
||||||
|
// Filter
|
||||||
|
virtual u16 GetBias() const;
|
||||||
|
virtual u8 GetMinFilter() const;
|
||||||
|
virtual u8 GetMagFilter() const;
|
||||||
|
virtual u8 GetConvolutionFilter() const;
|
||||||
|
virtual bool isASigned() const;
|
||||||
|
virtual bool isRSigned() const;
|
||||||
|
virtual bool isGSigned() const;
|
||||||
|
virtual bool isBSigned() const;
|
||||||
|
|
||||||
|
// Image Rect
|
||||||
|
virtual u16 GetWidth() const;
|
||||||
|
virtual u16 GetHeight() const;
|
||||||
|
|
||||||
|
// Border Color
|
||||||
|
virtual u32 GetBorderColor() const;
|
||||||
|
|
||||||
|
void SetControl3(u16 depth, u32 pitch);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RSXVertexTexture : public RSXTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RSXVertexTexture();
|
||||||
|
RSXVertexTexture(u8 index);
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// Offset
|
// Offset
|
||||||
|
@ -60,6 +119,4 @@ public:
|
||||||
|
|
||||||
// Border Color
|
// Border Color
|
||||||
u32 GetBorderColor() const;
|
u32 GetBorderColor() const;
|
||||||
|
|
||||||
void SetControl3(u16 depth, u32 pitch);
|
|
||||||
};
|
};
|
|
@ -14,33 +14,41 @@
|
||||||
|
|
||||||
u32 methodRegisters[0xffff];
|
u32 methodRegisters[0xffff];
|
||||||
|
|
||||||
void RSXThread::nativeRescale(float width, float height)
|
void RSXThread::NativeRescale(float width, float height)
|
||||||
{
|
{
|
||||||
switch (Ini.GSResolution.GetValue())
|
switch (Ini.GSResolution.GetValue())
|
||||||
{
|
{
|
||||||
case 1: // 1920x1080 window size
|
case 1: // 1920x1080 window size
|
||||||
|
{
|
||||||
m_width_scale = 1920 / width * 2.0f;
|
m_width_scale = 1920 / width * 2.0f;
|
||||||
m_height_scale = 1080 / height * 2.0f;
|
m_height_scale = 1080 / height * 2.0f;
|
||||||
m_width = 1920;
|
m_width = 1920;
|
||||||
m_height = 1080;
|
m_height = 1080;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // 1280x720 window size
|
case 2: // 1280x720 window size
|
||||||
|
{
|
||||||
m_width_scale = 1280 / width * 2.0f;
|
m_width_scale = 1280 / width * 2.0f;
|
||||||
m_height_scale = 720 / height * 2.0f;
|
m_height_scale = 720 / height * 2.0f;
|
||||||
m_width = 1280;
|
m_width = 1280;
|
||||||
m_height = 720;
|
m_height = 720;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // 720x480 window size
|
case 4: // 720x480 window size
|
||||||
|
{
|
||||||
m_width_scale = 720 / width * 2.0f;
|
m_width_scale = 720 / width * 2.0f;
|
||||||
m_height_scale = 480 / height * 2.0f;
|
m_height_scale = 480 / height * 2.0f;
|
||||||
m_width = 720;
|
m_width = 720;
|
||||||
m_height = 480;
|
m_height = 480;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // 720x576 window size
|
case 5: // 720x576 window size
|
||||||
|
{
|
||||||
m_width_scale = 720 / width * 2.0f;
|
m_width_scale = 720 / width * 2.0f;
|
||||||
m_height_scale = 576 / height * 2.0f;
|
m_height_scale = 576 / height * 2.0f;
|
||||||
m_width = 720;
|
m_width = 720;
|
||||||
m_height = 576;
|
m_height = 576;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,11 +103,11 @@ RSXVertexData::RSXVertexData()
|
||||||
|
|
||||||
void RSXVertexData::Reset()
|
void RSXVertexData::Reset()
|
||||||
{
|
{
|
||||||
//frequency = 0;
|
frequency = 0;
|
||||||
//stride = 0;
|
stride = 0;
|
||||||
//size = 0;
|
size = 0;
|
||||||
//type = 0;
|
type = 0;
|
||||||
//addr = 0;
|
addr = 0;
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,60 +189,21 @@ u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, cons
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define case_2(offset, step) \
|
||||||
#define case_16(a, m) \
|
case offset: \
|
||||||
case a + m: \
|
case offset + step:
|
||||||
case a + m * 2: \
|
#define case_4(offset, step) \
|
||||||
case a + m * 3: \
|
case_2(offset, step) \
|
||||||
case a + m * 4: \
|
case_2(offset + 2*step, step)
|
||||||
case a + m * 5: \
|
#define case_8(offset, step) \
|
||||||
case a + m * 6: \
|
case_4(offset, step) \
|
||||||
case a + m * 7: \
|
case_4(offset + 4*step, step)
|
||||||
case a + m * 8: \
|
#define case_16(offset, step) \
|
||||||
case a + m * 9: \
|
case_8(offset, step) \
|
||||||
case a + m * 10: \
|
case_8(offset + 8*step, step)
|
||||||
case a + m * 11: \
|
#define case_32(offset, step) \
|
||||||
case a + m * 12: \
|
case_16(offset, step) \
|
||||||
case a + m * 13: \
|
case_16(offset + 16*step, step)
|
||||||
case a + m * 14: \
|
|
||||||
case a + m * 15: \
|
|
||||||
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, const u32 args_addr, const u32 count)
|
void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count)
|
||||||
{
|
{
|
||||||
|
@ -252,8 +221,6 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
|
|
||||||
m_used_gcm_commands.insert(cmd);
|
m_used_gcm_commands.insert(cmd);
|
||||||
|
|
||||||
//static u32 draw_array_count = 0;
|
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
// NV406E
|
// NV406E
|
||||||
|
@ -331,6 +298,28 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto sync = [&]()
|
||||||
|
{
|
||||||
|
double limit;
|
||||||
|
switch (Ini.GSFrameLimit.GetValue())
|
||||||
|
{
|
||||||
|
case 1: limit = 50.; break;
|
||||||
|
case 2: limit = 59.94; break;
|
||||||
|
case 3: limit = 30.; break;
|
||||||
|
case 4: limit = 60.; break;
|
||||||
|
case 5: limit = m_fps_limit; break; //TODO
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - m_timer_sync.GetElapsedTimeInMilliSec())));
|
||||||
|
m_timer_sync.Start();
|
||||||
|
};
|
||||||
|
|
||||||
|
sync();
|
||||||
|
|
||||||
//Emu.Pause();
|
//Emu.Pause();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -363,26 +352,26 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
case_16(NV4097_SET_TEXTURE_FORMAT, 0x20):
|
case_16(NV4097_SET_TEXTURE_FORMAT, 0x20)
|
||||||
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20):
|
case_16(NV4097_SET_TEXTURE_OFFSET, 0x20)
|
||||||
case_16(NV4097_SET_TEXTURE_FILTER, 0x20):
|
case_16(NV4097_SET_TEXTURE_FILTER, 0x20)
|
||||||
case_16(NV4097_SET_TEXTURE_ADDRESS, 0x20):
|
case_16(NV4097_SET_TEXTURE_ADDRESS, 0x20)
|
||||||
case_16(NV4097_SET_TEXTURE_IMAGE_RECT, 32):
|
case_16(NV4097_SET_TEXTURE_IMAGE_RECT, 32)
|
||||||
case_16(NV4097_SET_TEXTURE_BORDER_COLOR, 0x20):
|
case_16(NV4097_SET_TEXTURE_BORDER_COLOR, 0x20)
|
||||||
case_16(NV4097_SET_TEXTURE_CONTROL0, 0x20):
|
case_16(NV4097_SET_TEXTURE_CONTROL0, 0x20)
|
||||||
case_16(NV4097_SET_TEXTURE_CONTROL1, 0x20):
|
case_16(NV4097_SET_TEXTURE_CONTROL1, 0x20)
|
||||||
{
|
{
|
||||||
// Done using methodRegisters in RSXTexture.cpp
|
// Done using methodRegisters in RSXTexture.cpp
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_TEX_COORD_CONTROL, 4):
|
case_16(NV4097_SET_TEX_COORD_CONTROL, 4)
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_TEX_COORD_CONTROL");
|
LOG_WARNING(RSX, "NV4097_SET_TEX_COORD_CONTROL");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_TEXTURE_CONTROL3, 4):
|
case_16(NV4097_SET_TEXTURE_CONTROL3, 4)
|
||||||
{
|
{
|
||||||
RSXTexture& tex = m_textures[index];
|
RSXTexture& tex = m_textures[index];
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
|
@ -392,8 +381,31 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Vertex Texture
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_FORMAT, 0x20)
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_OFFSET, 0x20)
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_FILTER, 0x20)
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_ADDRESS, 0x20)
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, 0x20)
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, 0x20)
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_CONTROL0, 0x20)
|
||||||
|
{
|
||||||
|
// Done using methodRegisters in RSXTexture.cpp
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case_4(NV4097_SET_VERTEX_TEXTURE_CONTROL3, 0x20)
|
||||||
|
{
|
||||||
|
RSXVertexTexture& tex = m_vertex_textures[index];
|
||||||
|
const u32 a0 = ARGS(0);
|
||||||
|
u32 pitch = a0 & 0xFFFFF;
|
||||||
|
u16 depth = a0 >> 20;
|
||||||
|
tex.SetControl3(depth, pitch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// Vertex data
|
// Vertex data
|
||||||
case_16(NV4097_SET_VERTEX_DATA4UB_M, 4):
|
case_16(NV4097_SET_VERTEX_DATA4UB_M, 4)
|
||||||
{
|
{
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
u8 v0 = a0;
|
u8 v0 = a0;
|
||||||
|
@ -401,7 +413,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
u8 v2 = a0 >> 16;
|
u8 v2 = a0 >> 16;
|
||||||
u8 v3 = a0 >> 24;
|
u8 v3 = a0 >> 24;
|
||||||
|
|
||||||
//m_vertex_data[index].Reset();
|
m_vertex_data[index].Reset();
|
||||||
m_vertex_data[index].size = 4;
|
m_vertex_data[index].size = 4;
|
||||||
m_vertex_data[index].type = CELL_GCM_VERTEX_UB;
|
m_vertex_data[index].type = CELL_GCM_VERTEX_UB;
|
||||||
m_vertex_data[index].data.push_back(v0);
|
m_vertex_data[index].data.push_back(v0);
|
||||||
|
@ -412,7 +424,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_VERTEX_DATA2F_M, 8):
|
case_16(NV4097_SET_VERTEX_DATA2F_M, 8)
|
||||||
{
|
{
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
const u32 a1 = ARGS(1);
|
const u32 a1 = ARGS(1);
|
||||||
|
@ -420,7 +432,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
float v0 = (float&)a0;
|
float v0 = (float&)a0;
|
||||||
float v1 = (float&)a1;
|
float v1 = (float&)a1;
|
||||||
|
|
||||||
//m_vertex_data[index].Reset();
|
m_vertex_data[index].Reset();
|
||||||
m_vertex_data[index].type = CELL_GCM_VERTEX_F;
|
m_vertex_data[index].type = CELL_GCM_VERTEX_F;
|
||||||
m_vertex_data[index].size = 2;
|
m_vertex_data[index].size = 2;
|
||||||
u32 pos = m_vertex_data[index].data.size();
|
u32 pos = m_vertex_data[index].data.size();
|
||||||
|
@ -432,7 +444,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_VERTEX_DATA4F_M, 16):
|
case_16(NV4097_SET_VERTEX_DATA4F_M, 16)
|
||||||
{
|
{
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
const u32 a1 = ARGS(1);
|
const u32 a1 = ARGS(1);
|
||||||
|
@ -444,7 +456,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
float v2 = (float&)a2;
|
float v2 = (float&)a2;
|
||||||
float v3 = (float&)a3;
|
float v3 = (float&)a3;
|
||||||
|
|
||||||
//m_vertex_data[index].Reset();
|
m_vertex_data[index].Reset();
|
||||||
m_vertex_data[index].type = CELL_GCM_VERTEX_F;
|
m_vertex_data[index].type = CELL_GCM_VERTEX_F;
|
||||||
m_vertex_data[index].size = 4;
|
m_vertex_data[index].size = 4;
|
||||||
u32 pos = m_vertex_data[index].data.size();
|
u32 pos = m_vertex_data[index].data.size();
|
||||||
|
@ -458,7 +470,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4):
|
case_16(NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4)
|
||||||
{
|
{
|
||||||
const u32 addr = GetAddress(ARGS(0) & 0x7fffffff, ARGS(0) >> 31);
|
const u32 addr = GetAddress(ARGS(0) & 0x7fffffff, ARGS(0) >> 31);
|
||||||
CMD_LOG("num=%d, addr=0x%x", index, addr);
|
CMD_LOG("num=%d, addr=0x%x", index, addr);
|
||||||
|
@ -469,7 +481,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_16(NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4):
|
case_16(NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4)
|
||||||
{
|
{
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
u16 frequency = a0 >> 16;
|
u16 frequency = a0 >> 16;
|
||||||
|
@ -493,7 +505,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK:
|
case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: 0x%x", ARGS(0));
|
||||||
|
}
|
||||||
|
|
||||||
//VertexData[0].prog.attributeInputMask = ARGS(0);
|
//VertexData[0].prog.attributeInputMask = ARGS(0);
|
||||||
}
|
}
|
||||||
|
@ -502,7 +516,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK:
|
case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: 0x%x", ARGS(0));
|
||||||
|
}
|
||||||
|
|
||||||
//VertexData[0].prog.attributeOutputMask = ARGS(0);
|
//VertexData[0].prog.attributeOutputMask = ARGS(0);
|
||||||
//FragmentData.prog.attributeInputMask = ARGS(0)/* & ~0x20*/;
|
//FragmentData.prog.attributeInputMask = ARGS(0)/* & ~0x20*/;
|
||||||
|
@ -525,8 +541,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_COLOR_MASK_MRT:
|
case NV4097_SET_COLOR_MASK_MRT:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_COLOR_MASK_MRT: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_COLOR_MASK_MRT: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Alpha testing
|
// Alpha testing
|
||||||
|
@ -629,8 +647,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_BLEND_COLOR2:
|
case NV4097_SET_BLEND_COLOR2:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_BLEND_COLOR2: 0x % x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_BLEND_COLOR2: 0x % x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_BLEND_EQUATION:
|
case NV4097_SET_BLEND_EQUATION:
|
||||||
|
@ -644,8 +664,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_REDUCE_DST_COLOR:
|
case NV4097_SET_REDUCE_DST_COLOR:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_REDUCE_DST_COLOR: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_REDUCE_DST_COLOR: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Depth bound testing
|
// Depth bound testing
|
||||||
|
@ -864,15 +886,19 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_CLEAR_RECT_HORIZONTAL:
|
case NV4097_SET_CLEAR_RECT_HORIZONTAL:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_CLEAR_RECT_HORIZONTAL: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_CLEAR_RECT_HORIZONTAL: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_CLEAR_RECT_VERTICAL:
|
case NV4097_SET_CLEAR_RECT_VERTICAL:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_CLEAR_RECT_VERTICAL: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_CLEAR_RECT_VERTICAL: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Arrays
|
// Arrays
|
||||||
|
@ -971,8 +997,27 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
const u32 a0 = ARGS(0);
|
const u32 a0 = ARGS(0);
|
||||||
|
|
||||||
//LOG_WARNING(RSX, "NV4097_SET_BEGIN_END: 0x%x", a0);
|
//LOG_WARNING(RSX, "NV4097_SET_BEGIN_END: 0x%x", a0);
|
||||||
|
if (!m_indexed_array.m_count && !m_draw_array_count)
|
||||||
|
{
|
||||||
|
u32 min_vertex_size = ~0;
|
||||||
|
for (auto &i : m_vertex_data)
|
||||||
|
{
|
||||||
|
if (!i.size)
|
||||||
|
continue;
|
||||||
|
|
||||||
m_read_buffer = false;
|
u32 vertex_size = i.data.size() / (i.size * i.GetTypeSize());
|
||||||
|
|
||||||
|
if (min_vertex_size > vertex_size)
|
||||||
|
{
|
||||||
|
min_vertex_size = vertex_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_draw_array_count = min_vertex_size;
|
||||||
|
m_draw_array_first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_read_buffer = Ini.GSReadColorBuffer.GetValue() || (!m_indexed_array.m_count && !m_draw_array_count);
|
||||||
|
|
||||||
if (a0)
|
if (a0)
|
||||||
{
|
{
|
||||||
|
@ -1029,10 +1074,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
|
|
||||||
if (count == 2)
|
if (count == 2)
|
||||||
{
|
{
|
||||||
const u32 start = ARGS(1);
|
if (ARGS(1))
|
||||||
if (start)
|
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start);
|
LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", ARGS(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1040,15 +1084,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
|
|
||||||
case NV4097_SET_TRANSFORM_PROGRAM_START:
|
case NV4097_SET_TRANSFORM_PROGRAM_START:
|
||||||
{
|
{
|
||||||
const u32 start = ARGS(0);
|
if (ARGS(0))
|
||||||
if (start)
|
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_START: start = %d", start);
|
LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_START: start = %d", ARGS(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_32(NV4097_SET_TRANSFORM_PROGRAM, 4):
|
case_32(NV4097_SET_TRANSFORM_PROGRAM, 4)
|
||||||
{
|
{
|
||||||
//LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count);
|
//LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count);
|
||||||
|
|
||||||
|
@ -1063,7 +1106,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_TRANSFORM_TIMEOUT:
|
case NV4097_SET_TRANSFORM_TIMEOUT:
|
||||||
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
// (cmd)[1] = CELL_GCM_ENDIAN_SWAP((count) | ((registerCount) << 16)); \
|
// (cmd)[1] = CELL_GCM_ENDIAN_SWAP((count) | ((registerCount) << 16)); \
|
||||||
|
|
||||||
|
@ -1074,6 +1117,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_cur_vertex_prog->Decompile();
|
//m_cur_vertex_prog->Decompile();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_TRANSFORM_CONSTANT_LOAD:
|
case NV4097_SET_TRANSFORM_CONSTANT_LOAD:
|
||||||
|
@ -1103,8 +1147,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_INVALIDATE_L2:
|
case NV4097_INVALIDATE_L2:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_INVALIDATE_L2: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_INVALIDATE_L2: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_INVALIDATE_VERTEX_CACHE_FILE:
|
case NV4097_INVALIDATE_VERTEX_CACHE_FILE:
|
||||||
|
@ -1122,8 +1168,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_INVALIDATE_ZCULL:
|
case NV4097_INVALIDATE_ZCULL:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_INVALIDATE_ZCULL: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_INVALIDATE_ZCULL: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Logic Ops
|
// Logic Ops
|
||||||
|
@ -1286,7 +1334,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_SCULL_CONTROL:
|
case NV4097_SET_SCULL_CONTROL:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_SCULL_CONTROL: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_SCULL_CONTROL: 0x%x", ARGS(0));
|
||||||
|
}
|
||||||
|
|
||||||
//This is stencil culling , nothing to do with stencil masking on regular color or depth buffer
|
//This is stencil culling , nothing to do with stencil masking on regular color or depth buffer
|
||||||
//const u32 a0 = ARGS(0);
|
//const u32 a0 = ARGS(0);
|
||||||
|
@ -1324,8 +1374,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_POINT_PARAMS_ENABLE:
|
case NV4097_SET_POINT_PARAMS_ENABLE:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_ERROR(RSX, "NV4097_SET_POINT_PARAMS_ENABLE: 0x%x", ARGS(0));
|
LOG_ERROR(RSX, "NV4097_SET_POINT_PARAMS_ENABLE: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_POINT_SPRITE_CONTROL:
|
case NV4097_SET_POINT_SPRITE_CONTROL:
|
||||||
|
@ -1394,7 +1446,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
m_height = buffers[m_gcm_current_buffer].height;
|
m_height = buffers[m_gcm_current_buffer].height;
|
||||||
|
|
||||||
// Rescale native resolution to fit 1080p/720p/480p/576p window size
|
// Rescale native resolution to fit 1080p/720p/480p/576p window size
|
||||||
nativeRescale((float)m_width, (float)m_height);
|
NativeRescale((float)m_width, (float)m_height);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1534,15 +1586,19 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_CONTEXT_DMA_SEMAPHORE:
|
case NV4097_SET_CONTEXT_DMA_SEMAPHORE:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_CONTEXT_DMA_NOTIFIES:
|
case NV4097_SET_CONTEXT_DMA_NOTIFIES:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_CONTEXT_DMA_NOTIFIES: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_CONTEXT_DMA_NOTIFIES: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_SET_SURFACE_CLIP_HORIZONTAL:
|
case NV4097_SET_SURFACE_CLIP_HORIZONTAL:
|
||||||
|
@ -1652,7 +1708,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_ZCULL_CONTROL0:
|
case NV4097_SET_ZCULL_CONTROL0:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_ZCULL_CONTROL0: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_ZCULL_CONTROL0: 0x%x", ARGS(0));
|
||||||
|
}
|
||||||
|
|
||||||
//m_set_depth_func = true;
|
//m_set_depth_func = true;
|
||||||
//m_depth_func = ARGS(0) >> 4;
|
//m_depth_func = ARGS(0) >> 4;
|
||||||
|
@ -1662,7 +1720,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_ZCULL_CONTROL1:
|
case NV4097_SET_ZCULL_CONTROL1:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_ZCULL_CONTROL1: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_ZCULL_CONTROL1: 0x%x", ARGS(0));
|
||||||
|
}
|
||||||
|
|
||||||
//m_set_depth_func = true;
|
//m_set_depth_func = true;
|
||||||
//m_depth_func = ARGS(0) >> 4;
|
//m_depth_func = ARGS(0) >> 4;
|
||||||
|
@ -1672,15 +1732,19 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV4097_SET_ZCULL_STATS_ENABLE:
|
case NV4097_SET_ZCULL_STATS_ENABLE:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_SET_ZCULL_STATS_ENABLE: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_SET_ZCULL_STATS_ENABLE: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV4097_ZCULL_SYNC:
|
case NV4097_ZCULL_SYNC:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV4097_ZCULL_SYNC: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV4097_ZCULL_SYNC: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Reports
|
// Reports
|
||||||
|
@ -1774,17 +1838,16 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
const u8 cullNearFarEnable = ARGS(0) & 0xf;
|
const u8 cullNearFarEnable = ARGS(0) & 0xf;
|
||||||
const u8 zclampEnable = (ARGS(0) >> 4) & 0xf;
|
const u8 zclampEnable = (ARGS(0) >> 4) & 0xf;
|
||||||
const u8 cullIgnoreW = (ARGS(0) >> 8) & 0xf;
|
const u8 cullIgnoreW = (ARGS(0) >> 8) & 0xf;
|
||||||
LOG_WARNING(RSX, "TODO: NV4097_SET_ZMIN_MAX_CONTROL: cullNearFarEnable=%d, zclampEnable=%d, cullIgnoreW=%d",
|
LOG_WARNING(RSX, "TODO: NV4097_SET_ZMIN_MAX_CONTROL: cullNearFarEnable=%d, zclampEnable=%d, cullIgnoreW=%d", cullNearFarEnable, zclampEnable, cullIgnoreW);
|
||||||
cullNearFarEnable, zclampEnable, cullIgnoreW);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Windows Clipping
|
// Windows Clipping (Doesn't seem to be relevant?)
|
||||||
case NV4097_SET_WINDOW_OFFSET:
|
case NV4097_SET_WINDOW_OFFSET:
|
||||||
{
|
{
|
||||||
const u16 x = ARGS(0);
|
const u16 x = ARGS(0);
|
||||||
const u16 y = ARGS(0) >> 16;
|
const u16 y = ARGS(0) >> 16;
|
||||||
LOG_WARNING(RSX, "TODO: NV4097_SET_WINDOW_OFFSET: x=%d, y=%d", x, y);
|
//LOG_WARNING(RSX, "TODO: NV4097_SET_WINDOW_OFFSET: x=%d, y=%d", x, y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1854,6 +1917,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
|
|
||||||
if (!offset)
|
if (!offset)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1865,15 +1929,19 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV0039_PITCH_IN:
|
case NV0039_PITCH_IN:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV0039_PITCH_IN: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV0039_PITCH_IN: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV0039_BUFFER_NOTIFY:
|
case NV0039_BUFFER_NOTIFY:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV0039_BUFFER_NOTIFY: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV0039_BUFFER_NOTIFY: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// NV3062
|
// NV3062
|
||||||
|
@ -1901,8 +1969,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
|
||||||
case NV309E_SET_CONTEXT_DMA_IMAGE:
|
case NV309E_SET_CONTEXT_DMA_IMAGE:
|
||||||
{
|
{
|
||||||
if (ARGS(0))
|
if (ARGS(0))
|
||||||
|
{
|
||||||
LOG_WARNING(RSX, "NV309E_SET_CONTEXT_DMA_IMAGE: 0x%x", ARGS(0));
|
LOG_WARNING(RSX, "NV309E_SET_CONTEXT_DMA_IMAGE: 0x%x", ARGS(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NV309E_SET_FORMAT:
|
case NV309E_SET_FORMAT:
|
||||||
|
@ -2241,7 +2311,9 @@ void RSXThread::Task()
|
||||||
if (put == get)
|
if (put == get)
|
||||||
{
|
{
|
||||||
if (m_flip_status == 0)
|
if (m_flip_status == 0)
|
||||||
|
{
|
||||||
m_sem_flip.post_and_wait();
|
m_sem_flip.post_and_wait();
|
||||||
|
}
|
||||||
|
|
||||||
m_sem_flush.post_and_wait();
|
m_sem_flush.post_and_wait();
|
||||||
}
|
}
|
||||||
|
@ -2250,49 +2322,51 @@ void RSXThread::Task()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//ConLog.Write("addr = 0x%x", m_ioAddress + get);
|
|
||||||
const u32 cmd = ReadIO32(get);
|
const u32 cmd = ReadIO32(get);
|
||||||
const u32 count = (cmd >> 18) & 0x7ff;
|
const u32 count = (cmd >> 18) & 0x7ff;
|
||||||
//if(cmd == 0) continue;
|
|
||||||
|
|
||||||
if (Ini.RSXLogging.GetValue())
|
if (Ini.RSXLogging.GetValue())
|
||||||
|
{
|
||||||
LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd);
|
LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd);
|
||||||
|
}
|
||||||
//LOG_NOTICE(Log::RSX, "put=0x%x, get=0x%x, cmd=0x%x (%s)", put, get, cmd, GetMethodName(cmd & 0xffff).c_str());
|
|
||||||
|
|
||||||
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
if (cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||||
{
|
{
|
||||||
u32 offs = cmd & 0x1fffffff;
|
u32 offs = cmd & 0x1fffffff;
|
||||||
//LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
|
//LOG_WARNING(RSX, "RSX: jump cmd (0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put);
|
||||||
m_ctrl->get.exchange(be_t<u32>::make(offs));
|
m_ctrl->get.exchange(be_t<u32>::make(offs));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
if (cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||||
{
|
{
|
||||||
m_call_stack.push(get + 4);
|
m_call_stack.push(get + 4);
|
||||||
u32 offs = cmd & ~3;
|
u32 offs = cmd & ~3;
|
||||||
//u32 addr = offs;
|
//LOG_WARNING(RSX, "RSX: call cmd (0x%x) #0x%x - 0x%x", offs, cmd, get);
|
||||||
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get);
|
|
||||||
m_ctrl->get.exchange(be_t<u32>::make(offs));
|
m_ctrl->get.exchange(be_t<u32>::make(offs));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
if (cmd == CELL_GCM_METHOD_FLAG_RETURN)
|
||||||
{
|
{
|
||||||
//LOG_WARNING(RSX, "rsx return!");
|
//LOG_WARNING(RSX, "rsx return!");
|
||||||
u32 get = m_call_stack.top();
|
u32 get = m_call_stack.top();
|
||||||
m_call_stack.pop();
|
m_call_stack.pop();
|
||||||
//LOG_WARNING(RSX, "rsx return(0x%x)", get);
|
//LOG_WARNING(RSX, "RSX: return cmd (0x%x)", get);
|
||||||
m_ctrl->get.exchange(be_t<u32>::make(get));
|
m_ctrl->get.exchange(be_t<u32>::make(get));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
|
||||||
{
|
{
|
||||||
//LOG_WARNING(RSX, "non increment cmd! 0x%x", cmd);
|
//LOG_WARNING(RSX,"RSX: non-increment cmd! 0x%x", cmd);
|
||||||
inc = 0;
|
inc = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//LOG_WARNING(RSX, "increment cmd! 0x%x", cmd);
|
//LOG_WARNING(RSX, "RSX: increment cmd! 0x%x", cmd);
|
||||||
|
inc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == 0) //nop
|
if (cmd == 0) //nop
|
||||||
|
@ -2317,13 +2391,14 @@ void RSXThread::Task()
|
||||||
{
|
{
|
||||||
value += (count + 1) * 4;
|
value += (count + 1) * 4;
|
||||||
});
|
});
|
||||||
//memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (const std::string& e)
|
catch (const std::string& e)
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "Exception: %s", e.c_str());
|
LOG_ERROR(RSX, "Exception: %s", e.c_str());
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (const char* e)
|
catch (const char* e)
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "Exception: %s", e);
|
LOG_ERROR(RSX, "Exception: %s", e);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include "Utilities/SSemaphore.h"
|
#include "Utilities/SSemaphore.h"
|
||||||
#include "Utilities/Thread.h"
|
#include "Utilities/Thread.h"
|
||||||
|
#include "Utilities/Timer.h"
|
||||||
|
|
||||||
enum Method
|
enum Method
|
||||||
{
|
{
|
||||||
|
@ -101,11 +102,14 @@ public:
|
||||||
protected:
|
protected:
|
||||||
std::stack<u32> m_call_stack;
|
std::stack<u32> m_call_stack;
|
||||||
CellGcmControl* m_ctrl;
|
CellGcmControl* m_ctrl;
|
||||||
|
Timer m_timer_sync;
|
||||||
|
double m_fps_limit = 59.94;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GcmTileInfo m_tiles[m_tiles_count];
|
GcmTileInfo m_tiles[m_tiles_count];
|
||||||
GcmZcullInfo m_zculls[m_zculls_count];
|
GcmZcullInfo m_zculls[m_zculls_count];
|
||||||
RSXTexture m_textures[m_textures_count];
|
RSXTexture m_textures[m_textures_count];
|
||||||
|
RSXVertexTexture m_vertex_textures[m_textures_count];
|
||||||
RSXVertexData m_vertex_data[m_vertex_count];
|
RSXVertexData m_vertex_data[m_vertex_count];
|
||||||
RSXIndexArrayData m_indexed_array;
|
RSXIndexArrayData m_indexed_array;
|
||||||
std::vector<RSXTransformConstant> m_fragment_constants;
|
std::vector<RSXTransformConstant> m_fragment_constants;
|
||||||
|
@ -515,6 +519,8 @@ protected:
|
||||||
m_line_stipple_factor = 1;
|
m_line_stipple_factor = 1;
|
||||||
m_vertex_data_base_offset = 0;
|
m_vertex_data_base_offset = 0;
|
||||||
m_vertex_data_base_index = 0;
|
m_vertex_data_base_index = 0;
|
||||||
|
|
||||||
|
// Construct Stipple Pattern
|
||||||
for (size_t i = 0; i < 32; i++) {
|
for (size_t i = 0; i < 32; i++) {
|
||||||
m_polygon_stipple_pattern[i] = 0xFFFFFFFF;
|
m_polygon_stipple_pattern[i] = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
@ -618,7 +624,7 @@ protected:
|
||||||
|
|
||||||
u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr);
|
u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr);
|
||||||
void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count);
|
void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count);
|
||||||
void nativeRescale(float width, float height);
|
void NativeRescale(float width, float height);
|
||||||
|
|
||||||
virtual void OnInit() = 0;
|
virtual void OnInit() = 0;
|
||||||
virtual void OnInitThread() = 0;
|
virtual void OnInitThread() = 0;
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum CellVideoOutResolutionId
|
||||||
CELL_VIDEO_OUT_RESOLUTION_960x720_3D_FRAME_PACKING = 0x89,
|
CELL_VIDEO_OUT_RESOLUTION_960x720_3D_FRAME_PACKING = 0x89,
|
||||||
CELL_VIDEO_OUT_RESOLUTION_800x720_3D_FRAME_PACKING = 0x8a,
|
CELL_VIDEO_OUT_RESOLUTION_800x720_3D_FRAME_PACKING = 0x8a,
|
||||||
CELL_VIDEO_OUT_RESOLUTION_640x720_3D_FRAME_PACKING = 0x8b,
|
CELL_VIDEO_OUT_RESOLUTION_640x720_3D_FRAME_PACKING = 0x8b,
|
||||||
|
CELL_VIDEO_OUT_RESOLUTION_720_SIMULVIEW_FRAME_PACKING = 0x91,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CellVideoOutScanMode
|
enum CellVideoOutScanMode
|
||||||
|
|
|
@ -526,6 +526,8 @@ int cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portN
|
||||||
port.channel = (u8)audioParam->nChannel;
|
port.channel = (u8)audioParam->nChannel;
|
||||||
port.block = (u8)audioParam->nBlock;
|
port.block = (u8)audioParam->nBlock;
|
||||||
port.attr = audioParam->attr;
|
port.attr = audioParam->attr;
|
||||||
|
port.addr = m_config.m_buffer + (128 * 1024 * i);
|
||||||
|
port.read_index_addr = m_config.m_indexes + (sizeof(u64) * i);
|
||||||
if (port.attr & CELL_AUDIO_PORTATTR_INITLEVEL)
|
if (port.attr & CELL_AUDIO_PORTATTR_INITLEVEL)
|
||||||
{
|
{
|
||||||
port.level = audioParam->level;
|
port.level = audioParam->level;
|
||||||
|
@ -578,8 +580,8 @@ int cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||||
portConfig->nChannel = port.channel;
|
portConfig->nChannel = port.channel;
|
||||||
portConfig->nBlock = port.block;
|
portConfig->nBlock = port.block;
|
||||||
portConfig->portSize = port.channel * port.block * 256 * sizeof(float);
|
portConfig->portSize = port.channel * port.block * 256 * sizeof(float);
|
||||||
portConfig->portAddr = m_config.m_buffer + (128 * 1024 * portNum); // 0x20020000
|
portConfig->portAddr = port.addr; // 0x20020000
|
||||||
portConfig->readIndexAddr = m_config.m_indexes + (sizeof(u64) * portNum); // 0x20010010 on ps3
|
portConfig->readIndexAddr = port.read_index_addr; // 0x20010010 on ps3
|
||||||
|
|
||||||
cellAudio->Log("*** port config: nChannel=%d, nBlock=%d, portSize=0x%x, portAddr=0x%x, readIndexAddr=0x%x",
|
cellAudio->Log("*** port config: nChannel=%d, nBlock=%d, portSize=0x%x, portAddr=0x%x, readIndexAddr=0x%x",
|
||||||
(u32)portConfig->nChannel, (u32)portConfig->nBlock, (u32)portConfig->portSize, (u32)portConfig->portAddr, (u32)portConfig->readIndexAddr);
|
(u32)portConfig->nChannel, (u32)portConfig->nBlock, (u32)portConfig->portSize, (u32)portConfig->portAddr, (u32)portConfig->readIndexAddr);
|
||||||
|
@ -730,6 +732,28 @@ int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||||
int cellAudioSetPortLevel(u32 portNum, float level)
|
int cellAudioSetPortLevel(u32 portNum, float level)
|
||||||
{
|
{
|
||||||
cellAudio->Todo("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level);
|
cellAudio->Todo("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level);
|
||||||
|
|
||||||
|
AudioPortConfig& port = m_config.m_ports[portNum];
|
||||||
|
|
||||||
|
if (portNum >= m_config.AUDIO_PORT_COUNT)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_opened)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_started)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(audioMutex);
|
||||||
|
|
||||||
|
port.level = level; // TODO
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,21 +863,94 @@ int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioAddData(u32 portNum, vm::ptr<be_t<float>> src, u32 samples, float volume)
|
int cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||||
{
|
{
|
||||||
cellAudio->Todo("cellAudioAddData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.addr(), samples, volume);
|
cellAudio->Todo("cellAudioAddData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.addr(), samples, volume);
|
||||||
|
|
||||||
|
AudioPortConfig& port = m_config.m_ports[portNum];
|
||||||
|
|
||||||
|
if (portNum >= m_config.AUDIO_PORT_COUNT)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_opened)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_started)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(audioMutex);
|
||||||
|
|
||||||
|
//u32 addr = port.addr;
|
||||||
|
//for (u32 i = 0; i < samples; i++)
|
||||||
|
//{
|
||||||
|
// vm::write32(addr, src[i]);
|
||||||
|
// addr += port.channel * port.block * sizeof(float);
|
||||||
|
//}
|
||||||
|
|
||||||
|
m_config.m_buffer = src.addr(); // TODO: write data from src in selected port
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioAdd2chData(u32 portNum, vm::ptr<be_t<float>> src, u32 samples, float volume)
|
int cellAudioAdd2chData(u32 portNum, vm::ptr<be_t<float>> src, u32 samples, float volume)
|
||||||
{
|
{
|
||||||
cellAudio->Todo("cellAudioAdd2chData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.addr(), samples, volume);
|
cellAudio->Todo("cellAudioAdd2chData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.addr(), samples, volume);
|
||||||
|
|
||||||
|
AudioPortConfig& port = m_config.m_ports[portNum];
|
||||||
|
|
||||||
|
if (portNum >= m_config.AUDIO_PORT_COUNT)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_opened)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_started)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(audioMutex);
|
||||||
|
|
||||||
|
m_config.m_buffer = src.addr(); // TODO
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellAudioAdd6chData(u32 portNum, vm::ptr<be_t<float>> src, float volume)
|
int cellAudioAdd6chData(u32 portNum, vm::ptr<be_t<float>> src, float volume)
|
||||||
{
|
{
|
||||||
cellAudio->Todo("cellAudioAdd6chData(portNum=0x%x, src_addr=0x%x, volume=%f)", portNum, src.addr(), volume);
|
cellAudio->Todo("cellAudioAdd6chData(portNum=0x%x, src_addr=0x%x, volume=%f)", portNum, src.addr(), volume);
|
||||||
|
|
||||||
|
AudioPortConfig& port = m_config.m_ports[portNum];
|
||||||
|
|
||||||
|
if (portNum >= m_config.AUDIO_PORT_COUNT)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_opened)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port.m_is_audio_port_started)
|
||||||
|
{
|
||||||
|
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(audioMutex);
|
||||||
|
|
||||||
|
m_config.m_buffer = src.addr(); // TODO
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -369,7 +369,7 @@ s32 _cellGcmInitBody(vm::ptr<CellGcmContextData> context, u32 cmdSize, u32 ioSiz
|
||||||
u32 ctx_begin = ioAddress/* + 0x1000*/;
|
u32 ctx_begin = ioAddress/* + 0x1000*/;
|
||||||
u32 ctx_size = 0x6ffc;
|
u32 ctx_size = 0x6ffc;
|
||||||
current_context.begin = ctx_begin;
|
current_context.begin = ctx_begin;
|
||||||
current_context.end = ctx_begin + ctx_size;
|
current_context.end = ctx_begin + ctx_size - 4;
|
||||||
current_context.current = current_context.begin;
|
current_context.current = current_context.begin;
|
||||||
current_context.callback.set(be_t<u32>::make(Emu.GetRSXCallback() - 4));
|
current_context.callback.set(be_t<u32>::make(Emu.GetRSXCallback() - 4));
|
||||||
|
|
||||||
|
@ -805,8 +805,7 @@ s32 cellGcmAddressToOffset(u64 address, vm::ptr<be_t<u32>> offset)
|
||||||
cellGcmSys->Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr());
|
cellGcmSys->Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr());
|
||||||
|
|
||||||
// Address not on main memory or local memory
|
// Address not on main memory or local memory
|
||||||
if (!address || address >= 0xD0000000) {
|
if (address >= 0xD0000000) {
|
||||||
cellGcmSys->Error("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr());
|
|
||||||
return CELL_GCM_ERROR_FAILURE;
|
return CELL_GCM_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,12 +1169,16 @@ s32 cellGcmCallback(vm::ptr<CellGcmContextData> context, u32 count)
|
||||||
{
|
{
|
||||||
cellGcmSys->Log("cellGcmCallback(context_addr=0x%x, count=0x%x)", context.addr(), count);
|
cellGcmSys->Log("cellGcmCallback(context_addr=0x%x, count=0x%x)", context.addr(), count);
|
||||||
|
|
||||||
GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH);
|
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
auto& ctrl = vm::get_ref<CellGcmControl>(gcm_info.control_addr);
|
auto& ctrl = vm::get_ref<CellGcmControl>(gcm_info.control_addr);
|
||||||
be_t<u32> res = be_t<u32>::make(context->current - context->begin - ctrl.put.read_relaxed());
|
be_t<u32> res = be_t<u32>::make(context->current - context->begin - ctrl.put.read_relaxed());
|
||||||
|
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
memmove(vm::get_ptr<void>(context->begin), vm::get_ptr<void>(context->current - res), res);
|
memmove(vm::get_ptr<void>(context->begin), vm::get_ptr<void>(context->current - res), res);
|
||||||
|
|
||||||
context->current = context->begin + res;
|
context->current = context->begin + res;
|
||||||
|
|
|
@ -391,3 +391,5 @@ struct CellPamfReader
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CellPamfReader) == 128, "Invalid CellPamfReader size");
|
static_assert(sizeof(CellPamfReader) == 128, "Invalid CellPamfReader size");
|
||||||
|
|
||||||
|
s32 cellPamfReaderInitialize(vm::ptr<CellPamfReader> pSelf, vm::ptr<const PamfHeader> pAddr, u64 fileSize, u32 attribute);
|
|
@ -1,8 +1,10 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
#include "Emu/SysCalls/Modules.h"
|
#include "Emu/SysCalls/Modules.h"
|
||||||
|
#include "Emu/FS/vfsFile.h"
|
||||||
|
|
||||||
#include "cellSail.h"
|
#include "cellSail.h"
|
||||||
|
#include "cellPamf.h"
|
||||||
|
|
||||||
Module *cellSail = nullptr;
|
Module *cellSail = nullptr;
|
||||||
|
|
||||||
|
@ -11,6 +13,7 @@ int cellSailMemAllocatorInitialize(vm::ptr<CellSailMemAllocator> pSelf, vm::ptr<
|
||||||
cellSail->Warning("cellSailMemAllocatorInitialize(pSelf_addr=0x%x, pCallbacks_addr=0x%x)", pSelf.addr(), pCallbacks.addr());
|
cellSail->Warning("cellSailMemAllocatorInitialize(pSelf_addr=0x%x, pCallbacks_addr=0x%x)", pSelf.addr(), pCallbacks.addr());
|
||||||
|
|
||||||
pSelf->callbacks = pCallbacks;
|
pSelf->callbacks = pCallbacks;
|
||||||
|
// TODO: Create a cellSail thread
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -91,9 +94,22 @@ int cellSailDescriptorIsAutoSelection(vm::ptr<CellSailDescriptor> pSelf)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSailDescriptorCreateDatabase()
|
int cellSailDescriptorCreateDatabase(vm::ptr<CellSailDescriptor> pSelf, vm::ptr<void> pDatabase, be_t<u32> size, be_t<u64> arg)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED_FUNC(cellSail);
|
cellSail->Warning("cellSailDescriptorCreateDatabase(pSelf=0x%x, pDatabase=0x%x, size=0x%x, arg=0x%x", pSelf.addr(), pDatabase.addr(), size, arg);
|
||||||
|
|
||||||
|
switch ((s32)pSelf->streamType) {
|
||||||
|
case CELL_SAIL_STREAM_PAMF:
|
||||||
|
{
|
||||||
|
u32 addr = pSelf->internalData[1];
|
||||||
|
auto ptr = vm::ptr<CellPamfReader>::make(addr);
|
||||||
|
memcpy(pDatabase.get_ptr(), ptr.get_ptr(), sizeof(CellPamfReader));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cellSail->Error("Unhandled stream type: %d", pSelf->streamType);
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,28 +632,52 @@ int cellSailPlayerAddDescriptor(vm::ptr<CellSailPlayer> pSelf, vm::ptr<CellSailD
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellSailPlayerCreateDescriptor(vm::ptr<CellSailPlayer> pSelf, s32 streamType, vm::ptr<u32> pMediaInfo, vm::ptr<const char> pUri, vm::ptr<CellSailDescriptor> ppDesc)
|
int cellSailPlayerCreateDescriptor(vm::ptr<CellSailPlayer> pSelf, s32 streamType, vm::ptr<u32> pMediaInfo, vm::ptr<const char> pUri, vm::ptr<u32> ppDesc)
|
||||||
{
|
{
|
||||||
cellSail->Todo("cellSailPlayerCreateDescriptor(pSelf_addr=0x%x, streamType=%d, pMediaInfo_addr=0x%x, pUri_addr=0x%x, ppDesc_addr=0x%x)", pSelf.addr(), streamType,
|
cellSail->Warning("cellSailPlayerCreateDescriptor(pSelf_addr=0x%x, streamType=%d, pMediaInfo_addr=0x%x, pUri_addr=0x%x, ppDesc_addr=0x%x)", pSelf.addr(), streamType,
|
||||||
pMediaInfo.addr(), pUri.addr(), ppDesc.addr());
|
pMediaInfo.addr(), pUri.addr(), ppDesc.addr());
|
||||||
|
|
||||||
//cellSail->Todo("Descriptor: %i", sizeof(CellSailDescriptor));
|
u32 descriptorAddress = Memory.Alloc(sizeof(CellSailDescriptor), 1);
|
||||||
//cellSail->Todo("Player: %i", sizeof(CellSailPlayer));
|
auto descriptor = vm::ptr<CellSailDescriptor>::make(descriptorAddress);
|
||||||
|
*ppDesc = descriptorAddress;
|
||||||
|
descriptor->streamType = streamType;
|
||||||
|
descriptor->registered = false;
|
||||||
|
|
||||||
// TODO: Let the game allocate memory for the descriptor, setup the descriptor and pass it back to the game
|
//pSelf->descriptors = 0;
|
||||||
|
|
||||||
//CellSailDescriptor *pDesc = new CellSailDescriptor();
|
|
||||||
//u32 descriptorAddress = pSelf->allocator->callbacks->pAlloc(pSelf->allocator->pArg, sizeof(CellSailDescriptor), sizeof(CellSailDescriptor));
|
|
||||||
u32 descriptorAddress = Memory.Alloc(sizeof(CellSailDescriptor), sizeof(CellSailDescriptor));
|
|
||||||
cellSail->Error("Address: 0x%x", descriptorAddress);
|
|
||||||
//vm::ptr<CellSailDescriptor> descriptor = vm::ptr<CellSailDescriptor>::make(Memory.RealToVirtualAddr(&descriptorAddress));
|
|
||||||
vm::ptr<CellSailDescriptor> descriptor = vm::ptr<CellSailDescriptor>::make(descriptorAddress);
|
|
||||||
//descriptor->streamType = streamType;
|
|
||||||
//descriptor->registered = false;
|
|
||||||
|
|
||||||
pSelf->descriptors = 0;
|
|
||||||
pSelf->repeatMode = 0;
|
pSelf->repeatMode = 0;
|
||||||
//ppDesc = descriptor;
|
|
||||||
|
switch (streamType)
|
||||||
|
{
|
||||||
|
case CELL_SAIL_STREAM_PAMF:
|
||||||
|
{
|
||||||
|
std::string uri = pUri.get_ptr();
|
||||||
|
if (uri.substr(0, 12) == "x-cell-fs://") {
|
||||||
|
std::string path = uri.substr(12);
|
||||||
|
vfsFile f;
|
||||||
|
if (f.Open(path)) {
|
||||||
|
u64 size = f.GetSize();
|
||||||
|
u32 buf_ = Memory.Alloc(size, 1);
|
||||||
|
auto bufPtr = vm::ptr<const PamfHeader>::make(buf_);
|
||||||
|
PamfHeader *buf = const_cast<PamfHeader*>(bufPtr.get_ptr());
|
||||||
|
assert(f.Read(buf, size) == size);
|
||||||
|
u32 sp_ = Memory.Alloc(sizeof(CellPamfReader), 1);
|
||||||
|
auto sp = vm::ptr<CellPamfReader>::make(sp_);
|
||||||
|
u32 r = cellPamfReaderInitialize(sp, bufPtr, size, 0);
|
||||||
|
|
||||||
|
descriptor->internalData[0] = buf_;
|
||||||
|
descriptor->internalData[1] = sp_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cellSail->Warning("Couldn't open PAMF: %s", uri.c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cellSail->Warning("Unhandled uri: %s", uri.c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cellSail->Error("Unhandled stream type: %d", streamType);
|
||||||
|
}
|
||||||
|
|
||||||
//cellSail->Todo("pSelf_addr=0x%x, pDesc_addr=0x%x", pSelf.addr(), descriptor.addr());
|
//cellSail->Todo("pSelf_addr=0x%x, pDesc_addr=0x%x", pSelf.addr(), descriptor.addr());
|
||||||
//cellSailPlayerAddDescriptor(pSelf, ppDesc);
|
//cellSailPlayerAddDescriptor(pSelf, ppDesc);
|
||||||
|
|
|
@ -679,8 +679,8 @@ typedef void(*CellSailPlayerFuncNotified)(u32 pArg, vm::ptr<CellSailEvent> event
|
||||||
|
|
||||||
struct CellSailMemAllocatorFuncs
|
struct CellSailMemAllocatorFuncs
|
||||||
{
|
{
|
||||||
CellSailMemAllocatorFuncAlloc pAlloc;
|
vm::ptr<CellSailMemAllocatorFuncAlloc> pAlloc;
|
||||||
CellSailMemAllocatorFuncFree pFree;
|
vm::ptr<CellSailMemAllocatorFuncFree> pFree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellSailMemAllocator
|
struct CellSailMemAllocator
|
||||||
|
@ -691,8 +691,8 @@ struct CellSailMemAllocator
|
||||||
|
|
||||||
struct CellSailFuture
|
struct CellSailFuture
|
||||||
{
|
{
|
||||||
u32 mutex_id;
|
be_t<u32> mutex_id;
|
||||||
u32 cond_id;
|
be_t<u32> cond_id;
|
||||||
volatile be_t<u32> flags;
|
volatile be_t<u32> flags;
|
||||||
be_t<s32> result;
|
be_t<s32> result;
|
||||||
be_t<u64> userParam;
|
be_t<u64> userParam;
|
||||||
|
|
|
@ -10,6 +10,14 @@
|
||||||
#include "Loader/PSF.h"
|
#include "Loader/PSF.h"
|
||||||
#include "cellSaveData.h"
|
#include "cellSaveData.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#undef CreateFile
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
extern Module *cellSysutil;
|
extern Module *cellSysutil;
|
||||||
|
|
||||||
// Auxiliary Classes
|
// Auxiliary Classes
|
||||||
|
@ -39,7 +47,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Auxiliary Functions
|
// Auxiliary Functions
|
||||||
u64 getSaveDataSize(const std::string& dirName)
|
u64 getSaveDataSize(const std::string& dirName)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +76,28 @@ void addSaveDataEntry(std::vector<SaveDataEntry>& saveEntries, const std::string
|
||||||
std::string localPath;
|
std::string localPath;
|
||||||
Emu.GetVFS().GetDevice(saveDir + "/ICON0.PNG", localPath);
|
Emu.GetVFS().GetDevice(saveDir + "/ICON0.PNG", localPath);
|
||||||
|
|
||||||
|
u64 atime = 0;
|
||||||
|
u64 mtime = 0;
|
||||||
|
u64 ctime = 0;
|
||||||
|
|
||||||
|
cellSysutil->Error("Running _stat in cellSaveData. Please report this to a RPCS3 developer!");
|
||||||
|
|
||||||
|
std::string pathy;
|
||||||
|
|
||||||
|
Emu.GetVFS().GetDevice("dev_hdd0", pathy);
|
||||||
|
|
||||||
|
struct stat buf;
|
||||||
|
int result = stat((pathy.substr(0, pathy.length() - 9) + f.GetPath()).c_str(), &buf);
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
cellSysutil->Error("_stat failed! (%s)", (pathy.substr(0, pathy.length() - 9) + f.GetPath()).c_str());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
atime = buf.st_atime;
|
||||||
|
mtime = buf.st_mtime;
|
||||||
|
ctime = buf.st_ctime;
|
||||||
|
}
|
||||||
|
|
||||||
SaveDataEntry saveEntry;
|
SaveDataEntry saveEntry;
|
||||||
saveEntry.dirName = psf.GetString("SAVEDATA_DIRECTORY");
|
saveEntry.dirName = psf.GetString("SAVEDATA_DIRECTORY");
|
||||||
saveEntry.listParam = psf.GetString("SAVEDATA_LIST_PARAM");
|
saveEntry.listParam = psf.GetString("SAVEDATA_LIST_PARAM");
|
||||||
|
@ -76,9 +105,9 @@ void addSaveDataEntry(std::vector<SaveDataEntry>& saveEntries, const std::string
|
||||||
saveEntry.subtitle = psf.GetString("SUB_TITLE");
|
saveEntry.subtitle = psf.GetString("SUB_TITLE");
|
||||||
saveEntry.details = psf.GetString("DETAIL");
|
saveEntry.details = psf.GetString("DETAIL");
|
||||||
saveEntry.sizeKB = (u32)(getSaveDataSize(saveDir) / 1024);
|
saveEntry.sizeKB = (u32)(getSaveDataSize(saveDir) / 1024);
|
||||||
saveEntry.st_atime_ = 0; // TODO
|
saveEntry.st_atime_ = atime;
|
||||||
saveEntry.st_mtime_ = 0; // TODO
|
saveEntry.st_mtime_ = mtime;
|
||||||
saveEntry.st_ctime_ = 0; // TODO
|
saveEntry.st_ctime_ = ctime;
|
||||||
saveEntry.iconBuf = NULL; // TODO: Here should be the PNG buffer
|
saveEntry.iconBuf = NULL; // TODO: Here should be the PNG buffer
|
||||||
saveEntry.iconBufSize = 0; // TODO: Size of the PNG file
|
saveEntry.iconBufSize = 0; // TODO: Size of the PNG file
|
||||||
saveEntry.isNew = false;
|
saveEntry.isNew = false;
|
||||||
|
@ -215,11 +244,11 @@ void getSaveDataStat(SaveDataEntry entry, vm::ptr<CellSaveDataStatGet> statGet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Fix the crash
|
statGet->fileList = vm::ptr<CellSaveDataFileStat>::make((u32)Memory.Alloc(sizeof(CellSaveDataFileStat) * fileEntries.size(), 8));
|
||||||
// statGet's fileList doesn't seem to be initiliazed properly, when called by cellSaveDataAutoSave2, thus causing a crash during memcpy.
|
for (u32 i = 0; i < fileEntries.size(); i++) {
|
||||||
statGet->fileList = vm::bptr<CellSaveDataFileStat>::make(be_t<u32>::make((u32)Memory.Alloc(sizeof(CellSaveDataFileStat) * (u32)fileEntries.size(), sizeof(CellSaveDataFileStat))));
|
CellSaveDataFileStat *dst = &statGet->fileList[i];
|
||||||
for (u32 i = 0; i < fileEntries.size(); i++)
|
memcpy(dst, &fileEntries[i], sizeof(CellSaveDataFileStat));
|
||||||
memcpy(&statGet->fileList[i], &fileEntries[i], sizeof(CellSaveDataFileStat));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 modifySaveDataFiles(vm::ptr<CellSaveDataFileCallback> funcFile, vm::ptr<CellSaveDataCBResult> result, const std::string& saveDataDir)
|
s32 modifySaveDataFiles(vm::ptr<CellSaveDataFileCallback> funcFile, vm::ptr<CellSaveDataCBResult> result, const std::string& saveDataDir)
|
||||||
|
@ -238,7 +267,7 @@ s32 modifySaveDataFiles(vm::ptr<CellSaveDataFileCallback> funcFile, vm::ptr<Cell
|
||||||
cellSysutil->Error("modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
|
cellSysutil->Error("modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message.
|
||||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||||
}
|
}
|
||||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) {
|
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,13 +286,13 @@ int cellVideoOutGetNumberOfDevice(u32 videoOut)
|
||||||
|
|
||||||
int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option)
|
int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option)
|
||||||
{
|
{
|
||||||
cellSysutil->Warning("cellVideoOutGetResolutionAvailability(videoOut=%d, resolutionId=0x%x, option_addr=0x%x, aspect=0x%x, option=0x%x)",
|
cellSysutil->Warning("cellVideoOutGetResolutionAvailability(videoOut=%d, resolutionId=0x%x, option_addr=0x%x, aspect=%d, option=%d)",
|
||||||
videoOut, resolutionId, aspect, option);
|
videoOut, resolutionId, aspect, option);
|
||||||
|
|
||||||
if(!ResolutionIdToNum(resolutionId))
|
if (!Ini.GS3DTV.GetValue() && (resolutionId == CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING || resolutionId == CELL_VIDEO_OUT_RESOLUTION_1024x720_3D_FRAME_PACKING ||
|
||||||
{
|
resolutionId == CELL_VIDEO_OUT_RESOLUTION_960x720_3D_FRAME_PACKING || resolutionId == CELL_VIDEO_OUT_RESOLUTION_800x720_3D_FRAME_PACKING ||
|
||||||
return CELL_EINVAL;
|
resolutionId == CELL_VIDEO_OUT_RESOLUTION_640x720_3D_FRAME_PACKING))
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
switch(videoOut)
|
switch(videoOut)
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,17 +116,16 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr<const char> drm_path)
|
||||||
std::string rap_path("/dev_hdd0/home/" + pf_str + "/exdata/");
|
std::string rap_path("/dev_hdd0/home/" + pf_str + "/exdata/");
|
||||||
|
|
||||||
// Search dev_usb000 for a compatible RAP file.
|
// Search dev_usb000 for a compatible RAP file.
|
||||||
vfsDir *raps_dir = new vfsDir(rap_path);
|
vfsDir raps_dir(rap_path);
|
||||||
if (!raps_dir->IsOpened())
|
if (!raps_dir.IsOpened())
|
||||||
sceNp->Warning("npDrmIsAvailable: Can't find RAP file for DRM!");
|
sceNp->Warning("npDrmIsAvailable: Can't find RAP file for DRM!");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::vector<DirEntryInfo> &entries = raps_dir->GetEntries();
|
for (const DirEntryInfo *entry : raps_dir)
|
||||||
for (auto &entry : entries)
|
|
||||||
{
|
{
|
||||||
if (entry.name.find(titleID) != std::string::npos)
|
if (entry->name.find(titleID) != std::string::npos)
|
||||||
{
|
{
|
||||||
rap_path += entry.name;
|
rap_path += entry->name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,14 @@
|
||||||
#include "Emu/SysCalls/Callback.h"
|
#include "Emu/SysCalls/Callback.h"
|
||||||
#include "Emu/SysCalls/CB_FUNC.h"
|
#include "Emu/SysCalls/CB_FUNC.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#undef CreateFile
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Emu/FS/VFS.h"
|
#include "Emu/FS/VFS.h"
|
||||||
#include "Emu/FS/vfsFile.h"
|
#include "Emu/FS/vfsFile.h"
|
||||||
#include "Emu/FS/vfsDir.h"
|
#include "Emu/FS/vfsDir.h"
|
||||||
|
@ -234,16 +242,48 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
|
||||||
|
|
||||||
const std::string _path = path.get_ptr();
|
const std::string _path = path.get_ptr();
|
||||||
|
|
||||||
|
u32 mode = 0;
|
||||||
|
s32 uid = 0;
|
||||||
|
s32 gid = 0;
|
||||||
|
u64 atime = 0;
|
||||||
|
u64 mtime = 0;
|
||||||
|
u64 ctime = 0;
|
||||||
|
u64 size = 0;
|
||||||
|
|
||||||
|
std::string real_path;
|
||||||
|
|
||||||
|
Emu.GetVFS().GetDevice(_path, real_path);
|
||||||
|
|
||||||
|
struct stat buf;
|
||||||
|
|
||||||
|
if (int result = stat(real_path.c_str(), &buf))
|
||||||
|
{
|
||||||
|
sys_fs->Error("_stat failed! (%s)", real_path.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode = buf.st_mode;
|
||||||
|
uid = buf.st_uid;
|
||||||
|
gid = buf.st_gid;
|
||||||
|
atime = buf.st_atime;
|
||||||
|
mtime = buf.st_mtime;
|
||||||
|
ctime = buf.st_ctime;
|
||||||
|
size = buf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
sb->st_mode =
|
sb->st_mode =
|
||||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
||||||
CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
|
CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
|
||||||
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
||||||
|
|
||||||
sb->st_uid = 0;
|
if (sb->st_mode == mode)
|
||||||
sb->st_gid = 0;
|
sys_fs->Error("Mode is the same. Report this to a RPCS3 developer! (%d)", mode);
|
||||||
sb->st_atime_ = 0; //TODO
|
|
||||||
sb->st_mtime_ = 0; //TODO
|
sb->st_uid = uid;
|
||||||
sb->st_ctime_ = 0; //TODO
|
sb->st_gid = gid;
|
||||||
|
sb->st_atime_ = atime;
|
||||||
|
sb->st_mtime_ = mtime;
|
||||||
|
sb->st_ctime_ = ctime;
|
||||||
sb->st_blksize = 4096;
|
sb->st_blksize = 4096;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -265,6 +305,9 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sb->st_size == size && size != 0)
|
||||||
|
sys_fs->Error("Size is the same. Report this to a RPCS3 developer! (%d)", size);
|
||||||
|
|
||||||
sys_fs->Warning("cellFsStat: \"%s\" not found.", path.get_ptr());
|
sys_fs->Warning("cellFsStat: \"%s\" not found.", path.get_ptr());
|
||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,10 @@ void sys_game_process_exitspawn(vm::ptr<const char> path, u32 argv_addr, u32 env
|
||||||
device = 0;
|
device = 0;
|
||||||
else if (_path.substr(1, 8) == "dev_hdd1")
|
else if (_path.substr(1, 8) == "dev_hdd1")
|
||||||
device = 1;
|
device = 1;
|
||||||
|
else if (_path.substr(1, 8) == "dev_bdvd")
|
||||||
|
device = 2;
|
||||||
|
|
||||||
|
if (device != 0)
|
||||||
Emu.BootGame(_path.c_str(), true, device);
|
Emu.BootGame(_path.c_str(), true, device);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -188,6 +191,8 @@ void sys_game_process_exitspawn2(vm::ptr<const char> path, u32 argv_addr, u32 en
|
||||||
device = 0;
|
device = 0;
|
||||||
else if (_path.substr(1, 8) == "dev_hdd1")
|
else if (_path.substr(1, 8) == "dev_hdd1")
|
||||||
device = 1;
|
device = 1;
|
||||||
|
else if (_path.substr(1, 8) == "dev_bdvd")
|
||||||
|
device = 2;
|
||||||
|
|
||||||
Emu.BootGame(_path.c_str(), true, device);
|
Emu.BootGame(_path.c_str(), true, device);
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,11 @@ void Emulator::SetTitleID(const std::string& id)
|
||||||
m_title_id = id;
|
m_title_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Emulator::SetTitle(const std::string& title)
|
||||||
|
{
|
||||||
|
m_title = title;
|
||||||
|
}
|
||||||
|
|
||||||
void Emulator::CheckStatus()
|
void Emulator::CheckStatus()
|
||||||
{
|
{
|
||||||
//auto& threads = GetCPU().GetThreads();
|
//auto& threads = GetCPU().GetThreads();
|
||||||
|
@ -150,7 +155,7 @@ bool Emulator::BootGame(const std::string& path, bool direct, int device)
|
||||||
"/BOOT.BIN",
|
"/BOOT.BIN",
|
||||||
"/PS3_GAME/USRDIR/EBOOT.BIN",
|
"/PS3_GAME/USRDIR/EBOOT.BIN",
|
||||||
"/USRDIR/EBOOT.BIN",
|
"/USRDIR/EBOOT.BIN",
|
||||||
"/EBOOT.BIN",
|
"/EBOOT.BIN"
|
||||||
};
|
};
|
||||||
auto curpath = path;
|
auto curpath = path;
|
||||||
|
|
||||||
|
@ -177,6 +182,8 @@ bool Emulator::BootGame(const std::string& path, bool direct, int device)
|
||||||
Emu.GetVFS().GetDevice("dev_hdd0", pathy);
|
Emu.GetVFS().GetDevice("dev_hdd0", pathy);
|
||||||
else if (device == 1)
|
else if (device == 1)
|
||||||
Emu.GetVFS().GetDevice("dev_hdd1", pathy);
|
Emu.GetVFS().GetDevice("dev_hdd1", pathy);
|
||||||
|
else if (device == 2)
|
||||||
|
Emu.GetVFS().GetDevice("dev_bdvd", pathy);
|
||||||
|
|
||||||
curpath = pathy.substr(0, pathy.length() - 9) + path;
|
curpath = pathy.substr(0, pathy.length() - 9) + path;
|
||||||
|
|
||||||
|
@ -237,6 +244,9 @@ void Emulator::Load()
|
||||||
LOG_NOTICE(LOADER, "Title: %s", title.c_str());
|
LOG_NOTICE(LOADER, "Title: %s", title.c_str());
|
||||||
LOG_NOTICE(LOADER, "Serial: %s", title_id.c_str());
|
LOG_NOTICE(LOADER, "Serial: %s", title_id.c_str());
|
||||||
|
|
||||||
|
title.length() ? SetTitle(title) : SetTitle(m_path);
|
||||||
|
SetTitleID(title_id);
|
||||||
|
|
||||||
// bdvd inserting imitation
|
// bdvd inserting imitation
|
||||||
vfsFile f1("/app_home/../dev_bdvd.path");
|
vfsFile f1("/app_home/../dev_bdvd.path");
|
||||||
if (f1.IsOpened())
|
if (f1.IsOpened())
|
||||||
|
|
|
@ -114,6 +114,7 @@ public:
|
||||||
std::string m_elf_path;
|
std::string m_elf_path;
|
||||||
std::string m_emu_path;
|
std::string m_emu_path;
|
||||||
std::string m_title_id;
|
std::string m_title_id;
|
||||||
|
std::string m_title;
|
||||||
s32 m_sdk_version;
|
s32 m_sdk_version;
|
||||||
|
|
||||||
Emulator();
|
Emulator();
|
||||||
|
@ -122,6 +123,7 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void SetPath(const std::string& path, const std::string& elf_path = "");
|
void SetPath(const std::string& path, const std::string& elf_path = "");
|
||||||
void SetTitleID(const std::string& id);
|
void SetTitleID(const std::string& id);
|
||||||
|
void SetTitle(const std::string& title);
|
||||||
|
|
||||||
std::string GetPath() const
|
std::string GetPath() const
|
||||||
{
|
{
|
||||||
|
@ -133,6 +135,16 @@ public:
|
||||||
return m_emu_path;
|
return m_emu_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GetTitleID() const
|
||||||
|
{
|
||||||
|
return m_title_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetTitle() const
|
||||||
|
{
|
||||||
|
return m_title;
|
||||||
|
}
|
||||||
|
|
||||||
void SetEmulatorPath(const std::string& path)
|
void SetEmulatorPath(const std::string& path)
|
||||||
{
|
{
|
||||||
m_emu_path = path;
|
m_emu_path = path;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "stdafx_gui.h"
|
#include "stdafx_gui.h"
|
||||||
#include "Emu/Memory/Memory.h"
|
#include "Emu/Memory/Memory.h"
|
||||||
|
#include "Emu/System.h"
|
||||||
#include "GLGSFrame.h"
|
#include "GLGSFrame.h"
|
||||||
#include "Utilities/Timer.h"
|
#include "Utilities/Timer.h"
|
||||||
|
|
||||||
|
@ -61,10 +62,12 @@ void GLGSFrame::Flip(void* context)
|
||||||
canvas->SwapBuffers();
|
canvas->SwapBuffers();
|
||||||
m_frames++;
|
m_frames++;
|
||||||
|
|
||||||
|
const std::string sub_title = Emu.GetTitle() += Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | ";
|
||||||
|
|
||||||
if (fps_t.GetElapsedTimeInSec() >= 0.5)
|
if (fps_t.GetElapsedTimeInSec() >= 0.5)
|
||||||
{
|
{
|
||||||
// can freeze on exit
|
// can freeze on exit
|
||||||
SetTitle(wxString::Format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec()));
|
SetTitle(sub_title + wxString::Format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec()));
|
||||||
m_frames = 0;
|
m_frames = 0;
|
||||||
fps_t.Start();
|
fps_t.Start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ public:
|
||||||
{
|
{
|
||||||
list->DeleteAllItems();
|
list->DeleteAllItems();
|
||||||
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
|
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
|
||||||
for(int c=0; c<list->GetColumnCount(); ++c)
|
for(int c=1; c<list->GetColumnCount(); ++c)
|
||||||
{
|
{
|
||||||
Column* col = GetColumnByPos(c);
|
Column* col = GetColumnByPos(c);
|
||||||
|
|
||||||
|
@ -175,7 +175,6 @@ public:
|
||||||
list->SetItemData(i, i);
|
list->SetItemData(i, i);
|
||||||
}
|
}
|
||||||
list->SetItem(i, c, fmt::FromUTF8(col->data[i]));
|
list->SetItem(i, c, fmt::FromUTF8(col->data[i]));
|
||||||
list->SetItem(i, 0, wxEmptyString); // don't insert icon path
|
|
||||||
list->SetItemColumnImage(i, 0, m_icon_indexes[i]);
|
list->SetItemColumnImage(i, 0, m_icon_indexes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Gui/KernelExplorer.h"
|
#include "Gui/KernelExplorer.h"
|
||||||
#include "Gui/MemoryViewer.h"
|
#include "Gui/MemoryViewer.h"
|
||||||
#include "Gui/RSXDebugger.h"
|
#include "Gui/RSXDebugger.h"
|
||||||
|
#include "Gui/MemoryStringSearcher.h"
|
||||||
#include "Gui/LLEModulesManager.h"
|
#include "Gui/LLEModulesManager.h"
|
||||||
|
|
||||||
#include <wx/dynlib.h>
|
#include <wx/dynlib.h>
|
||||||
|
@ -51,6 +52,7 @@ enum IDs
|
||||||
id_tools_kernel_explorer,
|
id_tools_kernel_explorer,
|
||||||
id_tools_memory_viewer,
|
id_tools_memory_viewer,
|
||||||
id_tools_rsx_debugger,
|
id_tools_rsx_debugger,
|
||||||
|
id_tools_string_search,
|
||||||
id_help_about,
|
id_help_about,
|
||||||
id_update_dbg,
|
id_update_dbg,
|
||||||
};
|
};
|
||||||
|
@ -112,6 +114,7 @@ MainFrame::MainFrame()
|
||||||
menu_tools->Append(id_tools_kernel_explorer, "&Kernel Explorer")->Enable(false);
|
menu_tools->Append(id_tools_kernel_explorer, "&Kernel Explorer")->Enable(false);
|
||||||
menu_tools->Append(id_tools_memory_viewer, "&Memory Viewer")->Enable(false);
|
menu_tools->Append(id_tools_memory_viewer, "&Memory Viewer")->Enable(false);
|
||||||
menu_tools->Append(id_tools_rsx_debugger, "&RSX Debugger")->Enable(false);
|
menu_tools->Append(id_tools_rsx_debugger, "&RSX Debugger")->Enable(false);
|
||||||
|
menu_tools->Append(id_tools_string_search, "&String Search")->Enable(false);
|
||||||
|
|
||||||
wxMenu* menu_help = new wxMenu();
|
wxMenu* menu_help = new wxMenu();
|
||||||
menubar->Append(menu_help, "&Help");
|
menubar->Append(menu_help, "&Help");
|
||||||
|
@ -151,6 +154,7 @@ MainFrame::MainFrame()
|
||||||
Bind(wxEVT_MENU, &MainFrame::OpenKernelExplorer, this, id_tools_kernel_explorer);
|
Bind(wxEVT_MENU, &MainFrame::OpenKernelExplorer, this, id_tools_kernel_explorer);
|
||||||
Bind(wxEVT_MENU, &MainFrame::OpenMemoryViewer, this, id_tools_memory_viewer);
|
Bind(wxEVT_MENU, &MainFrame::OpenMemoryViewer, this, id_tools_memory_viewer);
|
||||||
Bind(wxEVT_MENU, &MainFrame::OpenRSXDebugger, this, id_tools_rsx_debugger);
|
Bind(wxEVT_MENU, &MainFrame::OpenRSXDebugger, this, id_tools_rsx_debugger);
|
||||||
|
Bind(wxEVT_MENU, &MainFrame::OpenStringSearch, this, id_tools_string_search);
|
||||||
|
|
||||||
Bind(wxEVT_MENU, &MainFrame::AboutDialogHandler, this, id_help_about);
|
Bind(wxEVT_MENU, &MainFrame::AboutDialogHandler, this, id_help_about);
|
||||||
|
|
||||||
|
@ -342,7 +346,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
||||||
wxDialog diag(this, wxID_ANY, "Settings", wxDefaultPosition);
|
wxDialog diag(this, wxID_ANY, "Settings", wxDefaultPosition);
|
||||||
static const u32 width = 425;
|
static const u32 width = 425;
|
||||||
static const u32 height = 400;
|
static const u32 height = 460;
|
||||||
|
|
||||||
// Settings panels
|
// Settings panels
|
||||||
wxNotebook* nb_config = new wxNotebook(&diag, wxID_ANY, wxPoint(6,6), wxSize(width, height));
|
wxNotebook* nb_config = new wxNotebook(&diag, wxID_ANY, wxPoint(6,6), wxSize(width, height));
|
||||||
|
@ -378,6 +382,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
wxStaticBoxSizer* s_round_gs_render = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Render"));
|
wxStaticBoxSizer* s_round_gs_render = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Render"));
|
||||||
wxStaticBoxSizer* s_round_gs_res = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Default resolution"));
|
wxStaticBoxSizer* s_round_gs_res = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Default resolution"));
|
||||||
wxStaticBoxSizer* s_round_gs_aspect = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Default aspect ratio"));
|
wxStaticBoxSizer* s_round_gs_aspect = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Default aspect ratio"));
|
||||||
|
wxStaticBoxSizer* s_round_gs_frame_limit = new wxStaticBoxSizer(wxVERTICAL, p_graphics, _("Frame limit"));
|
||||||
|
|
||||||
// Input / Output
|
// Input / Output
|
||||||
wxStaticBoxSizer* s_round_io_pad_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Pad Handler"));
|
wxStaticBoxSizer* s_round_io_pad_handler = new wxStaticBoxSizer(wxVERTICAL, p_io, _("Pad Handler"));
|
||||||
|
@ -402,6 +407,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
wxComboBox* cbox_gs_render = new wxComboBox(p_graphics, wxID_ANY);
|
wxComboBox* cbox_gs_render = new wxComboBox(p_graphics, wxID_ANY);
|
||||||
wxComboBox* cbox_gs_resolution = new wxComboBox(p_graphics, wxID_ANY);
|
wxComboBox* cbox_gs_resolution = new wxComboBox(p_graphics, wxID_ANY);
|
||||||
wxComboBox* cbox_gs_aspect = new wxComboBox(p_graphics, wxID_ANY);
|
wxComboBox* cbox_gs_aspect = new wxComboBox(p_graphics, wxID_ANY);
|
||||||
|
wxComboBox* cbox_gs_frame_limit = new wxComboBox(p_graphics, wxID_ANY);
|
||||||
wxComboBox* cbox_pad_handler = new wxComboBox(p_io, wxID_ANY);
|
wxComboBox* cbox_pad_handler = new wxComboBox(p_io, wxID_ANY);
|
||||||
wxComboBox* cbox_keyboard_handler = new wxComboBox(p_io, wxID_ANY);
|
wxComboBox* cbox_keyboard_handler = new wxComboBox(p_io, wxID_ANY);
|
||||||
wxComboBox* cbox_mouse_handler = new wxComboBox(p_io, wxID_ANY);
|
wxComboBox* cbox_mouse_handler = new wxComboBox(p_io, wxID_ANY);
|
||||||
|
@ -414,6 +420,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log vertex/fragment programs");
|
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log vertex/fragment programs");
|
||||||
wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer");
|
wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer");
|
||||||
wxCheckBox* chbox_gs_dump_color = new wxCheckBox(p_graphics, wxID_ANY, "Write Color Buffers");
|
wxCheckBox* chbox_gs_dump_color = new wxCheckBox(p_graphics, wxID_ANY, "Write Color Buffers");
|
||||||
|
wxCheckBox* chbox_gs_read_color = new wxCheckBox(p_graphics, wxID_ANY, "Read Color Buffer");
|
||||||
wxCheckBox* chbox_gs_vsync = new wxCheckBox(p_graphics, wxID_ANY, "VSync");
|
wxCheckBox* chbox_gs_vsync = new wxCheckBox(p_graphics, wxID_ANY, "VSync");
|
||||||
wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor");
|
wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor");
|
||||||
wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file");
|
wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file");
|
||||||
|
@ -447,6 +454,9 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
cbox_gs_aspect->Append("4:3");
|
cbox_gs_aspect->Append("4:3");
|
||||||
cbox_gs_aspect->Append("16:9");
|
cbox_gs_aspect->Append("16:9");
|
||||||
|
|
||||||
|
for (auto item : { "Off", "50", "59.94", "30", "60", "Auto" })
|
||||||
|
cbox_gs_frame_limit->Append(item);
|
||||||
|
|
||||||
cbox_pad_handler->Append("Null");
|
cbox_pad_handler->Append("Null");
|
||||||
cbox_pad_handler->Append("Windows");
|
cbox_pad_handler->Append("Windows");
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
|
@ -501,6 +511,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
chbox_gs_log_prog ->SetValue(Ini.GSLogPrograms.GetValue());
|
chbox_gs_log_prog ->SetValue(Ini.GSLogPrograms.GetValue());
|
||||||
chbox_gs_dump_depth ->SetValue(Ini.GSDumpDepthBuffer.GetValue());
|
chbox_gs_dump_depth ->SetValue(Ini.GSDumpDepthBuffer.GetValue());
|
||||||
chbox_gs_dump_color ->SetValue(Ini.GSDumpColorBuffers.GetValue());
|
chbox_gs_dump_color ->SetValue(Ini.GSDumpColorBuffers.GetValue());
|
||||||
|
chbox_gs_read_color ->SetValue(Ini.GSReadColorBuffer.GetValue());
|
||||||
chbox_gs_vsync ->SetValue(Ini.GSVSyncEnable.GetValue());
|
chbox_gs_vsync ->SetValue(Ini.GSVSyncEnable.GetValue());
|
||||||
chbox_gs_3dmonitor ->SetValue(Ini.GS3DTV.GetValue());
|
chbox_gs_3dmonitor ->SetValue(Ini.GS3DTV.GetValue());
|
||||||
chbox_audio_dump ->SetValue(Ini.AudioDumpToFile.GetValue());
|
chbox_audio_dump ->SetValue(Ini.AudioDumpToFile.GetValue());
|
||||||
|
@ -521,6 +532,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
cbox_gs_render ->SetSelection(Ini.GSRenderMode.GetValue());
|
cbox_gs_render ->SetSelection(Ini.GSRenderMode.GetValue());
|
||||||
cbox_gs_resolution ->SetSelection(ResolutionIdToNum(Ini.GSResolution.GetValue()) - 1);
|
cbox_gs_resolution ->SetSelection(ResolutionIdToNum(Ini.GSResolution.GetValue()) - 1);
|
||||||
cbox_gs_aspect ->SetSelection(Ini.GSAspectRatio.GetValue() - 1);
|
cbox_gs_aspect ->SetSelection(Ini.GSAspectRatio.GetValue() - 1);
|
||||||
|
cbox_gs_frame_limit ->SetSelection(Ini.GSFrameLimit.GetValue());
|
||||||
cbox_pad_handler ->SetSelection(Ini.PadHandlerMode.GetValue());
|
cbox_pad_handler ->SetSelection(Ini.PadHandlerMode.GetValue());
|
||||||
cbox_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue());
|
cbox_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue());
|
||||||
cbox_mouse_handler ->SetSelection(Ini.MouseHandlerMode.GetValue());
|
cbox_mouse_handler ->SetSelection(Ini.MouseHandlerMode.GetValue());
|
||||||
|
@ -543,6 +555,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_round_gs_res->Add(cbox_gs_resolution, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_round_gs_res->Add(cbox_gs_resolution, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_round_gs_aspect->Add(cbox_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_round_gs_aspect->Add(cbox_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
|
s_round_gs_frame_limit->Add(cbox_gs_frame_limit, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
|
|
||||||
s_round_io_pad_handler->Add(cbox_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_round_io_pad_handler->Add(cbox_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_round_io_keyboard_handler->Add(cbox_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_round_io_keyboard_handler->Add(cbox_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
|
@ -565,9 +578,11 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
s_subpanel_graphics->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
|
s_subpanel_graphics->Add(s_round_gs_frame_limit, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(chbox_gs_log_prog, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(chbox_gs_log_prog, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
|
s_subpanel_graphics->Add(chbox_gs_read_color, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
s_subpanel_graphics->Add(chbox_gs_3dmonitor, wxSizerFlags().Border(wxALL, 5).Expand());
|
s_subpanel_graphics->Add(chbox_gs_3dmonitor, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||||
|
|
||||||
|
@ -625,9 +640,11 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||||
Ini.GSRenderMode.SetValue(cbox_gs_render->GetSelection());
|
Ini.GSRenderMode.SetValue(cbox_gs_render->GetSelection());
|
||||||
Ini.GSResolution.SetValue(ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1));
|
Ini.GSResolution.SetValue(ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1));
|
||||||
Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1);
|
Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1);
|
||||||
|
Ini.GSFrameLimit.SetValue(cbox_gs_frame_limit->GetSelection());
|
||||||
Ini.GSLogPrograms.SetValue(chbox_gs_log_prog->GetValue());
|
Ini.GSLogPrograms.SetValue(chbox_gs_log_prog->GetValue());
|
||||||
Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue());
|
Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue());
|
||||||
Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue());
|
Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue());
|
||||||
|
Ini.GSReadColorBuffer.SetValue(chbox_gs_read_color->GetValue());
|
||||||
Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue());
|
Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue());
|
||||||
Ini.GS3DTV.SetValue(chbox_gs_3dmonitor->GetValue());
|
Ini.GS3DTV.SetValue(chbox_gs_3dmonitor->GetValue());
|
||||||
Ini.PadHandlerMode.SetValue(cbox_pad_handler->GetSelection());
|
Ini.PadHandlerMode.SetValue(cbox_pad_handler->GetSelection());
|
||||||
|
@ -707,6 +724,10 @@ void MainFrame::OpenRSXDebugger(wxCommandEvent& WXUNUSED(event))
|
||||||
(new RSXDebugger(this)) -> Show();
|
(new RSXDebugger(this)) -> Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainFrame::OpenStringSearch(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
(new MemoryStringSearcher(this)) -> Show();
|
||||||
|
}
|
||||||
|
|
||||||
void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event))
|
void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
|
@ -805,9 +826,12 @@ void MainFrame::UpdateUI(wxCommandEvent& event)
|
||||||
wxMenuItem& kernel_explorer = *menubar.FindItem(id_tools_kernel_explorer);
|
wxMenuItem& kernel_explorer = *menubar.FindItem(id_tools_kernel_explorer);
|
||||||
wxMenuItem& memory_viewer = *menubar.FindItem(id_tools_memory_viewer);
|
wxMenuItem& memory_viewer = *menubar.FindItem(id_tools_memory_viewer);
|
||||||
wxMenuItem& rsx_debugger = *menubar.FindItem(id_tools_rsx_debugger);
|
wxMenuItem& rsx_debugger = *menubar.FindItem(id_tools_rsx_debugger);
|
||||||
|
wxMenuItem& string_search = *menubar.FindItem(id_tools_string_search);
|
||||||
kernel_explorer.Enable(!is_stopped);
|
kernel_explorer.Enable(!is_stopped);
|
||||||
memory_viewer.Enable(!is_stopped);
|
memory_viewer.Enable(!is_stopped);
|
||||||
rsx_debugger.Enable(!is_stopped);
|
rsx_debugger.Enable(!is_stopped);
|
||||||
|
string_search.Enable(!is_stopped);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//m_aui_mgr.Update();
|
//m_aui_mgr.Update();
|
||||||
|
|
|
@ -45,6 +45,7 @@ private:
|
||||||
void OpenKernelExplorer(wxCommandEvent& evt);
|
void OpenKernelExplorer(wxCommandEvent& evt);
|
||||||
void OpenMemoryViewer(wxCommandEvent& evt);
|
void OpenMemoryViewer(wxCommandEvent& evt);
|
||||||
void OpenRSXDebugger(wxCommandEvent& evt);
|
void OpenRSXDebugger(wxCommandEvent& evt);
|
||||||
|
void OpenStringSearch(wxCommandEvent& evt);
|
||||||
void OpenFnIdGenerator(wxCommandEvent& evt);
|
void OpenFnIdGenerator(wxCommandEvent& evt);
|
||||||
void AboutDialogHandler(wxCommandEvent& event);
|
void AboutDialogHandler(wxCommandEvent& event);
|
||||||
void UpdateUI(wxCommandEvent& event);
|
void UpdateUI(wxCommandEvent& event);
|
||||||
|
|
74
rpcs3/Gui/MemoryStringSearcher.cpp
Normal file
74
rpcs3/Gui/MemoryStringSearcher.cpp
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#include "stdafx_gui.h"
|
||||||
|
#include "rpcs3/Ini.h"
|
||||||
|
#include "Utilities/rPlatform.h"
|
||||||
|
#include "Utilities/Log.h"
|
||||||
|
#include "Emu/Memory/Memory.h"
|
||||||
|
#include "Emu/System.h"
|
||||||
|
|
||||||
|
#include "MemoryStringSearcher.h"
|
||||||
|
#include "Emu/RSX/sysutil_video.h"
|
||||||
|
#include "Emu/RSX/GSManager.h"
|
||||||
|
//#include "Emu/RSX/GCM.h"
|
||||||
|
|
||||||
|
#include <wx/notebook.h>
|
||||||
|
|
||||||
|
MemoryStringSearcher::MemoryStringSearcher(wxWindow* parent)
|
||||||
|
: wxFrame(parent, wxID_ANY, "String Searcher", wxDefaultPosition, wxSize(545, 64))
|
||||||
|
, exit(false)
|
||||||
|
{
|
||||||
|
this->SetBackgroundColour(wxColour(240,240,240));
|
||||||
|
//wxBoxSizer* s_panel = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
|
//Tools
|
||||||
|
//wxBoxSizer* s_tools = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
|
//Tabs
|
||||||
|
//wxNotebook* nb_rsx = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(482,475));
|
||||||
|
|
||||||
|
s_panel = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
t_addr = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(482, -1));
|
||||||
|
b_search = new wxButton(this, wxID_ANY, "Search", wxPoint(482, 0), wxSize(40, -1));
|
||||||
|
b_search->Bind(wxEVT_BUTTON, &MemoryStringSearcher::Search, this);
|
||||||
|
s_panel->Add(t_addr);
|
||||||
|
s_panel->Add(b_search);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MemoryStringSearcher::Search(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
const wxString wstr = t_addr->GetValue();
|
||||||
|
const char *str = wstr.c_str();
|
||||||
|
const u32 len = wstr.length();
|
||||||
|
|
||||||
|
LOG_NOTICE(GENERAL, "Searching for string %s", str);
|
||||||
|
|
||||||
|
// Search the address space for the string
|
||||||
|
u32 strIndex = 0;
|
||||||
|
u32 numFound = 0;
|
||||||
|
for (u32 addr = Memory.MainMem.GetStartAddr(); addr < Memory.MainMem.GetEndAddr(); addr++) {
|
||||||
|
if (!Memory.IsGoodAddr(addr)) {
|
||||||
|
strIndex = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 byte = vm::read8(addr);
|
||||||
|
if (byte == str[strIndex]) {
|
||||||
|
if (strIndex == len) {
|
||||||
|
// Found it
|
||||||
|
LOG_NOTICE(GENERAL, "Found @ %04x", addr - len);
|
||||||
|
numFound++;
|
||||||
|
strIndex = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
strIndex++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strIndex = 0;
|
||||||
|
|
||||||
|
if (addr % (1024 * 1024 * 64) == 0) { // Log every 64mb
|
||||||
|
LOG_NOTICE(GENERAL, "Searching %04x ...", addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_NOTICE(GENERAL, "Search completed (found %d matches)", numFound);
|
||||||
|
}
|
19
rpcs3/Gui/MemoryStringSearcher.h
Normal file
19
rpcs3/Gui/MemoryStringSearcher.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
#include <wx/listctrl.h>
|
||||||
|
|
||||||
|
class MemoryStringSearcher : public wxFrame
|
||||||
|
{
|
||||||
|
wxTextCtrl* t_addr;
|
||||||
|
wxBoxSizer* s_panel;
|
||||||
|
wxButton* b_search;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool exit;
|
||||||
|
MemoryStringSearcher(wxWindow* parent);
|
||||||
|
~MemoryStringSearcher()
|
||||||
|
{
|
||||||
|
exit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Search(wxCommandEvent& event);
|
||||||
|
};
|
|
@ -104,9 +104,11 @@ public:
|
||||||
IniEntry<u8> GSRenderMode;
|
IniEntry<u8> GSRenderMode;
|
||||||
IniEntry<u8> GSResolution;
|
IniEntry<u8> GSResolution;
|
||||||
IniEntry<u8> GSAspectRatio;
|
IniEntry<u8> GSAspectRatio;
|
||||||
|
IniEntry<u8> GSFrameLimit;
|
||||||
IniEntry<bool> GSLogPrograms;
|
IniEntry<bool> GSLogPrograms;
|
||||||
IniEntry<bool> GSDumpColorBuffers;
|
IniEntry<bool> GSDumpColorBuffers;
|
||||||
IniEntry<bool> GSDumpDepthBuffer;
|
IniEntry<bool> GSDumpDepthBuffer;
|
||||||
|
IniEntry<bool> GSReadColorBuffer;
|
||||||
IniEntry<bool> GSVSyncEnable;
|
IniEntry<bool> GSVSyncEnable;
|
||||||
IniEntry<bool> GS3DTV;
|
IniEntry<bool> GS3DTV;
|
||||||
|
|
||||||
|
@ -179,9 +181,11 @@ public:
|
||||||
GSRenderMode.Init("GS_RenderMode", path);
|
GSRenderMode.Init("GS_RenderMode", path);
|
||||||
GSResolution.Init("GS_Resolution", path);
|
GSResolution.Init("GS_Resolution", path);
|
||||||
GSAspectRatio.Init("GS_AspectRatio", path);
|
GSAspectRatio.Init("GS_AspectRatio", path);
|
||||||
|
GSFrameLimit.Init("GS_FrameLimit", path);
|
||||||
GSLogPrograms.Init("GS_LogPrograms", path);
|
GSLogPrograms.Init("GS_LogPrograms", path);
|
||||||
GSDumpColorBuffers.Init("GS_DumpColorBuffers", path);
|
GSDumpColorBuffers.Init("GS_DumpColorBuffers", path);
|
||||||
GSDumpDepthBuffer.Init("GS_DumpDepthBuffer", path);
|
GSDumpDepthBuffer.Init("GS_DumpDepthBuffer", path);
|
||||||
|
GSReadColorBuffer.Init("GS_GSReadColorBuffer", path);
|
||||||
GSVSyncEnable.Init("GS_VSyncEnable", path);
|
GSVSyncEnable.Init("GS_VSyncEnable", path);
|
||||||
GS3DTV.Init("GS_3DTV", path);
|
GS3DTV.Init("GS_3DTV", path);
|
||||||
|
|
||||||
|
@ -250,9 +254,11 @@ public:
|
||||||
GSRenderMode.Load(1);
|
GSRenderMode.Load(1);
|
||||||
GSResolution.Load(4);
|
GSResolution.Load(4);
|
||||||
GSAspectRatio.Load(2);
|
GSAspectRatio.Load(2);
|
||||||
|
GSFrameLimit.Load(0);
|
||||||
GSLogPrograms.Load(false);
|
GSLogPrograms.Load(false);
|
||||||
GSDumpColorBuffers.Load(false);
|
GSDumpColorBuffers.Load(false);
|
||||||
GSDumpDepthBuffer.Load(false);
|
GSDumpDepthBuffer.Load(false);
|
||||||
|
GSReadColorBuffer.Load(false);
|
||||||
GSVSyncEnable.Load(false);
|
GSVSyncEnable.Load(false);
|
||||||
GS3DTV.Load(false);
|
GS3DTV.Load(false);
|
||||||
|
|
||||||
|
@ -322,9 +328,11 @@ public:
|
||||||
GSRenderMode.Save();
|
GSRenderMode.Save();
|
||||||
GSResolution.Save();
|
GSResolution.Save();
|
||||||
GSAspectRatio.Save();
|
GSAspectRatio.Save();
|
||||||
|
GSFrameLimit.Save();
|
||||||
GSLogPrograms.Save();
|
GSLogPrograms.Save();
|
||||||
GSDumpColorBuffers.Save();
|
GSDumpColorBuffers.Save();
|
||||||
GSDumpDepthBuffer.Save();
|
GSDumpDepthBuffer.Save();
|
||||||
|
GSReadColorBuffer.Save();
|
||||||
GSVSyncEnable.Save();
|
GSVSyncEnable.Save();
|
||||||
GS3DTV.Save();
|
GS3DTV.Save();
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace loader
|
||||||
{
|
{
|
||||||
m_shdrs.resize(m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum);
|
m_shdrs.resize(m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum);
|
||||||
m_stream->Seek(handler::get_stream_offset() + (m_ehdr.is_le() ? m_ehdr.data_le.e_shoff : m_ehdr.data_be.e_shoff));
|
m_stream->Seek(handler::get_stream_offset() + (m_ehdr.is_le() ? m_ehdr.data_le.e_shoff : m_ehdr.data_be.e_shoff));
|
||||||
size_t size = (m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum) * sizeof(phdr);
|
size_t size = (m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum) * sizeof(shdr);
|
||||||
|
|
||||||
if (m_stream->Read(m_shdrs.data(), size) != size)
|
if (m_stream->Read(m_shdrs.data(), size) != size)
|
||||||
return broken_file;
|
return broken_file;
|
||||||
|
|
|
@ -281,7 +281,6 @@
|
||||||
<ClInclude Include="..\Utilities\StrFmt.h" />
|
<ClInclude Include="..\Utilities\StrFmt.h" />
|
||||||
<ClInclude Include="..\Utilities\Thread.h" />
|
<ClInclude Include="..\Utilities\Thread.h" />
|
||||||
<ClInclude Include="..\Utilities\Timer.h" />
|
<ClInclude Include="..\Utilities\Timer.h" />
|
||||||
<ClInclude Include="cellMic.h" />
|
|
||||||
<ClInclude Include="Crypto\aes.h" />
|
<ClInclude Include="Crypto\aes.h" />
|
||||||
<ClInclude Include="Crypto\ec.h" />
|
<ClInclude Include="Crypto\ec.h" />
|
||||||
<ClInclude Include="Crypto\key_vault.h" />
|
<ClInclude Include="Crypto\key_vault.h" />
|
||||||
|
@ -419,8 +418,9 @@
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellGifDec.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellGifDec.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellJpgDec.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellJpgDec.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellL10n.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellL10n.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellNetCtl.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellMic.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h" />
|
||||||
|
<ClInclude Include="Emu\SysCalls\Modules\cellNetCtl.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellPad.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellPad.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellPamf.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellPamf.h" />
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellPng.h" />
|
<ClInclude Include="Emu\SysCalls\Modules\cellPng.h" />
|
||||||
|
|
|
@ -69,16 +69,16 @@
|
||||||
<Filter Include="Emu\CPU\ARMv7\Modules">
|
<Filter Include="Emu\CPU\ARMv7\Modules">
|
||||||
<UniqueIdentifier>{1d9e6fc4-9a79-4329-a8b5-081e24822aaa}</UniqueIdentifier>
|
<UniqueIdentifier>{1d9e6fc4-9a79-4329-a8b5-081e24822aaa}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="GPU">
|
<Filter Include="Emu\GPU">
|
||||||
<UniqueIdentifier>{6674e2ab-90cd-47de-a852-d21643ab18c2}</UniqueIdentifier>
|
<UniqueIdentifier>{6674e2ab-90cd-47de-a852-d21643ab18c2}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="GPU\RSX">
|
<Filter Include="Emu\GPU\RSX">
|
||||||
<UniqueIdentifier>{fadb4b36-57af-4583-891d-d22ff369e266}</UniqueIdentifier>
|
<UniqueIdentifier>{fadb4b36-57af-4583-891d-d22ff369e266}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="GPU\RSX\Null">
|
<Filter Include="Emu\GPU\RSX\Null">
|
||||||
<UniqueIdentifier>{4adca4fa-b90f-4662-9eb0-1d29cf3cd2eb}</UniqueIdentifier>
|
<UniqueIdentifier>{4adca4fa-b90f-4662-9eb0-1d29cf3cd2eb}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="GPU\RSX\GL">
|
<Filter Include="Emu\GPU\RSX\GL">
|
||||||
<UniqueIdentifier>{6f1da5b2-52c5-416b-9b5c-b9897bc1b300}</UniqueIdentifier>
|
<UniqueIdentifier>{6f1da5b2-52c5-416b-9b5c-b9897bc1b300}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -546,37 +546,37 @@
|
||||||
<Filter>Emu\SysCalls\Modules</Filter>
|
<Filter>Emu\SysCalls\Modules</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\GLProgram.cpp">
|
<ClCompile Include="Emu\RSX\GL\GLProgram.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\GLProgramBuffer.cpp">
|
<ClCompile Include="Emu\RSX\GL\GLProgramBuffer.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\GLVertexProgram.cpp">
|
<ClCompile Include="Emu\RSX\GL\GLVertexProgram.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\OpenGL.cpp">
|
<ClCompile Include="Emu\RSX\GL\OpenGL.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\GLBuffers.cpp">
|
<ClCompile Include="Emu\RSX\GL\GLBuffers.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\GLFragmentProgram.cpp">
|
<ClCompile Include="Emu\RSX\GL\GLFragmentProgram.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GL\GLGSRender.cpp">
|
<ClCompile Include="Emu\RSX\GL\GLGSRender.cpp">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GSManager.cpp">
|
<ClCompile Include="Emu\RSX\GSManager.cpp">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\GSRender.cpp">
|
<ClCompile Include="Emu\RSX\GSRender.cpp">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\RSXTexture.cpp">
|
<ClCompile Include="Emu\RSX\RSXTexture.cpp">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\RSX\RSXThread.cpp">
|
<ClCompile Include="Emu\RSX\RSXThread.cpp">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Emu\SysCalls\lv2\sys_event_flag.cpp">
|
<ClCompile Include="Emu\SysCalls\lv2\sys_event_flag.cpp">
|
||||||
<Filter>Emu\SysCalls\lv2</Filter>
|
<Filter>Emu\SysCalls\lv2</Filter>
|
||||||
|
@ -742,6 +742,9 @@
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellL10n.h">
|
<ClInclude Include="Emu\SysCalls\Modules\cellL10n.h">
|
||||||
<Filter>Emu\SysCalls\Modules</Filter>
|
<Filter>Emu\SysCalls\Modules</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Emu\SysCalls\Modules\cellMic.h">
|
||||||
|
<Filter>Emu\SysCalls\Modules</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\SysCalls\Modules\cellMouse.h">
|
<ClInclude Include="Emu\SysCalls\Modules\cellMouse.h">
|
||||||
<Filter>Emu\SysCalls\Modules</Filter>
|
<Filter>Emu\SysCalls\Modules</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -1112,58 +1115,58 @@
|
||||||
<Filter>Emu\SysCalls</Filter>
|
<Filter>Emu\SysCalls</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\Null\NullGSRender.h">
|
<ClInclude Include="Emu\RSX\Null\NullGSRender.h">
|
||||||
<Filter>GPU\RSX\Null</Filter>
|
<Filter>Emu\GPU\RSX\Null</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLGSRender.h">
|
<ClInclude Include="Emu\RSX\GL\GLGSRender.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLProcTable.h">
|
<ClInclude Include="Emu\RSX\GL\GLProcTable.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLProgram.h">
|
<ClInclude Include="Emu\RSX\GL\GLProgram.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLProgramBuffer.h">
|
<ClInclude Include="Emu\RSX\GL\GLProgramBuffer.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLShaderParam.h">
|
<ClInclude Include="Emu\RSX\GL\GLShaderParam.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLVertexProgram.h">
|
<ClInclude Include="Emu\RSX\GL\GLVertexProgram.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\OpenGL.h">
|
<ClInclude Include="Emu\RSX\GL\OpenGL.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLBuffers.h">
|
<ClInclude Include="Emu\RSX\GL\GLBuffers.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GL\GLFragmentProgram.h">
|
<ClInclude Include="Emu\RSX\GL\GLFragmentProgram.h">
|
||||||
<Filter>GPU\RSX\GL</Filter>
|
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GSManager.h">
|
<ClInclude Include="Emu\RSX\GSManager.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GSRender.h">
|
<ClInclude Include="Emu\RSX\GSRender.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\RSXFragmentProgram.h">
|
<ClInclude Include="Emu\RSX\RSXFragmentProgram.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\RSXTexture.h">
|
<ClInclude Include="Emu\RSX\RSXTexture.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\RSXThread.h">
|
<ClInclude Include="Emu\RSX\RSXThread.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\RSXVertexProgram.h">
|
<ClInclude Include="Emu\RSX\RSXVertexProgram.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\sysutil_video.h">
|
<ClInclude Include="Emu\RSX\sysutil_video.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\RSX\GCM.h">
|
<ClInclude Include="Emu\RSX\GCM.h">
|
||||||
<Filter>GPU\RSX</Filter>
|
<Filter>Emu\GPU\RSX</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\SysCalls\lv2\sys_event_flag.h">
|
<ClInclude Include="Emu\SysCalls\lv2\sys_event_flag.h">
|
||||||
<Filter>Emu\SysCalls\lv2</Filter>
|
<Filter>Emu\SysCalls\lv2</Filter>
|
||||||
|
@ -1240,9 +1243,6 @@
|
||||||
<ClInclude Include="Crypto\ec.h">
|
<ClInclude Include="Crypto\ec.h">
|
||||||
<Filter>Crypto</Filter>
|
<Filter>Crypto</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="cellMic.h">
|
|
||||||
<Filter>Emu\SysCalls\Modules</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Emu\Cell\PPULLVMRecompiler.h">
|
<ClInclude Include="Emu\Cell\PPULLVMRecompiler.h">
|
||||||
<Filter>Emu\CPU\Cell</Filter>
|
<Filter>Emu\CPU\Cell</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
161
rpcs3/rpcs3.cpp
161
rpcs3/rpcs3.cpp
|
@ -3,6 +3,7 @@
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "rpcs3.h"
|
#include "rpcs3.h"
|
||||||
#include "Ini.h"
|
#include "Ini.h"
|
||||||
|
#include "Utilities/Log.h"
|
||||||
#include "Gui/ConLogFrame.h"
|
#include "Gui/ConLogFrame.h"
|
||||||
#include "Emu/GameInfo.h"
|
#include "Emu/GameInfo.h"
|
||||||
|
|
||||||
|
@ -42,6 +43,163 @@ Rpcs3App* TheApp;
|
||||||
|
|
||||||
std::string simplify_path(const std::string& path, bool is_dir);
|
std::string simplify_path(const std::string& path, bool is_dir);
|
||||||
|
|
||||||
|
typedef be_t<uint> CGprofile;
|
||||||
|
typedef int CGbool;
|
||||||
|
typedef be_t<uint> CGresource;
|
||||||
|
typedef be_t<uint> CGenum;
|
||||||
|
typedef be_t<uint> CGtype;
|
||||||
|
|
||||||
|
typedef be_t<unsigned int> CgBinaryOffset;
|
||||||
|
typedef CgBinaryOffset CgBinaryEmbeddedConstantOffset;
|
||||||
|
typedef CgBinaryOffset CgBinaryFloatOffset;
|
||||||
|
typedef CgBinaryOffset CgBinaryStringOffset;
|
||||||
|
typedef CgBinaryOffset CgBinaryParameterOffset;
|
||||||
|
|
||||||
|
// a few typedefs
|
||||||
|
typedef struct CgBinaryParameter CgBinaryParameter;
|
||||||
|
typedef struct CgBinaryEmbeddedConstant CgBinaryEmbeddedConstant;
|
||||||
|
typedef struct CgBinaryVertexProgram CgBinaryVertexProgram;
|
||||||
|
typedef struct CgBinaryFragmentProgram CgBinaryFragmentProgram;
|
||||||
|
typedef struct CgBinaryProgram CgBinaryProgram;
|
||||||
|
|
||||||
|
// fragment programs have their constants embedded in the microcode
|
||||||
|
struct CgBinaryEmbeddedConstant
|
||||||
|
{
|
||||||
|
be_t<unsigned int> ucodeCount; // occurances
|
||||||
|
be_t<unsigned int> ucodeOffset[1]; // offsets that need to be patched follow
|
||||||
|
};
|
||||||
|
|
||||||
|
// describe a binary program parameter (CgParameter is opaque)
|
||||||
|
struct CgBinaryParameter
|
||||||
|
{
|
||||||
|
CGtype type; // cgGetParameterType()
|
||||||
|
CGresource res; // cgGetParameterResource()
|
||||||
|
CGenum var; // cgGetParameterVariability()
|
||||||
|
be_t<int> resIndex; // cgGetParameterResourceIndex()
|
||||||
|
CgBinaryStringOffset name; // cgGetParameterName()
|
||||||
|
CgBinaryFloatOffset defaultValue; // default constant value
|
||||||
|
CgBinaryEmbeddedConstantOffset embeddedConst; // embedded constant information
|
||||||
|
CgBinaryStringOffset semantic; // cgGetParameterSemantic()
|
||||||
|
CGenum direction; // cgGetParameterDirection()
|
||||||
|
be_t<int> paramno; // 0..n: cgGetParameterIndex() -1: globals
|
||||||
|
CGbool isReferenced; // cgIsParameterReferenced()
|
||||||
|
CGbool isShared; // cgIsParameterShared()
|
||||||
|
};
|
||||||
|
|
||||||
|
// attributes needed for vshaders
|
||||||
|
struct CgBinaryVertexProgram
|
||||||
|
{
|
||||||
|
be_t<unsigned int> instructionCount; // #instructions
|
||||||
|
be_t<unsigned int> instructionSlot; // load address (indexed reads!)
|
||||||
|
be_t<unsigned int> registerCount; // R registers count
|
||||||
|
be_t<unsigned int> attributeInputMask; // attributes vs reads from
|
||||||
|
be_t<unsigned int> attributeOutputMask; // attributes vs writes (uses SET_VERTEX_ATTRIB_OUTPUT_MASK bits)
|
||||||
|
be_t<unsigned int> userClipMask; // user clip plane enables (for SET_USER_CLIP_PLANE_CONTROL)
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CgBinaryPTTNone = 0,
|
||||||
|
CgBinaryPTT2x16 = 1,
|
||||||
|
CgBinaryPTT1x32 = 2,
|
||||||
|
} CgBinaryPartialTexType;
|
||||||
|
|
||||||
|
// attributes needed for pshaders
|
||||||
|
struct CgBinaryFragmentProgram
|
||||||
|
{
|
||||||
|
be_t<unsigned int> instructionCount; // #instructions
|
||||||
|
be_t<unsigned int> attributeInputMask; // attributes fp reads (uses SET_VERTEX_ATTRIB_OUTPUT_MASK bits)
|
||||||
|
be_t<unsigned int> partialTexType; // texid 0..15 use two bits each marking whether the texture format requires partial load: see CgBinaryPartialTexType
|
||||||
|
be_t<unsigned short> texCoordsInputMask; // tex coords used by frag prog. (tex<n> is bit n)
|
||||||
|
be_t<unsigned short> texCoords2D; // tex coords that are 2d (tex<n> is bit n)
|
||||||
|
be_t<unsigned short> texCoordsCentroid; // tex coords that are centroid (tex<n> is bit n)
|
||||||
|
unsigned char registerCount; // R registers count
|
||||||
|
unsigned char outputFromH0; // final color from R0 or H0
|
||||||
|
unsigned char depthReplace; // fp generated z epth value
|
||||||
|
unsigned char pixelKill; // fp uses kill operations
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "Emu/RSX/GL/GLFragmentProgram.h"
|
||||||
|
#include "Emu/RSX/GL/GLVertexProgram.h"
|
||||||
|
// defines a binary program -- *all* address/offsets are relative to the begining of CgBinaryProgram
|
||||||
|
struct CgBinaryProgram
|
||||||
|
{
|
||||||
|
// vertex/pixel shader identification (BE/LE as well)
|
||||||
|
CGprofile profile;
|
||||||
|
|
||||||
|
// binary revision (used to verify binary and driver structs match)
|
||||||
|
be_t<unsigned int> binaryFormatRevision;
|
||||||
|
|
||||||
|
// total size of this struct including profile and totalSize field!
|
||||||
|
be_t<unsigned int> totalSize;
|
||||||
|
|
||||||
|
// parameter usually queried using cgGet[First/Next]LeafParameter
|
||||||
|
be_t<unsigned int> parameterCount;
|
||||||
|
CgBinaryParameterOffset parameterArray;
|
||||||
|
|
||||||
|
// depending on profile points to a CgBinaryVertexProgram or CgBinaryFragmentProgram struct
|
||||||
|
CgBinaryOffset program;
|
||||||
|
|
||||||
|
// raw ucode data
|
||||||
|
be_t<unsigned int> ucodeSize;
|
||||||
|
CgBinaryOffset ucode;
|
||||||
|
|
||||||
|
// variable length data follows
|
||||||
|
unsigned char data[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
void compile_shader(std::string path)
|
||||||
|
{
|
||||||
|
ShaderVar var("r0.yz.x");
|
||||||
|
var.symplify();
|
||||||
|
LOG_ERROR(GENERAL, var.get().c_str());
|
||||||
|
|
||||||
|
u32 ptr;
|
||||||
|
{
|
||||||
|
wxFile f(path);
|
||||||
|
|
||||||
|
if (!f.IsOpened())
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t size = f.Length();
|
||||||
|
vm::ps3::init();
|
||||||
|
ptr = vm::alloc(size);
|
||||||
|
f.Read(vm::get_ptr(ptr), size);
|
||||||
|
f.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
CgBinaryProgram& prog = vm::get_ref<CgBinaryProgram>(ptr);
|
||||||
|
LOG_ERROR(GENERAL, "%d - %x", (u32)prog.profile, (u32)prog.binaryFormatRevision);
|
||||||
|
|
||||||
|
std::string shader;
|
||||||
|
GLParamArray param_array;
|
||||||
|
u32 size;
|
||||||
|
|
||||||
|
if (prog.profile == 7004)
|
||||||
|
{
|
||||||
|
CgBinaryFragmentProgram& fprog = vm::get_ref<CgBinaryFragmentProgram>(ptr + prog.program);
|
||||||
|
|
||||||
|
u32 ctrl = (fprog.outputFromH0 ? 0 : 0x40) | (fprog.depthReplace ? 0xe : 0);
|
||||||
|
|
||||||
|
GLFragmentDecompilerThread(shader, param_array, ptr + prog.ucode, size, ctrl).Task();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CgBinaryVertexProgram& vprog = vm::get_ref<CgBinaryVertexProgram>(ptr + prog.program);
|
||||||
|
|
||||||
|
std::vector<u32> data;
|
||||||
|
be_t<u32>* vdata = vm::get_ptr<be_t<u32>>(ptr + prog.ucode);
|
||||||
|
for (u32 i = 0; i < prog.ucodeSize; ++i, ++vdata)
|
||||||
|
{
|
||||||
|
data.push_back(vdata[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLVertexDecompilerThread(data, shader, param_array).Task();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERROR(GENERAL, shader.c_str());
|
||||||
|
vm::close();
|
||||||
|
}
|
||||||
|
|
||||||
bool Rpcs3App::OnInit()
|
bool Rpcs3App::OnInit()
|
||||||
{
|
{
|
||||||
SetSendDbgCommandCallback([](DbgCommand id, CPUThread* t)
|
SetSendDbgCommandCallback([](DbgCommand id, CPUThread* t)
|
||||||
|
@ -140,6 +298,9 @@ bool Rpcs3App::OnInit()
|
||||||
|
|
||||||
OnArguments();
|
OnArguments();
|
||||||
|
|
||||||
|
//compile_shader("compile_shader0.spo");
|
||||||
|
//compile_shader("compile_shader1.spo");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,7 @@
|
||||||
<ClCompile Include="Gui\KernelExplorer.cpp" />
|
<ClCompile Include="Gui\KernelExplorer.cpp" />
|
||||||
<ClCompile Include="Gui\LLEModulesManager.cpp" />
|
<ClCompile Include="Gui\LLEModulesManager.cpp" />
|
||||||
<ClCompile Include="Gui\MainFrame.cpp" />
|
<ClCompile Include="Gui\MainFrame.cpp" />
|
||||||
|
<ClCompile Include="Gui\MemoryStringSearcher.cpp" />
|
||||||
<ClCompile Include="Gui\MemoryViewer.cpp" />
|
<ClCompile Include="Gui\MemoryViewer.cpp" />
|
||||||
<ClCompile Include="Gui\MsgDialog.cpp" />
|
<ClCompile Include="Gui\MsgDialog.cpp" />
|
||||||
<ClCompile Include="Gui\PADManager.cpp" />
|
<ClCompile Include="Gui\PADManager.cpp" />
|
||||||
|
|
|
@ -93,6 +93,9 @@
|
||||||
<ClCompile Include="Gui\LLEModulesManager.cpp">
|
<ClCompile Include="Gui\LLEModulesManager.cpp">
|
||||||
<Filter>Gui</Filter>
|
<Filter>Gui</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Gui\MemoryStringSearcher.cpp">
|
||||||
|
<Filter>Gui</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue