From 4c4be331f513712ae85eebeb5836831fb8638585 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 19 Sep 2020 00:59:34 +0200 Subject: [PATCH] HLE: Fix sceNpTrophyCreateContext fixes #7431 Soldner-X Assuming that a SceNpCommunicationId should have a format like "TEST12345", then there is no need to delete termination characters after we already created a truncated string with 9 characters + null terminator. The current behaviour does not work at all, because in case that we actually have a non-null termination character, deleteTerminateChar will step over the last x chars in the already truncated ID until it forcefully finds a character of its liking. eg. term='2': "TEST12345" => "TEST1" => "TEST1_00" --- rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp | 47 +++++++++++--------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index 97e30536ef..929c5234ee 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -322,19 +322,6 @@ error_code sceNpTrophyAbortHandle(u32 handle) return CELL_OK; } -void deleteTerminateChar(char* myStr, char _char) { - - char *del = &myStr[strlen(myStr)]; - - while (del > myStr && *del != _char) - del--; - - if (*del == _char) - *del = '\0'; - - return; -} - error_code sceNpTrophyCreateContext(vm::ptr context, vm::cptr commId, vm::cptr commSign, u64 options) { sceNpTrophy.warning("sceNpTrophyCreateContext(context=*0x%x, commId=*0x%x, commSign=*0x%x, options=0x%llx)", context, commId, commSign, options); @@ -369,33 +356,37 @@ error_code sceNpTrophyCreateContext(vm::ptr context, vm::cptrterm, commId->data, commId->num); - if (commId->term) + sceNpTrophy.warning("sceNpTrophyCreateContext data=%s term=%s num=%d", commId->data, commId->term, commId->num); + + // NOTE: commId->term is unused in our code (at least until someone finds out if we need to account for it) + + // generate trophy context name, limited to 9 characters + std::string_view name_sv(commId->data, 9); + + // resize the name if it was shorter than expected + if (const auto pos = name_sv.find_first_of('\0'); pos != std::string_view::npos) { - char trimchar[10]; - strcpy_trunc(trimchar, commId->data); - deleteTerminateChar(trimchar, commId->term); - name = fmt::format("%s_%02d", trimchar, commId->num); - } - else - { - name = fmt::format("%s_%02d", commId->data, commId->num); + name_sv = name_sv.substr(0, pos); } + // append the commId number as "_xx" + const std::string name = fmt::format("%s_%02d", name_sv, commId->num); + // open trophy pack file - fs::file stream(vfs::get(Emu.GetDir() + "TROPDIR/" + name + "/TROPHY.TRP")); + std::string trophy_path = vfs::get(Emu.GetDir() + "TROPDIR/" + name + "/TROPHY.TRP"); + fs::file stream(trophy_path); if (!stream && Emu.GetCat() == "GD") { - stream.open(vfs::get("/dev_bdvd/PS3_GAME/TROPDIR/" + name + "/TROPHY.TRP")); + sceNpTrophy.warning("sceNpTrophyCreateContext failed to open trophy file from boot path: '%s'", trophy_path); + trophy_path = vfs::get("/dev_bdvd/PS3_GAME/TROPDIR/" + name + "/TROPHY.TRP"); + stream.open(trophy_path); } // check if exists and opened if (!stream) { - return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; + return {SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST, trophy_path}; } // create trophy context