A bit more

This commit is contained in:
igor725 2024-05-04 02:18:58 +03:00
parent ecebeb15c2
commit 35eb9eecdb
No known key found for this signature in database
GPG Key ID: 46F13BBE46F8569D
3 changed files with 79 additions and 46 deletions

View File

@ -15,6 +15,19 @@
#undef min // We don't need it there
class Trophies: public ITrophies {
struct usr_context {
struct trophy {
uint32_t id;
uint32_t re; // reserved
uint64_t ts;
};
bool created;
uint32_t label;
std::vector<struct trophy> trophies;
} m_ctx[4];
struct trp_header {
uint32_t magic; // should be 0xDCA24D00
uint32_t version;
@ -113,13 +126,16 @@ class Trophies: public ITrophies {
ctx->group.cancelled = ctx->group.func(&ctx->group.data);
}
} else if (!ctx->itrop.cancelled) {
}
if (!ctx->itrop.cancelled) {
if (cheln == "trophyset-version") {
ctx->itrop.data.trophyset_version.assign(chel->GetContent());
} else if (cheln == "title-name") {
ctx->itrop.data.title_name.assign(chel->GetContent());
} else if (cheln == "title-detail") {
ctx->itrop.data.title_detail.assign(chel->GetContent());
} else if (cheln == "trophy") {
++ctx->itrop.data.trophy_count;
}
}
}
@ -144,6 +160,7 @@ class Trophies: public ITrophies {
if (std::equal(ext.rbegin(), ext.rend(), name.rbegin(), caseequal)) { // Test trp file extension
if (((ent.flag >> 24) & 0x03) == 0) {
ctx->pngim.data.pngsize = ent.len;
ctx->pngim.data.pngname.assign(ent.name);
ctx->pngim.data.pngdata = new char[ent.len]; // Developer should free this memory manually
trfile.seekg(ent.pos);
if (trfile.read((char*)ctx->pngim.data.pngdata, ent.len)) {
@ -402,6 +419,14 @@ class Trophies: public ITrophies {
return ErrCodes::NO_TROPHIES;
} // parseTRP()
bool createContext(int32_t userId, uint32_t label) final {}
bool getProgress(int32_t userId, uint32_t progress[4]) final {}
bool unlockTrophy(int32_t userId, int32_t trophyId) final {}
bool resetUserInfo(int32_t userId) final {}
};
ITrophies& accessTrophies() {

View File

@ -60,8 +60,9 @@ class ITrophies {
struct trp_png_cb {
struct data_t {
void* pngdata;
size_t pngsize;
std::string pngname;
void* pngdata;
size_t pngsize;
} data;
bool cancelled;
@ -73,6 +74,7 @@ class ITrophies {
std::string title_name;
std::string title_detail;
std::string trophyset_version;
uint32_t trophy_count;
} data;
bool cancelled;
@ -91,6 +93,11 @@ class ITrophies {
};
virtual ErrCodes parseTRP(trp_context* context) = 0;
virtual bool createContext(int32_t userId, uint32_t label) = 0;
virtual bool getProgress(int32_t userId, uint32_t progress[4]) = 0;
virtual bool unlockTrophy(int32_t userId, int32_t trophyId) = 0;
virtual bool resetUserInfo(int32_t userId) = 0;
};
#if defined(__APICALL_EXTERN)

View File

@ -9,14 +9,7 @@
LOG_DEFINE_MODULE(libSceNpTrophy);
namespace {
struct trp_context {
bool created;
SceNpServiceLabel label;
};
static trp_context contexts[4] = {};
} // namespace
namespace {} // namespace
extern "C" {
@ -36,35 +29,7 @@ EXPORT SYSV_ABI int sceNpTrophyAbortHandle(SceNpTrophyHandle handle) {
}
EXPORT SYSV_ABI int sceNpTrophyCreateContext(SceNpTrophyContext* context, int32_t userId, SceNpServiceLabel serviceLabel, uint64_t options) {
auto& ctx = contexts[userId];
if (ctx.created) return Err::NpTrophy::ALREADY_EXISTS;
// static std::once_flag init;
// std::call_once(init, []() {
// ITrophies::trp_context ctx = {
// .lightweight = false,
// .entry =
// {
// .func = [](ITrophies::trp_ent_cb::data_t* data) -> bool {
// printf("Trophy! %s: %s (id:%d)\n", data->name.c_str(), data->detail.c_str(), data->id);
// return false; // Do not cancel this callback
// },
// },
// .itrop =
// {
// .func = [](ITrophies::trp_inf_cb::data_t* data) -> bool {
// printf("Trophyset info: %s, %s, %s\n", data->trophyset_version.c_str(), data->title_name.c_str(), data->title_detail.c_str());
// return true;
// },
// },
// };
// accessTrophies().parseTRP(&ctx);
// });
ctx.created = true;
ctx.label = serviceLabel;
*context = userId;
return Ok;
return accessTrophies().createContext(userId, (uint32_t)serviceLabel) ? Ok : Err::NpTrophy::ALREADY_EXISTS;
}
EXPORT SYSV_ABI int sceNpTrophyDestroyContext(SceNpTrophyContext context) {
@ -162,20 +127,56 @@ EXPORT SYSV_ABI int sceNpTrophyGetTrophyInfo(SceNpTrophyContext context, SceNpTr
}
EXPORT SYSV_ABI int sceNpTrophyGetGameIcon(SceNpTrophyContext context, SceNpTrophyHandle handle, void* buffer, size_t* size) {
*size = 8;
*(uint64_t*)buffer = 0;
ITrophies::trp_context ctx = {
.pngim =
{
.func = [buffer, size](ITrophies::trp_png_cb::data_t* data) -> bool {
if (data->pngname == "ICON0.PNG") {
if (data->pngsize <= *size) {
::memcpy(buffer, data->pngdata, data->pngsize);
*size = data->pngsize;
}
delete data->pngdata;
return true;
}
return Ok;
return false;
},
},
};
return accessTrophies().parseTRP(&ctx) == ITrophies::ErrCodes::SUCCESS;
}
EXPORT SYSV_ABI int sceNpTrophyGetGroupIcon(SceNpTrophyContext context, SceNpTrophyHandle handle, SceNpTrophyGroupId groupId, void* buffer, size_t* size) {
*size = 8;
*(uint64_t*)buffer = 0;
return Ok;
}
EXPORT SYSV_ABI int sceNpTrophyGetTrophyIcon(SceNpTrophyContext context, SceNpTrophyHandle handle, SceNpTrophyId trophyId, void* buffer, size_t* size) {
*size = 8;
*(uint64_t*)buffer = 0;
return Ok;
auto name = std::format("TROP{:3}.PNG", trophyId);
ITrophies::trp_context ctx = {
.pngim =
{
.func = [name, buffer, size](ITrophies::trp_png_cb::data_t* data) -> bool {
if (data->pngname == name) {
if (data->pngsize <= *size) {
::memcpy(buffer, data->pngdata, data->pngsize);
*size = data->pngsize;
}
delete data->pngdata;
return true;
}
return false;
},
},
};
return accessTrophies().parseTRP(&ctx) == ITrophies::ErrCodes::SUCCESS;
}
EXPORT SYSV_ABI int sceNpTrophyShowTrophyList(SceNpTrophyContext context, SceNpTrophyHandle handle) {