This commit is contained in:
Nekotekina 2014-03-21 13:02:10 +04:00
commit cad7a05848
31 changed files with 1181 additions and 352 deletions

View file

@ -1418,6 +1418,10 @@ private:
{ {
DisAsm_V1_R2("stvewx", vs, ra, rb); DisAsm_V1_R2("stvewx", vs, ra, rb);
} }
void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc)
{
DisAsm_R2_OE_RC("subfze", rd, ra, oe, rc);
}
void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) void ADDZE(u32 rd, u32 ra, u32 oe, bool rc)
{ {
DisAsm_R2_OE_RC("addze", rd, ra, oe, rc); DisAsm_R2_OE_RC("addze", rd, ra, oe, rc);
@ -1434,6 +1438,10 @@ private:
{ {
DisAsm_V1_R2("stvx", vd, ra, rb); DisAsm_V1_R2("stvx", vd, ra, rb);
} }
void SUBFME(u32 rd, u32 ra, u32 oe, bool rc)
{
DisAsm_R2_OE_RC("subfme", rd, ra, oe, rc);
}
void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
{ {
DisAsm_R3_OE_RC("mulld", rd, ra, rb, oe, rc); DisAsm_R3_OE_RC("mulld", rd, ra, rb, oe, rc);
@ -1637,6 +1645,10 @@ private:
{ {
DisAsm_V1_R2("lvrx", vd, ra, rb); DisAsm_V1_R2("lvrx", vd, ra, rb);
} }
void LSWI(u32 rd, u32 ra, u32 nb)
{
DisAsm_R2_INT1("lswi", rd, ra, nb);
}
void LFSUX(u32 frd, u32 ra, u32 rb) void LFSUX(u32 frd, u32 ra, u32 rb)
{ {
DisAsm_F1_R2("lfsux", frd, ra, rb); DisAsm_F1_R2("lfsux", frd, ra, rb);
@ -1669,6 +1681,10 @@ private:
{ {
DisAsm_V1_R2("stvrx", sd, ra, rb); DisAsm_V1_R2("stvrx", sd, ra, rb);
} }
void STSWI(u32 rd, u32 ra, u32 nb)
{
DisAsm_R2_INT1("stswi", rd, ra, nb);
}
void STFDX(u32 frs, u32 ra, u32 rb) void STFDX(u32 frs, u32 ra, u32 rb)
{ {
DisAsm_F1_R2("stfdx", frs, ra, rb); DisAsm_F1_R2("stfdx", frs, ra, rb);

View file

@ -489,10 +489,12 @@ namespace PPU_instr
/*0x0b5*/bind_instr(g1f_list, STDUX, RS, RA, RB); /*0x0b5*/bind_instr(g1f_list, STDUX, RS, RA, RB);
/*0x0b7*/bind_instr(g1f_list, STWUX, RS, RA, RB); /*0x0b7*/bind_instr(g1f_list, STWUX, RS, RA, RB);
/*0x0c7*/bind_instr(g1f_list, STVEWX, VS, RA, RB); /*0x0c7*/bind_instr(g1f_list, STVEWX, VS, RA, RB);
/*0x0c8*/bind_instr(g1f_list, SUBFZE, RD, RA, OE, RC);
/*0x0ca*/bind_instr(g1f_list, ADDZE, RD, RA, OE, RC); /*0x0ca*/bind_instr(g1f_list, ADDZE, RD, RA, OE, RC);
/*0x0d6*/bind_instr(g1f_list, STDCX_, RS, RA, RB); /*0x0d6*/bind_instr(g1f_list, STDCX_, RS, RA, RB);
/*0x0d7*/bind_instr(g1f_list, STBX, RS, RA, RB); /*0x0d7*/bind_instr(g1f_list, STBX, RS, RA, RB);
/*0x0e7*/bind_instr(g1f_list, STVX, VS, RA, RB); /*0x0e7*/bind_instr(g1f_list, STVX, VS, RA, RB);
/*0x0e8*/bind_instr(g1f_list, SUBFME, RD, RA, OE, RC);
/*0x0e9*/bind_instr(g1f_list, MULLD, RD, RA, RB, OE, RC); /*0x0e9*/bind_instr(g1f_list, MULLD, RD, RA, RB, OE, RC);
/*0x0ea*/bind_instr(g1f_list, ADDME, RD, RA, OE, RC); /*0x0ea*/bind_instr(g1f_list, ADDME, RD, RA, OE, RC);
/*0x0eb*/bind_instr(g1f_list, MULLW, RD, RA, RB, OE, RC); /*0x0eb*/bind_instr(g1f_list, MULLW, RD, RA, RB, OE, RC);
@ -535,6 +537,7 @@ namespace PPU_instr
/*0x21b*/bind_instr(g1f_list, SRD, RA, RS, RB, RC); /*0x21b*/bind_instr(g1f_list, SRD, RA, RS, RB, RC);
/*0x227*/bind_instr(g1f_list, LVRX, VD, RA, RB); /*0x227*/bind_instr(g1f_list, LVRX, VD, RA, RB);
/*0x237*/bind_instr(g1f_list, LFSUX, FRD, RA, RB); /*0x237*/bind_instr(g1f_list, LFSUX, FRD, RA, RB);
/*0x255*/bind_instr(g1f_list, LSWI, RD, RA, NB);
/*0x256*/bind_instr(g1f_list, SYNC, L_9_10); /*0x256*/bind_instr(g1f_list, SYNC, L_9_10);
/*0x257*/bind_instr(g1f_list, LFDX, FRD, RA, RB); /*0x257*/bind_instr(g1f_list, LFDX, FRD, RA, RB);
/*0x277*/bind_instr(g1f_list, LFDUX, FRD, RA, RB); /*0x277*/bind_instr(g1f_list, LFDUX, FRD, RA, RB);
@ -542,6 +545,7 @@ namespace PPU_instr
/*0x296*/bind_instr(g1f_list, STWBRX, RS, RA, RB); /*0x296*/bind_instr(g1f_list, STWBRX, RS, RA, RB);
/*0x297*/bind_instr(g1f_list, STFSX, FRS, RA, RB); /*0x297*/bind_instr(g1f_list, STFSX, FRS, RA, RB);
/*0x2a7*/bind_instr(g1f_list, STVRX, VS, RA, RB); /*0x2a7*/bind_instr(g1f_list, STVRX, VS, RA, RB);
/*0x2d5*/bind_instr(g1f_list, STSWI, RD, RA, NB);
/*0x2d7*/bind_instr(g1f_list, STFDX, FRS, RA, RB); /*0x2d7*/bind_instr(g1f_list, STFDX, FRS, RA, RB);
/*0x307*/bind_instr(g1f_list, LVLXL, VD, RA, RB); /*0x307*/bind_instr(g1f_list, LVLXL, VD, RA, RB);
/*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB); /*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB);

View file

@ -2612,10 +2612,10 @@ private:
} }
void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
{ {
const s64 RA = CPU.GPR[ra]; const u64 RA = CPU.GPR[ra];
const s64 RB = CPU.GPR[rb]; const u64 RB = CPU.GPR[rb];
CPU.GPR[ra] = ~RA + RB + CPU.XER.CA; CPU.GPR[rd] = ~RA + RB + CPU.XER.CA;
CPU.XER.CA = ((u64)~RA + CPU.XER.CA > ~(u64)RB) | ((RA == 0) & CPU.XER.CA); CPU.XER.CA = (~RA + CPU.XER.CA > ~RB) | ((RA == 0) & CPU.XER.CA);
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
if(oe) UNK("subfeo"); if(oe) UNK("subfeo");
} }
@ -2734,6 +2734,14 @@ private:
if(oe) ConLog.Warning("addzeo"); if(oe) ConLog.Warning("addzeo");
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc)
{
const u64 RA = CPU.GPR[ra];
CPU.GPR[rd] = ~RA + CPU.XER.CA;
CPU.XER.CA = (~RA + CPU.XER.CA > ~0x0) | ((RA == 0) & CPU.XER.CA);
if (oe) ConLog.Warning("subfzeo");
if (rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void STDCX_(u32 rs, u32 ra, u32 rb) void STDCX_(u32 rs, u32 ra, u32 rb)
{ {
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
@ -2759,6 +2767,14 @@ private:
{ {
Memory.Write128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL, CPU.VPR[vs]._u128); Memory.Write128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL, CPU.VPR[vs]._u128);
} }
void SUBFME(u32 rd, u32 ra, u32 oe, bool rc)
{
const u64 RA = CPU.GPR[ra];
CPU.GPR[rd] = ~RA + CPU.XER.CA + 0xFFFFFFFFFFFFFFFF;
CPU.XER.CA = (~RA + CPU.XER.CA > ~0xFFFFFFFFFFFFFFFF) | ((RA == 0) & CPU.XER.CA);
if (oe) ConLog.Warning("subfmeo");
if (rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
{ {
CPU.GPR[rd] = (s64)((s64)CPU.GPR[ra] * (s64)CPU.GPR[rb]); CPU.GPR[rd] = (s64)((s64)CPU.GPR[ra] * (s64)CPU.GPR[rb]);
@ -3030,6 +3046,34 @@ private:
Memory.ReadRight(CPU.VPR[vd]._u8, addr & ~0xf, eb); Memory.ReadRight(CPU.VPR[vd]._u8, addr & ~0xf, eb);
} }
void LSWI(u32 rd, u32 ra, u32 nb)
{
u64 EA = ra ? CPU.GPR[ra] : 0;
u64 N = nb ? nb : 32;
u8 reg = CPU.GPR[rd];
while (N > 0)
{
if (N > 3)
{
CPU.GPR[reg] = Memory.Read32(EA);
EA += 4;
N -= 4;
}
else
{
u32 buf = 0;
while (N > 0)
{
N = N - 1;
buf |= Memory.Read8(EA) <<(N*8) ;
EA = EA + 1;
}
CPU.GPR[reg] = buf;
}
reg = (reg + 1) % 32;
}
}
void LFSUX(u32 frd, u32 ra, u32 rb) void LFSUX(u32 frd, u32 ra, u32 rb)
{ {
const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; const u64 addr = CPU.GPR[ra] + CPU.GPR[rb];
@ -3073,6 +3117,34 @@ private:
Memory.WriteRight(addr - eb, eb, CPU.VPR[vs]._u8); Memory.WriteRight(addr - eb, eb, CPU.VPR[vs]._u8);
} }
void STSWI(u32 rd, u32 ra, u32 nb)
{
u64 EA = ra ? CPU.GPR[ra] : 0;
u64 N = nb ? nb : 32;
u8 reg = CPU.GPR[rd];
while (N > 0)
{
if (N > 3)
{
Memory.Write32(EA, CPU.GPR[reg]);
EA += 4;
N -= 4;
}
else
{
u32 buf = CPU.GPR[reg];
while (N > 0)
{
N = N - 1;
Memory.Write8(EA, (0xFF000000 & buf) >> 24);
buf <<= 8;
EA = EA + 1;
}
}
reg = (reg + 1) % 32;
}
}
void STFDX(u32 frs, u32 ra, u32 rb) void STFDX(u32 frs, u32 ra, u32 rb)
{ {
Memory.Write64((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), (u64&)CPU.FPR[frs]); Memory.Write64((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), (u64&)CPU.FPR[frs]);

View file

@ -301,11 +301,13 @@ namespace PPU_opcodes
STDUX = 0x0b5, STDUX = 0x0b5,
STWUX = 0x0b7, STWUX = 0x0b7,
STVEWX = 0x0c7, //Store Vector Element Word Indexed STVEWX = 0x0c7, //Store Vector Element Word Indexed
ADDZE = 0x0ca, SUBFZE = 0x0c8,
ADDZE = 0x0ca,
STDCX_ = 0x0d6, STDCX_ = 0x0d6,
STBX = 0x0d7, STBX = 0x0d7,
STVX = 0x0e7, STVX = 0x0e7,
MULLD = 0x0e9, SUBFME = 0x0e8,
MULLD = 0x0e9,
ADDME = 0x0ea, ADDME = 0x0ea,
MULLW = 0x0eb, MULLW = 0x0eb,
DCBTST = 0x0f6, DCBTST = 0x0f6,
@ -347,7 +349,8 @@ namespace PPU_opcodes
SRW = 0x218, SRW = 0x218,
SRD = 0x21b, SRD = 0x21b,
LVRX = 0x227, //Load Vector Right Indexed LVRX = 0x227, //Load Vector Right Indexed
LFSUX = 0x237, LFSUX = 0x237,
LSWI = 0x255,
SYNC = 0x256, SYNC = 0x256,
LFDX = 0x257, LFDX = 0x257,
LFDUX = 0x277, LFDUX = 0x277,
@ -355,6 +358,7 @@ namespace PPU_opcodes
STWBRX = 0x296, STWBRX = 0x296,
STFSX = 0x297, STFSX = 0x297,
STVRX = 0x2a7, //Store Vector Right Indexed STVRX = 0x2a7, //Store Vector Right Indexed
STSWI = 0x2d5,
STFDX = 0x2d7, //Store Floating-Point Double Indexed STFDX = 0x2d7, //Store Floating-Point Double Indexed
LVLXL = 0x307, //Load Vector Left Indexed Last LVLXL = 0x307, //Load Vector Left Indexed Last
LHBRX = 0x316, LHBRX = 0x316,
@ -693,11 +697,13 @@ public:
virtual void STDUX(u32 rs, u32 ra, u32 rb) = 0; virtual void STDUX(u32 rs, u32 ra, u32 rb) = 0;
virtual void STWUX(u32 rs, u32 ra, u32 rb) = 0; virtual void STWUX(u32 rs, u32 ra, u32 rb) = 0;
virtual void STVEWX(u32 vs, u32 ra, u32 rb) = 0; virtual void STVEWX(u32 vs, u32 ra, u32 rb) = 0;
virtual void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) = 0;
virtual void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) = 0; virtual void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) = 0;
virtual void STDCX_(u32 rs, u32 ra, u32 rb) = 0; virtual void STDCX_(u32 rs, u32 ra, u32 rb) = 0;
virtual void STBX(u32 rs, u32 ra, u32 rb) = 0; virtual void STBX(u32 rs, u32 ra, u32 rb) = 0;
virtual void STVX(u32 vs, u32 ra, u32 rb) = 0; virtual void STVX(u32 vs, u32 ra, u32 rb) = 0;
virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) = 0;
virtual void ADDME(u32 rd, u32 ra, u32 oe, bool rc) = 0; virtual void ADDME(u32 rd, u32 ra, u32 oe, bool rc) = 0;
virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void DCBTST(u32 th, u32 ra, u32 rb) = 0; virtual void DCBTST(u32 th, u32 ra, u32 rb) = 0;
@ -738,6 +744,7 @@ public:
virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) = 0; virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) = 0;
virtual void SRD(u32 ra, u32 rs, u32 rb, bool rc) = 0; virtual void SRD(u32 ra, u32 rs, u32 rb, bool rc) = 0;
virtual void LVRX(u32 vd, u32 ra, u32 rb) = 0; virtual void LVRX(u32 vd, u32 ra, u32 rb) = 0;
virtual void LSWI(u32 rd, u32 ra, u32 nb) = 0;
virtual void LFSUX(u32 frd, u32 ra, u32 rb) = 0; virtual void LFSUX(u32 frd, u32 ra, u32 rb) = 0;
virtual void SYNC(u32 l) = 0; virtual void SYNC(u32 l) = 0;
virtual void LFDX(u32 frd, u32 ra, u32 rb) = 0; virtual void LFDX(u32 frd, u32 ra, u32 rb) = 0;
@ -746,6 +753,7 @@ public:
virtual void STWBRX(u32 rs, u32 ra, u32 rb) = 0; virtual void STWBRX(u32 rs, u32 ra, u32 rb) = 0;
virtual void STFSX(u32 frs, u32 ra, u32 rb) = 0; virtual void STFSX(u32 frs, u32 ra, u32 rb) = 0;
virtual void STVRX(u32 vs, u32 ra, u32 rb) = 0; virtual void STVRX(u32 vs, u32 ra, u32 rb) = 0;
virtual void STSWI(u32 rd, u32 ra, u32 nb) = 0;
virtual void STFDX(u32 frs, u32 ra, u32 rb) = 0; virtual void STFDX(u32 frs, u32 ra, u32 rb) = 0;
virtual void LVLXL(u32 vd, u32 ra, u32 rb) = 0; virtual void LVLXL(u32 vd, u32 ra, u32 rb) = 0;
virtual void LHBRX(u32 rd, u32 ra, u32 rb) = 0; virtual void LHBRX(u32 rd, u32 ra, u32 rb) = 0;

View file

@ -226,7 +226,6 @@ vfsDevice* VFS::GetDevice(const wxString& ps3_path, wxString& path) const
} }
if(max_i < 0) return nullptr; if(max_i < 0) return nullptr;
path = vfsDevice::GetWinPath(m_devices[max_i].GetLocalPath(), ps3_path(max_eq, ps3_path.Len() - max_eq)); path = vfsDevice::GetWinPath(m_devices[max_i].GetLocalPath(), ps3_path(max_eq, ps3_path.Len() - max_eq));
return &m_devices[max_i]; return &m_devices[max_i];
} }
@ -303,27 +302,27 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
{ {
int idx; int idx;
idx = res.Move(new VFSManagerEntry()); idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_hdd0\\"; res[idx].path = "$(EmulatorDir)/dev_hdd0/";
res[idx].mount = "/dev_hdd0/"; res[idx].mount = "/dev_hdd0/";
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry()); idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_hdd1\\"; res[idx].path = "$(EmulatorDir)/dev_hdd1/";
res[idx].mount = "/dev_hdd1/"; res[idx].mount = "/dev_hdd1/";
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry()); idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_flash\\"; res[idx].path = "$(EmulatorDir)/dev_flash/";
res[idx].mount = "/dev_flash/"; res[idx].mount = "/dev_flash/";
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry()); idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_usb000\\"; res[idx].path = "$(EmulatorDir)/dev_usb000/";
res[idx].mount = "/dev_usb000/"; res[idx].mount = "/dev_usb000/";
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry()); idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_usb000\\"; res[idx].path = "$(EmulatorDir)/dev_usb000/";
res[idx].mount = "/dev_usb/"; res[idx].mount = "/dev_usb/";
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;
@ -333,7 +332,7 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry()); idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)\\..\\"; res[idx].path = "$(GameDir)/../";
res[idx].mount = "/dev_bdvd/"; res[idx].mount = "/dev_bdvd/";
res[idx].device = vfsDevice_LocalFile; res[idx].device = vfsDevice_LocalFile;

View file

@ -48,8 +48,8 @@ u32 vfsDevice::CmpLocalPath(const wxString& local_path)
wxFileName path0(m_local_path); wxFileName path0(m_local_path);
path0.Normalize(); path0.Normalize();
wxArrayString arr0 = wxSplit(path0.GetFullPath(), '\\'); wxArrayString arr0 = wxSplit(path0.GetFullPath(), '/');
wxArrayString arr1 = wxSplit(local_path, '\\'); wxArrayString arr1 = wxSplit(local_path, '/');
const u32 lim = min(arr0.GetCount(), arr1.GetCount()); const u32 lim = min(arr0.GetCount(), arr1.GetCount());
u32 ret = 0; u32 ret = 0;
@ -168,7 +168,7 @@ wxString vfsDevice::GetWinPath(const wxString& p, bool is_dir)
{ {
if(!is_ls) if(!is_ls)
{ {
ret += '\\'; ret += '/';
is_ls = true; is_ls = true;
} }
@ -179,7 +179,7 @@ wxString vfsDevice::GetWinPath(const wxString& p, bool is_dir)
ret += p[i]; ret += p[i];
} }
if(is_dir && ret[ret.Len() - 1] != '\\') ret += '\\'; if(is_dir && ret[ret.Len() - 1] != '/') ret += '/';
wxFileName res(ret); wxFileName res(ret);
res.Normalize(); res.Normalize();
@ -191,7 +191,7 @@ wxString vfsDevice::GetWinPath(const wxString& l, const wxString& r)
if(l.IsEmpty()) return GetWinPath(r, false); if(l.IsEmpty()) return GetWinPath(r, false);
if(r.IsEmpty()) return GetWinPath(l); if(r.IsEmpty()) return GetWinPath(l);
return GetWinPath(l + '\\' + r, false); return GetWinPath(l + '/' + r, false);
} }
wxString vfsDevice::GetPs3Path(const wxString& p, bool is_dir) wxString vfsDevice::GetPs3Path(const wxString& p, bool is_dir)

View file

@ -56,7 +56,7 @@ bool vfsLocalFile::Create(const wxString& path)
for(uint p=1; p < path.Len() && path[p] != '\0' ; p++) for(uint p=1; p < path.Len() && path[p] != '\0' ; p++)
{ {
for(; p < path.Len() && path[p] != '\0'; p++) for(; p < path.Len() && path[p] != '\0'; p++)
if(path[p] == '\\') break; if(path[p] == '/') break;
if(p == path.Len() || path[p] == '\0') if(p == path.Len() || path[p] == '\0')
break; break;
@ -70,7 +70,7 @@ bool vfsLocalFile::Create(const wxString& path)
} }
//create file //create file
if(path(path.Len() - 1, 1) != '\\' && !wxFileExists(path)) if(path(path.Len() - 1, 1) != '/' && !wxFileExists(path))
{ {
wxFile f; wxFile f;
return f.Create(path); return f.Create(path);

View file

@ -302,7 +302,7 @@ public:
void Save(RSXTexture& tex) void Save(RSXTexture& tex)
{ {
static const wxString& dir_path = "textures"; static const wxString& dir_path = "textures";
static const wxString& file_fmt = dir_path + "\\" + "tex[%d].png"; static const wxString& file_fmt = dir_path + "/" + "tex[%d].png";
if(!wxDirExists(dir_path)) wxMkdir(dir_path); if(!wxDirExists(dir_path)) wxMkdir(dir_path);

View file

@ -38,6 +38,9 @@ void RSXTexture::Init()
// Image Rect // Image Rect
methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)] = (/*height*/1) | ((/*width*/1) << 16); methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)] = (/*height*/1) | ((/*width*/1) << 16);
// Border Color
methodRegisters[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index*32)] = 0;
} }
u32 RSXTexture::GetOffset() const u32 RSXTexture::GetOffset() const
@ -195,6 +198,11 @@ u16 RSXTexture::GetHeight() const
return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)]) & 0xffff); return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)]) & 0xffff);
} }
u32 RSXTexture::GetBorderColor() const
{
return methodRegisters[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index*32)];
}
void RSXTexture::SetControl3(u16 depth, u32 pitch) void RSXTexture::SetControl3(u16 depth, u32 pitch)
{ {
m_depth = depth; m_depth = depth;

View file

@ -58,5 +58,8 @@ public:
u16 GetWidth() const; u16 GetWidth() const;
u16 GetHeight() const; u16 GetHeight() const;
// Border Color
u32 GetBorderColor() const;
void SetControl3(u16 depth, u32 pitch); void SetControl3(u16 depth, u32 pitch);
}; };

