diff --git a/src/core/libraries/np_trophy/np_trophy.cpp b/src/core/libraries/np_trophy/np_trophy.cpp index c28e49dac..c23485d94 100644 --- a/src/core/libraries/np_trophy/np_trophy.cpp +++ b/src/core/libraries/np_trophy/np_trophy.cpp @@ -223,6 +223,14 @@ int PS4_SYSV_ABI sceNpTrophyGetGameIcon(OrbisNpTrophyContext context, OrbisNpTro return ORBIS_OK; } +struct GameTrophyInfo { + uint32_t numGroups; + uint32_t numTrophies; + uint32_t numTrophiesByRarity[5]; + uint32_t unlockedTrophies; + uint32_t unlockedTrophiesByRarity[5]; +}; + int PS4_SYSV_ABI sceNpTrophyGetGameInfo(OrbisNpTrophyContext context, OrbisNpTrophyHandle handle, OrbisNpTrophyGameDetails* details, OrbisNpTrophyGameData* data) { @@ -249,19 +257,8 @@ int PS4_SYSV_ABI sceNpTrophyGetGameInfo(OrbisNpTrophyContext context, OrbisNpTro if (result) { - uint32_t numGroups = 0; - uint32_t numTrophies = 0; - uint32_t numTrophiesByRarity[5]; - numTrophiesByRarity[1] = 0; - numTrophiesByRarity[2] = 0; - numTrophiesByRarity[3] = 0; - numTrophiesByRarity[4] = 0; - uint32_t unlockedTrophies = 0; - uint32_t unlockedTrophiesByRarity[5]; - unlockedTrophiesByRarity[1] = 0; - unlockedTrophiesByRarity[2] = 0; - unlockedTrophiesByRarity[3] = 0; - unlockedTrophiesByRarity[4] = 0; + GameTrophyInfo gameInfo; + memset(&gameInfo, 0, sizeof(GameTrophyInfo)); auto trophyconf = doc.child("trophyconf"); for (pugi::xml_node_iterator it = trophyconf.children().begin(); @@ -278,35 +275,35 @@ int PS4_SYSV_ABI sceNpTrophyGetGameInfo(OrbisNpTrophyContext context, OrbisNpTro } if (std::string(it->name()) == "group") - numGroups++; + gameInfo.numGroups++; if (std::string(it->name()) == "trophy") { std::string currentTrophyUnlockState = it->attribute("unlockstate").value(); std::string currentTrophyGrade = it->attribute("ttype").value(); - numTrophies++; + gameInfo.numTrophies++; if (!currentTrophyGrade.empty()) { int trophyGrade = GetTrophyGradeFromChar(currentTrophyGrade.at(0)); - numTrophiesByRarity[trophyGrade]++; + gameInfo.numTrophiesByRarity[trophyGrade]++; if (currentTrophyUnlockState == "unlocked") { - unlockedTrophies++; - unlockedTrophiesByRarity[trophyGrade]++; + gameInfo.unlockedTrophies++; + gameInfo.unlockedTrophiesByRarity[trophyGrade]++; } } } } - details->numGroups = numGroups; - details->numTrophies = numTrophies; - details->numPlatinum = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; - details->numGold = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; - details->numSilver = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; - details->numBronze = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; - data->unlockedTrophies = unlockedTrophies; - data->unlockedPlatinum = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; - data->unlockedGold = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; - data->unlockedSilver = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; - data->unlockedBronze = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; + details->numGroups = gameInfo.numGroups; + details->numTrophies = gameInfo.numTrophies; + details->numPlatinum = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; + details->numGold = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; + details->numSilver = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; + details->numBronze = gameInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; + data->unlockedTrophies = gameInfo.unlockedTrophies; + data->unlockedPlatinum = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; + data->unlockedGold = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; + data->unlockedSilver = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; + data->unlockedBronze = gameInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; // maybe this should be 1 instead of 100? data->progressPercentage = 100; @@ -323,6 +320,13 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupIcon(OrbisNpTrophyContext context, OrbisNpTr return ORBIS_OK; } +struct GroupTrophyInfo { + uint32_t numTrophies; + uint32_t numTrophiesByRarity[5]; + uint32_t unlockedTrophies; + uint32_t unlockedTrophiesByRarity[5]; +}; + int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTrophyHandle handle, OrbisNpTrophyGroupId groupId, OrbisNpTrophyGroupDetails* details, @@ -350,26 +354,14 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTr if (result) { - uint32_t numGroups = 0; - uint32_t numTrophies = 0; - uint32_t numTrophiesByRarity[5]; - numTrophiesByRarity[1] = 0; - numTrophiesByRarity[2] = 0; - numTrophiesByRarity[3] = 0; - numTrophiesByRarity[4] = 0; - uint32_t unlockedTrophies = 0; - uint32_t unlockedTrophiesByRarity[5]; - unlockedTrophiesByRarity[1] = 0; - unlockedTrophiesByRarity[2] = 0; - unlockedTrophiesByRarity[3] = 0; - unlockedTrophiesByRarity[4] = 0; + GroupTrophyInfo groupInfo; + memset(&groupInfo, 0, sizeof(GroupTrophyInfo)); auto trophyconf = doc.child("trophyconf"); for (pugi::xml_node_iterator it = trophyconf.children().begin(); it != trophyconf.children().end(); ++it) { if (std::string(it->name()) == "group") { - numGroups++; std::string currentGroupId = it->attribute("id").value(); if (!currentGroupId.empty()) { if (std::stoi(currentGroupId) == groupId) { @@ -385,6 +377,7 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTr } } + details->groupId = groupId; data->groupId = groupId; if (std::string(it->name()) == "trophy") { @@ -394,30 +387,31 @@ int PS4_SYSV_ABI sceNpTrophyGetGroupInfo(OrbisNpTrophyContext context, OrbisNpTr if (!currentTrophyGroupID.empty()) { if (std::stoi(currentTrophyGroupID) == groupId) { - numTrophies++; + groupInfo.numTrophies++; if (!currentTrophyGrade.empty()) { int trophyGrade = GetTrophyGradeFromChar(currentTrophyGrade.at(0)); - numTrophiesByRarity[trophyGrade]++; + groupInfo.numTrophiesByRarity[trophyGrade]++; if (currentTrophyUnlockState == "unlocked") { - unlockedTrophies++; - unlockedTrophiesByRarity[trophyGrade]++; + groupInfo.unlockedTrophies++; + groupInfo.unlockedTrophiesByRarity[trophyGrade]++; } } } } } } - - details->numTrophies = numTrophies; - details->numPlatinum = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; - details->numGold = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; - details->numSilver = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; - details->numBronze = numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; - data->unlockedTrophies = unlockedTrophies; - data->unlockedPlatinum = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; - data->unlockedGold = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; - data->unlockedSilver = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; - data->unlockedBronze = unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; + + details->numTrophies = groupInfo.numTrophies; + details->numPlatinum = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; + details->numGold = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; + details->numSilver = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; + details->numBronze = groupInfo.numTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; + data->unlockedTrophies = groupInfo.unlockedTrophies; + data->unlockedPlatinum = + groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_PLATINUM]; + data->unlockedGold = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_GOLD]; + data->unlockedSilver = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_SILVER]; + data->unlockedBronze = groupInfo.unlockedTrophiesByRarity[ORBIS_NP_TROPHY_GRADE_BRONZE]; // maybe this should be 1 instead of 100? data->progressPercentage = 100; @@ -925,7 +919,6 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr int numTrophiesUnlocked = 0; pugi::xml_node_iterator platinumIt; - int platinumTrophyGroup = -1; if (result) { auto trophyconf = doc.child("trophyconf"); @@ -937,40 +930,25 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr std::string currentTrophyDescription = it->child("detail").text().as_string(); std::string currentTrophyType = it->attribute("ttype").value(); std::string currentTrophyUnlockState = it->attribute("unlockstate").value(); + std::string currentIconPath = + trophyDir.string() + "/trophy00/Icons/TROP" + currentTrophyId + ".PNG"; if (currentTrophyType == "P") { platinumIt = it; - - if (std::string(platinumIt->attribute("gid").value()).empty()) { - platinumTrophyGroup = -1; - } else { - platinumTrophyGroup = - std::stoi(std::string(platinumIt->attribute("gid").value())); - } - if (trophyId == std::stoi(currentTrophyId)) { return ORBIS_NP_TROPHY_ERROR_PLATINUM_CANNOT_UNLOCK; } } if (std::string(it->name()) == "trophy") { - if (platinumTrophyGroup == -1) { - if (std::string(it->attribute("gid").value()).empty()) { + if (!std::string(it->attribute("pid").value()).empty()) { + if (std::stoi(std::string(it->attribute("pid").value())) != + ORBIS_NP_TROPHY_INVALID_TROPHY_ID) { numTrophies++; if (currentTrophyUnlockState == "unlocked") { numTrophiesUnlocked++; } } - } else { - if (!std::string(it->attribute("gid").value()).empty()) { - if (std::stoi(std::string(it->attribute("gid").value())) == - platinumTrophyGroup) { - numTrophies++; - if (currentTrophyUnlockState == "unlocked") { - numTrophiesUnlocked++; - } - } - } } if (std::stoi(currentTrophyId) == trophyId) { @@ -998,14 +976,14 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr .set_value(std::to_string(trophyTimestamp.tick).c_str()); } - g_trophy_ui.AddTrophyToQueue(trophyId, currentTrophyName); + g_trophy_ui.AddTrophyToQueue(currentIconPath, currentTrophyName); } } } } if (std::string(platinumIt->attribute("unlockstate").value()).empty()) { - if ((numTrophies - 2) == numTrophiesUnlocked) { + if ((numTrophies - 1) == numTrophiesUnlocked) { platinumIt->append_attribute("unlockstate") = "unlocked"; @@ -1022,12 +1000,14 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr std::string platinumTrophyId = platinumIt->attribute("id").value(); std::string platinumTrophyName = platinumIt->child("name").text().as_string(); + std::string platinumIconPath = + trophyDir.string() + "/trophy00/Icons/TROP" + platinumTrophyId + ".PNG"; *platinumId = std::stoi(platinumTrophyId); - g_trophy_ui.AddTrophyToQueue(*platinumId, platinumTrophyName); + g_trophy_ui.AddTrophyToQueue(platinumIconPath, platinumTrophyName); } } else if (std::string(platinumIt->attribute("unlockstate").value()) == "locked") { - if ((numTrophies - 2) == numTrophiesUnlocked) { + if ((numTrophies - 1) == numTrophiesUnlocked) { platinumIt->attribute("unlockstate").set_value("unlocked"); @@ -1044,9 +1024,11 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr std::string platinumTrophyId = platinumIt->attribute("id").value(); std::string platinumTrophyName = platinumIt->child("name").text().as_string(); + std::string platinumIconPath = + trophyDir.string() + "/trophy00/Icons/TROP" + platinumTrophyId + ".PNG"; *platinumId = std::stoi(platinumTrophyId); - g_trophy_ui.AddTrophyToQueue(*platinumId, platinumTrophyName); + g_trophy_ui.AddTrophyToQueue(platinumIconPath, platinumTrophyName); } } diff --git a/src/core/libraries/np_trophy/trophy_ui.cpp b/src/core/libraries/np_trophy/trophy_ui.cpp index 6f60e8f9a..bf8102645 100644 --- a/src/core/libraries/np_trophy/trophy_ui.cpp +++ b/src/core/libraries/np_trophy/trophy_ui.cpp @@ -5,6 +5,7 @@ #include #include "common/assert.h" #include "imgui/imgui_std.h" +#include "imgui/imgui_texture.h" #include "trophy_ui.h" using namespace ImGui; @@ -18,9 +19,9 @@ TrophyUI::~TrophyUI() { Finish(); } -void Libraries::NpTrophy::TrophyUI::AddTrophyToQueue(int trophyId, std::string trophyName) { +void Libraries::NpTrophy::TrophyUI::AddTrophyToQueue(std::string trophyIconPath, std::string trophyName) { TrophyInfo newInfo; - newInfo.trophyId = trophyId; + newInfo.trophyIconPath = trophyIconPath; newInfo.trophyName = trophyName; trophyQueue.push_back(newInfo); } @@ -31,13 +32,15 @@ void TrophyUI::Finish() { bool displayingTrophy; std::chrono::steady_clock::time_point trophyStartedTime; +bool iconLoaded = false; +RefCountedTexture trophyIcon; void TrophyUI::Draw() { const auto& io = GetIO(); const ImVec2 window_size{ - std::min(io.DisplaySize.x, 200.f), - std::min(io.DisplaySize.y, 75.f), + std::min(io.DisplaySize.x, 250.f), + std::min(io.DisplaySize.y, 70.f), }; if (trophyQueue.size() != 0) { @@ -53,20 +56,35 @@ void TrophyUI::Draw() { if (duration.count() >= 5) { trophyQueue.erase(trophyQueue.begin()); displayingTrophy = false; + iconLoaded = false; } if (trophyQueue.size() != 0) { SetNextWindowSize(window_size); SetNextWindowCollapsed(false); - SetNextWindowPos(ImVec2(io.DisplaySize.x - 200, 50)); + SetNextWindowPos(ImVec2(io.DisplaySize.x - 250, 50)); KeepNavHighlight(); TrophyInfo currentTrophyInfo = trophyQueue[0]; + + if (!iconLoaded) { + if (std::filesystem::exists(currentTrophyInfo.trophyIconPath)) { + trophyIcon = RefCountedTexture::DecodePngFile(currentTrophyInfo.trophyIconPath); + iconLoaded = true; + } else { + LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}", + currentTrophyInfo.trophyIconPath); + } + } + if (Begin("Trophy Window", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs)) { - Text("Trophy earned!"); - TextWrapped("%s", currentTrophyInfo.trophyName.c_str()); + if (iconLoaded) { + Image(trophyIcon.GetTexture().im_id, ImVec2(50, 50)); + ImGui::SameLine(); + } + TextWrapped("Trophy earned!\n%s", currentTrophyInfo.trophyName.c_str()); } End(); } diff --git a/src/core/libraries/np_trophy/trophy_ui.h b/src/core/libraries/np_trophy/trophy_ui.h index 060d80dec..cfe89a957 100644 --- a/src/core/libraries/np_trophy/trophy_ui.h +++ b/src/core/libraries/np_trophy/trophy_ui.h @@ -15,7 +15,7 @@ namespace Libraries::NpTrophy { struct TrophyInfo { - int trophyId = -1; + std::string trophyIconPath; std::string trophyName; }; @@ -26,7 +26,7 @@ public: TrophyUI(); ~TrophyUI() override; - void AddTrophyToQueue(int trophyId, std::string trophyName); + void AddTrophyToQueue(std::string trophyIconPath, std::string trophyName); void Finish();