mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 20:14:45 +00:00
platinum trophy support + extract trophy data on startup
This commit is contained in:
parent
315afc52fa
commit
dbd0404ed5
4 changed files with 98 additions and 49 deletions
|
@ -9,8 +9,8 @@
|
|||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "externals/pugixml/src/pugixml.hpp"
|
||||
#include "trophy_ui.h"
|
||||
#include "np_trophy.h"
|
||||
#include "trophy_ui.h"
|
||||
|
||||
namespace Libraries::NpTrophy {
|
||||
|
||||
|
@ -213,6 +213,9 @@ s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(OrbisNpTrophyContext context,
|
|||
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
// flags->flag_bits = 0u;
|
||||
// temporary workaround till i implement this properly
|
||||
uint32_t* flagTemp = reinterpret_cast<uint32_t*>(flags);
|
||||
*flagTemp = 0u;
|
||||
*count = 0;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -549,49 +552,106 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr
|
|||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
|
||||
// only do this if platinum is not unlocked
|
||||
*platinumId = ORBIS_NP_TROPHY_INVALID_TROPHY_ID;
|
||||
// check if all trophies are unlocked and if they are unlock plat and set its ID
|
||||
|
||||
int numTrophies = 0;
|
||||
int numTrophiesUnlocked = 0;
|
||||
|
||||
pugi::xml_node_iterator platinumIt;
|
||||
int platinumTrophyGroup = -1;
|
||||
|
||||
if (result) {
|
||||
bool foundTrophy = false;
|
||||
auto trophyconf = doc.child("trophyconf");
|
||||
for (pugi::xml_node_iterator it = trophyconf.children().begin();
|
||||
it != trophyconf.children().end() && !foundTrophy; ++it) {
|
||||
it != trophyconf.children().end(); ++it) {
|
||||
|
||||
std::string currentTrophyId =
|
||||
reinterpret_cast<const char*>(it->attribute("id").value());
|
||||
std::string currentTrophyName =
|
||||
reinterpret_cast<const char*>(it->child("name").text().as_string());
|
||||
std::string currentTrophyDescription =
|
||||
reinterpret_cast<const char*>(it->child("detail").text().as_string());
|
||||
std::string currentTrophyType =
|
||||
reinterpret_cast<const char*>(it->attribute("ttype").value());
|
||||
std::string currentTrophyUnlockState =
|
||||
reinterpret_cast<const char*>(it->attribute("unlockstate").value());
|
||||
std::string currentTrophyId = it->attribute("id").value();
|
||||
std::string currentTrophyName = it->child("name").text().as_string();
|
||||
std::string currentTrophyDescription = it->child("detail").text().as_string();
|
||||
std::string currentTrophyType = it->attribute("ttype").value();
|
||||
std::string currentTrophyUnlockState = it->attribute("unlockstate").value();
|
||||
|
||||
if (std::string(it->name()) == "trophy" && std::stoi(currentTrophyId) == trophyId) {
|
||||
if (currentTrophyType == "P") {
|
||||
platinumIt = it;
|
||||
|
||||
LOG_INFO(Lib_NpTrophy, "Found trophy to unlock {} : {}",
|
||||
it->child("name").text().as_string(),
|
||||
it->child("detail").text().as_string());
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
LOG_INFO(Lib_NpTrophy, "Trophy already unlocked");
|
||||
return ORBIS_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED;
|
||||
if (std::string(platinumIt->attribute("gid").value()).empty()) {
|
||||
platinumTrophyGroup = -1;
|
||||
} else {
|
||||
if (std::string(it->attribute("unlockstate").value()).empty()) {
|
||||
it->append_attribute("unlockstate") = "unlocked";
|
||||
} else {
|
||||
it->attribute("unlockstate").set_value("unlocked");
|
||||
}
|
||||
|
||||
g_trophy_ui.AddTrophyToQueue(trophyId, currentTrophyName, TrophyType::BRONZE);
|
||||
|
||||
//doc.save_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
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()) {
|
||||
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) {
|
||||
LOG_INFO(Lib_NpTrophy, "Found trophy to unlock {} : {}",
|
||||
it->child("name").text().as_string(),
|
||||
it->child("detail").text().as_string());
|
||||
if (currentTrophyUnlockState == "unlocked") {
|
||||
LOG_INFO(Lib_NpTrophy, "Trophy already unlocked");
|
||||
return ORBIS_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED;
|
||||
} else {
|
||||
if (std::string(it->attribute("unlockstate").value()).empty()) {
|
||||
it->append_attribute("unlockstate") = "unlocked";
|
||||
} else {
|
||||
it->attribute("unlockstate").set_value("unlocked");
|
||||
}
|
||||
|
||||
g_trophy_ui.AddTrophyToQueue(trophyId, currentTrophyName);
|
||||
}
|
||||
}
|
||||
foundTrophy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string(platinumIt->attribute("unlockstate").value()).empty()) {
|
||||
if ((numTrophies - 2) == numTrophiesUnlocked) {
|
||||
|
||||
platinumIt->append_attribute("unlockstate") = "unlocked";
|
||||
|
||||
std::string platinumTrophyId = platinumIt->attribute("id").value();
|
||||
std::string platinumTrophyName = platinumIt->child("name").text().as_string();
|
||||
|
||||
*platinumId = std::stoi(platinumTrophyId);
|
||||
g_trophy_ui.AddTrophyToQueue(*platinumId, platinumTrophyName);
|
||||
}
|
||||
} else if (std::string(platinumIt->attribute("unlockstate").value()) == "locked") {
|
||||
if ((numTrophies - 2) == numTrophiesUnlocked) {
|
||||
|
||||
platinumIt->attribute("unlockstate").set_value("unlocked");
|
||||
|
||||
std::string platinumTrophyId = platinumIt->attribute("id").value();
|
||||
std::string platinumTrophyName = platinumIt->child("name").text().as_string();
|
||||
|
||||
*platinumId = std::stoi(platinumTrophyId);
|
||||
g_trophy_ui.AddTrophyToQueue(*platinumId, platinumTrophyName);
|
||||
}
|
||||
}
|
||||
|
||||
doc.save_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
|
||||
} else
|
||||
LOG_INFO(Lib_NpTrophy, "couldnt parse xml : {}", result.description());
|
||||
|
||||
|
|
|
@ -19,12 +19,10 @@ TrophyUI::~TrophyUI() {
|
|||
Finish();
|
||||
}
|
||||
|
||||
void Libraries::NpTrophy::TrophyUI::AddTrophyToQueue(int trophyId, std::string trophyName,
|
||||
TrophyType trophyType) {
|
||||
void Libraries::NpTrophy::TrophyUI::AddTrophyToQueue(int trophyId, std::string trophyName) {
|
||||
TrophyInfo newInfo;
|
||||
newInfo.trophyId = trophyId;
|
||||
newInfo.trophyName = trophyName;
|
||||
newInfo.trophyType = trophyType;
|
||||
trophyQueue.push_back(newInfo);
|
||||
}
|
||||
|
||||
|
@ -66,8 +64,8 @@ void TrophyUI::Draw() {
|
|||
|
||||
TrophyInfo currentTrophyInfo = trophyQueue[0];
|
||||
if (Begin("Trophy Window", nullptr,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings
|
||||
| ImGuiWindowFlags_NoInputs)) {
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings |
|
||||
ImGuiWindowFlags_NoInputs)) {
|
||||
Text("Trophy earned!");
|
||||
TextWrapped(currentTrophyInfo.trophyName.c_str());
|
||||
|
||||
|
|
|
@ -14,18 +14,9 @@
|
|||
|
||||
namespace Libraries::NpTrophy {
|
||||
|
||||
enum TrophyType {
|
||||
UNKNOWN,
|
||||
PLATINUM,
|
||||
GOLD,
|
||||
SILVER,
|
||||
BRONZE,
|
||||
};
|
||||
|
||||
struct TrophyInfo {
|
||||
int trophyId = -1;
|
||||
std::string trophyName;
|
||||
TrophyType trophyType;
|
||||
};
|
||||
|
||||
class TrophyUI final : public ImGui::Layer {
|
||||
|
@ -36,7 +27,7 @@ public:
|
|||
TrophyUI();
|
||||
~TrophyUI() override;
|
||||
|
||||
void AddTrophyToQueue(int trophyId, std::string trophyName, TrophyType trophyType);
|
||||
void AddTrophyToQueue(int trophyId, std::string trophyName);
|
||||
|
||||
void Finish();
|
||||
|
||||
|
|
|
@ -102,8 +102,8 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||
param_sfo->open(sce_sys_folder.string() + "/param.sfo", {});
|
||||
id = std::string(param_sfo->GetString("CONTENT_ID"), 7, 9);
|
||||
Libraries::NpTrophy::game_serial = id;
|
||||
const auto trophyDir = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
id / "TrophyFiles";
|
||||
const auto trophyDir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / id / "TrophyFiles";
|
||||
if (!std::filesystem::exists(trophyDir)) {
|
||||
TRP trp;
|
||||
if (!trp.Extract(file.parent_path())) {
|
||||
|
|
Loading…
Add table
Reference in a new issue