View file

@ -322,6 +322,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
} }
break; break;
case_16(NV4097_SET_TEXTURE_BORDER_COLOR,0x20):
{
}
case NV4097_SET_SURFACE_FORMAT: case NV4097_SET_SURFACE_FORMAT:
{ {
u32 a0 = ARGS(0); u32 a0 = ARGS(0);

View file

@ -695,7 +695,7 @@ public:
do do
{ {
if(s[pos] == '\\' || s[pos] == '\0') if(s[pos] == '/' || s[pos] == '\0')
{ {
if(file_pos != -1) if(file_pos != -1)
{ {

View file

@ -459,6 +459,9 @@ void cellFontRenderSurfaceInit(mem_ptr_t<CellFontRenderSurface> surface, u32 buf
surface->pixelSizeByte = pixelSizeByte; surface->pixelSizeByte = pixelSizeByte;
surface->width = w; surface->width = w;
surface->height = h; surface->height = h;
if (!buffer_addr)
surface->buffer_addr = Memory.Alloc(bufferWidthByte * h, 1); // TODO: Huge memory leak
} }
void cellFontRenderSurfaceSetScissor(mem_ptr_t<CellFontRenderSurface> surface, s32 x0, s32 y0, s32 w, s32 h) void cellFontRenderSurfaceSetScissor(mem_ptr_t<CellFontRenderSurface> surface, s32 x0, s32 y0, s32 w, s32 h)

View file

@ -116,14 +116,10 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameConten
type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr()); type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr());
if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood()) if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood())
{
cellGame.Warning("cellGameBootCheck returns CELL_GAME_ERROR_PARAM. As a result size->hddFreeSizeKB may be 0.");
return CELL_GAME_ERROR_PARAM; return CELL_GAME_ERROR_PARAM;
}
// TODO: Locate the PARAM.SFO. The following path may be wrong.
vfsFile f("/app_home/PARAM.SFO");
PSFLoader psf(f);
if(!psf.Load(false))
return CELL_GAME_ERROR_FAILURE;
wxString dir = psf.m_info.serial(0,4) + psf.m_info.serial(5,5);
// TODO: Only works for HDD games // TODO: Only works for HDD games
type = CELL_GAME_GAMETYPE_HDD; type = CELL_GAME_GAMETYPE_HDD;
@ -131,6 +127,13 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameConten
size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
size->sysSizeKB = 0; size->sysSizeKB = 0;
// TODO: Locate the PARAM.SFO. The following path may be wrong.
vfsFile f("/app_home/PARAM.SFO");
PSFLoader psf(f);
if(!psf.Load(false))
return CELL_GAME_ERROR_FAILURE;
wxString dir = psf.m_info.serial(0,4) + psf.m_info.serial(5,5);
Memory.WriteString(dirName.GetAddr(), dir); Memory.WriteString(dirName.GetAddr(), dir);
return CELL_OK; return CELL_OK;

View file

@ -2,6 +2,7 @@
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/SC_FUNC.h"
// TODO: Is this really a module? Or is everything part of cellSysutil?
void cellSaveData_init(); void cellSaveData_init();
Module cellSaveData("cellSaveData", cellSaveData_init); Module cellSaveData("cellSaveData", cellSaveData_init);
@ -21,206 +22,227 @@ enum
CELL_SAVEDATA_ERROR_NOUSER, CELL_SAVEDATA_ERROR_NOUSER,
}; };
// Constants
enum
{
// CellSaveDataParamSize
CELL_SAVEDATA_DIRNAME_SIZE = 32,
CELL_SAVEDATA_FILENAME_SIZE = 13,
CELL_SAVEDATA_SECUREFILEID_SIZE = 16,
CELL_SAVEDATA_PREFIX_SIZE = 256,
CELL_SAVEDATA_LISTITEM_MAX = 2048,
CELL_SAVEDATA_SECUREFILE_MAX = 113,
CELL_SAVEDATA_DIRLIST_MAX = 2048,
CELL_SAVEDATA_INVALIDMSG_MAX = 256,
CELL_SAVEDATA_INDICATORMSG_MAX = 64,
// CellSaveDataSystemParamSize
CELL_SAVEDATA_SYSP_TITLE_SIZE = 128,
CELL_SAVEDATA_SYSP_SUBTITLE_SIZE = 128,
CELL_SAVEDATA_SYSP_DETAIL_SIZE = 1024,
CELL_SAVEDATA_SYSP_LPARAM_SIZE = 8,
};
// Datatypes // Datatypes
struct CellSaveDataSetList struct CellSaveDataSetList
{ {
unsigned int sortType; be_t<u32> sortType;
unsigned int sortOrder; be_t<u32> sortOrder;
char *dirNamePrefix; be_t<u32> dirNamePrefix_addr; // char*
}; };
struct CellSaveDataSetBuf struct CellSaveDataSetBuf
{ {
unsigned int dirListMax; be_t<u32> dirListMax;
unsigned int fileListMax; be_t<u32> fileListMax;
unsigned int reserved[6]; be_t<u32> reserved[6];
unsigned int bufSize; be_t<u32> bufSize;
void *buf; be_t<u32> buf_addr; // void*
}; };
struct CellSaveDataNewDataIcon struct CellSaveDataNewDataIcon
{ {
char *title; be_t<u32> title_addr; // char*
unsigned int iconBufSize; be_t<u32> iconBufSize;
void *iconBuf; be_t<u32> iconBuf_addr; // void*
}; };
struct CellSaveDataListNewData struct CellSaveDataListNewData
{ {
unsigned int iconPosition; be_t<u32> iconPosition;
char *dirName; be_t<u32> dirName_addr; // char*
CellSaveDataNewDataIcon *icon; be_t<u32> icon_addr; // CellSaveDataNewDataIcon*
}; };
struct CellSaveDataDirList struct CellSaveDataDirList
{ {
char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE]; s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE];
char listParam; //[CELL_SAVEDATA_SYSP_LPARAM_SIZE]; s8 listParam[CELL_SAVEDATA_SYSP_LPARAM_SIZE];
}; };
struct CellSaveDataListGet struct CellSaveDataListGet
{ {
unsigned int dirNum; be_t<u32> dirNum;
unsigned int dirListNum; be_t<u32> dirListNum;
CellSaveDataDirList *dirList; be_t<u32> dirList_addr; // CellSaveDataDirList*
}; };
struct CellSaveDataListSet struct CellSaveDataListSet
{ {
unsigned int focusPosition; be_t<u32> focusPosition;
char *focusDirName; be_t<u32> focusDirName_addr; // char*
unsigned int fixedListNum; be_t<u32> fixedListNum;
CellSaveDataDirList *fixedList; be_t<u32> fixedList_addr; // CellSaveDataDirList*
CellSaveDataListNewData *newData; be_t<u32> newData_addr; // CellSaveDataListNewData*
}; };
struct CellSaveDataFixedSet struct CellSaveDataFixedSet
{ {
char *dirName; be_t<u32> dirName_addr; // char*
CellSaveDataNewDataIcon *newIcon; be_t<u32> newIcon_addr; // CellSaveDataNewDataIcon*
unsigned int option; be_t<u32> option;
}; };
struct CellSaveDataSystemFileParam struct CellSaveDataSystemFileParam
{ {
char title; //[CELL_SAVEDATA_SYSP_TITLE_SIZE]; s8 title[CELL_SAVEDATA_SYSP_TITLE_SIZE];
char subTitle; //[CELL_SAVEDATA_SYSP_SUBTITLE_SIZE]; s8 subTitle[CELL_SAVEDATA_SYSP_SUBTITLE_SIZE];
char detail; //[CELL_SAVEDATA_SYSP_DETAIL_SIZE]; s8 detail[CELL_SAVEDATA_SYSP_DETAIL_SIZE];
unsigned int attribute; be_t<u32> attribute;
char reserved2[4]; s8 reserved2[4];
char listParam; //[CELL_SAVEDATA_SYSP_LPARAM_SIZE]; s8 listParam[CELL_SAVEDATA_SYSP_LPARAM_SIZE];
char reserved[256]; s8 reserved[256];
}; };
struct CellSaveDataDirStat struct CellSaveDataDirStat
{ {
s64 st_atime_; be_t<s64> st_atime_;
s64 st_mtime_; be_t<s64> st_mtime_;
s64 st_ctime_; be_t<s64> st_ctime_;
char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE]; s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE];
}; };
struct CellSaveDataFileStat struct CellSaveDataFileStat
{ {
unsigned int fileType; be_t<u32> fileType;
char reserved1[4]; u8 reserved1[4];
u64 st_size; be_t<u64> st_size;
s64 st_atime_; be_t<s64> st_atime_;
s64 st_mtime_; be_t<s64> st_mtime_;
s64 st_ctime_; be_t<s64> st_ctime_;
char fileName; //[CELL_SAVEDATA_FILENAME_SIZE]; u8 fileName[CELL_SAVEDATA_FILENAME_SIZE];
char reserved2[3]; u8 reserved2[3];
}; };
struct CellSaveDataStatGet struct CellSaveDataStatGet
{ {
int hddFreeSizeKB; be_t<s32> hddFreeSizeKB;
unsigned int isNewData; be_t<u32> isNewData;
CellSaveDataDirStat dir; CellSaveDataDirStat dir;
CellSaveDataSystemFileParam getParam; CellSaveDataSystemFileParam getParam;
unsigned int bind; be_t<u32> bind;
int sizeKB; be_t<s32> sizeKB;
int sysSizeKB; be_t<s32> sysSizeKB;
unsigned int fileNum; be_t<u32> fileNum;
unsigned int fileListNum; be_t<u32> fileListNum;
CellSaveDataFileStat *fileList; be_t<u32> fileList_addr; // CellSaveDataFileStat*
}; };
struct CellSaveDataAutoIndicator struct CellSaveDataAutoIndicator
{ {
unsigned int dispPosition; be_t<u32> dispPosition;
unsigned int dispMode; be_t<u32> dispMode;
char *dispMsg; be_t<u32> dispMsg_addr; // char*
unsigned int picBufSize; be_t<u32> picBufSize;
void *picBuf; be_t<u32> picBuf_addr; // void*
}; };
struct CellSaveDataStatSet struct CellSaveDataStatSet
{ {
CellSaveDataSystemFileParam *setParam; be_t<u32> setParam_addr; // CellSaveDataSystemFileParam*
unsigned int reCreateMode; be_t<u32> reCreateMode;
CellSaveDataAutoIndicator *indicator; be_t<u32> indicator_addr; // CellSaveDataAutoIndicator*
}; };
struct CellSaveDataFileGet struct CellSaveDataFileGet
{ {
unsigned int excSize; be_t<u32> excSize;
}; };
struct CellSaveDataFileSet struct CellSaveDataFileSet
{ {
unsigned int fileOperation; be_t<u32> fileOperation;
void *reserved; be_t<u32> reserved_addr; // void*
unsigned int fileType; be_t<u32> fileType;
unsigned char secureFileId; //[CELL_SAVEDATA_SECUREFILEID_SIZE]; u8 secureFileId[CELL_SAVEDATA_SECUREFILEID_SIZE];
char *fileName; be_t<u32> fileName_addr; // char*
unsigned int fileOffset; be_t<u32> fileOffset;
unsigned int fileSize; be_t<u32> fileSize;
unsigned int fileBufSize; be_t<u32> fileBufSize;
void *fileBuf; be_t<u32> fileBuf_addr; // void*
}; };
struct CellSaveDataCBResult struct CellSaveDataCBResult
{ {
int result; be_t<s32> result;
unsigned int progressBarInc; be_t<u32> progressBarInc;
int errNeedSizeKB; be_t<s32> errNeedSizeKB;
char *invalidMsg; be_t<u32> invalidMsg_addr; // char*
void *userdata; be_t<u32> userdata_addr; // void*
}; };
struct CellSaveDataDoneGet struct CellSaveDataDoneGet
{ {
int excResult; be_t<s32> excResult;
char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE]; s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE];
int sizeKB; be_t<s32> sizeKB;
int hddFreeSizeKB; be_t<s32> hddFreeSizeKB;
}; };
// Functions // Functions
int cellSaveDataListSave2() //unsigned int version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataListSave2() //u32 version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataListLoad2() //unsigned int version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataListLoad2() //u32 version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataFixedSave2() //unsigned int version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile,sys_memory_container_t container, void *userdata int cellSaveDataFixedSave2() //u32 version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile,sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataFixedLoad2() //unsigned int version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataFixedLoad2() //u32 version, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataAutoSave2() //unsigned int version, const char *dirName, unsigned int errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataAutoSave2() //u32 version, const char *dirName, u32 errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataAutoLoad2() //unsigned int version, const char *dirName, unsigned int errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataAutoLoad2() //u32 version, const char *dirName, u32 errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataListAutoSave() //unsigned int version, unsigned int errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile,sys_memory_container_t container, void *userdata int cellSaveDataListAutoSave() //u32 version, u32 errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile,sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataListAutoLoad() //unsigned int version, unsigned int errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataListAutoLoad() //u32 version, u32 errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
@ -238,49 +260,49 @@ int cellSaveDataFixedDelete() //CellSaveDataSetList *setList, CellSaveDataSetBuf
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserListSave() //unsigned int version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserListSave() //u32 version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserListLoad() //unsigned int version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserListLoad() //u32 version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataListCallback funcList, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserFixedSave() //unsigned int version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserFixedSave() //u32 version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserFixedLoad() //unsigned int version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserFixedLoad() //u32 version, CellSysutilUserId userId, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserAutoSave() //unsigned int version, CellSysutilUserId userId, const char *dirName, unsigned int errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserAutoSave() //u32 version, CellSysutilUserId userId, const char *dirName, u32 errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserAutoLoad() //unsigned int version, CellSysutilUserId userId, const char *dirName, unsigned int errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserAutoLoad() //u32 version, CellSysutilUserId userId, const char *dirName, u32 errDialog, CellSaveDataSetBuf *setBuf, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserListAutoSave() //unsigned int version, CellSysutilUserId userId, unsigned int errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserListAutoSave() //u32 version, CellSysutilUserId userId, u32 errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserListAutoLoad() //unsigned int version, CellSysutilUserId userId, unsigned int errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata int cellSaveDataUserListAutoLoad() //u32 version, CellSysutilUserId userId, u32 errDialog, CellSaveDataSetList *setList, CellSaveDataSetBuf *setBuf, CellSaveDataFixedCallback funcFixed, CellSaveDataStatCallback funcStat, CellSaveDataFileCallback funcFile, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
@ -302,31 +324,31 @@ int cellSaveDataListDelete() //CellSaveDataSetList *setList, CellSaveDataSetBuf
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataListImport() //CellSaveDataSetList *setList, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataListImport() //CellSaveDataSetList *setList, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataListExport() //CellSaveDataSetList *setList, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataListExport() //CellSaveDataSetList *setList, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataFixedImport() //const char *dirName, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataFixedImport() //const char *dirName, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataFixedExport() //const char *dirName, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataFixedExport() //const char *dirName, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataGetListItem() //const char *dirName, CellSaveDataDirStat *dir, CellSaveDataSystemFileParam *sysFileParam, unsigned int *bind, int *sizeKB int cellSaveDataGetListItem() //const char *dirName, CellSaveDataDirStat *dir, CellSaveDataSystemFileParam *sysFileParam, mem32_t bind, mem32_t sizeKB
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
@ -338,31 +360,31 @@ int cellSaveDataUserListDelete() //CellSysutilUserId userId, CellSaveDataSetList
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserListImport() //CellSysutilUserId userId, CellSaveDataSetList *setList, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataUserListImport() //CellSysutilUserId userId, CellSaveDataSetList *setList, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserListExport() //CellSysutilUserId userId, CellSaveDataSetList *setList, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataUserListExport() //CellSysutilUserId userId, CellSaveDataSetList *setList, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserFixedImport() //CellSysutilUserId userId, const char *dirName, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataUserFixedImport() //CellSysutilUserId userId, const char *dirName, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserFixedExport() //CellSysutilUserId userId, const char *dirName, unsigned int maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata int cellSaveDataUserFixedExport() //CellSysutilUserId userId, const char *dirName, u32 maxSizeKB, CellSaveDataDoneCallback funcDone, sys_memory_container_t container, void *userdata
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;
} }
int cellSaveDataUserGetListItem() //CellSysutilUserId userId, const char *dirName, CellSaveDataDirStat *dir, CellSaveDataSystemFileParam *sysFileParam, unsigned int *bind, int *sizeKB int cellSaveDataUserGetListItem() //CellSysutilUserId userId, const char *dirName, CellSaveDataDirStat *dir, CellSaveDataSystemFileParam *sysFileParam, mem32_t bind, mem32_t sizeKB
{ {
UNIMPLEMENTED_FUNC(cellSaveData); UNIMPLEMENTED_FUNC(cellSaveData);
return CELL_SAVEDATA_RET_OK; return CELL_SAVEDATA_RET_OK;

View file

@ -3,147 +3,13 @@
#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/SC_FUNC.h"
#include "Emu/Audio/sysutil_audio.h" #include "Emu/Audio/sysutil_audio.h"
// Parameter IDs #include "cellSysutil.h"
enum
{
//Integers
CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111,
CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN = 0x0112,
CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT = 0x0114,
CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT = 0x0115,
CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE = 0x0116,
CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME = 0x0117,
CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL = 0x0121,
CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT = 0x0123,
CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT = 0x0141,
CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ = 0x0151,
CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE = 0x0152,
CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE = 0x0153,
CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD = 0x0154,
CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD = 0x0155,
CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF = 0x0156,
//Strings #include "Loader/PSF.h"
CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME = 0x113,
CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME = 0x131,
};
enum
{
CELL_SYSUTIL_LANG_JAPANESE = 0,
CELL_SYSUTIL_LANG_ENGLISH_US = 1,
CELL_SYSUTIL_LANG_FRENCH = 2,
CELL_SYSUTIL_LANG_SPANISH = 3,
CELL_SYSUTIL_LANG_GERMAN = 4,
CELL_SYSUTIL_LANG_ITALIAN = 5,
CELL_SYSUTIL_LANG_DUTCH = 6,
CELL_SYSUTIL_LANG_PORTUGUESE_PT = 7,
CELL_SYSUTIL_LANG_RUSSIAN = 8,
CELL_SYSUTIL_LANG_KOREAN = 9,
CELL_SYSUTIL_LANG_CHINESE_T = 10,
CELL_SYSUTIL_LANG_CHINESE_S = 11,
CELL_SYSUTIL_LANG_FINNISH = 12,
CELL_SYSUTIL_LANG_SWEDISH = 13,
CELL_SYSUTIL_LANG_DANISH = 14,
CELL_SYSUTIL_LANG_NORWEGIAN = 15,
CELL_SYSUTIL_LANG_POLISH = 16,
CELL_SYSUTIL_LANG_PORTUGUESE_BR = 17,
CELL_SYSUTIL_LANG_ENGLISH_GB = 18,
};
enum
{
CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CIRCLE = 0,
CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CROSS = 1,
};
enum
{
CELL_SYSUTIL_DATE_FMT_YYYYMMDD = 0,
CELL_SYSUTIL_DATE_FMT_DDMMYYYY = 1,
CELL_SYSUTIL_DATE_FMT_MMDDYYYY = 2,
};
enum
{
CELL_SYSUTIL_TIME_FMT_CLOCK12 = 0,
CELL_SYSUTIL_TIME_FMT_CLOCK24 = 1,
};
enum
{
CELL_SYSUTIL_GAME_PARENTAL_OFF = 0,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL01 = 1,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL02 = 2,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL03 = 3,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL04 = 4,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL05 = 5,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL06 = 6,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL07 = 7,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL08 = 8,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL09 = 9,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL10 = 10,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL11 = 11,
};
enum
{
CELL_SYSUTIL_GAME_PARENTAL_LEVEL0_RESTRICT_OFF = 0,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL0_RESTRICT_ON = 1,
};
enum
{
CELL_SYSUTIL_CAMERA_PLFREQ_DISABLED = 0,
CELL_SYSUTIL_CAMERA_PLFREQ_50HZ = 1,
CELL_SYSUTIL_CAMERA_PLFREQ_60HZ = 2,
CELL_SYSUTIL_CAMERA_PLFREQ_DEVCIE_DEPEND = 4,
};
enum
{
CELL_SYSUTIL_PAD_RUMBLE_OFF = 0,
CELL_SYSUTIL_PAD_RUMBLE_ON = 1,
};
enum
{
CELL_MSGDIALOG_BUTTON_NONE = -1,
CELL_MSGDIALOG_BUTTON_INVALID = 0,
CELL_MSGDIALOG_BUTTON_OK = 1,
CELL_MSGDIALOG_BUTTON_YES = 1,
CELL_MSGDIALOG_BUTTON_NO = 2,
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
};
enum{
CELL_SYSCACHE_RET_OK_CLEARED = 0,
CELL_SYSCACHE_RET_OK_RELAYED = 1,
CELL_SYSCACHE_ID_SIZE = 32,
CELL_SYSCACHE_PATH_MAX = 1055,
CELL_SYSCACHE_ERROR_ACCESS_ERROR = 0x8002bc01,//I don't think we need this
CELL_SYSCACHE_ERROR_INTERNAL = 0x8002bc02,//not really useful, if we run out of HD space sysfs should handle that
CELL_SYSCACHE_ERROR_PARAM = 0x8002bc03,
CELL_SYSCACHE_ERROR_NOTMOUNTED = 0x8002bc04,//we don't really need to simulate the mounting, so this is probably useless
};
enum CellMsgDialogType
{
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
};
typedef void (*CellMsgDialogCallback)(int buttonType, mem_ptr_t<void> userData); typedef void (*CellMsgDialogCallback)(int buttonType, mem_ptr_t<void> userData);
typedef void (*CellHddGameStatCallback)(mem_ptr_t<CellHddGameCBResult> cbResult, mem_ptr_t<CellHddGameStatGet> get, mem_ptr_t<CellHddGameStatSet> set);
void cellSysutil_init(); void cellSysutil_init();
Module cellSysutil(0x0015, cellSysutil_init); Module cellSysutil(0x0015, cellSysutil_init);
@ -161,7 +27,7 @@ int cellSysutilGetSystemParamInt(int id, mem32_t value)
{ {
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_LANG"); cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_LANG");
value = CELL_SYSUTIL_LANG_ENGLISH_US; value = Ini.SysLanguage.GetValue();
break; break;
case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN:
@ -973,11 +839,77 @@ int cellSysCacheMount(mem_ptr_t<CellSysCacheParam> param)
char id[CELL_SYSCACHE_ID_SIZE]; char id[CELL_SYSCACHE_ID_SIZE];
strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE); strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE);
strncpy(param->getCachePath, ("/dev_hdd1/cache/" + std::string(id) + "/").c_str(), CELL_SYSCACHE_PATH_MAX); strncpy(param->getCachePath, ("/dev_hdd1/cache/" + std::string(id) + "/").c_str(), CELL_SYSCACHE_PATH_MAX);
Emu.GetVFS().CreateFile(wxString(param->getCachePath)); Emu.GetVFS().CreateDir(wxString(param->getCachePath));
return CELL_SYSCACHE_RET_OK_RELAYED; return CELL_SYSCACHE_RET_OK_RELAYED;
} }
int cellHddGameCheck(u32 version, u32 dirName_addr, u32 errDialog, mem_func_ptr_t<CellHddGameStatCallback> funcStat, u32 container)
{
cellSysutil.Warning("cellHddGameCheck(version=%d, dirName_addr=0x%xx, errDialog=%d, funcStat_addr=0x%x, container=%d)",
version, dirName_addr, errDialog, funcStat, container);
if (!Memory.IsGoodAddr(dirName_addr) || !funcStat.IsGood())
return CELL_HDDGAME_ERROR_PARAM;
std::string dirName = Memory.ReadString(dirName_addr).ToStdString();
if (dirName.size() != 9)
return CELL_HDDGAME_ERROR_PARAM;
MemoryAllocator<CellHddGameSystemFileParam> param;
MemoryAllocator<CellHddGameCBResult> result;
MemoryAllocator<CellHddGameStatGet> get;
MemoryAllocator<CellHddGameStatSet> set;
get->hddFreeSizeKB = 40000000; // 40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
get->isNewData = CELL_HDDGAME_ISNEWDATA_EXIST;
get->sysSizeKB = 0; // TODO
get->st_atime = 0; // TODO
get->st_ctime = 0; // TODO
get->st_mtime = 0; // TODO
get->sizeKB = CELL_HDDGAME_SIZEKB_NOTCALC;
memcpy(get->contentInfoPath, ("/dev_hdd0/game/"+dirName).c_str(), CELL_HDDGAME_PATH_MAX);
memcpy(get->hddGamePath, ("/dev_hdd0/game/"+dirName+"/USRDIR").c_str(), CELL_HDDGAME_PATH_MAX);
if (!Emu.GetVFS().ExistsDir(("/dev_hdd0/game/"+dirName).c_str()))
{
get->isNewData = CELL_HDDGAME_ISNEWDATA_NODIR;
}
else
{
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
vfsFile f(("/dev_hdd0/game/"+dirName+"/PARAM.SFO").c_str());
PSFLoader psf(f);
if (!psf.Load(false)) {
return CELL_HDDGAME_ERROR_BROKEN;
}
get->getParam.parentalLevel = psf.m_info.parental_lvl;
get->getParam.attribute = psf.m_info.attr;
get->getParam.resolution = psf.m_info.resolution;
get->getParam.soundFormat = psf.m_info.sound_format;
memcpy(get->getParam.title, psf.m_info.name.mb_str(), CELL_HDDGAME_SYSP_TITLE_SIZE);
memcpy(get->getParam.dataVersion, psf.m_info.app_ver.mb_str(), CELL_HDDGAME_SYSP_VERSION_SIZE);
memcpy(get->getParam.titleId, dirName.c_str(), CELL_HDDGAME_SYSP_TITLEID_SIZE);
for (u32 i=0; i<CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++) {
memcpy(get->getParam.titleLang[i], psf.m_info.name.mb_str(), CELL_HDDGAME_SYSP_TITLE_SIZE); // TODO: Get real titleLang name
}
}
// TODO ?
funcStat(result.GetAddr(), get.GetAddr(), set.GetAddr());
if (result->result != CELL_HDDGAME_CBRESULT_OK &&
result->result != CELL_HDDGAME_CBRESULT_OK_CANCEL)
return CELL_HDDGAME_ERROR_CBRESULT;
// TODO ?
return CELL_OK;
}
void cellSysutil_init() void cellSysutil_init()
{ {
cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt); cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt);
@ -1010,4 +942,9 @@ void cellSysutil_init()
cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount); cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount);
cellSysutil.AddFunc(0x744c1544, cellSysCacheClear); cellSysutil.AddFunc(0x744c1544, cellSysCacheClear);
cellSysutil.AddFunc(0x9117df20, cellHddGameCheck);
//cellSysutil.AddFunc(0x4bdec82a, cellHddGameCheck2);
//cellSysutil.AddFunc(0xf82e2ef7, cellHddGameGetSizeKB);
//cellSysutil.AddFunc(0x9ca9ffa7, cellHddGameSetSystemVer);
//cellSysutil.AddFunc(0xafd605b3, cellHddGameExitBroken);
} }

