diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 540ec94110..3ca2a3a7f4 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -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); diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index 2747479d81..52767e92bc 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -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); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index e2706dce69..6904a68703 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -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(CPU.GPR[rd]); if(oe) UNK("subfeo"); } @@ -2734,6 +2734,14 @@ private: if(oe) ConLog.Warning("addzeo"); if(rc) CPU.UpdateCR0(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(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(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]); diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index 09a044092e..b0ef854bfa 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -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; diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 48174ebe77..fc2c69f7e5 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -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& 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& 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; diff --git a/rpcs3/Emu/FS/vfsDevice.cpp b/rpcs3/Emu/FS/vfsDevice.cpp index df79fcdfb4..bc1014607b 100644 --- a/rpcs3/Emu/FS/vfsDevice.cpp +++ b/rpcs3/Emu/FS/vfsDevice.cpp @@ -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) diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index 3746f94f41..ef953b4f49 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -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); diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 4bd83f26e0..3f8dc8ac39 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -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); diff --git a/rpcs3/Emu/GS/RSXTexture.cpp b/rpcs3/Emu/GS/RSXTexture.cpp index 1b150a95ac..ccf8b90d48 100644 --- a/rpcs3/Emu/GS/RSXTexture.cpp +++ b/rpcs3/Emu/GS/RSXTexture.cpp @@ -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; diff --git a/rpcs3/Emu/GS/RSXTexture.h b/rpcs3/Emu/GS/RSXTexture.h index 8b87a9d7d9..d5db3480fb 100644 --- a/rpcs3/Emu/GS/RSXTexture.h +++ b/rpcs3/Emu/GS/RSXTexture.h @@ -58,5 +58,8 @@ public: u16 GetWidth() const; u16 GetHeight() const; + // Border Color + u32 GetBorderColor() const; + void SetControl3(u16 depth, u32 pitch); }; diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 4868845eb0..66277aee02 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -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); diff --git a/rpcs3/Emu/HDD/HDD.h b/rpcs3/Emu/HDD/HDD.h index ed3650ed54..0535a018c0 100644 --- a/rpcs3/Emu/HDD/HDD.h +++ b/rpcs3/Emu/HDD/HDD.h @@ -695,7 +695,7 @@ public: do { - if(s[pos] == '\\' || s[pos] == '\0') + if(s[pos] == '/' || s[pos] == '\0') { if(file_pos != -1) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp index 9e816ba8b6..8181010427 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp @@ -459,6 +459,9 @@ void cellFontRenderSurfaceInit(mem_ptr_t 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 surface, s32 x0, s32 y0, s32 w, s32 h) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 1b3ad08eae..2f0539052f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -116,14 +116,10 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_thddFreeSizeKB 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_thddFreeSizeKB = 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; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index 82518ff22a..d0cf1a4dda 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -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 sortType; + be_t sortOrder; + be_t dirNamePrefix_addr; // char* }; struct CellSaveDataSetBuf { - unsigned int dirListMax; - unsigned int fileListMax; - unsigned int reserved[6]; - unsigned int bufSize; - void *buf; + be_t dirListMax; + be_t fileListMax; + be_t reserved[6]; + be_t bufSize; + be_t buf_addr; // void* }; struct CellSaveDataNewDataIcon { - char *title; - unsigned int iconBufSize; - void *iconBuf; + be_t title_addr; // char* + be_t iconBufSize; + be_t iconBuf_addr; // void* }; struct CellSaveDataListNewData { - unsigned int iconPosition; - char *dirName; - CellSaveDataNewDataIcon *icon; + be_t iconPosition; + be_t dirName_addr; // char* + be_t 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 dirNum; + be_t dirListNum; + be_t dirList_addr; // CellSaveDataDirList* }; struct CellSaveDataListSet { - unsigned int focusPosition; - char *focusDirName; - unsigned int fixedListNum; - CellSaveDataDirList *fixedList; - CellSaveDataListNewData *newData; + be_t focusPosition; + be_t focusDirName_addr; // char* + be_t fixedListNum; + be_t fixedList_addr; // CellSaveDataDirList* + be_t newData_addr; // CellSaveDataListNewData* }; struct CellSaveDataFixedSet { - char *dirName; - CellSaveDataNewDataIcon *newIcon; - unsigned int option; + be_t dirName_addr; // char* + be_t newIcon_addr; // CellSaveDataNewDataIcon* + be_t 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 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 st_atime_; + be_t st_mtime_; + be_t 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 fileType; + u8 reserved1[4]; + be_t st_size; + be_t st_atime_; + be_t st_mtime_; + be_t st_ctime_; + u8 fileName[CELL_SAVEDATA_FILENAME_SIZE]; + u8 reserved2[3]; }; struct CellSaveDataStatGet { - int hddFreeSizeKB; - unsigned int isNewData; + be_t hddFreeSizeKB; + be_t isNewData; CellSaveDataDirStat dir; CellSaveDataSystemFileParam getParam; - unsigned int bind; - int sizeKB; - int sysSizeKB; - unsigned int fileNum; - unsigned int fileListNum; - CellSaveDataFileStat *fileList; + be_t bind; + be_t sizeKB; + be_t sysSizeKB; + be_t fileNum; + be_t fileListNum; + be_t fileList_addr; // CellSaveDataFileStat* }; struct CellSaveDataAutoIndicator { - unsigned int dispPosition; - unsigned int dispMode; - char *dispMsg; - unsigned int picBufSize; - void *picBuf; + be_t dispPosition; + be_t dispMode; + be_t dispMsg_addr; // char* + be_t picBufSize; + be_t picBuf_addr; // void* }; struct CellSaveDataStatSet { - CellSaveDataSystemFileParam *setParam; - unsigned int reCreateMode; - CellSaveDataAutoIndicator *indicator; + be_t setParam_addr; // CellSaveDataSystemFileParam* + be_t reCreateMode; + be_t indicator_addr; // CellSaveDataAutoIndicator* }; struct CellSaveDataFileGet { - unsigned int excSize; + be_t 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 fileOperation; + be_t reserved_addr; // void* + be_t fileType; + u8 secureFileId[CELL_SAVEDATA_SECUREFILEID_SIZE]; + be_t fileName_addr; // char* + be_t fileOffset; + be_t fileSize; + be_t fileBufSize; + be_t fileBuf_addr; // void* }; struct CellSaveDataCBResult { - int result; - unsigned int progressBarInc; - int errNeedSizeKB; - char *invalidMsg; - void *userdata; + be_t result; + be_t progressBarInc; + be_t errNeedSizeKB; + be_t invalidMsg_addr; // char* + be_t userdata_addr; // void* }; struct CellSaveDataDoneGet { - int excResult; - char dirName; //[CELL_SAVEDATA_DIRNAME_SIZE]; - int sizeKB; - int hddFreeSizeKB; + be_t excResult; + s8 dirName[CELL_SAVEDATA_DIRNAME_SIZE]; + be_t sizeKB; + be_t 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; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 033dec04c5..7ce3935dd4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -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 userData); +typedef void (*CellHddGameStatCallback)(mem_ptr_t cbResult, mem_ptr_t get, mem_ptr_t 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 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 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 param; + MemoryAllocator result; + MemoryAllocator get; + MemoryAllocator 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; igetParam.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); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h new file mode 100644 index 0000000000..eb53f7ea34 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h @@ -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 attribute; + be_t parentalLevel; + be_t resolution; + be_t soundFormat; + u8 reserved2[256]; +}; + +struct CellHddGameStatGet +{ + be_t hddFreeSizeKB; + be_t isNewData; + u8 contentInfoPath[CELL_HDDGAME_PATH_MAX]; + u8 hddGamePath[CELL_HDDGAME_PATH_MAX]; + u8 reserved0[2]; + be_t st_atime; + be_t st_mtime; + be_t st_ctime; + CellHddGameSystemFileParam getParam; + be_t sizeKB; + be_t sysSizeKB; + u8 reserved1[68]; +}; + +struct CellHddGameStatSet +{ + CellHddGameSystemFileParam *setParam; + u32 reserved_addr; // void* +}; + +struct CellHddGameCBResult +{ + be_t result; + be_t errNeedSizeKB; + u8 *invalidMsg; + u32 reserved_addr; // void* +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h index 3498b0293c..c48a2f9a2b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h @@ -28,28 +28,28 @@ enum CellUserInfoListType // Structs struct CellUserInfoUserStat { - u32 id; + be_t id; u8 name[CELL_USERINFO_USERNAME_SIZE]; }; struct CellUserInfoUserList { - u32 userId[CELL_USERINFO_USER_MAX]; + be_t userId[CELL_USERINFO_USER_MAX]; }; struct CellUserInfoListSet { - u32 title_addr; // (char*) - u32 focus; - u32 fixedListNum; + be_t title_addr; // (char*) + be_t focus; + be_t fixedListNum; mem_ptr_t fixedList; - u32 reserved_addr; // (void*) + be_t reserved_addr; // (void*) }; struct CellUserInfoTypeSet { - u32 title_addr; // (char*) - u32 focus; + be_t title_addr; // (char*) + be_t focus; CellUserInfoListType type; - u32 reserved_addr; // (void*) + be_t reserved_addr; // (void*) }; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index 872c25556d..74d210413d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -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_ttitle, "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 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; idGetTrophyUnlockState(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_tname, "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; } diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h index f57f18679b..6245c0688c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h @@ -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 numTrophies; + be_t numPlatinum; + be_t numGold; + be_t numSilver; + be_t 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 unlockedTrophies; + be_t unlockedPlatinum; + be_t unlockedGold; + be_t unlockedSilver; + be_t unlockedBronze; }; struct SceNpTrophyDetails { - s32 trophyId; // SceNpTrophyId - u32 trophyGrade; // SceNpTrophyGrade + be_t trophyId; // SceNpTrophyId + be_t 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 trophyId; // SceNpTrophyId bool unlocked; u8 reserved[3]; }; + +struct SceNpTrophyFlagArray +{ + u32 flag_bits[SCE_NP_TROPHY_FLAG_SETSIZE >> SCE_NP_TROPHY_FLAG_BITS_SHIFT]; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.h b/rpcs3/Emu/SysCalls/Modules/sys_net.h index 770a6958c2..6c7abd3f37 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.h +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.h @@ -2,9 +2,9 @@ struct sys_net_initialize_parameter { - u32 memory_addr; - int memory_size; - int flags; + be_t memory_addr; + be_t memory_size; + be_t flags; }; // The names of the following structs are modified to avoid overloading problems diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 7c92cb7e3d..9e73da3995 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -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 %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; } diff --git a/rpcs3/Gui/AboutDialog.h b/rpcs3/Gui/AboutDialog.h index 794abf6d9d..975a99278d 100644 --- a/rpcs3/Gui/AboutDialog.h +++ b/rpcs3/Gui/AboutDialog.h @@ -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/"); } diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index fc6ac9f582..f66c4e89a8 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -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(); } diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 778228b97b..e0689e0972 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -110,6 +110,7 @@ public: IniEntry HLESaveTTY; IniEntry HLEExitOnStop; IniEntry HLELogLvl; + IniEntry SysLanguage; IniEntry PadHandlerLeft; IniEntry 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('A')); PadHandlerDown.Load(static_cast('S')); @@ -239,6 +244,7 @@ public: HLESaveTTY.Save(); HLEExitOnStop.Save(); HLELogLvl.Save(); + SysLanguage.Save(); PadHandlerLeft.Save(); PadHandlerDown.Save(); diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp new file mode 100644 index 0000000000..e9ed6bd30b --- /dev/null +++ b/rpcs3/Loader/TROPUSR.cpp @@ -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; +} diff --git a/rpcs3/Loader/TROPUSR.h b/rpcs3/Loader/TROPUSR.h new file mode 100644 index 0000000000..a01fd75230 --- /dev/null +++ b/rpcs3/Loader/TROPUSR.h @@ -0,0 +1,83 @@ +#pragma once + +struct TROPUSRHeader +{ + be_t magic; // 81 8F 54 AD + be_t unk1; + be_t tables_count; + be_t unk2; + char reserved[32]; +}; + +struct TROPUSRTableHeader +{ + be_t type; + be_t entries_size; + be_t unk1; // Seems to be 1 + be_t entries_count; + be_t offset; + be_t reserved; +}; + +struct TROPUSREntry4 +{ + // Entry Header + be_t entry_type; // Always 0x4 + be_t entry_size; // Always 0x50 + be_t entry_id; // Entry ID + be_t entry_unk1; // Just zeroes? + + // Entry Contents + be_t trophy_id; // Trophy ID + be_t trophy_grade; // This seems interesting + be_t unk5; // Seems to be FF FF FF FF + char unk6[68]; // Just zeroes? +}; + +struct TROPUSREntry6 +{ + // Entry Header + be_t entry_type; // Always 6 + be_t entry_size; // Always 0x60 + be_t entry_id; // Entry ID + be_t entry_unk1; // Just zeroes? + + // Entry Contents + be_t trophy_id; // Trophy ID + be_t trophy_state; // Wild guess: 00 00 00 00 = Locked, 00 00 00 01 = Unlocked + be_t unk4; // This seems interesting + be_t unk5; // Just zeroes? + be_t timestamp1; + be_t timestamp2; + char unk6[64]; // Just zeroes? +}; + +class TROPUSRLoader +{ + vfsStream* m_file; + TROPUSRHeader m_header; + std::vector m_tableHeaders; + + std::vector m_table4; + std::vector 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); +}; diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index 0345bdb0df..3de3738208 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -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::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(); +} diff --git a/rpcs3/Loader/TRP.h b/rpcs3/Loader/TRP.h index e0994ce650..d86541e6c2 100644 --- a/rpcs3/Loader/TRP.h +++ b/rpcs3/Loader/TRP.h @@ -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(); }; \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index a02f6bf916..da64180a17 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -300,6 +300,7 @@ + @@ -338,6 +339,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 7e4015ba55..4a3e8de4da 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -469,6 +469,12 @@ Emu\SysCalls\lv2 + + Loader + + + Emu\SysCalls\Modules +