1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2025-02-01 04:51:49 +01:00

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"
This commit is contained in:
Megamouse 2020-09-19 00:59:34 +02:00
parent 511e9920c2
commit 4c4be331f5

View File

@ -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<u32> context, vm::cptr<SceNpCommunicationId> commId, vm::cptr<SceNpCommunicationSignature> 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<u32> context, vm::cptr<SceNpCommunic
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
}
// generate trophy context name
std::string name;
sceNpTrophy.warning("sceNpTrophyCreateContext term=%s data=%s num=%d", commId->term, 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