View file

@ -0,0 +1,228 @@
#pragma once
// Parameter IDs
enum
{
// Integers
CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111,
CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN = 0x0112,
CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT = 0x0114,
CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT = 0x0115,
CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE = 0x0116,
CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME = 0x0117,
CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL = 0x0121,
CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT = 0x0123,
CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT = 0x0141,
CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ = 0x0151,
CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE = 0x0152,
CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE = 0x0153,
CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD = 0x0154,
CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD = 0x0155,
CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF = 0x0156,
// Strings
CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME = 0x113,
CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME = 0x131,
};
enum
{
CELL_SYSUTIL_LANG_JAPANESE = 0,
CELL_SYSUTIL_LANG_ENGLISH_US = 1,
CELL_SYSUTIL_LANG_FRENCH = 2,
CELL_SYSUTIL_LANG_SPANISH = 3,
CELL_SYSUTIL_LANG_GERMAN = 4,
CELL_SYSUTIL_LANG_ITALIAN = 5,
CELL_SYSUTIL_LANG_DUTCH = 6,
CELL_SYSUTIL_LANG_PORTUGUESE_PT = 7,
CELL_SYSUTIL_LANG_RUSSIAN = 8,
CELL_SYSUTIL_LANG_KOREAN = 9,
CELL_SYSUTIL_LANG_CHINESE_T = 10,
CELL_SYSUTIL_LANG_CHINESE_S = 11,
CELL_SYSUTIL_LANG_FINNISH = 12,
CELL_SYSUTIL_LANG_SWEDISH = 13,
CELL_SYSUTIL_LANG_DANISH = 14,
CELL_SYSUTIL_LANG_NORWEGIAN = 15,
CELL_SYSUTIL_LANG_POLISH = 16,
CELL_SYSUTIL_LANG_PORTUGUESE_BR = 17,
CELL_SYSUTIL_LANG_ENGLISH_GB = 18,
};
enum
{
CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CIRCLE = 0,
CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CROSS = 1,
};
enum
{
CELL_SYSUTIL_DATE_FMT_YYYYMMDD = 0,
CELL_SYSUTIL_DATE_FMT_DDMMYYYY = 1,
CELL_SYSUTIL_DATE_FMT_MMDDYYYY = 2,
};
enum
{
CELL_SYSUTIL_TIME_FMT_CLOCK12 = 0,
CELL_SYSUTIL_TIME_FMT_CLOCK24 = 1,
};
enum
{
CELL_SYSUTIL_GAME_PARENTAL_OFF = 0,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL01 = 1,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL02 = 2,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL03 = 3,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL04 = 4,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL05 = 5,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL06 = 6,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL07 = 7,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL08 = 8,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL09 = 9,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL10 = 10,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL11 = 11,
};
enum
{
CELL_SYSUTIL_GAME_PARENTAL_LEVEL0_RESTRICT_OFF = 0,
CELL_SYSUTIL_GAME_PARENTAL_LEVEL0_RESTRICT_ON = 1,
};
enum
{
CELL_SYSUTIL_CAMERA_PLFREQ_DISABLED = 0,
CELL_SYSUTIL_CAMERA_PLFREQ_50HZ = 1,
CELL_SYSUTIL_CAMERA_PLFREQ_60HZ = 2,
CELL_SYSUTIL_CAMERA_PLFREQ_DEVCIE_DEPEND = 4,
};
enum
{
CELL_SYSUTIL_PAD_RUMBLE_OFF = 0,
CELL_SYSUTIL_PAD_RUMBLE_ON = 1,
};
enum
{
CELL_MSGDIALOG_BUTTON_NONE = -1,
CELL_MSGDIALOG_BUTTON_INVALID = 0,
CELL_MSGDIALOG_BUTTON_OK = 1,
CELL_MSGDIALOG_BUTTON_YES = 1,
CELL_MSGDIALOG_BUTTON_NO = 2,
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
};
enum
{
CELL_SYSCACHE_RET_OK_CLEARED = 0,
CELL_SYSCACHE_RET_OK_RELAYED = 1,
CELL_SYSCACHE_ID_SIZE = 32,
CELL_SYSCACHE_PATH_MAX = 1055,
CELL_SYSCACHE_ERROR_ACCESS_ERROR = 0x8002bc01, // I don't think we need this
CELL_SYSCACHE_ERROR_INTERNAL = 0x8002bc02, // Not really useful, if we run out of HDD space sys_fs should handle that
CELL_SYSCACHE_ERROR_PARAM = 0x8002bc03,
CELL_SYSCACHE_ERROR_NOTMOUNTED = 0x8002bc04, // We don't really need to simulate the mounting, so this is probably useless
};
enum CellMsgDialogType
{
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
};
// cellSysutil: cellHddGame
enum
{
// Return Codes
CELL_HDDGAME_RET_CANCEL = 1,
CELL_HDDGAME_ERROR_CBRESULT = 0x8002ba01,
CELL_HDDGAME_ERROR_ACCESS_ERROR = 0x8002ba02,
CELL_HDDGAME_ERROR_INTERNAL = 0x8002ba03,
CELL_HDDGAME_ERROR_PARAM = 0x8002ba04,
CELL_HDDGAME_ERROR_NOSPACE = 0x8002ba05,
CELL_HDDGAME_ERROR_BROKEN = 0x8002ba06,
CELL_HDDGAME_ERROR_FAILURE = 0x8002ba07,
// Callback Result
CELL_HDDGAME_CBRESULT_OK_CANCEL = 1,
CELL_HDDGAME_CBRESULT_OK = 0,
CELL_HDDGAME_CBRESULT_ERR_NOSPACE = -1,
CELL_HDDGAME_CBRESULT_ERR_BROKEN = -3,
CELL_HDDGAME_CBRESULT_ERR_NODATA = -4,
CELL_HDDGAME_CBRESULT_ERR_INVALID = -5,
// Character Strings
CELL_HDDGAME_INVALIDMSG_MAX = 256,
CELL_HDDGAME_PATH_MAX = 1055,
CELL_HDDGAME_SYSP_TITLE_SIZE = 128,
CELL_HDDGAME_SYSP_TITLEID_SIZE = 10,
CELL_HDDGAME_SYSP_VERSION_SIZE = 6,
CELL_HDDGAME_SYSP_SYSTEMVER_SIZE = 8,
// HDD Directory exists
CELL_HDDGAME_ISNEWDATA_EXIST = 0,
CELL_HDDGAME_ISNEWDATA_NODIR = 1,
// Languages
CELL_HDDGAME_SYSP_LANGUAGE_NUM = 20,
// Stat Get
CELL_HDDGAME_SIZEKB_NOTCALC = -1,
};
struct CellHddGameSystemFileParam
{
u8 title[CELL_HDDGAME_SYSP_TITLE_SIZE];
u8 titleLang[CELL_HDDGAME_SYSP_LANGUAGE_NUM][CELL_HDDGAME_SYSP_TITLE_SIZE];
u8 titleId[CELL_HDDGAME_SYSP_TITLEID_SIZE];
u8 reserved0[2];
u8 dataVersion[CELL_HDDGAME_SYSP_VERSION_SIZE];
u8 reserved1[2];
be_t<u32> attribute;
be_t<u32> parentalLevel;
be_t<u32> resolution;
be_t<u32> soundFormat;
u8 reserved2[256];
};
struct CellHddGameStatGet
{
be_t<s32> hddFreeSizeKB;
be_t<u32> isNewData;
u8 contentInfoPath[CELL_HDDGAME_PATH_MAX];
u8 hddGamePath[CELL_HDDGAME_PATH_MAX];
u8 reserved0[2];
be_t<u64> st_atime;
be_t<u64> st_mtime;
be_t<u64> st_ctime;
CellHddGameSystemFileParam getParam;
be_t<s32> sizeKB;
be_t<s32> sysSizeKB;
u8 reserved1[68];
};
struct CellHddGameStatSet
{
CellHddGameSystemFileParam *setParam;
u32 reserved_addr; // void*
};
struct CellHddGameCBResult
{
be_t<u32> result;
be_t<s32> errNeedSizeKB;
u8 *invalidMsg;
u32 reserved_addr; // void*
};

