mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-24 12:25:00 +00:00
Trophy pop-up and viewer enhancements (#2493)
* Include trophy rarity icons in pop up, remove newlines from viewer Fix layout Update platinum.png Fix linux and apple * Smaller type icons, center text vertically * use original icons * MacOS fixes * Address Review comments Update build.yml Update build.yml Update build.yml Update build.yml Update build.yml Update build.yml Update build.yml test * Move trophy type to leftmost and trophy art to rightmost * Embed resources * Revert packaging of resources with builds --------- Co-authored-by: rainmakerv2 <30595646+jpau02@users.noreply.github.com>
This commit is contained in:
parent
4f1baece33
commit
22ca57b1f2
12 changed files with 795 additions and 27 deletions
|
@ -941,7 +941,7 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr
|
|||
std::filesystem::path current_icon_path =
|
||||
trophy_dir / "trophy00" / "Icons" / trophy_icon_file;
|
||||
|
||||
AddTrophyToQueue(current_icon_path, current_trophy_name);
|
||||
AddTrophyToQueue(current_icon_path, current_trophy_name, current_trophy_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -978,7 +978,7 @@ int PS4_SYSV_ABI sceNpTrophyUnlockTrophy(OrbisNpTrophyContext context, OrbisNpTr
|
|||
trophy_dir / "trophy00" / "Icons" / platinum_icon_file;
|
||||
|
||||
*platinumId = platinum_trophy_id;
|
||||
AddTrophyToQueue(platinum_icon_path, platinum_trophy_name);
|
||||
AddTrophyToQueue(platinum_icon_path, platinum_trophy_name, "P");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <cmrc/cmrc.hpp>
|
||||
#include <imgui.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
|
@ -10,6 +11,8 @@
|
|||
#include "imgui/imgui_std.h"
|
||||
#include "trophy_ui.h"
|
||||
|
||||
CMRC_DECLARE(res);
|
||||
|
||||
using namespace ImGui;
|
||||
namespace Libraries::NpTrophy {
|
||||
|
||||
|
@ -17,14 +20,34 @@ std::optional<TrophyUI> current_trophy_ui;
|
|||
std::queue<TrophyInfo> trophy_queue;
|
||||
std::mutex queueMtx;
|
||||
|
||||
TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName)
|
||||
: trophy_name(trophyName) {
|
||||
TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName,
|
||||
const std::string_view& rarity)
|
||||
: trophy_name(trophyName), trophy_type(rarity) {
|
||||
|
||||
if (std::filesystem::exists(trophyIconPath)) {
|
||||
trophy_icon = RefCountedTexture::DecodePngFile(trophyIconPath);
|
||||
} else {
|
||||
LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}",
|
||||
fmt::UTF(trophyIconPath.u8string()));
|
||||
}
|
||||
|
||||
std::string pathString;
|
||||
if (trophy_type == "P") {
|
||||
pathString = "Resources/platinum.png";
|
||||
} else if (trophy_type == "G") {
|
||||
pathString = "Resources/gold.png";
|
||||
} else if (trophy_type == "S") {
|
||||
pathString = "Resources/silver.png";
|
||||
} else if (trophy_type == "B") {
|
||||
pathString = "Resources/bronze.png";
|
||||
}
|
||||
|
||||
auto resource = cmrc::res::get_filesystem();
|
||||
auto trophytypefile = resource.open(pathString);
|
||||
std::filesystem::path trophyTypePath = pathString;
|
||||
if (std::filesystem::exists(trophyTypePath))
|
||||
trophy_type_icon = RefCountedTexture::DecodePngFile(trophyTypePath);
|
||||
|
||||
AddLayer(this);
|
||||
}
|
||||
|
||||
|
@ -42,29 +65,49 @@ void TrophyUI::Draw() {
|
|||
float AdjustWidth = io.DisplaySize.x / 1280;
|
||||
float AdjustHeight = io.DisplaySize.y / 720;
|
||||
const ImVec2 window_size{
|
||||
std::min(io.DisplaySize.x, (300 * AdjustWidth)),
|
||||
std::min(io.DisplaySize.x, (350 * AdjustWidth)),
|
||||
std::min(io.DisplaySize.y, (70 * AdjustHeight)),
|
||||
};
|
||||
|
||||
SetNextWindowSize(window_size);
|
||||
SetNextWindowCollapsed(false);
|
||||
SetNextWindowPos(ImVec2(io.DisplaySize.x - (300 * AdjustWidth), (50 * AdjustHeight)));
|
||||
SetNextWindowPos(ImVec2(io.DisplaySize.x - (370 * AdjustWidth), (50 * AdjustHeight)));
|
||||
KeepNavHighlight();
|
||||
if (Begin("Trophy Window", nullptr,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings |
|
||||
ImGuiWindowFlags_NoInputs)) {
|
||||
if (trophy_icon) {
|
||||
Image(trophy_icon.GetTexture().im_id, ImVec2((50 * AdjustWidth), (50 * AdjustHeight)));
|
||||
ImGui::SameLine();
|
||||
if (trophy_type_icon) {
|
||||
SetCursorPosY((window_size.y * 0.5f) - (25 * AdjustHeight));
|
||||
Image(trophy_type_icon.GetTexture().im_id,
|
||||
ImVec2((50 * AdjustWidth), (50 * AdjustHeight)));
|
||||
} else {
|
||||
// placeholder
|
||||
const auto pos = GetCursorScreenPos();
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{50.0f},
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{50.0f * AdjustHeight},
|
||||
GetColorU32(ImVec4{0.7f}));
|
||||
ImGui::Indent(60);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
SetWindowFontScale((1.2 * AdjustHeight));
|
||||
char earned_text[] = "Trophy earned!\n%s";
|
||||
const float text_height =
|
||||
ImGui::CalcTextSize(std::strcat(earned_text, trophy_name.c_str())).y;
|
||||
SetCursorPosY((window_size.y - text_height) * 0.5f);
|
||||
|
||||
ImGui::PushTextWrapPos(window_size.x - (60 * AdjustWidth));
|
||||
TextWrapped("Trophy earned!\n%s", trophy_name.c_str());
|
||||
ImGui::SameLine(window_size.x - (60 * AdjustWidth));
|
||||
|
||||
if (trophy_icon) {
|
||||
SetCursorPosY((window_size.y * 0.5f) - (25 * AdjustHeight));
|
||||
Image(trophy_icon.GetTexture().im_id, ImVec2((50 * AdjustWidth), (50 * AdjustHeight)));
|
||||
} else {
|
||||
// placeholder
|
||||
const auto pos = GetCursorScreenPos();
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(pos, pos + ImVec2{30.0f * AdjustHeight},
|
||||
GetColorU32(ImVec4{0.7f}));
|
||||
}
|
||||
}
|
||||
End();
|
||||
|
||||
|
@ -74,14 +117,16 @@ void TrophyUI::Draw() {
|
|||
if (!trophy_queue.empty()) {
|
||||
TrophyInfo next_trophy = trophy_queue.front();
|
||||
trophy_queue.pop();
|
||||
current_trophy_ui.emplace(next_trophy.trophy_icon_path, next_trophy.trophy_name);
|
||||
current_trophy_ui.emplace(next_trophy.trophy_icon_path, next_trophy.trophy_name,
|
||||
next_trophy.trophy_type);
|
||||
} else {
|
||||
current_trophy_ui.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::string& trophyName) {
|
||||
void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::string& trophyName,
|
||||
const std::string_view& rarity) {
|
||||
std::lock_guard<std::mutex> lock(queueMtx);
|
||||
|
||||
if (Config::getisTrophyPopupDisabled()) {
|
||||
|
@ -90,10 +135,11 @@ void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::st
|
|||
TrophyInfo new_trophy;
|
||||
new_trophy.trophy_icon_path = trophyIconPath;
|
||||
new_trophy.trophy_name = trophyName;
|
||||
new_trophy.trophy_type = rarity;
|
||||
trophy_queue.push(new_trophy);
|
||||
} else {
|
||||
current_trophy_ui.emplace(trophyIconPath, trophyName);
|
||||
current_trophy_ui.emplace(trophyIconPath, trophyName, rarity);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Libraries::NpTrophy
|
||||
} // namespace Libraries::NpTrophy
|
||||
|
|
|
@ -17,7 +17,8 @@ namespace Libraries::NpTrophy {
|
|||
|
||||
class TrophyUI final : public ImGui::Layer {
|
||||
public:
|
||||
TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName);
|
||||
TrophyUI(const std::filesystem::path& trophyIconPath, const std::string& trophyName,
|
||||
const std::string_view& rarity);
|
||||
~TrophyUI() override;
|
||||
|
||||
void Finish();
|
||||
|
@ -26,15 +27,19 @@ public:
|
|||
|
||||
private:
|
||||
std::string trophy_name;
|
||||
std::string_view trophy_type;
|
||||
float trophy_timer = 5.0f;
|
||||
ImGui::RefCountedTexture trophy_icon;
|
||||
ImGui::RefCountedTexture trophy_type_icon;
|
||||
};
|
||||
|
||||
struct TrophyInfo {
|
||||
std::filesystem::path trophy_icon_path;
|
||||
std::string trophy_name;
|
||||
std::string_view trophy_type;
|
||||
};
|
||||
|
||||
void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::string& trophyName);
|
||||
void AddTrophyToQueue(const std::filesystem::path& trophyIconPath, const std::string& trophyName,
|
||||
const std::string_view& rarity);
|
||||
|
||||
}; // namespace Libraries::NpTrophy
|
||||
}; // namespace Libraries::NpTrophy
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <cmrc/cmrc.hpp>
|
||||
#include "common/path_util.h"
|
||||
#include "trophy_viewer.h"
|
||||
|
||||
CMRC_DECLARE(res);
|
||||
|
||||
TrophyViewer::TrophyViewer(QString trophyPath, QString gameTrpPath) : QMainWindow() {
|
||||
this->setWindowTitle(tr("Trophy Viewer"));
|
||||
this->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
@ -115,13 +118,34 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
|
|||
item->setData(Qt::DecorationRole, icon);
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
|
||||
tableWidget->setItem(row, 1, item);
|
||||
|
||||
const std::string filename = GetTrpType(trpType[row].at(0));
|
||||
QTableWidgetItem* typeitem = new QTableWidgetItem();
|
||||
|
||||
auto resource = cmrc::res::get_filesystem();
|
||||
std::string resourceString = "Resources/" + filename;
|
||||
auto trophytypefile = resource.open(resourceString);
|
||||
|
||||
QImage type_icon =
|
||||
QImage(QString::fromStdString(resourceString))
|
||||
.scaled(QSize(64, 64), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
typeitem->setData(Qt::DecorationRole, type_icon);
|
||||
typeitem->setFlags(typeitem->flags() & ~Qt::ItemIsEditable);
|
||||
tableWidget->setItem(row, 6, typeitem);
|
||||
|
||||
std::string detailString = trophyDetails[row].toStdString();
|
||||
std::size_t newline_pos = 0;
|
||||
while ((newline_pos = detailString.find("\n", newline_pos)) != std::string::npos) {
|
||||
detailString.replace(newline_pos, 1, " ");
|
||||
++newline_pos;
|
||||
}
|
||||
|
||||
if (!trophyNames.isEmpty() && !trophyDetails.isEmpty()) {
|
||||
SetTableItem(tableWidget, row, 0, trpUnlocked[row]);
|
||||
SetTableItem(tableWidget, row, 2, trophyNames[row]);
|
||||
SetTableItem(tableWidget, row, 3, trophyDetails[row]);
|
||||
SetTableItem(tableWidget, row, 3, QString::fromStdString(detailString));
|
||||
SetTableItem(tableWidget, row, 4, trpId[row]);
|
||||
SetTableItem(tableWidget, row, 5, trpHidden[row]);
|
||||
SetTableItem(tableWidget, row, 6, GetTrpType(trpType[row].at(0)));
|
||||
SetTableItem(tableWidget, row, 7, trpPid[row]);
|
||||
}
|
||||
tableWidget->verticalHeader()->resizeSection(row, icon.height());
|
||||
|
@ -157,7 +181,7 @@ void TrophyViewer::SetTableItem(QTableWidget* parent, int row, int column, QStri
|
|||
label->setGraphicsEffect(shadowEffect); // Apply shadow effect to the QLabel
|
||||
|
||||
layout->addWidget(label);
|
||||
if (column != 1 && column != 2)
|
||||
if (column != 1 && column != 2 && column != 3)
|
||||
layout->setAlignment(Qt::AlignCenter);
|
||||
widget->setLayout(layout);
|
||||
parent->setItem(row, column, item);
|
||||
|
|
|
@ -32,17 +32,17 @@ private:
|
|||
QString gameTrpPath_;
|
||||
TRP trp;
|
||||
|
||||
QString GetTrpType(const QChar trp_) {
|
||||
std::string GetTrpType(const QChar trp_) {
|
||||
switch (trp_.toLatin1()) {
|
||||
case 'B':
|
||||
return "Bronze";
|
||||
return "bronze.png";
|
||||
case 'S':
|
||||
return "Silver";
|
||||
return "silver.png";
|
||||
case 'G':
|
||||
return "Gold";
|
||||
return "gold.png";
|
||||
case 'P':
|
||||
return "Platinum";
|
||||
return "platinum.png";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue