feat(libs): NpTrophy2 impl + fopen not found logic update

This commit is contained in:
boykopovar 2026-09-13 11:01:59 +03:00
parent 0c2cfe0564
commit 4781694512
7 changed files with 192 additions and 67 deletions

View File

@ -1,4 +1,6 @@
#include <cstdint>
#include <stdexcept>
#include <string>
#include "prx/libSceNpTrophy2/include/NpTrophy2.hpp"
#include "prx/libc/include/General.hpp"
@ -6,26 +8,26 @@
extern "C" {
int APS5_VABI sceNpTrophy2CreateContext(int* context, int user_id, uint32_t service_label, uint64_t options) {
(void)context;
if (context == nullptr) {
APS5_INVALID_ARG_EX;
}
(void)user_id;
(void)service_label;
(void)options;
NotImplemented_nid_no_patch(__func__);
return 0;
*context = NP_TROPHY2_CONTEXT_DEFAULT;
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2DestroyContext(int context) {
(void)context;
NotImplemented_nid_no_patch(__func__);
return 0;
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2RegisterContext(int context, int handle, uint64_t options) {
(void)context;
(void)handle;
(void)options;
NotImplemented_nid_no_patch(__func__);
return 0;
return SCE_NP_TROPHY2_OK;
}
}

View File

@ -1,4 +1,7 @@
#include <cstddef>
#include <cstring>
#include <stdexcept>
#include <string>
#include "prx/libSceNpTrophy2/include/NpTrophy2.hpp"
#include "prx/libc/include/General.hpp"
@ -6,28 +9,47 @@
extern "C" {
int APS5_VABI sceNpTrophy2GetGameInfo(int context, int handle, NpTrophy2GameDetails* details, NpTrophy2GameData* data) {
if (details == nullptr || data == nullptr) {
APS5_INVALID_ARG_EX;
}
(void)context;
(void)handle;
(void)details;
(void)data;
NotImplemented_nid_no_patch(__func__);
return 0;
if (details != nullptr) {
std::memset(details, 0, sizeof(*details));
details->num_groups = NP_TROPHY2_NUM_GROUPS;
details->num_trophies = NP_TROPHY2_NUM_TROPHIES;
details->num_platinum = NP_TROPHY2_NUM_PLATINUM;
details->num_gold = NP_TROPHY2_NUM_GOLD;
details->num_silver = NP_TROPHY2_NUM_SILVER;
details->num_bronze = NP_TROPHY2_NUM_BRONZE;
std::strncpy(details->title, NP_TROPHY2_GAME_TITLE, sizeof(details->title) - 1);
}
if (data != nullptr) {
std::memset(data, 0, sizeof(*data));
data->unlocked_trophies = NP_TROPHY2_UNLOCKED_TROPHIES;
data->unlocked_platinum = NP_TROPHY2_UNLOCKED_PLATINUM;
data->unlocked_gold = NP_TROPHY2_UNLOCKED_GOLD;
data->unlocked_silver = NP_TROPHY2_UNLOCKED_SILVER;
data->unlocked_bronze = NP_TROPHY2_UNLOCKED_BRONZE;
data->progress_percentage = NP_TROPHY2_PROGRESS_PERCENTAGE;
}
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2GetGameIcon(int context, int handle, void* buffer, size_t* size) {
(void)context;
(void)handle;
(void)buffer;
(void)size;
NotImplemented_nid_no_patch(__func__);
return 0;
if (size != nullptr) {
*size = NP_TROPHY2_ICON_SIZE_NONE;
}
throw std::runtime_error(std::string(__func__) + ": icon file not found");
}
int APS5_VABI sceNpTrophy2RegisterUnlockCallback(void* callback, void* userdata) {
(void)callback;
(void)userdata;
NotImplemented_nid_no_patch(__func__);
return 0;
return SCE_NP_TROPHY2_OK;
}
}

View File

@ -1,5 +1,8 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <string>
#include "prx/libSceNpTrophy2/include/NpTrophy2.hpp"
#include "prx/libc/include/General.hpp"
@ -7,25 +10,64 @@
extern "C" {
int APS5_VABI sceNpTrophy2GetGroupInfo(int context, int handle, int group_id, NpTrophy2GroupDetails* details, NpTrophy2GroupData* data) {
if (details == nullptr || data == nullptr) {
APS5_INVALID_ARG_EX;
}
(void)context;
(void)handle;
(void)group_id;
(void)details;
(void)data;
NotImplemented_nid_no_patch(__func__);
return 0;
const std::int32_t normalized_group_id = (group_id < 0 ? NP_TROPHY2_GROUP_ID_BASE : group_id);
if (details != nullptr) {
std::memset(details, 0, sizeof(*details));
details->group_id = normalized_group_id;
details->num_trophies = NP_TROPHY2_NUM_TROPHIES;
details->num_platinum = NP_TROPHY2_NUM_PLATINUM;
details->num_gold = NP_TROPHY2_NUM_GOLD;
details->num_silver = NP_TROPHY2_NUM_SILVER;
details->num_bronze = NP_TROPHY2_NUM_BRONZE;
std::strncpy(details->title, NP_TROPHY2_GROUP_TITLE, sizeof(details->title) - 1);
}
if (data != nullptr) {
std::memset(data, 0, sizeof(*data));
data->group_id = normalized_group_id;
data->unlocked_trophies = NP_TROPHY2_UNLOCKED_TROPHIES;
data->unlocked_platinum = NP_TROPHY2_UNLOCKED_PLATINUM;
data->unlocked_gold = NP_TROPHY2_UNLOCKED_GOLD;
data->unlocked_silver = NP_TROPHY2_UNLOCKED_SILVER;
data->unlocked_bronze = NP_TROPHY2_UNLOCKED_BRONZE;
data->progress_percentage = NP_TROPHY2_PROGRESS_PERCENTAGE;
}
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2GetGroupInfoArray(int context, int handle, uint32_t offset, uint32_t limit, NpTrophy2GroupDetails* details_array, NpTrophy2GroupData* data_array, uint32_t* count) {
if (count == nullptr) {
APS5_INVALID_ARG_EX;
}
(void)context;
(void)handle;
(void)offset;
(void)limit;
(void)details_array;
(void)data_array;
(void)count;
NotImplemented_nid_no_patch(__func__);
return 0;
const uint32_t out_count = (offset == 0 && limit != 0 ? 1u : 0u);
*count = out_count;
if (out_count != 0 && details_array != nullptr) {
std::memset(details_array, 0, sizeof(*details_array));
details_array->group_id = NP_TROPHY2_GROUP_ID_BASE;
details_array->num_trophies = NP_TROPHY2_NUM_TROPHIES;
details_array->num_platinum = NP_TROPHY2_NUM_PLATINUM;
details_array->num_gold = NP_TROPHY2_NUM_GOLD;
details_array->num_silver = NP_TROPHY2_NUM_SILVER;
details_array->num_bronze = NP_TROPHY2_NUM_BRONZE;
std::strncpy(details_array->title, NP_TROPHY2_GROUP_TITLE, sizeof(details_array->title) - 1);
}
if (out_count != 0 && data_array != nullptr) {
std::memset(data_array, 0, sizeof(*data_array));
data_array->group_id = NP_TROPHY2_GROUP_ID_BASE;
data_array->unlocked_trophies = NP_TROPHY2_UNLOCKED_TROPHIES;
data_array->unlocked_platinum = NP_TROPHY2_UNLOCKED_PLATINUM;
data_array->unlocked_gold = NP_TROPHY2_UNLOCKED_GOLD;
data_array->unlocked_silver = NP_TROPHY2_UNLOCKED_SILVER;
data_array->unlocked_bronze = NP_TROPHY2_UNLOCKED_BRONZE;
data_array->progress_percentage = NP_TROPHY2_PROGRESS_PERCENTAGE;
}
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2GetGroupIcon(int context, int handle, int group_id, void* buffer, size_t* size) {
@ -33,9 +75,10 @@ int APS5_VABI sceNpTrophy2GetGroupIcon(int context, int handle, int group_id, vo
(void)handle;
(void)group_id;
(void)buffer;
(void)size;
NotImplemented_nid_no_patch(__func__);
return 0;
if (size != nullptr) {
*size = NP_TROPHY2_ICON_SIZE_NONE;
}
throw std::runtime_error(std::string(__func__) + ": icon file not found");
}
}

View File

@ -1,24 +1,27 @@
#include <stdexcept>
#include <string>
#include "prx/libSceNpTrophy2/include/NpTrophy2.hpp"
#include "prx/libc/include/General.hpp"
extern "C" {
int APS5_VABI sceNpTrophy2CreateHandle(int* handle) {
(void)handle;
NotImplemented_nid_no_patch(__func__);
return 0;
if (handle == nullptr) {
APS5_INVALID_ARG_EX;
}
*handle = NP_TROPHY2_HANDLE_DEFAULT;
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2DestroyHandle(int handle) {
(void)handle;
NotImplemented_nid_no_patch(__func__);
return 0;
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2AbortHandle(int handle) {
(void)handle;
NotImplemented_nid_no_patch(__func__);
return 0;
return SCE_NP_TROPHY2_OK;
}
}

View File

@ -1,5 +1,8 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <string>
#include "prx/libSceNpTrophy2/include/NpTrophy2.hpp"
#include "prx/libc/include/General.hpp"
@ -7,25 +10,61 @@
extern "C" {
int APS5_VABI sceNpTrophy2GetTrophyInfo(int context, int handle, int trophy_id, NpTrophy2Details* details, NpTrophy2Data* data) {
if (details == nullptr || data == nullptr) {
APS5_INVALID_ARG_EX;
}
(void)context;
(void)handle;
(void)trophy_id;
(void)details;
(void)data;
NotImplemented_nid_no_patch(__func__);
return 0;
if (details != nullptr) {
std::memset(details, 0, sizeof(*details));
details->trophy_id = trophy_id;
details->trophy_grade = NP_TROPHY2_TROPHY_GRADE_BRONZE;
details->group_id = NP_TROPHY2_GROUP_ID_BASE;
details->hidden = false;
details->has_reward = false;
details->target.value = NP_TROPHY2_PROGRESS_VALUE_NONE;
std::strncpy(details->name, NP_TROPHY2_TROPHY_NAME, sizeof(details->name) - 1);
std::strncpy(details->description, NP_TROPHY2_TROPHY_DESCRIPTION, sizeof(details->description) - 1);
std::strncpy(details->reward, NP_TROPHY2_TROPHY_REWARD, sizeof(details->reward) - 1);
}
if (data != nullptr) {
std::memset(data, 0, sizeof(*data));
data->trophy_id = trophy_id;
data->unlocked = false;
data->progress.value = NP_TROPHY2_PROGRESS_VALUE_NONE;
data->timestamp_tick = 0;
}
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2GetTrophyInfoArray(int context, int handle, uint32_t offset, uint32_t limit, NpTrophy2Details* details_array, NpTrophy2Data* data_array, uint32_t* count) {
if (count == nullptr) {
APS5_INVALID_ARG_EX;
}
(void)context;
(void)handle;
(void)offset;
(void)limit;
(void)details_array;
(void)data_array;
(void)count;
NotImplemented_nid_no_patch(__func__);
return 0;
const uint32_t out_count = (offset == 0 && limit != 0 ? 1u : 0u);
*count = out_count;
if (out_count != 0 && details_array != nullptr) {
std::memset(details_array, 0, sizeof(*details_array));
details_array->trophy_id = NP_TROPHY2_TROPHY_ID_DEFAULT;
details_array->trophy_grade = NP_TROPHY2_TROPHY_GRADE_BRONZE;
details_array->group_id = NP_TROPHY2_GROUP_ID_BASE;
details_array->hidden = false;
details_array->has_reward = false;
details_array->target.value = NP_TROPHY2_PROGRESS_VALUE_NONE;
std::strncpy(details_array->name, NP_TROPHY2_TROPHY_NAME, sizeof(details_array->name) - 1);
std::strncpy(details_array->description, NP_TROPHY2_TROPHY_DESCRIPTION, sizeof(details_array->description) - 1);
std::strncpy(details_array->reward, NP_TROPHY2_TROPHY_REWARD, sizeof(details_array->reward) - 1);
}
if (out_count != 0 && data_array != nullptr) {
std::memset(data_array, 0, sizeof(*data_array));
data_array->trophy_id = NP_TROPHY2_TROPHY_ID_DEFAULT;
data_array->unlocked = false;
data_array->progress.value = NP_TROPHY2_PROGRESS_VALUE_NONE;
data_array->timestamp_tick = 0;
}
return SCE_NP_TROPHY2_OK;
}
int APS5_VABI sceNpTrophy2GetTrophyIcon(int context, int handle, int trophy_id, void* buffer, size_t* size) {
@ -33,9 +72,10 @@ int APS5_VABI sceNpTrophy2GetTrophyIcon(int context, int handle, int trophy_id,
(void)handle;
(void)trophy_id;
(void)buffer;
(void)size;
NotImplemented_nid_no_patch(__func__);
return 0;
if (size != nullptr) {
*size = NP_TROPHY2_ICON_SIZE_NONE;
}
throw std::runtime_error(std::string(__func__) + ": icon file not found");
}
}

View File

@ -5,6 +5,11 @@
#include <stdexcept>
#include <utility>
static constexpr const char* FOPEN_EXT_VERT = ".vert";
static constexpr const char* FOPEN_MSG_NULL_ARG = "null argument";
static constexpr const char* FOPEN_MSG_NOT_FOUND = "file not found";
static constexpr const char* FOPEN_MSG_OPEN_FAILED = "open failed";
class FileStream {
std::FILE* _handle;
bool _dynamic;

View File

@ -12,22 +12,32 @@ extern "C" {
[[noreturn]] void APS5_VABI _ZSt11_Xbad_allocv_nid_postfix();
FileStream* APS5_VABI fopen_nid_postfix(const char* filename, const char* mode) {
if (!filename || !mode) throw std::runtime_error("fopen: null argument");
std::unique_ptr<std::FILE, decltype(&std::fclose)> handle(std::fopen(filename, mode), std::fclose);
if (!handle) {
std::string msg = "fopen: open failed: \"";
msg += std::filesystem::absolute(filename).string();
msg += "\": ";
msg += std::strerror(errno);
throw std::runtime_error(msg);
FileStream* APS5_VABI fopen_nid_postfix(const char* filename, const char* mode) {
if (!filename || !mode) throw std::runtime_error(std::string(__func__) + ": " + FOPEN_MSG_NULL_ARG);
std::unique_ptr<std::FILE, decltype(&std::fclose)> handle(std::fopen(filename, mode), std::fclose);
const auto abs_path = std::filesystem::absolute(filename).string();
if (!handle) {
const auto reason = std::strerror(errno);
const std::filesystem::path fpath(filename);
bool sibling_exists = false;
std::error_code ec;
for (const auto& entry : std::filesystem::directory_iterator(std::filesystem::absolute(fpath.parent_path()), ec)) {
if (!ec && entry.path().stem() == fpath.stem() && entry.path().extension() != fpath.extension()) {
sibling_exists = true;
break;
}
}
auto stream = std::make_unique<FileStream>(handle.get(), true);
handle.release();
APS5_LOG_OUT("success: \"%s\"", filename);
return stream.release();
if (sibling_exists) {
APS5_LOG_OUT("%s: \"%s\": %s", FOPEN_MSG_NOT_FOUND, abs_path.c_str(), reason);
return nullptr;
}
throw std::runtime_error(std::string(__func__) + ": " + FOPEN_MSG_OPEN_FAILED + ": \"" + abs_path + "\": " + reason);
}
APS5_LOG_OUT("success: \"%s\"", abs_path.c_str());
auto stream = std::make_unique<FileStream>(handle.get(), true);
handle.release();
return stream.release();
}
int APS5_VABI fclose_nid_postfix(FileStream* stream) {
GetNativeStream(stream);