View file

@ -28,28 +28,28 @@ enum CellUserInfoListType
// Structs // Structs
struct CellUserInfoUserStat struct CellUserInfoUserStat
{ {
u32 id; be_t<u32> id;
u8 name[CELL_USERINFO_USERNAME_SIZE]; u8 name[CELL_USERINFO_USERNAME_SIZE];
}; };
struct CellUserInfoUserList struct CellUserInfoUserList
{ {
u32 userId[CELL_USERINFO_USER_MAX]; be_t<u32> userId[CELL_USERINFO_USER_MAX];
}; };
struct CellUserInfoListSet struct CellUserInfoListSet
{ {
u32 title_addr; // (char*) be_t<u32> title_addr; // (char*)
u32 focus; be_t<u32> focus;
u32 fixedListNum; be_t<u32> fixedListNum;
mem_ptr_t<CellUserInfoUserList> fixedList; mem_ptr_t<CellUserInfoUserList> fixedList;
u32 reserved_addr; // (void*) be_t<u32> reserved_addr; // (void*)
}; };
struct CellUserInfoTypeSet struct CellUserInfoTypeSet
{ {
u32 title_addr; // (char*) be_t<u32> title_addr; // (char*)
u32 focus; be_t<u32> focus;
CellUserInfoListType type; CellUserInfoListType type;
u32 reserved_addr; // (void*) be_t<u32> reserved_addr; // (void*)
}; };

