mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-24 19:52:37 +01:00
Merge branch 'master' of https://github.com/DHrpcs3/rpcs3
This commit is contained in:
commit
cad7a05848
@ -1418,6 +1418,10 @@ private:
|
||||
{
|
||||
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)
|
||||
{
|
||||
DisAsm_R2_OE_RC("addze", rd, ra, oe, rc);
|
||||
@ -1434,6 +1438,10 @@ private:
|
||||
{
|
||||
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)
|
||||
{
|
||||
DisAsm_R3_OE_RC("mulld", rd, ra, rb, oe, rc);
|
||||
@ -1637,6 +1645,10 @@ private:
|
||||
{
|
||||
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)
|
||||
{
|
||||
DisAsm_F1_R2("lfsux", frd, ra, rb);
|
||||
@ -1669,6 +1681,10 @@ private:
|
||||
{
|
||||
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)
|
||||
{
|
||||
DisAsm_F1_R2("stfdx", frs, ra, rb);
|
||||
|
@ -489,10 +489,12 @@ namespace PPU_instr
|
||||
/*0x0b5*/bind_instr(g1f_list, STDUX, RS, RA, RB);
|
||||
/*0x0b7*/bind_instr(g1f_list, STWUX, RS, 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);
|
||||
/*0x0d6*/bind_instr(g1f_list, STDCX_, RS, RA, RB);
|
||||
/*0x0d7*/bind_instr(g1f_list, STBX, RS, 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);
|
||||
/*0x0ea*/bind_instr(g1f_list, ADDME, RD, RA, 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);
|
||||
/*0x227*/bind_instr(g1f_list, LVRX, VD, 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);
|
||||
/*0x257*/bind_instr(g1f_list, LFDX, 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);
|
||||
/*0x297*/bind_instr(g1f_list, STFSX, FRS, 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);
|
||||
/*0x307*/bind_instr(g1f_list, LVLXL, VD, RA, RB);
|
||||
/*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB);
|
||||
|
@ -2612,10 +2612,10 @@ private:
|
||||
}
|
||||
void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
|
||||
{
|
||||
const s64 RA = CPU.GPR[ra];
|
||||
const s64 RB = CPU.GPR[rb];
|
||||
CPU.GPR[ra] = ~RA + RB + CPU.XER.CA;
|
||||
CPU.XER.CA = ((u64)~RA + CPU.XER.CA > ~(u64)RB) | ((RA == 0) & CPU.XER.CA);
|
||||
const u64 RA = CPU.GPR[ra];
|
||||
const u64 RB = CPU.GPR[rb];
|
||||
CPU.GPR[rd] = ~RA + RB + 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(oe) UNK("subfeo");
|
||||
}
|
||||
@ -2734,6 +2734,14 @@ private:
|
||||
if(oe) ConLog.Warning("addzeo");
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
const u64 addr = CPU.GPR[ra] + CPU.GPR[rb];
|
||||
@ -3073,6 +3117,34 @@ private:
|
||||
|
||||
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)
|
||||
{
|
||||
Memory.Write64((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), (u64&)CPU.FPR[frs]);
|
||||
|
@ -301,11 +301,13 @@ namespace PPU_opcodes
|
||||
STDUX = 0x0b5,
|
||||
STWUX = 0x0b7,
|
||||
STVEWX = 0x0c7, //Store Vector Element Word Indexed
|
||||
ADDZE = 0x0ca,
|
||||
SUBFZE = 0x0c8,
|
||||
ADDZE = 0x0ca,
|
||||
STDCX_ = 0x0d6,
|
||||
STBX = 0x0d7,
|
||||
STVX = 0x0e7,
|
||||
MULLD = 0x0e9,
|
||||
SUBFME = 0x0e8,
|
||||
MULLD = 0x0e9,
|
||||
ADDME = 0x0ea,
|
||||
MULLW = 0x0eb,
|
||||
DCBTST = 0x0f6,
|
||||
@ -347,7 +349,8 @@ namespace PPU_opcodes
|
||||
SRW = 0x218,
|
||||
SRD = 0x21b,
|
||||
LVRX = 0x227, //Load Vector Right Indexed
|
||||
LFSUX = 0x237,
|
||||
LFSUX = 0x237,
|
||||
LSWI = 0x255,
|
||||
SYNC = 0x256,
|
||||
LFDX = 0x257,
|
||||
LFDUX = 0x277,
|
||||
@ -355,6 +358,7 @@ namespace PPU_opcodes
|
||||
STWBRX = 0x296,
|
||||
STFSX = 0x297,
|
||||
STVRX = 0x2a7, //Store Vector Right Indexed
|
||||
STSWI = 0x2d5,
|
||||
STFDX = 0x2d7, //Store Floating-Point Double Indexed
|
||||
LVLXL = 0x307, //Load Vector Left Indexed Last
|
||||
LHBRX = 0x316,
|
||||
@ -693,11 +697,13 @@ public:
|
||||
virtual void STDUX(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 SUBFZE(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 STBX(u32 rs, 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 SUBFME(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 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 SRD(u32 ra, u32 rs, u32 rb, bool rc) = 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 SYNC(u32 l) = 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 STFSX(u32 frs, 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 LVLXL(u32 vd, u32 ra, u32 rb) = 0;
|
||||
virtual void LHBRX(u32 rd, u32 ra, u32 rb) = 0;
|
||||
|
@ -226,7 +226,6 @@ vfsDevice* VFS::GetDevice(const wxString& ps3_path, wxString& path) const
|
||||
}
|
||||
|
||||
if(max_i < 0) return nullptr;
|
||||
|
||||
path = vfsDevice::GetWinPath(m_devices[max_i].GetLocalPath(), ps3_path(max_eq, ps3_path.Len() - max_eq));
|
||||
return &m_devices[max_i];
|
||||
}
|
||||
@ -303,27 +302,27 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
|
||||
{
|
||||
int idx;
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(EmulatorDir)\\dev_hdd0\\";
|
||||
res[idx].path = "$(EmulatorDir)/dev_hdd0/";
|
||||
res[idx].mount = "/dev_hdd0/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(EmulatorDir)\\dev_hdd1\\";
|
||||
res[idx].path = "$(EmulatorDir)/dev_hdd1/";
|
||||
res[idx].mount = "/dev_hdd1/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(EmulatorDir)\\dev_flash\\";
|
||||
res[idx].path = "$(EmulatorDir)/dev_flash/";
|
||||
res[idx].mount = "/dev_flash/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(EmulatorDir)\\dev_usb000\\";
|
||||
res[idx].path = "$(EmulatorDir)/dev_usb000/";
|
||||
res[idx].mount = "/dev_usb000/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(EmulatorDir)\\dev_usb000\\";
|
||||
res[idx].path = "$(EmulatorDir)/dev_usb000/";
|
||||
res[idx].mount = "/dev_usb/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
@ -333,7 +332,7 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
idx = res.Move(new VFSManagerEntry());
|
||||
res[idx].path = "$(GameDir)\\..\\";
|
||||
res[idx].path = "$(GameDir)/../";
|
||||
res[idx].mount = "/dev_bdvd/";
|
||||
res[idx].device = vfsDevice_LocalFile;
|
||||
|
||||
|
@ -48,8 +48,8 @@ u32 vfsDevice::CmpLocalPath(const wxString& local_path)
|
||||
wxFileName path0(m_local_path);
|
||||
path0.Normalize();
|
||||
|
||||
wxArrayString arr0 = wxSplit(path0.GetFullPath(), '\\');
|
||||
wxArrayString arr1 = wxSplit(local_path, '\\');
|
||||
wxArrayString arr0 = wxSplit(path0.GetFullPath(), '/');
|
||||
wxArrayString arr1 = wxSplit(local_path, '/');
|
||||
|
||||
const u32 lim = min(arr0.GetCount(), arr1.GetCount());
|
||||
u32 ret = 0;
|
||||
@ -168,7 +168,7 @@ wxString vfsDevice::GetWinPath(const wxString& p, bool is_dir)
|
||||
{
|
||||
if(!is_ls)
|
||||
{
|
||||
ret += '\\';
|
||||
ret += '/';
|
||||
is_ls = true;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ wxString vfsDevice::GetWinPath(const wxString& p, bool is_dir)
|
||||
ret += p[i];
|
||||
}
|
||||
|
||||
if(is_dir && ret[ret.Len() - 1] != '\\') ret += '\\';
|
||||
if(is_dir && ret[ret.Len() - 1] != '/') ret += '/';
|
||||
|
||||
wxFileName res(ret);
|
||||
res.Normalize();
|
||||
@ -191,7 +191,7 @@ wxString vfsDevice::GetWinPath(const wxString& l, const wxString& r)
|
||||
if(l.IsEmpty()) return GetWinPath(r, false);
|
||||
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)
|
||||
|
@ -56,7 +56,7 @@ bool vfsLocalFile::Create(const wxString& path)
|
||||
for(uint p=1; 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')
|
||||
break;
|
||||
@ -70,7 +70,7 @@ bool vfsLocalFile::Create(const wxString& path)
|
||||
}
|
||||
|
||||
//create file
|
||||
if(path(path.Len() - 1, 1) != '\\' && !wxFileExists(path))
|
||||
if(path(path.Len() - 1, 1) != '/' && !wxFileExists(path))
|
||||
{
|
||||
wxFile f;
|
||||
return f.Create(path);
|
||||
|
@ -302,7 +302,7 @@ public:
|
||||
void Save(RSXTexture& tex)
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -38,6 +38,9 @@ void RSXTexture::Init()
|
||||
|
||||
// Image Rect
|
||||
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
|
||||
@ -195,6 +198,11 @@ u16 RSXTexture::GetHeight() const
|
||||
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)
|
||||
{
|
||||
m_depth = depth;
|
||||
|
@ -58,5 +58,8 @@ public:
|
||||
u16 GetWidth() const;
|
||||
u16 GetHeight() const;
|
||||
|
||||
// Border Color
|
||||
u32 GetBorderColor() const;
|
||||
|
||||
void SetControl3(u16 depth, u32 pitch);
|
||||
};
|
||||
|
@ -322,6 +322,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
}
|
||||
break;
|
||||
|
||||
case_16(NV4097_SET_TEXTURE_BORDER_COLOR,0x20):
|
||||
{
|
||||
}
|
||||
|
||||
case NV4097_SET_SURFACE_FORMAT:
|
||||
{
|
||||
u32 a0 = ARGS(0);
|
||||
|
@ -695,7 +695,7 @@ public:
|
||||
|
||||
do
|
||||
{
|
||||
if(s[pos] == '\\' || s[pos] == '\0')
|
||||
if(s[pos] == '/' || s[pos] == '\0')
|
||||
{
|
||||
if(file_pos != -1)
|
||||
{
|
||||
|
@ -459,6 +459,9 @@ void cellFontRenderSurfaceInit(mem_ptr_t<CellFontRenderSurface> surface, u32 buf
|
||||
surface->pixelSizeByte = pixelSizeByte;
|
||||
surface->width = w;
|
||||
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)
|
||||
|
@ -116,14 +116,10 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameConten
|
||||
type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr());
|
||||
|
||||
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;
|
||||
|
||||
// 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
|
||||
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->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
|
||||
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);
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
// TODO: Is this really a module? Or is everything part of cellSysutil?
|
||||
void cellSaveData_init();
|
||||
Module cellSaveData("cellSaveData", cellSaveData_init);
|
||||
|
||||
@ -21,206 +22,227 @@ enum
|
||||
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
|
||||
struct CellSaveDataSetList
|
||||
{
|
||||
unsigned int sortType;
|
||||
unsigned int sortOrder;
|
||||
char *dirNamePrefix;
|
||||
be_t<u32> sortType;
|
||||
be_t<u32> sortOrder;
|
||||
be_t<u32> dirNamePrefix_addr; // char*
|
||||
};
|
||||
|
||||
struct CellSaveDataSetBuf
|
||||
{
|
||||
unsigned int dirListMax;
|
||||
unsigned int fileListMax;
|
||||
unsigned int reserved[6];
|
||||
unsigned int bufSize;
|
||||
void *buf;
|
||||
be_t<u32> dirListMax;
|
||||
be_t<u32> fileListMax;
|
||||
be_t<u32> reserved[6];
|
||||
be_t<u32> bufSize;
|
||||
be_t<u32> buf_addr; // void*
|
||||
};
|
||||
|
||||
struct CellSaveDataNewDataIcon
|
||||
{
|
||||
char *title;
|
||||
unsigned int iconBufSize;
|
||||
void *iconBuf;
|
||||
be_t<u32> title_addr; // char*
|
||||
be_t<u32> iconBufSize;
|
||||
be_t<u32> iconBuf_addr; // void*
|
||||
};
|
||||
|
||||
struct CellSaveDataListNewData
|
||||
{
|
||||
unsigned int iconPosition;
|
||||
char *dirName;
|
||||
CellSaveDataNewDataIcon *icon;
|
||||
be_t<u32> iconPosition;
|
||||
be_t<u32> dirName_addr; // char*
|
||||
be_t<u32> icon_addr; // CellSaveDataNewDataIcon*
|
||||
};
|
||||
|
||||
struct CellSaveDataDirList
|
||||
{
|
||||
char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
char listParam; //[CELL_SAVEDATA_SYSP_LPARAM_SIZE];
|
||||
s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
s8 listParam[CELL_SAVEDATA_SYSP_LPARAM_SIZE];
|
||||
};
|
||||
|
||||
struct CellSaveDataListGet
|
||||
{
|
||||
unsigned int dirNum;
|
||||
unsigned int dirListNum;
|
||||
CellSaveDataDirList *dirList;
|
||||
be_t<u32> dirNum;
|
||||
be_t<u32> dirListNum;
|
||||
be_t<u32> dirList_addr; // CellSaveDataDirList*
|
||||
};
|
||||
|
||||
struct CellSaveDataListSet
|
||||
{
|
||||
unsigned int focusPosition;
|
||||
char *focusDirName;
|
||||
unsigned int fixedListNum;
|
||||
CellSaveDataDirList *fixedList;
|
||||
CellSaveDataListNewData *newData;
|
||||
be_t<u32> focusPosition;
|
||||
be_t<u32> focusDirName_addr; // char*
|
||||
be_t<u32> fixedListNum;
|
||||
be_t<u32> fixedList_addr; // CellSaveDataDirList*
|
||||
be_t<u32> newData_addr; // CellSaveDataListNewData*
|
||||
};
|
||||
|
||||
struct CellSaveDataFixedSet
|
||||
{
|
||||
char *dirName;
|
||||
CellSaveDataNewDataIcon *newIcon;
|
||||
unsigned int option;
|
||||
be_t<u32> dirName_addr; // char*
|
||||
be_t<u32> newIcon_addr; // CellSaveDataNewDataIcon*
|
||||
be_t<u32> option;
|
||||
};
|
||||
|
||||
struct CellSaveDataSystemFileParam
|
||||
{
|
||||
char title; //[CELL_SAVEDATA_SYSP_TITLE_SIZE];
|
||||
char subTitle; //[CELL_SAVEDATA_SYSP_SUBTITLE_SIZE];
|
||||
char detail; //[CELL_SAVEDATA_SYSP_DETAIL_SIZE];
|
||||
unsigned int attribute;
|
||||
char reserved2[4];
|
||||
char listParam; //[CELL_SAVEDATA_SYSP_LPARAM_SIZE];
|
||||
char reserved[256];
|
||||
s8 title[CELL_SAVEDATA_SYSP_TITLE_SIZE];
|
||||
s8 subTitle[CELL_SAVEDATA_SYSP_SUBTITLE_SIZE];
|
||||
s8 detail[CELL_SAVEDATA_SYSP_DETAIL_SIZE];
|
||||
be_t<u32> attribute;
|
||||
s8 reserved2[4];
|
||||
s8 listParam[CELL_SAVEDATA_SYSP_LPARAM_SIZE];
|
||||
s8 reserved[256];
|
||||
};
|
||||
|
||||
struct CellSaveDataDirStat
|
||||
{
|
||||
s64 st_atime_;
|
||||
s64 st_mtime_;
|
||||
s64 st_ctime_;
|
||||
char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
be_t<s64> st_atime_;
|
||||
be_t<s64> st_mtime_;
|
||||
be_t<s64> st_ctime_;
|
||||
s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
};
|
||||
|
||||
struct CellSaveDataFileStat
|
||||
{
|
||||
unsigned int fileType;
|
||||
char reserved1[4];
|
||||
u64 st_size;
|
||||
s64 st_atime_;
|
||||
s64 st_mtime_;
|
||||
s64 st_ctime_;
|
||||
char fileName; //[CELL_SAVEDATA_FILENAME_SIZE];
|
||||
char reserved2[3];
|
||||
be_t<u32> fileType;
|
||||
u8 reserved1[4];
|
||||
be_t<u64> st_size;
|
||||
be_t<s64> st_atime_;
|
||||
be_t<s64> st_mtime_;
|
||||
be_t<s64> st_ctime_;
|
||||
u8 fileName[CELL_SAVEDATA_FILENAME_SIZE];
|
||||
u8 reserved2[3];
|
||||
};
|
||||
|
||||
struct CellSaveDataStatGet
|
||||
{
|
||||
int hddFreeSizeKB;
|
||||
unsigned int isNewData;
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
be_t<u32> isNewData;
|
||||
CellSaveDataDirStat dir;
|
||||
CellSaveDataSystemFileParam getParam;
|
||||
unsigned int bind;
|
||||
int sizeKB;
|
||||
int sysSizeKB;
|
||||
unsigned int fileNum;
|
||||
unsigned int fileListNum;
|
||||
CellSaveDataFileStat *fileList;
|
||||
be_t<u32> bind;
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> sysSizeKB;
|
||||
be_t<u32> fileNum;
|
||||
be_t<u32> fileListNum;
|
||||
be_t<u32> fileList_addr; // CellSaveDataFileStat*
|
||||
};
|
||||
|
||||
struct CellSaveDataAutoIndicator
|
||||
{
|
||||
unsigned int dispPosition;
|
||||
unsigned int dispMode;
|
||||
char *dispMsg;
|
||||
unsigned int picBufSize;
|
||||
void *picBuf;
|
||||
be_t<u32> dispPosition;
|
||||
be_t<u32> dispMode;
|
||||
be_t<u32> dispMsg_addr; // char*
|
||||
be_t<u32> picBufSize;
|
||||
be_t<u32> picBuf_addr; // void*
|
||||
};
|
||||
|
||||
struct CellSaveDataStatSet
|
||||
{
|
||||
CellSaveDataSystemFileParam *setParam;
|
||||
unsigned int reCreateMode;
|
||||
CellSaveDataAutoIndicator *indicator;
|
||||
be_t<u32> setParam_addr; // CellSaveDataSystemFileParam*
|
||||
be_t<u32> reCreateMode;
|
||||
be_t<u32> indicator_addr; // CellSaveDataAutoIndicator*
|
||||
};
|
||||
|
||||
struct CellSaveDataFileGet
|
||||
{
|
||||
unsigned int excSize;
|
||||
be_t<u32> excSize;
|
||||
};
|
||||
|
||||
struct CellSaveDataFileSet
|
||||
{
|
||||
unsigned int fileOperation;
|
||||
void *reserved;
|
||||
unsigned int fileType;
|
||||
unsigned char secureFileId; //[CELL_SAVEDATA_SECUREFILEID_SIZE];
|
||||
char *fileName;
|
||||
unsigned int fileOffset;
|
||||
unsigned int fileSize;
|
||||
unsigned int fileBufSize;
|
||||
void *fileBuf;
|
||||
be_t<u32> fileOperation;
|
||||
be_t<u32> reserved_addr; // void*
|
||||
be_t<u32> fileType;
|
||||
u8 secureFileId[CELL_SAVEDATA_SECUREFILEID_SIZE];
|
||||
be_t<u32> fileName_addr; // char*
|
||||
be_t<u32> fileOffset;
|
||||
be_t<u32> fileSize;
|
||||
be_t<u32> fileBufSize;
|
||||
be_t<u32> fileBuf_addr; // void*
|
||||
};
|
||||
|
||||
struct CellSaveDataCBResult
|
||||
{
|
||||
int result;
|
||||
unsigned int progressBarInc;
|
||||
int errNeedSizeKB;
|
||||
char *invalidMsg;
|
||||
void *userdata;
|
||||
be_t<s32> result;
|
||||
be_t<u32> progressBarInc;
|
||||
be_t<s32> errNeedSizeKB;
|
||||
be_t<u32> invalidMsg_addr; // char*
|
||||
be_t<u32> userdata_addr; // void*
|
||||
};
|
||||
|
||||
struct CellSaveDataDoneGet
|
||||
{
|
||||
int excResult;
|
||||
char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
int sizeKB;
|
||||
int hddFreeSizeKB;
|
||||
be_t<s32> excResult;
|
||||
s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
};
|
||||
|
||||
// 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return CELL_SAVEDATA_RET_OK;
|
||||
@ -238,49 +260,49 @@ int cellSaveDataFixedDelete() //CellSaveDataSetList *setList, CellSaveDataSetBuf
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return CELL_SAVEDATA_RET_OK;
|
||||
@ -302,31 +324,31 @@ int cellSaveDataListDelete() //CellSaveDataSetList *setList, CellSaveDataSetBuf
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return CELL_SAVEDATA_RET_OK;
|
||||
@ -338,31 +360,31 @@ int cellSaveDataUserListDelete() //CellSysutilUserId userId, CellSaveDataSetList
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return CELL_SAVEDATA_RET_OK;
|
||||
|
@ -3,147 +3,13 @@
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include "Emu/Audio/sysutil_audio.h"
|
||||
|
||||
// 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,
|
||||
#include "cellSysutil.h"
|
||||
|
||||
//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 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,
|
||||
};
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
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();
|
||||
Module cellSysutil(0x0015, cellSysutil_init);
|
||||
@ -161,7 +27,7 @@ int cellSysutilGetSystemParamInt(int id, mem32_t value)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
|
||||
cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_LANG");
|
||||
value = CELL_SYSUTIL_LANG_ENGLISH_US;
|
||||
value = Ini.SysLanguage.GetValue();
|
||||
break;
|
||||
|
||||
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];
|
||||
strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE);
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt);
|
||||
@ -1010,4 +942,9 @@ void cellSysutil_init()
|
||||
cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount);
|
||||
cellSysutil.AddFunc(0x744c1544, cellSysCacheClear);
|
||||
|
||||
cellSysutil.AddFunc(0x9117df20, cellHddGameCheck);
|
||||
//cellSysutil.AddFunc(0x4bdec82a, cellHddGameCheck2);
|
||||
//cellSysutil.AddFunc(0xf82e2ef7, cellHddGameGetSizeKB);
|
||||
//cellSysutil.AddFunc(0x9ca9ffa7, cellHddGameSetSystemVer);
|
||||
//cellSysutil.AddFunc(0xafd605b3, cellHddGameExitBroken);
|
||||
}
|
||||
|
228
rpcs3/Emu/SysCalls/Modules/cellSysutil.h
Normal file
228
rpcs3/Emu/SysCalls/Modules/cellSysutil.h
Normal 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*
|
||||
};
|
@ -28,28 +28,28 @@ enum CellUserInfoListType
|
||||
// Structs
|
||||
struct CellUserInfoUserStat
|
||||
{
|
||||
u32 id;
|
||||
be_t<u32> id;
|
||||
u8 name[CELL_USERINFO_USERNAME_SIZE];
|
||||
};
|
||||
|
||||
struct CellUserInfoUserList
|
||||
{
|
||||
u32 userId[CELL_USERINFO_USER_MAX];
|
||||
be_t<u32> userId[CELL_USERINFO_USER_MAX];
|
||||
};
|
||||
|
||||
struct CellUserInfoListSet
|
||||
{
|
||||
u32 title_addr; // (char*)
|
||||
u32 focus;
|
||||
u32 fixedListNum;
|
||||
be_t<u32> title_addr; // (char*)
|
||||
be_t<u32> focus;
|
||||
be_t<u32> fixedListNum;
|
||||
mem_ptr_t<CellUserInfoUserList> fixedList;
|
||||
u32 reserved_addr; // (void*)
|
||||
be_t<u32> reserved_addr; // (void*)
|
||||
};
|
||||
|
||||
struct CellUserInfoTypeSet
|
||||
{
|
||||
u32 title_addr; // (char*)
|
||||
u32 focus;
|
||||
be_t<u32> title_addr; // (char*)
|
||||
be_t<u32> focus;
|
||||
CellUserInfoListType type;
|
||||
u32 reserved_addr; // (void*)
|
||||
be_t<u32> reserved_addr; // (void*)
|
||||
};
|
||||
|
@ -1,10 +1,14 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include "wx/xml/xml.h"
|
||||
|
||||
#include "sceNp.h"
|
||||
#include "sceNpTrophy.h"
|
||||
|
||||
#include "Loader/TRP.h"
|
||||
#include "Loader/TROPUSR.h"
|
||||
#include "Emu/SysCalls/lv2/SC_Time.h"
|
||||
|
||||
void sceNpTrophy_unload();
|
||||
void sceNpTrophy_init();
|
||||
@ -16,6 +20,8 @@ struct sceNpTrophyInternalContext
|
||||
// TODO
|
||||
std::string trp_name;
|
||||
vfsStream* trp_stream;
|
||||
|
||||
TROPUSRLoader* tropusr;
|
||||
};
|
||||
|
||||
struct sceNpTrophyInternal
|
||||
@ -116,23 +122,49 @@ int sceNpTrophyRegisterContext(u32 context, u32 handle, u32 statusCb_addr, u32 a
|
||||
// TODO: There are other possible errors
|
||||
|
||||
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
|
||||
|
||||
if (!ctxt.trp_stream)
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
|
||||
int ret;
|
||||
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
|
||||
if (trp.Install("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name))
|
||||
ret = CELL_OK;
|
||||
else
|
||||
ret = SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name;
|
||||
if (!trp.Install(trophyPath))
|
||||
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
|
||||
|
||||
TROPUSRLoader* tropusr = new TROPUSRLoader();
|
||||
tropusr->Load(trophyPath + "/TROPUSR.DAT", trophyPath + "/TROPCONF.SFM");
|
||||
ctxt.tropusr = tropusr;
|
||||
|
||||
// TODO: Callbacks
|
||||
|
||||
trp.Close();
|
||||
return ret;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyGetGameProgress()
|
||||
@ -161,7 +193,6 @@ int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, mem64_t reqspace, u
|
||||
// TODO: There are other possible errors
|
||||
|
||||
sceNpTrophyInternalContext& ctxt = s_npTrophyInstance.contexts[context];
|
||||
|
||||
if (!ctxt.trp_stream)
|
||||
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;
|
||||
// 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
|
||||
memcpy(details->title, "Trophy Set", SCE_NP_TROPHY_NAME_MAX_SIZE);
|
||||
memcpy(details->description, "Hey! Implement a XML reader, and load the description from TROP.SFM", SCE_NP_TROPHY_DESCR_MAX_SIZE);
|
||||
details->numTrophies = 0;
|
||||
details->numPlatinum = 0;
|
||||
details->numGold = 0;
|
||||
details->numSilver = 0;
|
||||
details->numBronze = 0;
|
||||
data->unlockedTrophies = 0;
|
||||
data->unlockedPlatinum = 0;
|
||||
data->unlockedGold = 0;
|
||||
data->unlockedSilver = 0;
|
||||
data->unlockedBronze = 0;
|
||||
std::string titleName;
|
||||
std::string titleDetail;
|
||||
for (wxXmlNode *n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
|
||||
if (n->GetName() == "title-name")
|
||||
titleName = n->GetNodeContent().mb_str();
|
||||
if (n->GetName() == "title-detail")
|
||||
titleDetail = n->GetNodeContent().mb_str();
|
||||
if (n->GetName() == "trophy")
|
||||
{
|
||||
u32 trophy_id = atoi(n->GetAttribute("id").mb_str());
|
||||
|
||||
details->numTrophies++;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -216,9 +272,29 @@ int sceNpTrophyDestroyHandle()
|
||||
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;
|
||||
}
|
||||
|
||||
@ -228,9 +304,31 @@ int sceNpTrophyTerm()
|
||||
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;
|
||||
}
|
||||
|
||||
@ -251,14 +349,43 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, mem_ptr_t<Sc
|
||||
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
// 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
|
||||
memcpy(details->name, "Some Trophy", SCE_NP_TROPHY_NAME_MAX_SIZE);
|
||||
memcpy(details->description, "Hey! Implement a XML reader, and load the description from TROP.SFM", SCE_NP_TROPHY_DESCR_MAX_SIZE);
|
||||
details->hidden = false;
|
||||
details->trophyId = trophyId;
|
||||
details->trophyGrade = SCE_NP_TROPHY_GRADE_GOLD;
|
||||
std::string name;
|
||||
std::string detail;
|
||||
for (wxXmlNode *n = doc.GetRoot()->GetChildren(); n; n = n->GetNext()) {
|
||||
if (n->GetName() == "trophy" && (trophyId == atoi(n->GetAttribute("id").mb_str())))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,13 @@ enum
|
||||
SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE = 1024,
|
||||
SCE_NP_TROPHY_NAME_MAX_SIZE = 128,
|
||||
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
|
||||
@ -68,11 +75,11 @@ enum SceNpTrophyGrade
|
||||
|
||||
struct SceNpTrophyGameDetails
|
||||
{
|
||||
u32 numTrophies;
|
||||
u32 numPlatinum;
|
||||
u32 numGold;
|
||||
u32 numSilver;
|
||||
u32 numBronze;
|
||||
be_t<u32> numTrophies;
|
||||
be_t<u32> numPlatinum;
|
||||
be_t<u32> numGold;
|
||||
be_t<u32> numSilver;
|
||||
be_t<u32> numBronze;
|
||||
u8 title[SCE_NP_TROPHY_TITLE_MAX_SIZE];
|
||||
u8 description[SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE];
|
||||
u8 reserved[4];
|
||||
@ -80,26 +87,32 @@ struct SceNpTrophyGameDetails
|
||||
|
||||
struct SceNpTrophyGameData
|
||||
{
|
||||
u32 unlockedTrophies;
|
||||
u32 unlockedPlatinum;
|
||||
u32 unlockedGold;
|
||||
u32 unlockedSilver;
|
||||
u32 unlockedBronze;
|
||||
be_t<u32> unlockedTrophies;
|
||||
be_t<u32> unlockedPlatinum;
|
||||
be_t<u32> unlockedGold;
|
||||
be_t<u32> unlockedSilver;
|
||||
be_t<u32> unlockedBronze;
|
||||
};
|
||||
|
||||
struct SceNpTrophyDetails
|
||||
{
|
||||
s32 trophyId; // SceNpTrophyId
|
||||
u32 trophyGrade; // SceNpTrophyGrade
|
||||
be_t<s32> trophyId; // SceNpTrophyId
|
||||
be_t<u32> trophyGrade; // SceNpTrophyGrade
|
||||
u8 name[SCE_NP_TROPHY_NAME_MAX_SIZE];
|
||||
u8 description[SCE_NP_TROPHY_DESCR_MAX_SIZE];
|
||||
bool hidden;
|
||||
u8 reserved[3];
|
||||
};
|
||||
|
||||
struct SceNpTrophyData {
|
||||
struct SceNpTrophyData
|
||||
{
|
||||
CellRtcTick timestamp;
|
||||
s32 trophyId; // SceNpTrophyId
|
||||
be_t<s32> trophyId; // SceNpTrophyId
|
||||
bool unlocked;
|
||||
u8 reserved[3];
|
||||
};
|
||||
|
||||
struct SceNpTrophyFlagArray
|
||||
{
|
||||
u32 flag_bits[SCE_NP_TROPHY_FLAG_SETSIZE >> SCE_NP_TROPHY_FLAG_BITS_SHIFT];
|
||||
};
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
struct sys_net_initialize_parameter
|
||||
{
|
||||
u32 memory_addr;
|
||||
int memory_size;
|
||||
int flags;
|
||||
be_t<u32> memory_addr;
|
||||
be_t<s32> memory_size;
|
||||
be_t<s32> flags;
|
||||
};
|
||||
|
||||
// The names of the following structs are modified to avoid overloading problems
|
||||
|
@ -141,7 +141,7 @@ void Emulator::Load()
|
||||
m_path = elf_path;
|
||||
}
|
||||
|
||||
ConLog.Write("Loading '%s'...", m_path.wx_str());
|
||||
ConLog.Write("Loading '%s'...", m_path.ToStdString().c_str());
|
||||
GetInfo().Reset();
|
||||
m_vfs.Init(m_path);
|
||||
|
||||
@ -149,7 +149,7 @@ void Emulator::Load()
|
||||
ConLog.Write("Mount info:");
|
||||
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();
|
||||
|
||||
@ -162,7 +162,7 @@ void Emulator::Load()
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -441,7 +441,7 @@ void Emulator::LoadPoints(const std::string& path)
|
||||
if(version != bpdb_version ||
|
||||
(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;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,6 @@ AboutDialog::AboutDialog(wxWindow *parent)
|
||||
wxButton* b_forum = new wxButton(this, b_id_forum, "Forum");
|
||||
Connect(b_id_website, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutDialog::OpenWebsite));
|
||||
Connect(b_id_forum, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutDialog::OpenForum));
|
||||
b_website->Disable();
|
||||
|
||||
s_panel_buttons->AddSpacer(12);
|
||||
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))
|
||||
{
|
||||
wxLaunchDefaultBrowser("http://www.emunewz.net/forum/forumdisplay.php?fid=162");
|
||||
wxLaunchDefaultBrowser("http://rpcs3.net/");
|
||||
}
|
||||
|
||||
void AboutDialog::OpenForum(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxLaunchDefaultBrowser("http://www.emunewz.net/forum/forumdisplay.php?fid=162");
|
||||
wxLaunchDefaultBrowser("http://forum.rpcs3.net/");
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
|
||||
}
|
||||
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_subpanel1(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_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_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_gs_render = 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_audio_out = 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_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("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_gs_log_prog->SetValue(Ini.GSLogPrograms.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_audio_out->SetSelection(Ini.AudioOutMode.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->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_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));
|
||||
|
||||
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_audio, 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_subpanel2, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_panel->Add(s_subpanel3, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
|
||||
diag.SetSizerAndFit( s_panel );
|
||||
|
||||
@ -500,6 +530,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue());
|
||||
Ini.HLEExitOnStop.SetValue(chbox_hle_exitonstop->GetValue());
|
||||
Ini.HLELogLvl.SetValue(cbox_hle_loglvl->GetSelection());
|
||||
Ini.SysLanguage.SetValue(cbox_sys_lang->GetSelection());
|
||||
|
||||
Ini.Save();
|
||||
}
|
||||
|
@ -110,6 +110,7 @@ public:
|
||||
IniEntry<bool> HLESaveTTY;
|
||||
IniEntry<bool> HLEExitOnStop;
|
||||
IniEntry<u8> HLELogLvl;
|
||||
IniEntry<u8> SysLanguage;
|
||||
|
||||
IniEntry<int> PadHandlerLeft;
|
||||
IniEntry<int> PadHandlerDown;
|
||||
@ -178,6 +179,9 @@ public:
|
||||
HLESaveTTY.Init("HLESaveTTY", path);
|
||||
HLEExitOnStop.Init("HLEExitOnStop", path);
|
||||
HLELogLvl.Init("HLELogLvl", path);
|
||||
|
||||
path = DefPath + "/" + "System";
|
||||
SysLanguage.Init("SysLanguage", path);
|
||||
}
|
||||
|
||||
void Load()
|
||||
@ -200,6 +204,7 @@ public:
|
||||
HLESaveTTY.Load(false);
|
||||
HLEExitOnStop.Load(false);
|
||||
HLELogLvl.Load(0);
|
||||
SysLanguage.Load(1);
|
||||
|
||||
PadHandlerLeft.Load(static_cast<int>('A'));
|
||||
PadHandlerDown.Load(static_cast<int>('S'));
|
||||
@ -239,6 +244,7 @@ public:
|
||||
HLESaveTTY.Save();
|
||||
HLEExitOnStop.Save();
|
||||
HLELogLvl.Save();
|
||||
SysLanguage.Save();
|
||||
|
||||
PadHandlerLeft.Save();
|
||||
PadHandlerDown.Save();
|
||||
|
212
rpcs3/Loader/TROPUSR.cpp
Normal file
212
rpcs3/Loader/TROPUSR.cpp
Normal 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
83
rpcs3/Loader/TROPUSR.h
Normal 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);
|
||||
};
|
@ -5,14 +5,20 @@ TRPLoader::TRPLoader(vfsStream& f) : trp_f(f)
|
||||
{
|
||||
}
|
||||
|
||||
TRPLoader::~TRPLoader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool TRPLoader::Install(std::string dest, bool show)
|
||||
{
|
||||
if(!trp_f.IsOpened()) return false;
|
||||
if(!LoadHeader(show)) return false;
|
||||
if(!trp_f.IsOpened())
|
||||
return false;
|
||||
|
||||
if (!dest.empty() && dest.back() != '/')
|
||||
dest += '/';
|
||||
|
||||
Emu.GetVFS().CreateDir(dest);
|
||||
for (const TRPEntry& entry : m_entries)
|
||||
{
|
||||
char* buffer = new char [entry.size];
|
||||
@ -28,13 +34,11 @@ bool TRPLoader::Install(std::string dest, bool show)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TRPLoader::Close()
|
||||
{
|
||||
return trp_f.Close();
|
||||
}
|
||||
|
||||
bool TRPLoader::LoadHeader(bool show)
|
||||
{
|
||||
if(!trp_f.IsOpened())
|
||||
return false;
|
||||
|
||||
trp_f.Seek(0);
|
||||
if (trp_f.Read(&m_header, sizeof(TRPHeader)) != sizeof(TRPHeader))
|
||||
return false;
|
||||
@ -59,3 +63,36 @@ bool TRPLoader::LoadHeader(bool show)
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -30,7 +30,13 @@ class TRPLoader
|
||||
|
||||
public:
|
||||
TRPLoader(vfsStream& f);
|
||||
~TRPLoader();
|
||||
virtual bool Install(std::string dest, 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();
|
||||
};
|
@ -300,6 +300,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellPngDec.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellResc.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\cellSync.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
|
||||
@ -338,6 +339,7 @@
|
||||
<ClCompile Include="Loader\PKG.cpp" />
|
||||
<ClCompile Include="Loader\PSF.cpp" />
|
||||
<ClCompile Include="Loader\SELF.cpp" />
|
||||
<ClCompile Include="Loader\TROPUSR.cpp" />
|
||||
<ClCompile Include="Loader\TRP.cpp" />
|
||||
<ClCompile Include="rpcs3.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -469,6 +469,12 @@
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Spinlock.cpp">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
</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>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
|
Loading…
Reference in New Issue
Block a user