From 3fdb50b0ea9fb84ae9206bb98816251e8c5e962f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Sun, 16 Feb 2014 02:51:04 +0100 Subject: [PATCH] Some sceNpTrophy syscalls and few fixes * Restored deleted functions in FuncList.cpp * Fixed bugs in TRPLoader. * Implemented some sceNpTrophy syscalls. * Added sceNp headers (required for sceNpTrophy). * Updated .gitignore to ignore trophies. NOTE: Thanks to the new sceNpTrophy syscalls, RPCS3 can install the trophy contents in dev_hdd0/home/00000001/trophy/. Remember this is still on an experimental stage. --- .gitignore | 3 + rpcs3/Emu/SysCalls/FuncList.cpp | 5 + rpcs3/Emu/SysCalls/Modules/sceNp.cpp | 12 + rpcs3/Emu/SysCalls/Modules/sceNp.h | 26 ++ rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp | 286 +++++++++++++++++++++ rpcs3/Loader/TRP.cpp | 8 +- rpcs3/Loader/TRP.h | 24 +- rpcs3/rpcs3.vcxproj | 1 + rpcs3/rpcs3.vcxproj.filters | 3 + 9 files changed, 352 insertions(+), 16 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules/sceNp.cpp create mode 100644 rpcs3/Emu/SysCalls/Modules/sceNp.h create mode 100644 rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp diff --git a/.gitignore b/.gitignore index 274d7b4459..6e0001f131 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,6 @@ rpcs3/git-version.h !/bin/dev_hdd0/game/ /bin/dev_hdd0/game/* !/bin/dev_hdd0/game/TEST12345/ + +# Ignore other system generated files +bin/dev_hdd0/home/00000001/trophy diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index 4828964090..8ab729dd9c 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -1592,6 +1592,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0x1d99c3ee: FUNC_LOG_ERROR("TODO: cellOskDialogGetInputText"); case 0x1dfbfdd6: FUNC_LOG_ERROR("TODO: cellSaveDataListLoad2"); case 0x1dfcce99: FUNC_LOG_ERROR("TODO: cellSysutilGameDataExit"); + case 0x1e7bff94: FUNC_LOG_ERROR("TODO: cellSysCacheMount"); case 0x1e930eef: FUNC_LOG_ERROR("TODO: cellVideoOutGetDeviceInfo"); case 0x1f6629e4: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetErrorHook2"); case 0x20543730: FUNC_LOG_ERROR("TODO: cellMsgDialogClose"); @@ -1646,6 +1647,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0x6dfff31d: FUNC_LOG_ERROR("TODO: cellWebBrowserSetSystemCallbackUsrdata"); case 0x6e7264ed: FUNC_LOG_ERROR("TODO: cellSaveDataUserFixedLoad"); case 0x71acb8d3: FUNC_LOG_ERROR("TODO: cellSysutilAvcSetVideoMuting"); + case 0x744c1544: FUNC_LOG_ERROR("TODO: cellSysCacheClear"); case 0x749c9b5f: FUNC_LOG_ERROR("TODO: cellWebBrowserInitialize"); case 0x75bbb672: FUNC_LOG_ERROR("TODO: cellVideoOutGetNumberOfDevice"); case 0x7603d3db: FUNC_LOG_ERROR("TODO: cellMsgDialogOpen2"); @@ -2456,6 +2458,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0x0e2939e5: FUNC_LOG_ERROR("TODO: cellFsFtruncate"); case 0x103b8632: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaWithInitialData"); case 0x190912f6: FUNC_LOG_ERROR("TODO: cellFsStReadGetCurrentAddr"); + case 0x1a108ab7: FUNC_LOG_ERROR("TODO: cellFsGetBlockSize"); case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber"); case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit"); case 0x27800c6b: FUNC_LOG_ERROR("TODO: cellFsStRead"); @@ -3759,6 +3762,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0x5fdfb2fe: FUNC_LOG_ERROR("TODO: _sys_spu_printf_detach_group"); case 0x608212fc: FUNC_LOG_ERROR("TODO: sys_mempool_free_block"); case 0x620e35a7: FUNC_LOG_ERROR("TODO: sys_game_get_system_sw_version"); + case 0x67f9fedb: FUNC_LOG_ERROR("TODO: sys_game_process_exitspawn2"); case 0x68b9b011: FUNC_LOG_ERROR("TODO: _sys_memset"); case 0x6bf66ea7: FUNC_LOG_ERROR("TODO: _sys_memcpy"); case 0x6e05231d: FUNC_LOG_ERROR("TODO: sys_game_watchdog_stop"); @@ -3834,6 +3838,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0xf7f7fb20: FUNC_LOG_ERROR("TODO: _sys_free"); case 0xfa7f693d: FUNC_LOG_ERROR("TODO: _sys_vprintf"); case 0xfb5db080: FUNC_LOG_ERROR("TODO: _sys_memcmp"); + case 0xfc52a7a9: FUNC_LOG_ERROR("TODO: sys_game_process_exitspawn"); } ConLog.Error("Unknown func id: 0x%08x", id); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp new file mode 100644 index 0000000000..7d019f813b --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -0,0 +1,12 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +#include "sceNp.h" + +void sceNp_init(); +Module sceNp(0x0016, sceNpTrophy_init); + +void sceNpTrophy_init() +{ +} diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.h b/rpcs3/Emu/SysCalls/Modules/sceNp.h new file mode 100644 index 0000000000..b140316963 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.h @@ -0,0 +1,26 @@ +#pragma once + +// Return Codes +enum +{ +}; + +enum +{ + SCE_NP_COMMUNICATION_SIGNATURE_SIZE = 160, + SCE_NET_NP_COMMUNICATION_PASSPHRASE_SIZE = 128, +}; + +// Structs +struct SceNpCommunicationId +{ + char data[9]; + char term; + u8 num; + char dummy; +}; + +struct SceNpCommunicationSignature +{ + uint8_t data[SCE_NP_COMMUNICATION_SIGNATURE_SIZE]; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp new file mode 100644 index 0000000000..c69c716a59 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -0,0 +1,286 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +#include "sceNp.h" +#include "Loader/TRP.h" + +void sceNpTrophy_unload(); +void sceNpTrophy_init(); +Module sceNpTrophy(0xf035, sceNpTrophy_init, nullptr, sceNpTrophy_unload); + +enum +{ + SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED = 0x80022901, + SCE_NP_TROPHY_ERROR_NOT_INITIALIZED = 0x80022902, + SCE_NP_TROPHY_ERROR_NOT_SUPPORTED = 0x80022903, + SCE_NP_TROPHY_ERROR_CONTEXT_NOT_REGISTERED = 0x80022904, + SCE_NP_TROPHY_ERROR_OUT_OF_MEMORY = 0x80022905, + SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT = 0x80022906, + SCE_NP_TROPHY_ERROR_EXCEEDS_MAX = 0x80022907, + SCE_NP_TROPHY_ERROR_INSUFFICIENT = 0x80022909, + SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT = 0x8002290a, + SCE_NP_TROPHY_ERROR_INVALID_FORMAT = 0x8002290b, + SCE_NP_TROPHY_ERROR_BAD_RESPONSE = 0x8002290c, + SCE_NP_TROPHY_ERROR_INVALID_GRADE = 0x8002290d, + SCE_NP_TROPHY_ERROR_INVALID_CONTEXT = 0x8002290e, + SCE_NP_TROPHY_ERROR_PROCESSING_ABORTED = 0x8002290f, + SCE_NP_TROPHY_ERROR_ABORT = 0x80022910, + SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE = 0x80022911, + SCE_NP_TROPHY_ERROR_LOCKED = 0x80022912, + SCE_NP_TROPHY_ERROR_HIDDEN = 0x80022913, + SCE_NP_TROPHY_ERROR_CANNOT_UNLOCK_PLATINUM = 0x80022914, + SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED = 0x80022915, + SCE_NP_TROPHY_ERROR_INVALID_TYPE = 0x80022916, + SCE_NP_TROPHY_ERROR_INVALID_HANDLE = 0x80022917, + SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID = 0x80022918, + SCE_NP_TROPHY_ERROR_UNKNOWN_NP_COMM_ID = 0x80022919, + SCE_NP_TROPHY_ERROR_DISC_IO = 0x8002291a, + SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST = 0x8002291b, + SCE_NP_TROPHY_ERROR_UNSUPPORTED_FORMAT = 0x8002291c, + SCE_NP_TROPHY_ERROR_ALREADY_INSTALLED = 0x8002291d, + SCE_NP_TROPHY_ERROR_BROKEN_DATA = 0x8002291e, + SCE_NP_TROPHY_ERROR_VERIFICATION_FAILURE = 0x8002291f, + SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID = 0x80022920, + SCE_NP_TROPHY_ERROR_UNKNOWN_TROPHY_ID = 0x80022921, + SCE_NP_TROPHY_ERROR_UNKNOWN_TITLE = 0x80022922, + SCE_NP_TROPHY_ERROR_UNKNOWN_FILE = 0x80022923, + SCE_NP_TROPHY_ERROR_DISC_NOT_MOUNTED = 0x80022924, + SCE_NP_TROPHY_ERROR_SHUTDOWN = 0x80022925, + SCE_NP_TROPHY_ERROR_TITLE_ICON_NOT_FOUND = 0x80022926, + SCE_NP_TROPHY_ERROR_TROPHY_ICON_NOT_FOUND = 0x80022927, + SCE_NP_TROPHY_ERROR_INSUFFICIENT_DISK_SPACE = 0x80022928, + SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE = 0x8002292a, + SCE_NP_TROPHY_ERROR_SAVEDATA_USER_DOES_NOT_MATCH = 0x8002292b, + SCE_NP_TROPHY_ERROR_TROPHY_ID_DOES_NOT_EXIST = 0x8002292c, + SCE_NP_TROPHY_ERROR_SERVICE_UNAVAILABLE = 0x8002292d, + SCE_NP_TROPHY_ERROR_UNKNOWN = 0x800229ff, +}; + + +struct sceNpTrophyInternalContext +{ + // TODO + std::string trp_name; + vfsStream* trp_stream; +}; + +struct sceNpTrophyInternal +{ + bool m_bInitialized; + std::vector contexts; + + sceNpTrophyInternal() + : m_bInitialized(false) + { + } +}; + +sceNpTrophyInternal* s_npTrophyInstance = new sceNpTrophyInternal(); + +// Functions +int sceNpTrophyInit(u32 pool_addr, u32 poolSize, u32 containerId, u64 options) +{ + sceNpTrophy.Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=%d, options=0x%llx)", pool_addr, poolSize, containerId, options); + + if (s_npTrophyInstance->m_bInitialized) + return SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED; + if (options) + return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; + + s_npTrophyInstance->m_bInitialized = true; + return CELL_OK; +} + +int sceNpTrophyCreateContext(mem32_t context, mem_ptr_t commID, mem_ptr_t commSign, u64 options) +{ + sceNpTrophy.Warning("sceNpTrophyCreateContext(context_addr=0x%x, commID_addr=0x%x, commSign_addr=0x%x, options=0x%llx)", + context.GetAddr(), commID.GetAddr(), commSign.GetAddr(), options); + + if (!(s_npTrophyInstance->m_bInitialized)) + return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + if (!context.IsGood()) + return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; + if (options & (~(u64)1)) + SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; + // TODO: There are other possible errors + + // TODO: Is the TROPHY.TRP file necessarily located in this path? + wxString ps3_path = "/app_home/TROPDIR/"; + wxString local_path; + Emu.GetVFS().GetDevice(ps3_path, local_path); + + vfsLocalDir dir(local_path); + if(!dir.Open(local_path)) + return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; + + // TODO: Following method will retrieve the TROPHY.TRP of the first folder that contains such file + const DirEntryInfo* entry = dir.Read(); + while (entry) + { + if (!(entry->flags & DirEntry_TypeFile)) + { + vfsStream* stream = Emu.GetVFS().Open(ps3_path + entry->name + "/TROPHY.TRP", vfsRead); + if (stream) + { + sceNpTrophyInternalContext ctxt; + ctxt.trp_stream = stream; + ctxt.trp_name = entry->name; + s_npTrophyInstance->contexts.push_back(ctxt); + return CELL_OK; + } + } + entry->name; + entry = dir.Read(); + } + + return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; +} + +int sceNpTrophyCreateHandle(mem32_t handle) +{ + sceNpTrophy.Warning("sceNpTrophyCreateHandle(handle_addr=0x%x)", handle.GetAddr()); + + if (!(s_npTrophyInstance->m_bInitialized)) + return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + if (!handle.IsGood()) + return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; + // TODO: There are other possible errors + + // TODO: ? + + return CELL_OK; +} + +int sceNpTrophyRegisterContext(u32 context, u32 handle, u32 statusCb_addr, u32 arg_addr, u64 options) +{ + sceNpTrophy.Warning("sceNpTrophyRegisterContext(context=%d, handle=%d, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)", + context, handle, statusCb_addr, arg_addr, options); + + if (!(s_npTrophyInstance->m_bInitialized)) + return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + if (!Memory.IsGoodAddr(statusCb_addr)) + return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; + if (options & (~(u64)1)) + SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; + // TODO: There are other possible errors + + int ret; + sceNpTrophyInternalContext& ctxt = s_npTrophyInstance->contexts[context]; + TRPLoader trp(*(ctxt.trp_stream)); + + // 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; + + // TODO: Callbacks + + trp.Close(); + return ret; +} + +int sceNpTrophyGetGameProgress() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophySetSoundLevel() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyGetRequiredDiskSpace() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyDestroyContext() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyAbortHandle() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyGetGameInfo() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyDestroyHandle() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyUnlockTrophy() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyTerm() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyGetTrophyUnlockState() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyGetTrophyIcon() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyGetTrophyInfo() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +int sceNpTrophyGetGameIcon() +{ + UNIMPLEMENTED_FUNC(sceNpTrophy); + return CELL_OK; +} + +void sceNpTrophy_unload() +{ + s_npTrophyInstance->m_bInitialized = false; +} + +void sceNpTrophy_init() +{ + sceNpTrophy.AddFunc(0x079f0e87, sceNpTrophyGetGameProgress); + sceNpTrophy.AddFunc(0x1197b52c, sceNpTrophyRegisterContext); + sceNpTrophy.AddFunc(0x1c25470d, sceNpTrophyCreateHandle); + sceNpTrophy.AddFunc(0x27deda93, sceNpTrophySetSoundLevel); + sceNpTrophy.AddFunc(0x370136fe, sceNpTrophyGetRequiredDiskSpace); + sceNpTrophy.AddFunc(0x3741ecc7, sceNpTrophyDestroyContext); + sceNpTrophy.AddFunc(0x39567781, sceNpTrophyInit); + sceNpTrophy.AddFunc(0x48bd97c7, sceNpTrophyAbortHandle); + sceNpTrophy.AddFunc(0x49d18217, sceNpTrophyGetGameInfo); + sceNpTrophy.AddFunc(0x623cd2dc, sceNpTrophyDestroyHandle); + sceNpTrophy.AddFunc(0x8ceedd21, sceNpTrophyUnlockTrophy); + sceNpTrophy.AddFunc(0xa7fabf4d, sceNpTrophyTerm); + sceNpTrophy.AddFunc(0xb3ac3478, sceNpTrophyGetTrophyUnlockState); + sceNpTrophy.AddFunc(0xbaedf689, sceNpTrophyGetTrophyIcon); + sceNpTrophy.AddFunc(0xe3bf9a28, sceNpTrophyCreateContext); + sceNpTrophy.AddFunc(0xfce6d30a, sceNpTrophyGetTrophyInfo); + sceNpTrophy.AddFunc(0xff299e03, sceNpTrophyGetGameIcon); +} \ No newline at end of file diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index 6d52438166..c3b99b525a 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -9,10 +9,14 @@ bool TRPLoader::Install(std::string dest, bool show) { if(!trp_f.IsOpened()) return false; if(!LoadHeader(show)) return false; - + + if (!dest.empty() && dest.back() != '/') + dest += '/'; + for (const TRPEntry& entry : m_entries) { char* buffer = new char [entry.size]; + Emu.GetVFS().Create(dest+entry.name); vfsFile file(dest+entry.name, vfsWrite); trp_f.Seek(entry.offset); trp_f.Read(buffer, entry.size); @@ -35,7 +39,7 @@ bool TRPLoader::LoadHeader(bool show) if (trp_f.Read(&m_header, sizeof(TRPHeader)) != sizeof(TRPHeader)) return false; - if (!m_header.CheckMagic()) + if (m_header.trp_magic != 0xDCA24D00) return false; if (show) diff --git a/rpcs3/Loader/TRP.h b/rpcs3/Loader/TRP.h index 64ed0abc11..e0994ce650 100644 --- a/rpcs3/Loader/TRP.h +++ b/rpcs3/Loader/TRP.h @@ -3,26 +3,22 @@ struct TRPHeader { - u32 trp_magic; - u32 trp_version; - u64 trp_file_size; - u32 trp_files_count; - u32 trp_element_size; - u32 trp_unknown; + be_t trp_magic; + be_t trp_version; + be_t trp_file_size; + be_t trp_files_count; + be_t trp_element_size; + be_t trp_unknown; unsigned char sha1[20]; unsigned char padding[16]; - - bool CheckMagic() const { - return trp_magic == 0xDCA23D00; - } }; struct TRPEntry { - char name[20]; - u64 offset; - u64 size; - u32 unknown; + char name[32]; + be_t offset; + be_t size; + be_t unknown; char padding[12]; }; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 3c47e75874..d54859b8a4 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -292,6 +292,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index b594ddbb64..a076af31e7 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -394,6 +394,9 @@ Loader + + Emu\SysCalls\Modules +