View file

@ -1,10 +1,14 @@
#include "stdafx.h" #include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/SC_FUNC.h"
#include "wx/xml/xml.h"
#include "sceNp.h" #include "sceNp.h"
#include "sceNpTrophy.h" #include "sceNpTrophy.h"
#include "Loader/TRP.h" #include "Loader/TRP.h"
#include "Loader/TROPUSR.h"
#include "Emu/SysCalls/lv2/SC_Time.h"
void sceNpTrophy_unload(); void sceNpTrophy_unload();
void sceNpTrophy_init(); void sceNpTrophy_init();
@ -16,6 +20,8 @@ struct sceNpTrophyInternalContext
// TODO // TODO
std::string trp_name; std::string trp_name;
vfsStream* trp_stream; vfsStream* trp_stream;
TROPUSRLoader* tropusr;
}; };
struct sceNpTrophyInternal struct sceNpTrophyInternal
@ -116,23 +122,49 @@ int sceNpTrophyRegisterContext(u32 context, u32 handle, u32 statusCb_addr, u32 a
// TODO: There are other possible errors // TODO: There are other possible errors
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context]; sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
if (!ctxt.trp_stream) if (!ctxt.trp_stream)
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
int ret;
TRPLoader trp(*(ctxt.trp_stream)); TRPLoader trp(*(ctxt.trp_stream));
if (!trp.LoadHeader())
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
// Rename or discard certain entries based on the files found
char target [32];
sprintf(target, "TROP_%02d.SFM", Ini.SysLanguage.GetValue());
if (trp.ContainsEntry(target)) {
trp.RemoveEntry("TROPCONF.SFM");
trp.RemoveEntry("TROP.SFM");
trp.RenameEntry(target, "TROPCONF.SFM");
}
else if (trp.ContainsEntry("TROP.SFM")) {
trp.RemoveEntry("TROPCONF.SFM");
trp.RenameEntry("TROP.SFM", "TROPCONF.SFM");
}
else if (!trp.ContainsEntry("TROPCONF.SFM")) {
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
}
// Discard unnecessary TROP_XX.SFM files
for (int i=0; i<=18; i++) {
sprintf(target, "TROP_%02d.SFM", i);
if (i != Ini.SysLanguage.GetValue())
trp.RemoveEntry(target);
}
// TODO: Get the path of the current user // TODO: Get the path of the current user
if (trp.Install("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name)) std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name;
ret = CELL_OK; if (!trp.Install(trophyPath))
else return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
ret = SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
TROPUSRLoader* tropusr = new TROPUSRLoader();
tropusr->Load(trophyPath + "/TROPUSR.DAT", trophyPath + "/TROPCONF.SFM");
ctxt.tropusr = tropusr;
// TODO: Callbacks // TODO: Callbacks
trp.Close(); return CELL_OK;
return ret;
} }
int sceNpTrophyGetGameProgress() int sceNpTrophyGetGameProgress()
@ -161,7 +193,6 @@ int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, mem64_t reqspace, u
// TODO: There are other possible errors // TODO: There are other possible errors
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context]; sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
if (!ctxt.trp_stream) if (!ctxt.trp_stream)
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
@ -192,21 +223,46 @@ int sceNpTrophyGetGameInfo(u32 context, u32 handle, mem_ptr_t<SceNpTrophyGameDet
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
// TODO: There are other possible errors // TODO: There are other possible errors
// sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context]; wxString path;
wxXmlDocument doc;
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user
doc.Load(path);
// TODO: This data is faked, implement a XML reader and get it from TROP.SFM std::string titleName;
memcpy(details->title, "Trophy Set", SCE_NP_TROPHY_NAME_MAX_SIZE); std::string titleDetail;
memcpy(details->description, "Hey! Implement a XML reader, and load the description from TROP.SFM", SCE_NP_TROPHY_DESCR_MAX_SIZE); for (wxXmlNode *n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
details->numTrophies = 0; if (n->GetName() == "title-name")
details->numPlatinum = 0; titleName = n->GetNodeContent().mb_str();
details->numGold = 0; if (n->GetName() == "title-detail")
details->numSilver = 0; titleDetail = n->GetNodeContent().mb_str();
details->numBronze = 0; if (n->GetName() == "trophy")
data->unlockedTrophies = 0; {
data->unlockedPlatinum = 0; u32 trophy_id = atoi(n->GetAttribute("id").mb_str());
data->unlockedGold = 0;
data->unlockedSilver = 0; details->numTrophies++;
data->unlockedBronze = 0; switch (((const char *)n->GetAttribute("ttype").mb_str())[0]) {
case 'B': details->numBronze++; break;
case 'S': details->numSilver++; break;
case 'G': details->numGold++; break;
case 'P': details->numPlatinum++; break;
}
if (ctxt.tropusr->GetTrophyUnlockState(trophy_id))
{
data->unlockedTrophies++;
switch (((const char *)n->GetAttribute("ttype").mb_str())[0]) {
case 'B': data->unlockedBronze++; break;
case 'S': data->unlockedSilver++; break;
case 'G': data->unlockedGold++; break;
case 'P': data->unlockedPlatinum++; break;
}
}
}
}
memcpy(details->title, titleName.c_str(), SCE_NP_TROPHY_NAME_MAX_SIZE);
memcpy(details->description, titleDetail.c_str(), SCE_NP_TROPHY_DESCR_MAX_SIZE);
return CELL_OK; return CELL_OK;
} }
@ -216,9 +272,29 @@ int sceNpTrophyDestroyHandle()
return CELL_OK; return CELL_OK;
} }
int sceNpTrophyUnlockTrophy() int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, mem32_t platinumId)
{ {
UNIMPLEMENTED_FUNC(sceNpTrophy); sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=%d, handle=%d, trophyId=%d, platinumId_addr=0x%x)",
context, handle, trophyId, platinumId.GetAddr());
if (!s_npTrophyInstance.m_bInitialized)
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
if (!platinumId.IsGood())
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
// TODO: There are other possible errors
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
if (trophyId >= ctxt.tropusr->GetTrophiesCount())
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
if (ctxt.tropusr->GetTrophyUnlockState(trophyId))
return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;
u64 timestamp1 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong
u64 timestamp2 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong
ctxt.tropusr->UnlockTrophy(trophyId, timestamp1, timestamp2);
ctxt.tropusr->Save("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPUSR.DAT");
platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
return CELL_OK; return CELL_OK;
} }
@ -228,9 +304,31 @@ int sceNpTrophyTerm()
return CELL_OK; return CELL_OK;
} }
int sceNpTrophyGetTrophyUnlockState() int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, mem_ptr_t<SceNpTrophyFlagArray> flags, mem32_t count)
{ {
UNIMPLEMENTED_FUNC(sceNpTrophy); sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState(context=%d, handle=%d, flags_addr=0x%x, count_addr=0x%x)",
context, handle, flags.GetAddr(), count.GetAddr());
if (!s_npTrophyInstance.m_bInitialized)
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
if (!flags.IsGood() || !count.IsGood())
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
// TODO: There are other possible errors
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
count = ctxt.tropusr->GetTrophiesCount();
if (count.GetValue() > 128)
ConLog.Warning("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!");
// Pack up to 128 bools in u32 flag_bits[4]
for (u32 id=0; id<count.GetValue(); id++)
{
if (ctxt.tropusr->GetTrophyUnlockState(id))
flags->flag_bits[id/32] |= 1<<(id%32);
else
flags->flag_bits[id/32] &= ~(1<<(id%32));
}
return CELL_OK; return CELL_OK;
} }
@ -251,14 +349,43 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, mem_ptr_t<Sc
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
// TODO: There are other possible errors // TODO: There are other possible errors
// sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context]; wxString path;
wxXmlDocument doc;
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user
doc.Load(path);
// TODO: This data is faked, implement a XML reader and get it from TROP.SFM std::string name;
memcpy(details->name, "Some Trophy", SCE_NP_TROPHY_NAME_MAX_SIZE); std::string detail;
memcpy(details->description, "Hey! Implement a XML reader, and load the description from TROP.SFM", SCE_NP_TROPHY_DESCR_MAX_SIZE); for (wxXmlNode *n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
details->hidden = false; if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").mb_str())))
details->trophyId = trophyId; {
details->trophyGrade = SCE_NP_TROPHY_GRADE_GOLD; details->trophyId = trophyId;
switch (((const char *)n->GetAttribute("ttype").mb_str())[0]) {
case 'B': details->trophyGrade = SCE_NP_TROPHY_GRADE_BRONZE; break;
case 'S': details->trophyGrade = SCE_NP_TROPHY_GRADE_SILVER; break;
case 'G': details->trophyGrade = SCE_NP_TROPHY_GRADE_GOLD; break;
case 'P': details->trophyGrade = SCE_NP_TROPHY_GRADE_PLATINUM; break;
}
switch (((const char *)n->GetAttribute("ttype").mb_str())[0]) {
case 'y': details->hidden = true; break;
case 'n': details->hidden = false; break;
}
for (wxXmlNode *n2 = n->GetChildren(); n2; n2 = n2->GetNext()) {
if (n2->GetName() == "name") name = n2->GetNodeContent().mb_str();
if (n2->GetName() == "detail") detail = n2->GetNodeContent().mb_str();
}
data->trophyId = trophyId;
data->unlocked = ctxt.tropusr->GetTrophyUnlockState(trophyId);
data->timestamp.tick = ctxt.tropusr->GetTrophyTimestamp(trophyId);
}
}
memcpy(details->name, name.c_str(), SCE_NP_TROPHY_NAME_MAX_SIZE);
memcpy(details->description, detail.c_str(), SCE_NP_TROPHY_DESCR_MAX_SIZE);
return CELL_OK; return CELL_OK;
} }

View file

@ -55,6 +55,13 @@ enum
SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE = 1024, SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE = 1024,
SCE_NP_TROPHY_NAME_MAX_SIZE = 128, SCE_NP_TROPHY_NAME_MAX_SIZE = 128,
SCE_NP_TROPHY_DESCR_MAX_SIZE = 1024, SCE_NP_TROPHY_DESCR_MAX_SIZE = 1024,
SCE_NP_TROPHY_FLAG_SETSIZE = 128,
SCE_NP_TROPHY_FLAG_BITS_SHIFT = 5,
SCE_NP_TROPHY_INVALID_CONTEXT = 0,
SCE_NP_TROPHY_INVALID_HANDLE = 0,
SCE_NP_TROPHY_INVALID_TROPHY_ID = -1,
}; };
enum SceNpTrophyGrade enum SceNpTrophyGrade
@ -68,11 +75,11 @@ enum SceNpTrophyGrade
struct SceNpTrophyGameDetails struct SceNpTrophyGameDetails
{ {
u32 numTrophies; be_t<u32> numTrophies;
u32 numPlatinum; be_t<u32> numPlatinum;
u32 numGold; be_t<u32> numGold;
u32 numSilver; be_t<u32> numSilver;
u32 numBronze; be_t<u32> numBronze;
u8 title[SCE_NP_TROPHY_TITLE_MAX_SIZE]; u8 title[SCE_NP_TROPHY_TITLE_MAX_SIZE];
u8 description[SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE]; u8 description[SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE];
u8 reserved[4]; u8 reserved[4];
@ -80,26 +87,32 @@ struct SceNpTrophyGameDetails
struct SceNpTrophyGameData struct SceNpTrophyGameData
{ {
u32 unlockedTrophies; be_t<u32> unlockedTrophies;
u32 unlockedPlatinum; be_t<u32> unlockedPlatinum;
u32 unlockedGold; be_t<u32> unlockedGold;
u32 unlockedSilver; be_t<u32> unlockedSilver;
u32 unlockedBronze; be_t<u32> unlockedBronze;
}; };
struct SceNpTrophyDetails struct SceNpTrophyDetails
{ {
s32 trophyId; // SceNpTrophyId be_t<s32> trophyId; // SceNpTrophyId
u32 trophyGrade; // SceNpTrophyGrade be_t<u32> trophyGrade; // SceNpTrophyGrade
u8 name[SCE_NP_TROPHY_NAME_MAX_SIZE]; u8 name[SCE_NP_TROPHY_NAME_MAX_SIZE];
u8 description[SCE_NP_TROPHY_DESCR_MAX_SIZE]; u8 description[SCE_NP_TROPHY_DESCR_MAX_SIZE];
bool hidden; bool hidden;
u8 reserved[3]; u8 reserved[3];
}; };
struct SceNpTrophyData { struct SceNpTrophyData
{
CellRtcTick timestamp; CellRtcTick timestamp;
s32 trophyId; // SceNpTrophyId be_t<s32> trophyId; // SceNpTrophyId
bool unlocked; bool unlocked;
u8 reserved[3]; u8 reserved[3];
}; };
struct SceNpTrophyFlagArray
{
u32 flag_bits[SCE_NP_TROPHY_FLAG_SETSIZE >> SCE_NP_TROPHY_FLAG_BITS_SHIFT];
};

View file

@ -2,9 +2,9 @@
struct sys_net_initialize_parameter struct sys_net_initialize_parameter
{ {
u32 memory_addr; be_t<u32> memory_addr;
int memory_size; be_t<s32> memory_size;
int flags; be_t<s32> flags;
}; };
// The names of the following structs are modified to avoid overloading problems // The names of the following structs are modified to avoid overloading problems

View file

@ -141,7 +141,7 @@ void Emulator::Load()
m_path = elf_path; m_path = elf_path;
} }
ConLog.Write("Loading '%s'...", m_path.wx_str()); ConLog.Write("Loading '%s'...", m_path.ToStdString().c_str());
GetInfo().Reset(); GetInfo().Reset();
m_vfs.Init(m_path); m_vfs.Init(m_path);
@ -149,7 +149,7 @@ void Emulator::Load()
ConLog.Write("Mount info:"); ConLog.Write("Mount info:");
for(uint i=0; i<m_vfs.m_devices.GetCount(); ++i) for(uint i=0; i<m_vfs.m_devices.GetCount(); ++i)
{ {
ConLog.Write("%s -> %s", m_vfs.m_devices[i].GetPs3Path().wx_str(), m_vfs.m_devices[i].GetLocalPath().wx_str()); ConLog.Write("%s -> %s", m_vfs.m_devices[i].GetPs3Path().ToStdString().c_str(), m_vfs.m_devices[i].GetLocalPath().ToStdString().c_str());
} }
ConLog.SkipLn(); ConLog.SkipLn();
@ -162,7 +162,7 @@ void Emulator::Load()
if(!f.IsOpened()) if(!f.IsOpened())
{ {
ConLog.Error("Elf not found! (%s - %s)", m_path.wx_str(), m_elf_path.wx_str()); ConLog.Error("Elf not found! (%s - %s)", m_path.ToStdString().c_str(), m_elf_path.ToStdString().c_str());
return; return;
} }
@ -441,7 +441,7 @@ void Emulator::LoadPoints(const std::string& path)
if(version != bpdb_version || if(version != bpdb_version ||
(sizeof(u16) + break_count * sizeof(u64) + sizeof(u32) + marked_count * sizeof(u64) + sizeof(u32)) != length) (sizeof(u16) + break_count * sizeof(u64) + sizeof(u32) + marked_count * sizeof(u64) + sizeof(u32)) != length)
{ {
ConLog.Error("'%s' is broken", wxString(path).wx_str()); ConLog.Error("'%s' is broken", path.c_str());
return; return;
} }

View file

@ -61,7 +61,6 @@ AboutDialog::AboutDialog(wxWindow *parent)
wxButton* b_forum = new wxButton(this, b_id_forum, "Forum"); wxButton* b_forum = new wxButton(this, b_id_forum, "Forum");
Connect(b_id_website, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutDialog::OpenWebsite)); Connect(b_id_website, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutDialog::OpenWebsite));
Connect(b_id_forum, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutDialog::OpenForum)); Connect(b_id_forum, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutDialog::OpenForum));
b_website->Disable();
s_panel_buttons->AddSpacer(12); s_panel_buttons->AddSpacer(12);
s_panel_buttons->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5); s_panel_buttons->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
@ -82,10 +81,10 @@ AboutDialog::AboutDialog(wxWindow *parent)
void AboutDialog::OpenWebsite(wxCommandEvent& WXUNUSED(event)) void AboutDialog::OpenWebsite(wxCommandEvent& WXUNUSED(event))
{ {
wxLaunchDefaultBrowser("http://www.emunewz.net/forum/forumdisplay.php?fid=162"); wxLaunchDefaultBrowser("http://rpcs3.net/");
} }
void AboutDialog::OpenForum(wxCommandEvent& WXUNUSED(event)) void AboutDialog::OpenForum(wxCommandEvent& WXUNUSED(event))
{ {
wxLaunchDefaultBrowser("http://www.emunewz.net/forum/forumdisplay.php?fid=162"); wxLaunchDefaultBrowser("http://forum.rpcs3.net/");
} }

View file

@ -202,7 +202,7 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
} }
else else
{ {
ConLog.Error("Ps3 executable not found in selected folder (%s)", ctrl.GetPath().wx_str()); ConLog.Error("Ps3 executable not found in selected folder (%s)", ctrl.GetPath().ToStdString().c_str());
} }
} }
@ -328,6 +328,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
wxBoxSizer* s_panel(new wxBoxSizer(wxHORIZONTAL)); wxBoxSizer* s_panel(new wxBoxSizer(wxHORIZONTAL));
wxBoxSizer* s_subpanel1(new wxBoxSizer(wxVERTICAL)); wxBoxSizer* s_subpanel1(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_subpanel2(new wxBoxSizer(wxVERTICAL)); wxBoxSizer* s_subpanel2(new wxBoxSizer(wxVERTICAL));
wxBoxSizer* s_subpanel3(new wxBoxSizer(wxVERTICAL));
wxStaticBoxSizer* s_round_cpu( new wxStaticBoxSizer( wxVERTICAL, &diag, _("CPU") ) ); wxStaticBoxSizer* s_round_cpu( new wxStaticBoxSizer( wxVERTICAL, &diag, _("CPU") ) );
wxStaticBoxSizer* s_round_cpu_decoder( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Decoder") ) ); wxStaticBoxSizer* s_round_cpu_decoder( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Decoder") ) );
@ -348,6 +349,9 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
wxStaticBoxSizer* s_round_hle( new wxStaticBoxSizer( wxVERTICAL, &diag, _("HLE / Misc.") ) ); wxStaticBoxSizer* s_round_hle( new wxStaticBoxSizer( wxVERTICAL, &diag, _("HLE / Misc.") ) );
wxStaticBoxSizer* s_round_hle_log_lvl( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Log lvl") ) ); wxStaticBoxSizer* s_round_hle_log_lvl( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Log lvl") ) );
wxStaticBoxSizer* s_round_sys( new wxStaticBoxSizer( wxVERTICAL, &diag, _("System") ) );
wxStaticBoxSizer* s_round_sys_lang( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Language") ) );
wxComboBox* cbox_cpu_decoder = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_cpu_decoder = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_gs_render = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_gs_render = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_gs_resolution = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_gs_resolution = new wxComboBox(&diag, wxID_ANY);
@ -357,6 +361,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
wxComboBox* cbox_mouse_handler = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_mouse_handler = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_audio_out = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_audio_out = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_hle_loglvl = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_hle_loglvl = new wxComboBox(&diag, wxID_ANY);
wxComboBox* cbox_sys_lang = new wxComboBox(&diag, wxID_ANY);
wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors"); wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors");
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(&diag, wxID_ANY, "Log vertex/fragment programs"); wxCheckBox* chbox_gs_log_prog = new wxCheckBox(&diag, wxID_ANY, "Log vertex/fragment programs");
@ -405,6 +410,25 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
cbox_hle_loglvl->Append("Errors"); cbox_hle_loglvl->Append("Errors");
cbox_hle_loglvl->Append("Nothing"); cbox_hle_loglvl->Append("Nothing");
cbox_sys_lang->Append("Japanese");
cbox_sys_lang->Append("English (US)");
cbox_sys_lang->Append("French");
cbox_sys_lang->Append("Spanish");
cbox_sys_lang->Append("German");
cbox_sys_lang->Append("Italian");
cbox_sys_lang->Append("Dutch");
cbox_sys_lang->Append("Portuguese (PT)");
cbox_sys_lang->Append("Russian");
cbox_sys_lang->Append("Korean");
cbox_sys_lang->Append("Chinese (Trad.)");
cbox_sys_lang->Append("Chinese (Simp.)");
cbox_sys_lang->Append("Finnish");
cbox_sys_lang->Append("Swedish");
cbox_sys_lang->Append("Danish");
cbox_sys_lang->Append("Norwegian");
cbox_sys_lang->Append("Polish");
cbox_sys_lang->Append("English (UK)");
chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue()); chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue());
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());
@ -428,6 +452,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue()); cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue());
cbox_audio_out->SetSelection(Ini.AudioOutMode.GetValue()); cbox_audio_out->SetSelection(Ini.AudioOutMode.GetValue());
cbox_hle_loglvl->SetSelection(Ini.HLELogLvl.GetValue()); cbox_hle_loglvl->SetSelection(Ini.HLELogLvl.GetValue());
cbox_sys_lang->SetSelection(Ini.SysLanguage.GetValue());
s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand());
@ -461,6 +486,9 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
s_round_hle->Add(chbox_hle_savetty, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_hle->Add(chbox_hle_savetty, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_hle->Add(chbox_hle_exitonstop, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_hle->Add(chbox_hle_exitonstop, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_sys_lang->Add(cbox_sys_lang, wxSizerFlags().Border(wxALL, 5).Expand());
s_round_sys->Add(s_round_sys_lang, wxSizerFlags().Border(wxALL, 5).Expand());
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
s_b_panel->Add(new wxButton(&diag, wxID_OK), wxSizerFlags().Border(wxALL, 5).Center()); s_b_panel->Add(new wxButton(&diag, wxID_OK), wxSizerFlags().Border(wxALL, 5).Center());
@ -474,9 +502,11 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
s_subpanel2->Add(s_round_io, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel2->Add(s_round_io, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel2->Add(s_round_audio, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel2->Add(s_round_audio, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel2->Add(s_round_hle, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel2->Add(s_round_hle, wxSizerFlags().Border(wxALL, 5).Expand());
s_subpanel3->Add(s_round_sys, wxSizerFlags().Border(wxALL, 5).Expand());
s_panel->Add(s_subpanel1, wxSizerFlags().Border(wxALL, 5).Expand()); s_panel->Add(s_subpanel1, wxSizerFlags().Border(wxALL, 5).Expand());
s_panel->Add(s_subpanel2, wxSizerFlags().Border(wxALL, 5).Expand()); s_panel->Add(s_subpanel2, wxSizerFlags().Border(wxALL, 5).Expand());
s_panel->Add(s_subpanel3, wxSizerFlags().Border(wxALL, 5).Expand());
diag.SetSizerAndFit( s_panel ); diag.SetSizerAndFit( s_panel );
@ -500,6 +530,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue()); Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue());
Ini.HLEExitOnStop.SetValue(chbox_hle_exitonstop->GetValue()); Ini.HLEExitOnStop.SetValue(chbox_hle_exitonstop->GetValue());
Ini.HLELogLvl.SetValue(cbox_hle_loglvl->GetSelection()); Ini.HLELogLvl.SetValue(cbox_hle_loglvl->GetSelection());
Ini.SysLanguage.SetValue(cbox_sys_lang->GetSelection());
Ini.Save(); Ini.Save();
} }

View file

@ -110,6 +110,7 @@ public:
IniEntry<bool> HLESaveTTY; IniEntry<bool> HLESaveTTY;
IniEntry<bool> HLEExitOnStop; IniEntry<bool> HLEExitOnStop;
IniEntry<u8> HLELogLvl; IniEntry<u8> HLELogLvl;
IniEntry<u8> SysLanguage;
IniEntry<int> PadHandlerLeft; IniEntry<int> PadHandlerLeft;
IniEntry<int> PadHandlerDown; IniEntry<int> PadHandlerDown;
@ -178,6 +179,9 @@ public:
HLESaveTTY.Init("HLESaveTTY", path); HLESaveTTY.Init("HLESaveTTY", path);
HLEExitOnStop.Init("HLEExitOnStop", path); HLEExitOnStop.Init("HLEExitOnStop", path);
HLELogLvl.Init("HLELogLvl", path); HLELogLvl.Init("HLELogLvl", path);
path = DefPath + "/" + "System";
SysLanguage.Init("SysLanguage", path);
} }
void Load() void Load()
@ -200,6 +204,7 @@ public:
HLESaveTTY.Load(false); HLESaveTTY.Load(false);
HLEExitOnStop.Load(false); HLEExitOnStop.Load(false);
HLELogLvl.Load(0); HLELogLvl.Load(0);
SysLanguage.Load(1);
PadHandlerLeft.Load(static_cast<int>('A')); PadHandlerLeft.Load(static_cast<int>('A'));
PadHandlerDown.Load(static_cast<int>('S')); PadHandlerDown.Load(static_cast<int>('S'));
@ -239,6 +244,7 @@ public:
HLESaveTTY.Save(); HLESaveTTY.Save();
HLEExitOnStop.Save(); HLEExitOnStop.Save();
HLELogLvl.Save(); HLELogLvl.Save();
SysLanguage.Save();
PadHandlerLeft.Save(); PadHandlerLeft.Save();
PadHandlerDown.Save(); PadHandlerDown.Save();

212
rpcs3/Loader/TROPUSR.cpp Normal file
View file

@ -0,0 +1,212 @@
#include "stdafx.h"
#include "TROPUSR.h"
#include "wx/xml/xml.h"
TROPUSRLoader::TROPUSRLoader()
{
m_file = NULL;
memset(&m_header, 0, sizeof(m_header));
}
TROPUSRLoader::~TROPUSRLoader()
{
Close();
}
bool TROPUSRLoader::Load(std::string& filepath, std::string& configpath)
{
if (m_file)
Close();
if (!Emu.GetVFS().ExistsFile(filepath))
Generate(filepath, configpath);
m_file = Emu.GetVFS().OpenFile(filepath, vfsRead);
LoadHeader();
LoadTableHeaders();
LoadTables();
m_file->Close();
m_file = NULL;
return true;
}
bool TROPUSRLoader::LoadHeader()
{
if(!m_file->IsOpened())
return false;
m_file->Seek(0);
if (m_file->Read(&m_header, sizeof(TROPUSRHeader)) != sizeof(TROPUSRHeader))
return false;
return true;
}
bool TROPUSRLoader::LoadTableHeaders()
{
if(!m_file->IsOpened())
return false;
m_file->Seek(0x30);
m_tableHeaders.clear();
m_tableHeaders.resize(m_header.tables_count);
for (TROPUSRTableHeader& tableHeader : m_tableHeaders) {
if (m_file->Read(&tableHeader, sizeof(TROPUSRTableHeader)) != sizeof(TROPUSRTableHeader))
return false;
}
return true;
}
bool TROPUSRLoader::LoadTables()
{
if(!m_file->IsOpened())
return false;
for (const TROPUSRTableHeader& tableHeader : m_tableHeaders)
{
m_file->Seek(tableHeader.offset);
if (tableHeader.type == 4)
{
m_table4.clear();
m_table4.resize(tableHeader.entries_count);
for (auto& entry : m_table4) {
if (m_file->Read(&entry, sizeof(TROPUSREntry4)) != sizeof(TROPUSREntry4))
return false;
}
}
if (tableHeader.type == 6)
{
m_table6.clear();
m_table6.resize(tableHeader.entries_count);
for (auto& entry : m_table6) {
if (m_file->Read(&entry, sizeof(TROPUSREntry6)) != sizeof(TROPUSREntry6))
return false;
}
}
// TODO: Other tables
}
return true;
}
// TODO: TROPUSRLoader::Save deletes the TROPUSR and creates it again. This is probably very slow.
bool TROPUSRLoader::Save(std::string& filepath)
{
if (m_file)
Close();
if (!Emu.GetVFS().ExistsFile(filepath))
Emu.GetVFS().CreateFile(filepath);
m_file = Emu.GetVFS().OpenFile(filepath, vfsWrite);
m_file->Write(&m_header, sizeof(TROPUSRHeader));
for (const TROPUSRTableHeader& tableHeader : m_tableHeaders)
m_file->Write(&tableHeader, sizeof(TROPUSRTableHeader));
for (const auto& entry : m_table4)
m_file->Write(&entry, sizeof(TROPUSREntry4));
for (const auto& entry : m_table6)
m_file->Write(&entry, sizeof(TROPUSREntry6));
m_file->Close();
return true;
}
bool TROPUSRLoader::Generate(std::string& filepath, std::string& configpath)
{
wxString path;
wxXmlDocument doc;
Emu.GetVFS().GetDevice(configpath.c_str(), path);
doc.Load(path);
m_table4.clear();
m_table6.clear();
for (wxXmlNode *n = doc.GetRoot()->GetChildren(); n; n = n->GetNext())
{
if (n->GetName() == "trophy")
{
u32 trophy_id = atoi(n->GetAttribute("id").mb_str());
u32 trophy_grade;
switch (((const char *)n->GetAttribute("ttype").mb_str())[0])
{
case 'B': trophy_grade = 4; break;
case 'S': trophy_grade = 3; break;
case 'G': trophy_grade = 2; break;
case 'P': trophy_grade = 1; break;
default: trophy_grade = 0;
}
TROPUSREntry4 entry4 = {4, sizeof(TROPUSREntry4)-0x10, m_table4.size(), 0, trophy_id, trophy_grade, 0xFFFFFFFF};
TROPUSREntry6 entry6 = {6, sizeof(TROPUSREntry6)-0x10, m_table6.size(), 0, trophy_id, 0, 0, 0, 0, 0};
m_table4.push_back(entry4);
m_table6.push_back(entry6);
}
}
u64 offset = sizeof(TROPUSRHeader) + 2 * sizeof(TROPUSRTableHeader);
TROPUSRTableHeader table4header = {4, sizeof(TROPUSREntry4)-0x10, 1, m_table4.size(), offset, 0};
offset += m_table4.size() * sizeof(TROPUSREntry4);
TROPUSRTableHeader table6header = {6, sizeof(TROPUSREntry6)-0x10, 1, m_table6.size(), offset, 0};
offset += m_table6.size() * sizeof(TROPUSREntry6);
m_tableHeaders.clear();
m_tableHeaders.push_back(table4header);
m_tableHeaders.push_back(table6header);
m_header.magic = 0x818F54AD;
m_header.unk1 = 0x00010000;
m_header.tables_count = m_tableHeaders.size();
m_header.unk2 = 0;
Save(filepath);
return true;
}
u32 TROPUSRLoader::GetTrophiesCount()
{
return m_table6.size();
}
u32 TROPUSRLoader::GetTrophyUnlockState(u32 id)
{
if (id >= m_table6.size())
ConLog.Warning("TROPUSRLoader::GetUnlockState: Invalid id=%d", id);
return m_table6[id].trophy_state; // Let's assume the trophies are stored ordered
}
u32 TROPUSRLoader::GetTrophyTimestamp(u32 id)
{
if (id >= m_table6.size())
ConLog.Warning("TROPUSRLoader::GetTrophyTimestamp: Invalid id=%d", id);
// TODO: What timestamp does sceNpTrophyGetTrophyInfo want, timestamp1 or timestamp2?
return m_table6[id].timestamp2; // Let's assume the trophies are stored ordered
}
bool TROPUSRLoader::UnlockTrophy(u32 id, u64 timestamp1, u64 timestamp2)
{
if (id >= m_table6.size())
return false;
m_table6[id].trophy_state = 1;
m_table6[id].timestamp1 = timestamp1;
m_table6[id].timestamp2 = timestamp2;
return true;
}
bool TROPUSRLoader::Close()
{
if (m_file && m_file->Close())
{
m_file = NULL;
return true;
}
return false;
}

83
rpcs3/Loader/TROPUSR.h Normal file
View file

@ -0,0 +1,83 @@
#pragma once
struct TROPUSRHeader
{
be_t<u32> magic; // 81 8F 54 AD
be_t<u32> unk1;
be_t<u32> tables_count;
be_t<u32> unk2;
char reserved[32];
};
struct TROPUSRTableHeader
{
be_t<u32> type;
be_t<u32> entries_size;
be_t<u32> unk1; // Seems to be 1
be_t<u32> entries_count;
be_t<u64> offset;
be_t<u64> reserved;
};
struct TROPUSREntry4
{
// Entry Header
be_t<u32> entry_type; // Always 0x4
be_t<u32> entry_size; // Always 0x50
be_t<u32> entry_id; // Entry ID
be_t<u32> entry_unk1; // Just zeroes?
// Entry Contents
be_t<u32> trophy_id; // Trophy ID
be_t<u32> trophy_grade; // This seems interesting
be_t<u32> unk5; // Seems to be FF FF FF FF
char unk6[68]; // Just zeroes?
};
struct TROPUSREntry6
{
// Entry Header
be_t<u32> entry_type; // Always 6
be_t<u32> entry_size; // Always 0x60
be_t<u32> entry_id; // Entry ID
be_t<u32> entry_unk1; // Just zeroes?
// Entry Contents
be_t<u32> trophy_id; // Trophy ID
be_t<u32> trophy_state; // Wild guess: 00 00 00 00 = Locked, 00 00 00 01 = Unlocked
be_t<u32> unk4; // This seems interesting
be_t<u32> unk5; // Just zeroes?
be_t<u64> timestamp1;
be_t<u64> timestamp2;
char unk6[64]; // Just zeroes?
};
class TROPUSRLoader
{
vfsStream* m_file;
TROPUSRHeader m_header;
std::vector<TROPUSRTableHeader> m_tableHeaders;
std::vector<TROPUSREntry4> m_table4;
std::vector<TROPUSREntry6> m_table6;
virtual bool Generate(std::string& filepath, std::string& configpath);
virtual bool LoadHeader();
virtual bool LoadTableHeaders();
virtual bool LoadTables();
public:
TROPUSRLoader();
~TROPUSRLoader();
virtual bool Load(std::string& filepath, std::string& configpath);
virtual bool Save(std::string& filepath);
virtual bool Close();
virtual u32 GetTrophiesCount();
virtual u32 GetTrophyUnlockState(u32 id);
virtual u32 GetTrophyTimestamp(u32 id);
virtual bool UnlockTrophy(u32 id, u64 timestamp1, u64 timestamp2);
};

View file

@ -5,14 +5,20 @@ TRPLoader::TRPLoader(vfsStream& f) : trp_f(f)
{ {
} }
TRPLoader::~TRPLoader()
{
Close();
}
bool TRPLoader::Install(std::string dest, bool show) bool TRPLoader::Install(std::string dest, bool show)
{ {
if(!trp_f.IsOpened()) return false; if(!trp_f.IsOpened())
if(!LoadHeader(show)) return false; return false;
if (!dest.empty() && dest.back() != '/') if (!dest.empty() && dest.back() != '/')
dest += '/'; dest += '/';
Emu.GetVFS().CreateDir(dest);
for (const TRPEntry& entry : m_entries) for (const TRPEntry& entry : m_entries)
{ {
char* buffer = new char [entry.size]; char* buffer = new char [entry.size];
@ -28,13 +34,11 @@ bool TRPLoader::Install(std::string dest, bool show)
return true; return true;
} }
bool TRPLoader::Close()
{
return trp_f.Close();
}
bool TRPLoader::LoadHeader(bool show) bool TRPLoader::LoadHeader(bool show)
{ {
if(!trp_f.IsOpened())
return false;
trp_f.Seek(0); trp_f.Seek(0);
if (trp_f.Read(&m_header, sizeof(TRPHeader)) != sizeof(TRPHeader)) if (trp_f.Read(&m_header, sizeof(TRPHeader)) != sizeof(TRPHeader))
return false; return false;
@ -59,3 +63,36 @@ bool TRPLoader::LoadHeader(bool show)
return true; return true;
} }
bool TRPLoader::ContainsEntry(char *filename)
{
for (const TRPEntry& entry : m_entries) {
if (!strcmp(entry.name, filename))
return true;
}
return false;
}
void TRPLoader::RemoveEntry(char *filename)
{
std::vector<TRPEntry>::iterator i = m_entries.begin();
while (i != m_entries.end()) {
if (!strcmp(i->name, filename))
i = m_entries.erase(i);
else
i++;
}
}
void TRPLoader::RenameEntry(char *oldname, char *newname)
{
for (const TRPEntry& entry : m_entries) {
if (!strcmp(entry.name, oldname))
memcpy((void*)entry.name, newname, 32);
}
}
bool TRPLoader::Close()
{
return trp_f.Close();
}

View file

@ -30,7 +30,13 @@ class TRPLoader
public: public:
TRPLoader(vfsStream& f); TRPLoader(vfsStream& f);
~TRPLoader();
virtual bool Install(std::string dest, bool show = false); virtual bool Install(std::string dest, bool show = false);
virtual bool LoadHeader(bool show = false); virtual bool LoadHeader(bool show = false);
virtual bool ContainsEntry(char *filename);
virtual void RemoveEntry(char *filename);
virtual void RenameEntry(char *oldname, char *newname);
virtual bool Close(); virtual bool Close();
}; };

View file

@ -300,6 +300,7 @@
<ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellResc.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellRtc.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellRtc.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSaveData.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSpurs.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellSpurs.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSync.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellSync.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" /> <ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
@ -338,6 +339,7 @@
<ClCompile Include="Loader\PKG.cpp" /> <ClCompile Include="Loader\PKG.cpp" />
<ClCompile Include="Loader\PSF.cpp" /> <ClCompile Include="Loader\PSF.cpp" />
<ClCompile Include="Loader\SELF.cpp" /> <ClCompile Include="Loader\SELF.cpp" />
<ClCompile Include="Loader\TROPUSR.cpp" />
<ClCompile Include="Loader\TRP.cpp" /> <ClCompile Include="Loader\TRP.cpp" />
<ClCompile Include="rpcs3.cpp" /> <ClCompile Include="rpcs3.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">

View file

@ -469,6 +469,12 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_Spinlock.cpp"> <ClCompile Include="Emu\SysCalls\lv2\SC_Spinlock.cpp">
<Filter>Emu\SysCalls\lv2</Filter> <Filter>Emu\SysCalls\lv2</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Loader\TROPUSR.cpp">
<Filter>Loader</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Modules\cellSaveData.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="rpcs3.rc" /> <ResourceCompile Include="rpcs3.rc" />