From 72e4989b1e1643c9237ba68ae4e3fe77fa489c63 Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 5 Oct 2026 09:48:46 +0400 Subject: [PATCH] Add trophy notification support Co-authored-by: Felipe <54341095+Pipe530@users.noreply.github.com> --- CMakeLists.txt | 11 +- assets/sounds/trophy-unlock.wav | Bin 0 -> 316844 bytes src/common/CMakeLists.txt | 1 + src/common/emulatorConfig.cpp | 4 + src/common/emulatorConfig.h | 2 + src/common/trophies.cpp | 264 ++++ src/common/trophies.h | 48 + src/graphics/presentation/systemOverlay.cpp | 239 ++- src/graphics/presentation/systemOverlay.h | 5 + src/launcher/CMakeLists.txt | 1 + .../forms/configuration_edit_dialog.ui | 19 +- src/launcher/include/configuration.h | 4 + .../include/configurationListWidget.h | 2 + src/launcher/include/gameContent.h | 1 - src/launcher/include/trophyViewerDialog.h | 5 +- src/launcher/src/configurationEditDialog.cpp | 6 +- src/launcher/src/configurationListWidget.cpp | 3 +- src/launcher/src/mainDialog.cpp | 2 + src/launcher/src/trophyViewerDialog.cpp | 548 +------ src/libs/libNet.cpp | 1125 +------------- src/libs/libTrophy.cpp | 1288 +++++++++++++++++ src/main.cpp | 7 + 22 files changed, 1967 insertions(+), 1618 deletions(-) create mode 100644 assets/sounds/trophy-unlock.wav create mode 100644 src/common/trophies.cpp create mode 100644 src/common/trophies.h create mode 100644 src/libs/libTrophy.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f940723c7..2ebfa982c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.18...4.3) +cmake_minimum_required(VERSION 3.19...4.3) if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0) set(CMAKE_POLICY_VERSION_MINIMUM 3.10 CACHE STRING "Minimum policy version for bundled dependencies") @@ -725,6 +725,15 @@ endif() add_executable(kyty_emulator "${KYTY_SOURCE_DIR}/main.cpp" ${kyty_emulator_src}) configure_macos_guest_address_space(kyty_emulator) +set(KYTY_TROPHY_UNLOCK_SOUND "${CMAKE_CURRENT_SOURCE_DIR}/assets/sounds/trophy-unlock.wav") +add_custom_target(kyty_trophy_sound + COMMAND ${CMAKE_COMMAND} -E make_directory "$/assets/sounds" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${KYTY_TROPHY_UNLOCK_SOUND}" + "$/assets/sounds/trophy-unlock.wav" + VERBATIM) +add_dependencies(kyty_emulator kyty_trophy_sound) +install(FILES "${KYTY_TROPHY_UNLOCK_SOUND}" DESTINATION assets/sounds) + target_link_libraries(kyty_emulator ${kyty_emulator_link_libraries}) if (WIN32) target_link_libraries(kyty_emulator opengl32) diff --git a/assets/sounds/trophy-unlock.wav b/assets/sounds/trophy-unlock.wav new file mode 100644 index 0000000000000000000000000000000000000000..22d065c49a84410c32e5be40ebe2ebbc6fa19db3 GIT binary patch literal 316844 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≪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

DO#Wi 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 literal 0 HcmV?d00001 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c6978a724..d3617c077 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -27,6 +27,7 @@ target_link_libraries(common kyty_git_version spdlog::spdlog ZArchive::zarchive + nlohmann_json::nlohmann_json ) get_property(inc_headers TARGET common PROPERTY INCLUDE_DIRECTORIES) diff --git a/src/common/emulatorConfig.cpp b/src/common/emulatorConfig.cpp index ccceb5f8c..2884b788b 100644 --- a/src/common/emulatorConfig.cpp +++ b/src/common/emulatorConfig.cpp @@ -156,6 +156,10 @@ bool TessellationEnabled() { return g_config->tessellation_enabled; } +bool TrophyEnabled() { + return g_config->trophy_enabled; +} + bool PlayGoHackEnabled() { return g_config->playgo_hack_enabled; } diff --git a/src/common/emulatorConfig.h b/src/common/emulatorConfig.h index 92cea9103..fc29e94bf 100644 --- a/src/common/emulatorConfig.h +++ b/src/common/emulatorConfig.h @@ -74,6 +74,7 @@ struct ConfigOptions { bool renderdoc_enabled = false; bool readback_linear_images = false; bool tessellation_enabled = false; + bool trophy_enabled = true; bool playgo_hack_enabled = false; #if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS bool red_zone_protection_enabled = false; @@ -123,6 +124,7 @@ bool GpuAssistedValidationEnabled(); bool RenderDocEnabled(); bool ReadbackLinearImagesEnabled(); bool TessellationEnabled(); +bool TrophyEnabled(); bool PlayGoHackEnabled(); #if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS bool RedZoneProtectionEnabled(); diff --git a/src/common/trophies.cpp b/src/common/trophies.cpp new file mode 100644 index 000000000..b28dbb554 --- /dev/null +++ b/src/common/trophies.cpp @@ -0,0 +1,264 @@ +#include "common/trophies.h" + +#include "common/file.h" + +#include +#include +#include +#include +#include +#include + +namespace Common::Trophies { +namespace { + +using Json = nlohmann::json; +using Files = std::map>; + +constexpr uint64_t MaxUnlocksSize = uint64_t {1} << 20u; +constexpr uint64_t MaxPackageSize = uint64_t {1} << 30u; + +uint64_t ReadBigEndian(const std::byte* data, size_t size) { + uint64_t value = 0; + for (size_t i = 0; i < size; ++i) { + value = (value << 8u) | std::to_integer(data[i]); + } + return value; +} + +int ReadId(const Json& value) { + if (value.is_number_integer()) { + const auto number = value.get(); + return number >= 0 && number <= INT32_MAX ? static_cast(number) : -1; + } + if (!value.is_string()) { + return -1; + } + const auto& text = value.get_ref(); + int id = -1; + const auto [end, error] = std::from_chars(text.data(), text.data() + text.size(), id); + return error == std::errc {} && end == text.data() + text.size() && id >= 0 ? id : -1; +} + +Json ReadJson(const Files& files, std::string_view name) { + const auto entry = files.find(name); + if (entry == files.end()) { + return {}; + } + return Json::parse(entry->second.begin(), entry->second.end(), nullptr, false); +} + +Package ParsePackage(std::span data, int console_language) { + if (data.size() < 0x40 || data.size() > MaxPackageSize || + ReadBigEndian(data.data(), 4) != 0xb228c60a || ReadBigEndian(data.data() + 4, 4) != 1) { + return {}; + } + const auto size = ReadBigEndian(data.data() + 8, 8); + const auto count = ReadBigEndian(data.data() + 0x10, 4); + const auto toc = ReadBigEndian(data.data() + 0x14, 4); + if (size < 0x40 || size > data.size() || count > 4096 || toc > size || + 0x20 + count * 0x40 > size - toc) { + return {}; + } + Files files; + for (uint64_t i = 0; i < count; ++i) { + const auto* entry = data.data() + toc + 0x20 + i * 0x40; + const auto* name = reinterpret_cast(entry); + const std::string_view filename(name, std::find(name, name + 0x20, '\0') - name); + const auto offset = ReadBigEndian(entry + 0x20, 8); + const auto length = ReadBigEndian(entry + 0x28, 8); + if (offset > size || length > size - offset) { + return {}; + } + files.emplace(filename, data.subspan(offset, length)); + } + const auto conf = ReadJson(files, "tropconf.json"); + if (!conf.is_object() || !conf.contains("trophies") || !conf["trophies"].is_array() || + conf["trophies"].size() > 1000 || !conf.contains("defaultLanguage") || + !conf["defaultLanguage"].is_string()) { + return {}; + } + static constexpr std::array locales = { + "ja-JP", "en-US", "fr-FR", "es-ES", "de-DE", "it-IT", "nl-NL", "pt-PT", + "ru-RU", "ko-KR", "zh-Hant", "zh-Hans", "fi-FI", "sv-SE", "da-DK", "no-NO", + "pl-PL", "pt-BR", "en-GB", "tr-TR", "es-419", "ar-AE", "fr-CA", "cs-CZ", + "hu-HU", "el-GR", "ro-RO", "th-TH", "vi-VN", "id-ID"}; + const auto locale = + locales[console_language >= 0 && console_language < locales.size() ? console_language : 1]; + auto meta = ReadJson(files, fmt::format("tropmeta_{}.json", locale)); + if (meta.is_null()) { + meta = ReadJson(files, fmt::format("tropmeta_{}.json", + conf["defaultLanguage"].get_ref())); + } + if (!meta.is_object() || !meta.contains("metadata") || !meta["metadata"].is_object()) { + return {}; + } + const auto& texts = meta["metadata"]; + if (!texts.contains("titleMetadata") || !texts["titleMetadata"].is_object() || + !texts["titleMetadata"].contains("name") || !texts["titleMetadata"]["name"].is_string() || + !texts.contains("trophyMetadata") || !texts["trophyMetadata"].is_array()) { + return {}; + } + Package package; + package.title = texts["titleMetadata"]["name"].get(); + package.groups.emplace(-1, package.title); + uint64_t icon_bytes = 0; + for (const auto& definition: conf["trophies"]) { + if (!definition.is_object() || !definition.contains("id") || + !definition.contains("grade") || !definition["grade"].is_string()) { + return {}; + } + Trophy trophy; + trophy.id = ReadId(definition["id"]); + const auto grade = definition["grade"].get(); + const auto grade_index = std::string_view("PGSB").find(grade); + if (trophy.id < 0 || grade.size() != 1 || grade_index == std::string_view::npos) { + return {}; + } + trophy.grade = static_cast(grade_index) + 1; + if (definition.contains("groupId")) { + trophy.group_id = ReadId(definition["groupId"]); + if (trophy.group_id < 0) { + return {}; + } + } + if (definition.contains("platinumTrophyId")) { + trophy.platinum_id = ReadId(definition["platinumTrophyId"]); + } + trophy.hidden = definition.contains("hidden") && definition["hidden"] == true; + trophy.has_reward = definition.contains("hasReward") && definition["hasReward"] == true; + if (definition.contains("unlockCondition")) { + const auto& condition = definition["unlockCondition"]; + if (condition.is_object() && condition.contains("progressive") && + condition["progressive"] == true) { + if (!condition.contains("targetValue") || !condition["targetValue"].is_string()) { + return {}; + } + const auto& value = condition["targetValue"].get_ref(); + uint64_t target = 0; + const auto [end, error] = + std::from_chars(value.data(), value.data() + value.size(), target); + if (error != std::errc {} || end != value.data() + value.size()) { + return {}; + } + trophy.target = target; + } + } + const auto icon = files.find(fmt::format("trop{:04}.png", trophy.id)); + if (icon != files.end()) { + if (icon->second.size() > size - icon_bytes) { + return {}; + } + trophy.icon_png.assign(icon->second.begin(), icon->second.end()); + icon_bytes += icon->second.size(); + } + package.groups.try_emplace(trophy.group_id); + if (package.groups.size() > 50 || + !package.trophies.emplace(trophy.id, std::move(trophy)).second) { + return {}; + } + } + if (texts.contains("groupMetadata") && texts["groupMetadata"].is_array()) { + for (const auto& group: texts["groupMetadata"]) { + if (group.is_object() && group.contains("id") && group.contains("name") && + group["name"].is_string()) { + const auto found = package.groups.find(ReadId(group["id"])); + if (found != package.groups.end()) { + found->second = group["name"].get(); + } + } + } + } + for (const auto& text: texts["trophyMetadata"]) { + if (!text.is_object() || !text.contains("id")) { + continue; + } + const auto found = package.trophies.find(ReadId(text["id"])); + if (found == package.trophies.end()) { + continue; + } + for (const auto& [key, field]: {std::pair {"name", &found->second.name}, + {"detail", &found->second.description}, + {"reward", &found->second.reward}}) { + if (text.contains(key) && text[key].is_string()) { + *field = text[key].get(); + } + } + } + return package; +} + +} // namespace + +Package LoadPackage(const std::filesystem::path& path, int console_language) { + File file(path, File::Mode::Read); + if (file.IsInvalid() || file.Size() > MaxPackageSize) { + return {}; + } + return ParsePackage(file.ReadWholeBuffer(), console_language); +} + +std::filesystem::path PackagePath(uint32_t service_label) { + return std::filesystem::path(PackageDirectory) / fmt::format("trophy{:02}.ucp", service_label); +} + +std::filesystem::path UnlocksPath(const std::filesystem::path& root, std::string_view title_id, + int user_id, uint32_t service_label) { + if (title_id.empty() || !std::all_of(title_id.begin(), title_id.end(), [](char c) { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || + c == '_' || c == '-'; + })) { + return {}; + } + return root / "_SaveData" / title_id / + fmt::format("trophies_{}_{}.json", user_id, service_label); +} + +std::set LoadUnlocks(const std::filesystem::path& path) { + File file(path, File::Mode::Read); + if (file.IsInvalid() || file.Size() > MaxUnlocksSize) { + return {}; + } + const auto bytes = file.ReadWholeBuffer(); + const auto json = Json::parse(bytes.begin(), bytes.end(), nullptr, false); + if (!json.is_object() || !json.contains("unlockedTrophies") || + !json["unlockedTrophies"].is_array()) { + return {}; + } + std::set unlocked; + for (const auto& value: json["unlockedTrophies"]) { + const auto id = ReadId(value); + if (id >= 0) { + unlocked.insert(id); + } + } + return unlocked; +} + +bool SaveUnlocks(const std::filesystem::path& path, const std::set& unlocked) { + if (path.empty() || !File::CreateDirectories(path.parent_path())) { + return false; + } + const auto text = Json {{"unlockedTrophies", unlocked}}.dump(); + auto temporary = path; + temporary += ".tmp"; + File file; + if (text.size() > MaxUnlocksSize || !file.Create(temporary)) { + return false; + } + uint32_t written = 0; + file.Write(text.data(), static_cast(text.size()), &written); + const bool complete = written == text.size() && file.Flush(); + file.Close(); + std::error_code error; + if (complete) { + std::filesystem::rename(temporary, path, error); + if (!error) { + return true; + } + } + std::filesystem::remove(temporary, error); + return false; +} + +} // namespace Common::Trophies diff --git a/src/common/trophies.h b/src/common/trophies.h new file mode 100644 index 000000000..7be1ed726 --- /dev/null +++ b/src/common/trophies.h @@ -0,0 +1,48 @@ +#ifndef KYTY_COMMON_TROPHIES_H_ +#define KYTY_COMMON_TROPHIES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Common::Trophies { + +inline constexpr char PackageDirectory[] = "sce_sys/trophy2"; + +struct Trophy { + int id = 0; + int group_id = -1; + int platinum_id = -1; + int grade = 0; + std::optional target; + std::string name; + std::string description; + std::string reward; + std::vector icon_png; + bool hidden = false; + bool has_reward = false; +}; + +struct Package { + std::string title; + std::map groups; + std::map trophies; +}; + +[[nodiscard]] Package LoadPackage(const std::filesystem::path& path, int console_language); +[[nodiscard]] std::filesystem::path PackagePath(uint32_t service_label); +[[nodiscard]] std::filesystem::path UnlocksPath(const std::filesystem::path& root, + std::string_view title_id, int user_id, + uint32_t service_label); +[[nodiscard]] std::set LoadUnlocks(const std::filesystem::path& path); +[[nodiscard]] bool SaveUnlocks(const std::filesystem::path& path, const std::set& unlocked); + +} // namespace Common::Trophies + +#endif // KYTY_COMMON_TROPHIES_H_ diff --git a/src/graphics/presentation/systemOverlay.cpp b/src/graphics/presentation/systemOverlay.cpp index 56ed70617..ab4863b88 100644 --- a/src/graphics/presentation/systemOverlay.cpp +++ b/src/graphics/presentation/systemOverlay.cpp @@ -3,14 +3,17 @@ #include #include "common/assert.h" +#include "common/logging/log.h" #include "common/stringUtils.h" #include "graphics/host_gpu/graphicContext.h" #include "imgui.h" +#include "imgui_internal.h" #include "imgui_impl_vulkan.h" #include "libs/controller.h" #include "libs/dialog.h" #include "libs/ime.h" #include "libs/imeDialog.h" +#include "stb_image.h" #include #include @@ -18,12 +21,17 @@ #include #include #include +#include #include +#include +#include #include +#include #include #include #include #include +#include namespace Libs::Graphics { @@ -178,6 +186,14 @@ bool g_input_lifecycle_active = false; bool g_controller_captured = false; OverlaySession g_session; SDL_Window* g_input_window = nullptr; +struct TrophyNotification { + std::string name; + int32_t grade; + std::vector icon_png; +}; +std::mutex g_trophy_notification_mutex; +std::deque g_trophy_notifications; +std::atomic g_trophy_notification_active {false}; void ClearInputEvents() { std::scoped_lock lock(g_input_mutex); @@ -467,8 +483,9 @@ SystemOverlayVisualState GetSystemOverlayVisualState() noexcept { const auto core = CoreIme::GetVisualState(); const auto dialog = DialogIme::GetVisualState(); const auto system = SystemDialog::GetVisualState(); - return {core.active || dialog.active || system.active, - core.revision + dialog.revision + system.revision}; + const bool trophy_active = g_trophy_notification_active.load(std::memory_order_acquire); + return {core.active || dialog.active || system.active || trophy_active, + core.revision + dialog.revision + system.revision + (trophy_active ? 1u : 0u)}; } bool ProcessSystemOverlayInput(const SDL_Event& event) { @@ -599,12 +616,34 @@ bool ProcessSystemOverlayInput(const SDL_Event& event) { } } +void NotifyTrophyUnlocked(std::string_view name, int32_t grade, + std::span icon_png) { + std::scoped_lock lock(g_trophy_notification_mutex); + g_trophy_notifications.push_back( + {std::string(name), grade, std::vector(icon_png.begin(), icon_png.end())}); + g_trophy_notification_active.store(true, std::memory_order_release); +} + struct SystemOverlay::Impl { + using Clock = std::chrono::steady_clock; + explicit Impl(GraphicContext& context): graphics(context) {} ~Impl() { + SDL_DestroyAudioStream(trophy_sound_stream); + SDL_free(trophy_sound_data); + if (trophy_sound_initialized) { + SDL_QuitSubSystem(SDL_INIT_AUDIO); + } ReleaseVulkan(); if (imgui_context != nullptr) { + ImGui::SetCurrentContext(imgui_context); + if (trophy_notification_image) { + ImGui::UnregisterUserTexture(trophy_notification_image.get()); + } + for (const auto& texture: retired_trophy_images) { + ImGui::UnregisterUserTexture(texture.get()); + } ImGui::DestroyContext(imgui_context); } } @@ -631,6 +670,75 @@ struct SystemOverlay::Impl { style.ItemSpacing = {8.0f, 8.0f}; } + void PlayTrophySound() { + if (!trophy_sound_attempted) { + trophy_sound_attempted = true; + trophy_sound_initialized = SDL_InitSubSystem(SDL_INIT_AUDIO); + if (!trophy_sound_initialized) { + LOGF("[Trophy] could not initialize audio: %s\n", SDL_GetError()); + return; + } + const char* base_path = SDL_GetBasePath(); + if (base_path == nullptr) { + LOGF("[Trophy] could not locate sound: %s\n", SDL_GetError()); + return; + } + const std::string path = std::string(base_path) + "assets/sounds/trophy-unlock.wav"; + SDL_AudioSpec spec {}; + if (!SDL_LoadWAV(path.c_str(), &spec, &trophy_sound_data, &trophy_sound_size)) { + LOGF("[Trophy] could not load %s: %s\n", path.c_str(), SDL_GetError()); + return; + } + if (trophy_sound_size > static_cast(std::numeric_limits::max())) { + LOGF("[Trophy] sound is too large: %s\n", path.c_str()); + return; + } + trophy_sound_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, + &spec, nullptr, nullptr); + if (trophy_sound_stream == nullptr) { + LOGF("[Trophy] could not open audio stream: %s\n", SDL_GetError()); + return; + } + } + if (trophy_sound_stream != nullptr && + (!SDL_PutAudioStreamData(trophy_sound_stream, trophy_sound_data, + static_cast(trophy_sound_size)) || + !SDL_ResumeAudioStreamDevice(trophy_sound_stream))) { + LOGF("[Trophy] could not play sound: %s\n", SDL_GetError()); + } + } + + std::unique_ptr LoadTrophyIcon(std::span encoded) { + if (encoded.empty() || + encoded.size() > static_cast(std::numeric_limits::max())) { + return nullptr; + } + + const auto* data = reinterpret_cast(encoded.data()); + const int size = static_cast(encoded.size()); + int width = 0; + int height = 0; + if (!stbi_info_from_memory(data, size, &width, &height, nullptr) || width <= 0 || + height <= 0 || width > 512 || height > 512) { + LOGF("[Trophy] invalid icon or dimensions exceed 512x512\n"); + return nullptr; + } + auto* pixels = stbi_load_from_memory(data, size, &width, &height, nullptr, 4); + if (pixels == nullptr) { + LOGF("[Trophy] could not decode trophy icon: %s\n", stbi_failure_reason()); + return nullptr; + } + + auto texture = std::make_unique(); + texture->Create(ImTextureFormat_RGBA32, width, height); + std::memcpy(texture->Pixels, pixels, + static_cast(width) * static_cast(height) * 4); + texture->UseColors = true; + stbi_image_free(pixels); + ImGui::RegisterUserTexture(texture.get()); + return texture; + } + void EnsureVulkan(vk::Format format, uint32_t image_count) { EnsureContext(); if (vulkan_initialized) { @@ -952,9 +1060,104 @@ struct SystemOverlay::Impl { } } + void DrawTrophyNotification(vk::Extent2D frame_extent, Clock::time_point now) { + std::erase_if(retired_trophy_images, [](const auto& texture) { + if (texture->Status != ImTextureStatus_Destroyed) { + return false; + } + ImGui::UnregisterUserTexture(texture.get()); + return true; + }); + constexpr float TOAST_LIFETIME = 5.0f; + if (trophy_notification && + std::chrono::duration(now - trophy_notification_born).count() >= + TOAST_LIFETIME) { + trophy_notification.reset(); + if (trophy_notification_image) { + // Keep the texture registered until the backend retires in-flight frames. + trophy_notification_image->WantDestroyNextFrame = true; + retired_trophy_images.push_back(std::move(trophy_notification_image)); + } + } + if (!trophy_notification) { + { + std::scoped_lock lock(g_trophy_notification_mutex); + if (g_trophy_notifications.empty()) { + g_trophy_notification_active.store(!retired_trophy_images.empty(), + std::memory_order_release); + return; + } + trophy_notification = std::move(g_trophy_notifications.front()); + g_trophy_notifications.pop_front(); + } + trophy_notification_born = now; + trophy_notification_image = LoadTrophyIcon(trophy_notification->icon_png); + PlayTrophySound(); + } + const float age = std::chrono::duration(now - trophy_notification_born).count(); + const float screen_scale = + std::clamp(std::min(static_cast(frame_extent.width) / 1920.0f, + static_cast(frame_extent.height) / 1080.0f), + 0.65f, 1.25f); + const float width = std::max( + 0.0f, std::min(440.0f * screen_scale, static_cast(frame_extent.width) - 32.0f)); + const float height = 104.0f * screen_scale; + const float fade_in = std::clamp(age / 0.22f, 0.0f, 1.0f); + const float fade_out = std::clamp((TOAST_LIFETIME - age) / 0.4f, 0.0f, 1.0f); + const float alpha = std::min(fade_in, fade_out); + const float slide = (1.0f - fade_in) * (width + 24.0f); + const ImVec2 top_left {static_cast(frame_extent.width) - 24.0f - width + slide, + 32.0f}; + const ImVec2 bottom_right {top_left.x + width, top_left.y + height}; + auto* draw = ImGui::GetForegroundDrawList(); + draw->AddRectFilled({top_left.x + 5.0f, top_left.y + 6.0f}, + {bottom_right.x + 5.0f, bottom_right.y + 6.0f}, + IM_COL32(0, 0, 0, static_cast(95.0f * alpha)), 10.0f); + draw->AddRectFilled(top_left, bottom_right, + IM_COL32(18, 21, 29, static_cast(242.0f * alpha)), 10.0f); + draw->AddRect(top_left, bottom_right, + IM_COL32(190, 154, 78, static_cast(200.0f * alpha)), 10.0f, + ImDrawFlags_RoundCornersAll, 1.5f); + + if (trophy_notification_image != nullptr) { + constexpr float ICON_SIZE = 88.0f; + const ImVec2 icon_min {top_left.x + 8.0f * screen_scale, + top_left.y + (height - ICON_SIZE * screen_scale) * 0.5f}; + const ImVec2 icon_max {icon_min.x + ICON_SIZE * screen_scale, + icon_min.y + ICON_SIZE * screen_scale}; + draw->AddImage(trophy_notification_image->GetTexRef(), icon_min, icon_max, {0, 0}, + {1, 1}, IM_COL32(255, 255, 255, static_cast(255.0f * alpha))); + } + + const ImVec2 text_position {top_left.x + + (trophy_notification_image ? 112.0f : 18.0f) * screen_scale, + top_left.y + 18.0f * screen_scale}; + draw->PushClipRect(top_left, {bottom_right.x - 12.0f * screen_scale, bottom_right.y}, true); + draw->AddText(nullptr, 13.0f * screen_scale, text_position, + IM_COL32(232, 203, 139, static_cast(255.0f * alpha)), "Trophy earned"); + draw->AddText(nullptr, 21.0f * screen_scale, + {text_position.x, text_position.y + 22.0f * screen_scale}, + IM_COL32(255, 255, 255, static_cast(255.0f * alpha)), + trophy_notification->name.c_str()); + constexpr std::array GRADE_LABELS {"Platinum", "Gold", "Silver", "Bronze"}; + constexpr std::array GRADE_COLORS { + IM_COL32(161, 225, 245, 255), IM_COL32(255, 207, 82, 255), IM_COL32(211, 220, 232, 255), + IM_COL32(211, 142, 91, 255)}; + const int grade = trophy_notification->grade; + if (grade > 0 && grade <= static_cast(GRADE_LABELS.size())) { + draw->AddText(nullptr, 13.0f * screen_scale, + {text_position.x, text_position.y + 50.0f * screen_scale}, + ImGui::GetColorU32(GRADE_COLORS[grade - 1], alpha), + GRADE_LABELS[grade - 1]); + } + draw->PopClipRect(); + } + bool PrepareFrame(vk::Extent2D frame_extent, vk::Format format, uint32_t image_count) { OverlaySnapshot snapshot; - if (!GetOverlaySnapshot(&snapshot)) { + const bool has_overlay = GetOverlaySnapshot(&snapshot); + const auto now = Clock::now(); + if (!has_overlay && !g_trophy_notification_active.load(std::memory_order_acquire)) { return false; } const auto prepared_session = snapshot.session; @@ -977,7 +1180,6 @@ struct SystemOverlay::Impl { auto& io = ImGui::GetIO(); io.DisplaySize = {static_cast(frame_extent.width), static_cast(frame_extent.height)}; - const auto now = std::chrono::steady_clock::now(); io.DeltaTime = last_frame == std::chrono::steady_clock::time_point {} ? 1.0f / 60.0f : std::clamp(std::chrono::duration(now - last_frame).count(), @@ -985,15 +1187,19 @@ struct SystemOverlay::Impl { last_frame = now; ImGui_ImplVulkan_NewFrame(); ImGui::NewFrame(); - if (!GetOverlaySnapshot(&snapshot) || snapshot.session != prepared_session) { + GetOverlaySnapshot(&snapshot); + if (snapshot.session != prepared_session) { ImGui::EndFrame(); return false; } - if (snapshot.session.kind == OverlayKind::Dialog) { - DrawDialog(snapshot.dialog, frame_extent); - } else { - DrawIme(snapshot.ime, frame_extent); + if (has_overlay) { + if (snapshot.session.kind == OverlayKind::Dialog) { + DrawDialog(snapshot.dialog, frame_extent); + } else { + DrawIme(snapshot.ime, frame_extent); + } } + DrawTrophyNotification(frame_extent, now); ImGui::Render(); extent = frame_extent; return true; @@ -1040,9 +1246,18 @@ struct SystemOverlay::Impl { float button_height = 42.0f; ImVec2 panel_offset {}; ImVec2 right_stick {}; - OverlaySession session; - vk::Extent2D extent {}; - std::chrono::steady_clock::time_point last_frame; + OverlaySession session; + std::unique_ptr trophy_notification_image; + std::optional trophy_notification; + Clock::time_point trophy_notification_born; + std::vector> retired_trophy_images; + SDL_AudioStream* trophy_sound_stream = nullptr; + uint8_t* trophy_sound_data = nullptr; + uint32_t trophy_sound_size = 0; + bool trophy_sound_attempted = false; + bool trophy_sound_initialized = false; + vk::Extent2D extent {}; + std::chrono::steady_clock::time_point last_frame; }; SystemOverlay::SystemOverlay(GraphicContext& graphics): m_impl(std::make_unique(graphics)) {} diff --git a/src/graphics/presentation/systemOverlay.h b/src/graphics/presentation/systemOverlay.h index 7fbb157f2..1ecdbc3d8 100644 --- a/src/graphics/presentation/systemOverlay.h +++ b/src/graphics/presentation/systemOverlay.h @@ -4,7 +4,10 @@ #include "common/common.h" #include "graphics/host_gpu/vulkanCommon.h" +#include #include +#include +#include union SDL_Event; struct SDL_Window; @@ -22,6 +25,8 @@ void InitializeSystemOverlayInput(SDL_Window* window); void ShutdownSystemOverlayInput(); bool ProcessSystemOverlayInput(const SDL_Event& event); SystemOverlayVisualState GetSystemOverlayVisualState() noexcept; +void NotifyTrophyUnlocked(std::string_view name, int32_t grade, + std::span icon_png); class SystemOverlay final { public: diff --git a/src/launcher/CMakeLists.txt b/src/launcher/CMakeLists.txt index d57962375..77949e559 100644 --- a/src/launcher/CMakeLists.txt +++ b/src/launcher/CMakeLists.txt @@ -96,6 +96,7 @@ install(TARGETS launcher if(APPLE) install(TARGETS kyty_emulator DESTINATION "KytyPS5.app/Contents/MacOS") + install(FILES "${KYTY_TROPHY_UNLOCK_SOUND}" DESTINATION "KytyPS5.app/Contents/Resources/assets/sounds") # Deploy and ad-hoc sign the Qt frameworks and plugins in the bundle. find_program(KYTY_MACDEPLOYQT NAMES macdeployqt PATHS "${Qt6_DIR}/../../../bin" NO_DEFAULT_PATH) if(NOT KYTY_MACDEPLOYQT) diff --git a/src/launcher/forms/configuration_edit_dialog.ui b/src/launcher/forms/configuration_edit_dialog.ui index 52589949a..82fdd0072 100644 --- a/src/launcher/forms/configuration_edit_dialog.ui +++ b/src/launcher/forms/configuration_edit_dialog.ui @@ -6,7 +6,7 @@ 0 0 - 760 + 840 620 @@ -182,7 +182,22 @@ - + + + Notifications + + + + Show trophy unlock notifications and play their sound. +To use your own sound, replace the emulator's assets/sounds/trophy-unlock.wav with a WAV file and restart the game. + Enable trophy notifications + true + + + + + + Debugging && logs diff --git a/src/launcher/include/configuration.h b/src/launcher/include/configuration.h index 92c05b8da..5b88a28e6 100644 --- a/src/launcher/include/configuration.h +++ b/src/launcher/include/configuration.h @@ -122,6 +122,7 @@ public: bool hide_cursor_enabled = false; bool readback_linear_images = false; bool tessellation_enabled = false; + bool trophy_enabled = true; int vblank_frequency = 60; int console_language = DEFAULT_CONSOLE_LANGUAGE; bool vulkan_validation_enabled = false; @@ -154,6 +155,7 @@ public: hide_cursor_enabled = other.hide_cursor_enabled; readback_linear_images = other.readback_linear_images; tessellation_enabled = other.tessellation_enabled; + trophy_enabled = other.trophy_enabled; vblank_frequency = other.vblank_frequency; console_language = other.console_language; vulkan_validation_enabled = other.vulkan_validation_enabled; @@ -201,6 +203,7 @@ public: KYTY_CFG_SET(hide_cursor_enabled); KYTY_CFG_SET(readback_linear_images); KYTY_CFG_SET(tessellation_enabled); + KYTY_CFG_SET(trophy_enabled); KYTY_CFG_SET(vblank_frequency); KYTY_CFG_SET(console_language); KYTY_CFG_SET(vulkan_validation_enabled); @@ -244,6 +247,7 @@ public: KYTY_CFG_GET(hide_cursor_enabled); KYTY_CFG_GET(readback_linear_images); KYTY_CFG_GET(tessellation_enabled); + trophy_enabled = s->value("trophy_enabled", trophy_enabled).toBool(); vblank_frequency = s->value("vblank_frequency", vblank_frequency).toInt(); console_language = s->value("console_language", console_language).toInt(); if (console_language < 0 || console_language > MAX_CONSOLE_LANGUAGE) { diff --git a/src/launcher/include/configurationListWidget.h b/src/launcher/include/configurationListWidget.h index 34b58ad96..097fa8e5b 100644 --- a/src/launcher/include/configurationListWidget.h +++ b/src/launcher/include/configurationListWidget.h @@ -28,6 +28,7 @@ public: ~ConfigurationListWidget() override; void SetRunEnabled(bool flag) { m_run_enabled = flag; } + void SetRuntimeDirectory(const QString& directory) { m_runtime_directory = directory; } [[nodiscard]] const ConfigurationItem* GetSelectedItem() const { return m_selected_item; } ConfigurationItem* GetSelectedItem() { return m_selected_item; } @@ -78,6 +79,7 @@ private: bool m_run_enabled = true; Ui::ConfigurationListWidget* m_ui = nullptr; QString m_settings_file; + QString m_runtime_directory; QStringList m_game_dirs; Configuration m_global_info; QMap m_custom_infos; diff --git a/src/launcher/include/gameContent.h b/src/launcher/include/gameContent.h index 08765170d..f5d31ac27 100644 --- a/src/launcher/include/gameContent.h +++ b/src/launcher/include/gameContent.h @@ -12,7 +12,6 @@ namespace GameContent { inline constexpr uint64_t MaxMetadataSize = uint64_t {1} << 20u; inline constexpr uint64_t MaxImageSize = uint64_t {32} << 20u; -inline constexpr uint64_t MaxTrophyPackageSize = uint64_t {128} << 20u; [[nodiscard]] std::filesystem::path ToPath(const QString& path); [[nodiscard]] QString FromPath(const std::filesystem::path& path); diff --git a/src/launcher/include/trophyViewerDialog.h b/src/launcher/include/trophyViewerDialog.h index 9dc013664..589cf2282 100644 --- a/src/launcher/include/trophyViewerDialog.h +++ b/src/launcher/include/trophyViewerDialog.h @@ -12,10 +12,11 @@ public: explicit TrophyViewerDialog(QWidget* parent = nullptr); static bool HasTrophyData(const Configuration* info); - static void ShowForGame(const Configuration* info, QWidget* parent); + static void ShowForGame(const Configuration* info, const QString& runtime_directory, + QWidget* parent); private: - bool LoadGame(const Configuration& info, QString& error); + bool LoadGame(const Configuration& info, const QString& runtime_directory, QString& error); QTabWidget* m_tabs = nullptr; }; diff --git a/src/launcher/src/configurationEditDialog.cpp b/src/launcher/src/configurationEditDialog.cpp index 682be2a91..140f881a1 100644 --- a/src/launcher/src/configurationEditDialog.cpp +++ b/src/launcher/src/configurationEditDialog.cpp @@ -123,6 +123,7 @@ ConfigurationEditDialog::ConfigurationEditDialog(Configuration& info, QWidget* p : QDialog(parent, Qt::WindowCloseButtonHint), m_ui(new Ui::ConfigurationEditDialog), m_info(info) { m_ui->setupUi(this); + setMinimumWidth(width()); InitGameDirectories(); m_ui->controller_group->setVisible(false); @@ -164,9 +165,6 @@ ConfigurationEditDialog::ConfigurationEditDialog(Configuration& info, QWidget* p m_ui->lineEdit_printf_file->setEnabled(log == Configuration::LogDirection::File); }); - // Keep the controls at a usable minimum while allowing the settings window - // and its expanding fields to use any additional space the user gives them. - layout()->setSizeConstraint(QLayout::SetMinimumSize); setSizeGripEnabled(true); restoreGeometry(g_last_geometry); @@ -276,6 +274,7 @@ void ConfigurationEditDialog::Init(const Configuration& info) { m_ui->checkBox_hide_cursor->setChecked(info.hide_cursor_enabled); m_ui->checkBox_readback->setChecked(info.readback_linear_images); m_ui->checkBox_tessellation->setChecked(info.tessellation_enabled); + m_ui->checkBox_trophy_notifications->setChecked(info.trophy_enabled); m_ui->spinBox_vblank_frequency->setValue(info.vblank_frequency); m_ui->comboBox_console_language->clear(); m_ui->comboBox_console_language->addItems(CONSOLE_LANGUAGE_NAMES); @@ -429,6 +428,7 @@ static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui, boo info.hide_cursor_enabled = ui.checkBox_hide_cursor->isChecked(); info.readback_linear_images = ui.checkBox_readback->isChecked(); info.tessellation_enabled = ui.checkBox_tessellation->isChecked(); + info.trophy_enabled = ui.checkBox_trophy_notifications->isChecked(); info.vblank_frequency = ui.spinBox_vblank_frequency->value(); info.console_language = ui.comboBox_console_language->currentIndex(); info.vulkan_validation_enabled = ui.checkBox_vulkan_validation->isChecked(); diff --git a/src/launcher/src/configurationListWidget.cpp b/src/launcher/src/configurationListWidget.cpp index 5fb5e9161..39eaa44b8 100644 --- a/src/launcher/src/configurationListWidget.cpp +++ b/src/launcher/src/configurationListWidget.cpp @@ -835,7 +835,8 @@ void ConfigurationListWidget::ViewTrophies() { return; } - TrophyViewerDialog::ShowForGame(&item->GetInfo(), this); + const auto config = CreateConfiguration(*item); + TrophyViewerDialog::ShowForGame(config.get(), m_runtime_directory, this); } void ConfigurationListWidget::open_game_folder() { diff --git a/src/launcher/src/mainDialog.cpp b/src/launcher/src/mainDialog.cpp index 43792d4fe..dbc6d4e00 100644 --- a/src/launcher/src/mainDialog.cpp +++ b/src/launcher/src/mainDialog.cpp @@ -170,6 +170,7 @@ void MainDialogPrivate::FindInterpreter() { } bool found = QFile::exists(m_interpreter); + m_ui->widget->SetRuntimeDirectory(QFileInfo(m_interpreter).absolutePath()); if (found) { m_ui->label_Interpreter->setText(tr("Emulator: ") + m_interpreter); @@ -244,6 +245,7 @@ static QStringList CreateEmulatorArgs(const Configuration& info) { args << "--hide-cursor"; } args << "--readback-linear-images" << BoolArg(info.readback_linear_images); + args << "--trophy-notifications" << BoolArg(info.trophy_enabled); if (info.tessellation_enabled) { args << "--tessellation"; } diff --git a/src/launcher/src/trophyViewerDialog.cpp b/src/launcher/src/trophyViewerDialog.cpp index e08d78d10..886a6811e 100644 --- a/src/launcher/src/trophyViewerDialog.cpp +++ b/src/launcher/src/trophyViewerDialog.cpp @@ -1,462 +1,62 @@ #include "trophyViewerDialog.h" #include "common/archive.h" +#include "common/trophies.h" #include "configuration.h" #include "gameContent.h" #include -#include -#include #include -#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include #include #include -#include -#include -#include #include #include #include -#include #include -#include -#include -#include - -#include namespace { -constexpr quint32 UCP_MAGIC = 0xb228c60a; -constexpr quint32 UCP_VERSION = 1; -constexpr int UCP_HEADER_LEN = 0x40; -constexpr int UCP_TOC_SKIP = 0x20; -constexpr int UCP_ENTRY_LEN = 0x40; -constexpr int UCP_NAME_LEN = 0x20; -constexpr quint32 UCP_MAX_FILES = 4096; -constexpr quint64 UCP_MAX_EXTRACTED_SIZE = quint64 {64} << 20u; - -struct UcpEntry { - QString name; - quint64 offset = 0; - quint64 size = 0; -}; - -struct TrophyDefinition { - QString id; - QString grade; - bool hidden = false; - bool has_reward = false; -}; - -struct TrophyText { - QString name; - QString detail; - QString reward; -}; - -struct TrophyRow { - QString id; - QString name; - QString detail; - QString grade; - QString reward; - bool hidden = false; - bool has_reward = false; - QPixmap icon; -}; - -struct TrophySet { - QString tab_title; - QList trophies; -}; - -static bool CanRead(const QByteArray& data, qsizetype offset, qsizetype size) { - return offset >= 0 && size >= 0 && offset <= data.size() && size <= data.size() - offset; -} - -static QString ReadFixedString(const QByteArray& data, qsizetype offset, qsizetype max_size) { - if (!CanRead(data, offset, max_size)) { - return {}; - } - - qsizetype len = 0; - while (len < max_size && data.at(offset + len) != '\0') { - len++; - } - - return QString::fromLatin1(data.constData() + offset, len); -} - -static bool IsUsedUcpEntry(const QString& name) { - const auto lower = name.toCaseFolded(); - return lower == QStringLiteral("tropconf.json") || lower == QStringLiteral("tropmeta.json") || - (lower.startsWith(QStringLiteral("tropmeta_")) && - lower.endsWith(QStringLiteral(".json"))) || - (lower.startsWith(QStringLiteral("trop")) && lower.endsWith(QStringLiteral(".png"))); -} - -static bool ReadUcp(const QString& file_name, QMap& files, QString& error) { - const QByteArray data = - GameContent::ReadPath(GameContent::ToPath(file_name), GameContent::MaxTrophyPackageSize); - if (data.isEmpty()) { - error = QObject::tr("Could not open %1").arg(QDir::toNativeSeparators(file_name)); - return false; - } - - if (data.size() < UCP_HEADER_LEN) { - error = QObject::tr("%1 is too small to be a trophy package.") - .arg(QFileInfo(file_name).fileName()); - return false; - } - - const auto magic = qFromBigEndian(data.constData() + 0x00); - if (magic != UCP_MAGIC) { - error = QObject::tr("%1 has an invalid trophy package magic.") - .arg(QFileInfo(file_name).fileName()); - return false; - } - - const auto version = qFromBigEndian(data.constData() + 0x04); - if (version != UCP_VERSION) { - error = QObject::tr("%1 uses unsupported trophy package version %2.") - .arg(QFileInfo(file_name).fileName(), QString::number(version)); - return false; - } - - const auto declared_size = qFromBigEndian(data.constData() + 0x08); - if (declared_size < UCP_HEADER_LEN || declared_size > static_cast(data.size())) { - error = QObject::tr("%1 is truncated.").arg(QFileInfo(file_name).fileName()); - return false; - } - - const auto file_count = qFromBigEndian(data.constData() + 0x10); - if (file_count > UCP_MAX_FILES) { - error = QObject::tr("%1 contains too many files.").arg(QFileInfo(file_name).fileName()); - return false; - } - const auto toc_offset = static_cast(qFromBigEndian(data.constData() + 0x14)); - const auto data_size = declared_size; - - const quint64 table_size = UCP_TOC_SKIP + static_cast(file_count) * UCP_ENTRY_LEN; - if (toc_offset > data_size || table_size > data_size - toc_offset || - !std::in_range(toc_offset + table_size)) { - error = QObject::tr("%1 has an invalid table of contents.") - .arg(QFileInfo(file_name).fileName()); - return false; - } - - quint64 extracted_size = 0; - for (quint32 i = 0; i < file_count; i++) { - const auto entry_offset = static_cast(toc_offset + UCP_TOC_SKIP + - static_cast(i) * UCP_ENTRY_LEN); - UcpEntry entry; - entry.name = ReadFixedString(data, entry_offset, UCP_NAME_LEN).trimmed(); - entry.offset = qFromBigEndian(data.constData() + entry_offset + 0x20); - entry.size = qFromBigEndian(data.constData() + entry_offset + 0x28); - - if (entry.name.isEmpty()) { - continue; - } - if (entry.offset > data_size || entry.size > data_size - entry.offset || - !std::in_range(entry.offset) || !std::in_range(entry.size)) { - error = QObject::tr("%1 has an invalid entry for %2.") - .arg(QFileInfo(file_name).fileName(), entry.name); - return false; - } - if (!IsUsedUcpEntry(entry.name)) { - continue; - } - - const auto entry_limit = entry.name.endsWith(QStringLiteral(".png"), Qt::CaseInsensitive) - ? GameContent::MaxImageSize - : GameContent::MaxMetadataSize; - if (entry.size > entry_limit || entry.size > UCP_MAX_EXTRACTED_SIZE - extracted_size) { - error = QObject::tr("%1 contains an oversized entry for %2.") - .arg(QFileInfo(file_name).fileName(), entry.name); - return false; - } - - files.insert(entry.name.toCaseFolded(), data.mid(static_cast(entry.offset), - static_cast(entry.size))); - extracted_size += entry.size; - } - - return true; -} - -static const QByteArray* FindFile(const QMap& files, const QString& name) { - const auto it = files.constFind(name.toCaseFolded()); - return it == files.constEnd() ? nullptr : &it.value(); -} - -static const QByteArray* FindFirstTrophyMetadataFile(const QMap& files) { - for (auto it = files.constBegin(); it != files.constEnd(); ++it) { - if (it.key().startsWith(QStringLiteral("tropmeta_")) && - it.key().endsWith(QStringLiteral(".json"))) { - return &it.value(); - } - } - - return FindFile(files, QStringLiteral("tropmeta.json")); -} - -static bool ReadJsonObject(const QByteArray& data, const QString& file_name, QJsonObject& object, - QString& error) { - QJsonParseError parse_error; - const auto doc = QJsonDocument::fromJson(data, &parse_error); - if (parse_error.error != QJsonParseError::NoError || !doc.isObject()) { - error = QObject::tr("Could not read %1: %2").arg(file_name, parse_error.errorString()); - return false; - } - - object = doc.object(); - return true; -} - -static QString JsonString(const QJsonValue& value) { - if (value.isString()) { - return value.toString(); - } - if (value.isDouble()) { - const double number = value.toDouble(); - if (number == static_cast(number)) { - return QString::number(static_cast(number)); - } - return QString::number(number); - } - if (value.isBool()) { - return value.toBool() ? QStringLiteral("true") : QStringLiteral("false"); - } - - return {}; -} - -static QList ReadDefinitions(const QJsonObject& tropconf) { - QList ret; - - const auto trophies = tropconf.value(QStringLiteral("trophies")).toArray(); - for (const auto& value: trophies) { - const auto obj = value.toObject(); - TrophyDefinition def; - def.id = JsonString(obj.value(QStringLiteral("id"))).trimmed(); - def.grade = JsonString(obj.value(QStringLiteral("grade"))).trimmed(); - def.hidden = obj.value(QStringLiteral("hidden")).toBool(false); - def.has_reward = obj.value(QStringLiteral("hasReward")).toBool(false); - - if (!def.id.isEmpty()) { - ret.append(def); - } - } - - return ret; -} - -static QMap ReadMetadata(const QJsonObject& tropmeta) { - QMap ret; - - const auto metadata = tropmeta.value(QStringLiteral("metadata")).toObject(); - const auto trophies = metadata.value(QStringLiteral("trophyMetadata")).toArray(); - for (const auto& value: trophies) { - const auto obj = value.toObject(); - const auto id = JsonString(obj.value(QStringLiteral("id"))).trimmed(); - if (id.isEmpty()) { - continue; - } - - TrophyText text; - text.name = JsonString(obj.value(QStringLiteral("name"))).trimmed(); - text.detail = JsonString(obj.value(QStringLiteral("detail"))).trimmed(); - text.reward = JsonString(obj.value(QStringLiteral("reward"))).trimmed(); - ret.insert(id, text); - } - - return ret; -} - -static QString GradeToText(const QString& grade) { - if (grade == QStringLiteral("P")) { - return QObject::tr("Platinum"); - } - if (grade == QStringLiteral("G")) { - return QObject::tr("Gold"); - } - if (grade == QStringLiteral("S")) { - return QObject::tr("Silver"); - } - if (grade == QStringLiteral("B")) { - return QObject::tr("Bronze"); - } - - return grade; -} - -static QPixmap LoadTrophyIcon(const QMap& files, const QString& id) { - QStringList names; - names.append(QStringLiteral("trop%1.png").arg(id)); - - bool id_is_number = false; - const int id_num = id.toInt(&id_is_number); - if (id_is_number) { - names.append(QStringLiteral("trop%1.png").arg(id_num, 4, 10, QLatin1Char('0'))); - } - - for (const auto& name: names) { - const auto* data = FindFile(files, name); - if (data == nullptr) { - continue; - } - - QPixmap pixmap; - if (pixmap.loadFromData(*data)) { - return pixmap; - } - } - - return {}; -} - -static QString TrophyTabTitle(const QString& file_name) { - static const QRegularExpression trophy_file_re(QStringLiteral("^trophy(\\d+)\\.ucp$"), - QRegularExpression::CaseInsensitiveOption); - - const auto name = QFileInfo(file_name).fileName(); - const auto match = trophy_file_re.match(name); - if (match.hasMatch()) { - return QObject::tr("Trophy %1").arg(match.captured(1)); - } - - return QFileInfo(file_name).completeBaseName(); -} - -static bool BuildTrophySet(const QString& ucp_file, TrophySet& set, QString& error) { - QMap files; - if (!ReadUcp(ucp_file, files, error)) { - return false; - } - - const auto* conf_data = FindFile(files, QStringLiteral("tropconf.json")); - if (conf_data == nullptr) { - error = - QObject::tr("%1 does not contain tropconf.json.").arg(QFileInfo(ucp_file).fileName()); - return false; - } - - QJsonObject tropconf; - if (!ReadJsonObject(*conf_data, QStringLiteral("tropconf.json"), tropconf, error)) { - return false; - } - - const auto default_language = - JsonString(tropconf.value(QStringLiteral("defaultLanguage"))).trimmed(); - const QByteArray* meta_data = nullptr; - if (!default_language.isEmpty()) { - meta_data = FindFile(files, QStringLiteral("tropmeta_%1.json").arg(default_language)); - } - if (meta_data == nullptr) { - meta_data = FindFirstTrophyMetadataFile(files); - } - if (meta_data == nullptr) { - error = QObject::tr("%1 does not contain readable trophy metadata.") - .arg(QFileInfo(ucp_file).fileName()); - return false; - } - - QJsonObject tropmeta; - if (!ReadJsonObject(*meta_data, QStringLiteral("tropmeta.json"), tropmeta, error)) { - return false; - } - - const auto definitions = ReadDefinitions(tropconf); - if (definitions.isEmpty()) { - error = QObject::tr("%1 does not define any trophies.").arg(QFileInfo(ucp_file).fileName()); - return false; - } - - const auto texts = ReadMetadata(tropmeta); - - set.tab_title = TrophyTabTitle(ucp_file); - for (const auto& def: definitions) { - const auto text = texts.value(def.id); - - TrophyRow row; - row.id = def.id; - row.grade = def.grade; - row.hidden = def.hidden; - row.has_reward = def.has_reward; - row.reward = text.reward; - row.name = text.name; - row.detail = text.detail; - row.icon = LoadTrophyIcon(files, def.id); - - if (row.name.isEmpty()) { - row.name = - row.hidden ? QObject::tr("Hidden Trophy") : QObject::tr("Trophy %1").arg(def.id); - } - if (row.detail.isEmpty() && row.hidden) { - row.detail = QObject::tr("This trophy is hidden."); - } - - set.trophies.append(row); - } - - return true; -} +static const QRegularExpression TrophyFilePattern(QStringLiteral("^trophy(\\d+)\\.ucp$")); static QStringList FindTrophyFiles(const Configuration* info) { if (info == nullptr || info->basedir.isEmpty()) { return {}; } - QStringList files; - for (const auto& file: - GameContent::ListFiles(info->basedir, QStringLiteral("sce_sys/trophy2"))) { - const auto name = QFileInfo(file).fileName(); - if (name.startsWith(QStringLiteral("trophy"), Qt::CaseInsensitive) && - name.endsWith(QStringLiteral(".ucp"), Qt::CaseInsensitive)) { + for (const auto& file: GameContent::ListFiles( + info->basedir, QString::fromLatin1(Common::Trophies::PackageDirectory))) { + if (TrophyFilePattern.match(QFileInfo(file).fileName()).hasMatch()) { files.append(file); } } - files.sort(Qt::CaseInsensitive); + files.sort(); + return files; +} - QStringList trophy_files; - QSet seen; - for (const auto& file: files) { - auto key = QFileInfo(file).canonicalFilePath(); - if (key.isEmpty()) { - key = file; - } - key = QDir::cleanPath(key).toCaseFolded(); - - if (!seen.contains(key)) { - seen.insert(key); - trophy_files.append(file); - } +static QString GradeToText(int grade) { + switch (grade) { + case 1: return QObject::tr("Platinum"); + case 2: return QObject::tr("Gold"); + case 3: return QObject::tr("Silver"); + case 4: return QObject::tr("Bronze"); + default: return {}; } - return trophy_files; } static void PrepareTable(QTableWidget* table) { - table->setColumnCount(4); table->setHorizontalHeaderLabels({QObject::tr("Unlocked"), QObject::tr("Trophy"), QObject::tr("Name"), QObject::tr("Description")}); table->setAlternatingRowColors(true); table->setEditTriggers(QAbstractItemView::NoEditTriggers); table->setSelectionBehavior(QAbstractItemView::SelectRows); table->setSelectionMode(QAbstractItemView::SingleSelection); + table->setIconSize(QSize(96, 96)); table->setShowGrid(false); table->setWordWrap(true); table->verticalHeader()->setVisible(false); @@ -469,30 +69,16 @@ static void PrepareTable(QTableWidget* table) { table->setColumnWidth(3, 480); } -static QTableWidgetItem* CreateItem(const QString& text) { - auto* item = new QTableWidgetItem(text); - item->setFlags(item->flags() & ~Qt::ItemIsEditable); - return item; -} - -static QString TrophyTooltip(const TrophyRow& row) { - QStringList lines; - lines.append(row.name); - if (!row.detail.isEmpty()) { - lines.append(row.detail); - } - - const auto grade = GradeToText(row.grade); - if (!grade.isEmpty()) { - lines.append(QObject::tr("Grade: %1").arg(grade)); - } - if (row.hidden) { +static QString TrophyTooltip(const Common::Trophies::Trophy& trophy) { + QStringList lines {QString::fromStdString(trophy.name), + QString::fromStdString(trophy.description), + QObject::tr("Grade: %1").arg(GradeToText(trophy.grade))}; + if (trophy.hidden) { lines.append(QObject::tr("Hidden trophy")); } - if (row.has_reward && !row.reward.isEmpty()) { - lines.append(QObject::tr("Reward: %1").arg(row.reward)); + if (trophy.has_reward && !trophy.reward.empty()) { + lines.append(QObject::tr("Reward: %1").arg(QString::fromStdString(trophy.reward))); } - return lines.join(QLatin1Char('\n')); } @@ -516,7 +102,8 @@ bool TrophyViewerDialog::HasTrophyData(const Configuration* info) { return !FindTrophyFiles(info).isEmpty(); } -void TrophyViewerDialog::ShowForGame(const Configuration* info, QWidget* parent) { +void TrophyViewerDialog::ShowForGame(const Configuration* info, const QString& runtime_directory, + QWidget* parent) { if (info == nullptr) { return; } @@ -527,7 +114,7 @@ void TrophyViewerDialog::ShowForGame(const Configuration* info, QWidget* parent) } QString error; - if (!dlg.LoadGame(*info, error)) { + if (!dlg.LoadGame(*info, runtime_directory, error)) { QMessageBox::warning(parent, tr("Trophy Viewer"), error); return; } @@ -535,66 +122,71 @@ void TrophyViewerDialog::ShowForGame(const Configuration* info, QWidget* parent) dlg.exec(); } -bool TrophyViewerDialog::LoadGame(const Configuration& info, QString& error) { - const auto reader = Common::OpenArchive(GameContent::ToPath(info.basedir)); +bool TrophyViewerDialog::LoadGame(const Configuration& info, const QString& runtime_directory, + QString& error) { + const auto reader = Common::OpenArchive(GameContent::ToPath(info.basedir)); const auto trophy_files = FindTrophyFiles(&info); if (trophy_files.isEmpty()) { - error = tr("No trophy package found in sce_sys/trophy2."); + error = tr("No trophy package found in %1.") + .arg(QString::fromLatin1(Common::Trophies::PackageDirectory)); return false; } - QStringList errors; for (const auto& file: trophy_files) { - TrophySet set; - QString set_error; - if (!BuildTrophySet(file, set, set_error)) { - errors.append(set_error); + const auto package = + Common::Trophies::LoadPackage(GameContent::ToPath(file), info.console_language); + if (package.trophies.empty()) { + errors.append(tr("Could not read trophy package %1.").arg(QFileInfo(file).fileName())); continue; } - - auto* table = new QTableWidget(set.trophies.size(), 4, m_tabs); + const auto label = TrophyFilePattern.match(QFileInfo(file).fileName()).captured(1).toUInt(); + const auto unlocked = Common::Trophies::LoadUnlocks( + Common::Trophies::UnlocksPath(GameContent::ToPath(runtime_directory), + info.title_id.toStdString(), info.user_id, label)); + auto* table = new QTableWidget(static_cast(package.trophies.size()), 4, m_tabs); PrepareTable(table); - - for (int row_index = 0; row_index < set.trophies.size(); row_index++) { - const auto& row = set.trophies.at(row_index); - table->setRowHeight(row_index, 112); - - auto* status = CreateItem(tr("locked")); + int row_index = 0; + for (const auto& [id, trophy]: package.trophies) { + const bool trophy_unlocked = unlocked.contains(id); + auto* status = new QTableWidgetItem(trophy_unlocked ? tr("UNLOCKED") : tr("LOCKED")); status->setTextAlignment(Qt::AlignCenter); - if (row.hidden) { - status->setForeground(QBrush(Qt::gray)); - } + auto status_font = status->font(); + status_font.setBold(true); + status->setFont(status_font); table->setItem(row_index, 0, status); - auto* icon_label = new QLabel(table); - icon_label->setAlignment(Qt::AlignCenter); - icon_label->setMinimumSize(QSize(108, 108)); - if (!row.icon.isNull()) { - icon_label->setPixmap( - row.icon.scaled(QSize(96, 96), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + auto* icon_item = new QTableWidgetItem; + icon_item->setTextAlignment(Qt::AlignCenter); + QPixmap icon; + if (icon.loadFromData(reinterpret_cast(trophy.icon_png.data()), + static_cast(trophy.icon_png.size()))) { + if (!trophy_unlocked) { + icon = QPixmap::fromImage( + icon.toImage().convertToFormat(QImage::Format_Grayscale8)); + } + icon_item->setIcon(QIcon(icon)); } - table->setCellWidget(row_index, 1, icon_label); + table->setItem(row_index, 1, icon_item); - auto* name = CreateItem(row.name); - auto font = name->font(); + const auto name_text = trophy.name.empty() ? (trophy.hidden ? tr("Hidden Trophy") + : tr("Trophy %1").arg(id)) + : QString::fromStdString(trophy.name); + auto* name = new QTableWidgetItem(name_text); + auto font = name->font(); font.setBold(true); name->setFont(font); - name->setToolTip(TrophyTooltip(row)); + name->setToolTip(TrophyTooltip(trophy)); + auto* detail = new QTableWidgetItem(QString::fromStdString(trophy.description)); + detail->setToolTip(name->toolTip()); table->setItem(row_index, 2, name); - - auto* detail = CreateItem(row.detail); - detail->setToolTip(TrophyTooltip(row)); table->setItem(row_index, 3, detail); + ++row_index; } - - m_tabs->addTab(table, set.tab_title); + m_tabs->addTab(table, tr("Trophy %1").arg(label)); } - if (m_tabs->count() == 0) { - error = errors.isEmpty() ? tr("No readable trophy data found.") - : errors.join(QLatin1Char('\n')); + error = errors.join(QLatin1Char('\n')); return false; } - return true; } diff --git a/src/libs/libNet.cpp b/src/libs/libNet.cpp index 84733440a..59d4c97ba 100644 --- a/src/libs/libNet.cpp +++ b/src/libs/libNet.cpp @@ -8,7 +8,6 @@ #include "loader/symbolDatabase.h" #include -#include #include #include #include @@ -19,6 +18,13 @@ namespace Libs { +namespace LibNpTrophy2 { +void InitNet_1_NpTrophy2(Loader::SymbolDatabase* s); +} +namespace LibNpUniversalDataSystem { +void InitNet_1_NpUniversalDataSystem(Loader::SymbolDatabase* s); +} + namespace Network::Net { struct NetEtherAddr; } // namespace Network::Net @@ -1930,1123 +1936,6 @@ LIB_DEFINE(InitNet_1_NpAuth) { } // namespace LibNpAuth -namespace LibNpTrophy2 { - -LIB_VERSION("NpTrophy2", 1, "NpTrophy2", 1, 1); - -constexpr int NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND = -2141898479; /* 0x80553911 */ - -struct NpTrophy2Progress { - int32_t type; - uint8_t reserved[4]; - uint64_t value; -}; - -struct NpTrophy2GameDetails { - uint32_t num_groups; - uint32_t num_trophies; - uint32_t num_platinum; - uint32_t num_gold; - uint32_t num_silver; - uint32_t num_bronze; - char title[128]; -}; - -struct NpTrophy2GameData { - uint32_t unlocked_trophies; - uint32_t unlocked_platinum; - uint32_t unlocked_gold; - uint32_t unlocked_silver; - uint32_t unlocked_bronze; - uint32_t progress_percentage; -}; - -struct NpTrophy2GroupDetails { - int32_t group_id; - uint32_t num_trophies; - uint32_t num_platinum; - uint32_t num_gold; - uint32_t num_silver; - uint32_t num_bronze; - char title[128]; -}; - -struct NpTrophy2GroupData { - int32_t group_id; - uint32_t unlocked_trophies; - uint32_t unlocked_platinum; - uint32_t unlocked_gold; - uint32_t unlocked_silver; - uint32_t unlocked_bronze; - uint32_t progress_percentage; - uint8_t reserved[4]; -}; - -struct NpTrophy2Details { - int32_t trophy_id; - int32_t trophy_grade; - int32_t group_id; - bool hidden; - bool has_reward; - uint8_t reserved2[2]; - NpTrophy2Progress target; - char name[128]; - char description[1024]; - char reward[128]; -}; - -struct NpTrophy2Data { - int32_t trophy_id; - bool unlocked; - uint8_t reserved[3]; - NpTrophy2Progress progress; - uint64_t timestamp_tick; -}; - -static_assert(sizeof(NpTrophy2GameDetails) == 152); -static_assert(sizeof(NpTrophy2GameData) == 24); -static_assert(sizeof(NpTrophy2GroupDetails) == 152); -static_assert(sizeof(NpTrophy2GroupData) == 32); -static_assert(sizeof(NpTrophy2Details) == 1312); -static_assert(sizeof(NpTrophy2Data) == 32); - -static void NpTrophy2FillTitle(char* dst, size_t dst_size, const char* src) { - if (dst == nullptr || dst_size == 0) { - return; - } - - std::strncpy(dst, src, dst_size - 1); - dst[dst_size - 1] = '\0'; -} - -static int KYTY_SYSV_ABI NpTrophy2CreateHandle(int* handle) { - PRINT_NAME(); - - if (handle != nullptr) { - *handle = 1; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2CreateContext(int* context, int user_id, uint32_t service_label, - uint64_t options) { - PRINT_NAME(); - - if (context != nullptr) { - *context = 1; - } - - LOGF("\t user_id = %d\n" - "\t service_label = %u\n" - "\t options = 0x%016" PRIx64 "\n", - user_id, service_label, options); - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2RegisterContext(int context, int handle, uint64_t options) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t options = 0x%016" PRIx64 "\n", - context, handle, options); - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2GetGameInfo(int context, int handle, - NpTrophy2GameDetails* details, - NpTrophy2GameData* data) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t details = 0x%016" PRIx64 "\n" - "\t data = 0x%016" PRIx64 "\n", - context, handle, reinterpret_cast(details), reinterpret_cast(data)); - - if (details != nullptr) { - std::memset(details, 0, sizeof(*details)); - details->num_trophies = 1; - details->num_bronze = 1; - NpTrophy2FillTitle(details->title, sizeof(details->title), "Kyty"); - } - if (data != nullptr) { - std::memset(data, 0, sizeof(*data)); - } - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2GetGroupInfo(int context, int handle, int group_id, - NpTrophy2GroupDetails* details, - NpTrophy2GroupData* data) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t group_id = %d\n" - "\t details = 0x%016" PRIx64 "\n" - "\t data = 0x%016" PRIx64 "\n", - context, handle, group_id, reinterpret_cast(details), - reinterpret_cast(data)); - - const auto normalized_group_id = (group_id < 0 ? 0 : group_id); - - if (details != nullptr) { - std::memset(details, 0, sizeof(*details)); - details->group_id = normalized_group_id; - details->num_trophies = 1; - details->num_bronze = 1; - NpTrophy2FillTitle(details->title, sizeof(details->title), "Base Game"); - } - if (data != nullptr) { - std::memset(data, 0, sizeof(*data)); - data->group_id = normalized_group_id; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2GetGroupInfoArray(int context, int handle, uint32_t offset, - uint32_t limit, - NpTrophy2GroupDetails* details_array, - NpTrophy2GroupData* data_array, - uint32_t* count) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t offset = %" PRIu32 "\n" - "\t limit = %" PRIu32 "\n" - "\t details_array = 0x%016" PRIx64 "\n" - "\t data_array = 0x%016" PRIx64 "\n" - "\t count = 0x%016" PRIx64 "\n", - context, handle, offset, limit, reinterpret_cast(details_array), - reinterpret_cast(data_array), reinterpret_cast(count)); - - const uint32_t out_count = (offset == 0 && limit != 0 ? 1u : 0u); - - if (count != nullptr) { - *count = out_count; - } - if (out_count != 0 && details_array != nullptr) { - std::memset(details_array, 0, sizeof(*details_array)); - details_array->group_id = 0; - details_array->num_trophies = 1; - details_array->num_bronze = 1; - NpTrophy2FillTitle(details_array->title, sizeof(details_array->title), "Base Game"); - } - if (out_count != 0 && data_array != nullptr) { - std::memset(data_array, 0, sizeof(*data_array)); - data_array->group_id = 0; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2GetTrophyInfo(int context, int handle, int trophy_id, - NpTrophy2Details* details, NpTrophy2Data* data) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t trophy_id = %d\n" - "\t details = 0x%016" PRIx64 "\n" - "\t data = 0x%016" PRIx64 "\n", - context, handle, trophy_id, reinterpret_cast(details), - reinterpret_cast(data)); - - if (details != nullptr) { - std::memset(details, 0, sizeof(*details)); - details->trophy_id = trophy_id; - details->trophy_grade = 4; - details->group_id = 0; - details->target.type = 0; - details->target.value = 0; - NpTrophy2FillTitle(details->name, sizeof(details->name), "Trophy"); - NpTrophy2FillTitle(details->description, sizeof(details->description), "Trophy"); - } - if (data != nullptr) { - std::memset(data, 0, sizeof(*data)); - data->trophy_id = trophy_id; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2GetTrophyInfoArray(int context, int handle, uint32_t offset, - uint32_t limit, - NpTrophy2Details* details_array, - NpTrophy2Data* data_array, uint32_t* count) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t offset = %" PRIu32 "\n" - "\t limit = %" PRIu32 "\n" - "\t details_array = 0x%016" PRIx64 "\n" - "\t data_array = 0x%016" PRIx64 "\n" - "\t count = 0x%016" PRIx64 "\n", - context, handle, offset, limit, reinterpret_cast(details_array), - reinterpret_cast(data_array), reinterpret_cast(count)); - - const uint32_t out_count = (offset == 0 && limit != 0 ? 1u : 0u); - - if (count != nullptr) { - *count = out_count; - } - if (out_count != 0 && details_array != nullptr) { - std::memset(details_array, 0, sizeof(*details_array)); - details_array->trophy_id = 0; - details_array->trophy_grade = 4; - details_array->group_id = 0; - NpTrophy2FillTitle(details_array->name, sizeof(details_array->name), "Trophy"); - NpTrophy2FillTitle(details_array->description, sizeof(details_array->description), - "Trophy"); - } - if (out_count != 0 && data_array != nullptr) { - std::memset(data_array, 0, sizeof(*data_array)); - data_array->trophy_id = 0; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2GetGameIcon(int context, int handle, void* buffer, size_t* size) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t buffer = 0x%016" PRIx64 "\n" - "\t size = 0x%016" PRIx64 "\n", - context, handle, reinterpret_cast(buffer), reinterpret_cast(size)); - - if (size != nullptr) { - *size = 0; - } - - return NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND; -} - -static int KYTY_SYSV_ABI NpTrophy2GetGroupIcon(int context, int handle, int group_id, void* buffer, - size_t* size) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t group_id = %d\n" - "\t buffer = 0x%016" PRIx64 "\n" - "\t size = 0x%016" PRIx64 "\n", - context, handle, group_id, reinterpret_cast(buffer), - reinterpret_cast(size)); - - if (size != nullptr) { - *size = 0; - } - - return NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND; -} - -static int KYTY_SYSV_ABI NpTrophy2GetTrophyIcon(int context, int handle, int trophy_id, - void* buffer, size_t* size) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t trophy_id = %d\n" - "\t buffer = 0x%016" PRIx64 "\n" - "\t size = 0x%016" PRIx64 "\n", - context, handle, trophy_id, reinterpret_cast(buffer), - reinterpret_cast(size)); - - if (size != nullptr) { - *size = 0; - } - - return NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND; -} - -static int KYTY_SYSV_ABI NpTrophy2RegisterUnlockCallback(void* callback, void* userdata) { - PRINT_NAME(); - - LOGF("\t callback = 0x%016" PRIx64 "\n" - "\t userdata = 0x%016" PRIx64 "\n", - reinterpret_cast(callback), reinterpret_cast(userdata)); - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2AbortHandle(int handle) { - PRINT_NAME(); - - LOGF("\t handle = %d\n", handle); - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2DestroyHandle(int handle) { - PRINT_NAME(); - - LOGF("\t handle = %d\n", handle); - - return 0; -} - -static int KYTY_SYSV_ABI NpTrophy2DestroyContext(int context) { - PRINT_NAME(); - - LOGF("\t context = %d\n", context); - - return 0; -} - -LIB_DEFINE(InitNet_1_NpTrophy2) { - LIB_FUNC("Bagshr7OQ6Q", LibNpTrophy2::NpTrophy2CreateContext); - LIB_FUNC("Gz1rmUZpROM", LibNpTrophy2::NpTrophy2CreateHandle); - LIB_FUNC("bIDov3wBu5Q", LibNpTrophy2::NpTrophy2RegisterContext); - LIB_FUNC("4IzqhhUQ3nk", LibNpTrophy2::NpTrophy2GetGameInfo); - LIB_FUNC("DoZWauG8mu0", LibNpTrophy2::NpTrophy2GetGroupInfo); - LIB_FUNC("+PDSI6WgPRc", LibNpTrophy2::NpTrophy2GetGroupInfoArray); - LIB_FUNC("EwNylPdWUTM", LibNpTrophy2::NpTrophy2GetTrophyInfo); - LIB_FUNC("y3zHpdZO6ME", LibNpTrophy2::NpTrophy2GetTrophyInfoArray); - LIB_FUNC("2QgUy+xJqS0", LibNpTrophy2::NpTrophy2GetGameIcon); - LIB_FUNC("6IjXJUy6ZnA", LibNpTrophy2::NpTrophy2GetGroupIcon); - LIB_FUNC("-9LLVU0uvs8", LibNpTrophy2::NpTrophy2GetTrophyIcon); - LIB_FUNC("sUXGfNMalIo", LibNpTrophy2::NpTrophy2RegisterUnlockCallback); - LIB_FUNC("fYapWA9xVmA", LibNpTrophy2::NpTrophy2AbortHandle); - LIB_FUNC("d8P11CI40KE", LibNpTrophy2::NpTrophy2DestroyHandle); - LIB_FUNC("sysY2FHYff4", LibNpTrophy2::NpTrophy2DestroyContext); -} - -} // namespace LibNpTrophy2 - -namespace LibNpUniversalDataSystem { - -LIB_VERSION("NpUniversalDataSystem", 1, "NpUniversalDataSystem", 1, 1); - -constexpr int NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT = -2141900542; /* 0x80553102 */ - -struct NpUniversalDataSystemInitParam { - size_t size; - size_t pool_size; -}; - -struct NpUniversalDataSystemMemoryStat { - size_t pool_size; - size_t max_inuse_size; - size_t current_inuse_size; -}; - -struct NpUniversalDataSystemEvent {}; - -struct NpUniversalDataSystemEventPropertyObject {}; - -struct NpUniversalDataSystemEventPropertyArray {}; - -struct NpUniversalDataSystemStorageStat { - size_t in_events; - size_t out_events; - size_t lost_events; - size_t max_inuse_size; - size_t current_events; - size_t current_inuse_size; - size_t current_free_size; -}; - -static int KYTY_SYSV_ABI -NpUniversalDataSystemInitialize(const NpUniversalDataSystemInitParam* param) { - PRINT_NAME(); - - if (param == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t size = %" PRIu64 "\n" - "\t pool_size = %" PRIu64 "\n", - static_cast(param->size), static_cast(param->pool_size)); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemCreateContext(int* context, int user_id, - uint32_t service_label, - uint64_t options) { - PRINT_NAME(); - - if (context != nullptr) { - *context = 1; - } - - LOGF("\t user_id = %d\n" - "\t service_label = %u\n" - "\t options = 0x%016" PRIx64 "\n", - user_id, service_label, options); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemCreateHandle(int* handle) { - PRINT_NAME(); - - if (handle == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - if (handle != nullptr) { - *handle = 1; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemDestroyHandle(int handle) { - PRINT_NAME(); - - LOGF("\t handle = %d\n", handle); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemAbortHandle(int handle) { - PRINT_NAME(); - - LOGF("\t handle = %d\n", handle); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemCreateEvent( - const char* event_name, const NpUniversalDataSystemEventPropertyObject* prop, - NpUniversalDataSystemEvent** new_event, NpUniversalDataSystemEventPropertyObject** prop_ptr) { - PRINT_NAME(); - - if (event_name == nullptr || new_event == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - *new_event = new NpUniversalDataSystemEvent; - if (prop_ptr != nullptr) { - *prop_ptr = (prop != nullptr ? const_cast(prop) - : new NpUniversalDataSystemEventPropertyObject); - } - - LOGF("\t event_name = %s\n" - "\t prop = 0x%016" PRIx64 "\n" - "\t new_event = 0x%016" PRIx64 "\n" - "\t prop_ptr = 0x%016" PRIx64 "\n", - event_name != nullptr ? event_name : "", reinterpret_cast(prop), - reinterpret_cast(*new_event), - prop_ptr != nullptr ? reinterpret_cast(*prop_ptr) : 0); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemPostEvent(int context, int handle, const void* event, - uint64_t options) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t event = 0x%016" PRIx64 "\n" - "\t options = 0x%016" PRIx64 "\n", - context, handle, reinterpret_cast(event), options); - - return 0; -} - -static int KYTY_SYSV_ABI -NpUniversalDataSystemEventEstimateSize(const NpUniversalDataSystemEvent* event, size_t* size) { - PRINT_NAME(); - - LOGF("\t event = 0x%016" PRIx64 "\n" - "\t size = 0x%016" PRIx64 "\n", - reinterpret_cast(event), reinterpret_cast(size)); - - if (event == nullptr || size == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - *size = 3; - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventToString(const NpUniversalDataSystemEvent* event, - char* buf, size_t buf_size, - size_t* string_size) { - PRINT_NAME(); - - LOGF("\t event = 0x%016" PRIx64 "\n" - "\t buf = 0x%016" PRIx64 "\n" - "\t buf_size = %" PRIu64 "\n" - "\t string_size = 0x%016" PRIx64 "\n", - reinterpret_cast(event), reinterpret_cast(buf), - static_cast(buf_size), reinterpret_cast(string_size)); - - if (event == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - const char* json = "{}"; - if (string_size != nullptr) { - *string_size = std::strlen(json) + 1; - } - if (buf != nullptr && buf_size > 0) { - std::snprintf(buf, buf_size, "%s", json); - } - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemDestroyEvent(NpUniversalDataSystemEvent* event) { - PRINT_NAME(); - - LOGF("\t event = 0x%016" PRIx64 "\n", reinterpret_cast(event)); - - delete event; - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemRegisterContext(int context, int handle, - uint64_t options) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t handle = %d\n" - "\t options = 0x%016" PRIx64 "\n", - context, handle, options); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemDestroyContext(int context) { - PRINT_NAME(); - - LOGF("\t context = %d\n", context); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemGetMemoryStat(NpUniversalDataSystemMemoryStat* stat) { - PRINT_NAME(); - - if (stat == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - *stat = {}; - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemCreateEventPropertyObject( - NpUniversalDataSystemEventPropertyObject** new_object) { - PRINT_NAME(); - - if (new_object == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - *new_object = new NpUniversalDataSystemEventPropertyObject; - - LOGF("\t new_object = 0x%016" PRIx64 "\n", reinterpret_cast(*new_object)); - - return 0; -} - -static int KYTY_SYSV_ABI -NpUniversalDataSystemDestroyEventPropertyObject(NpUniversalDataSystemEventPropertyObject* object) { - PRINT_NAME(); - - LOGF("\t object = 0x%016" PRIx64 "\n", reinterpret_cast(object)); - - delete object; - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetString( - NpUniversalDataSystemEventPropertyObject* object, const char* key, const char* value) { - PRINT_NAME(); - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %s\n", - reinterpret_cast(object), key != nullptr ? key : "", - value != nullptr ? value : ""); - - if (object == nullptr || key == nullptr || value == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetInt32( - NpUniversalDataSystemEventPropertyObject* object, const char* key, int32_t value) { - PRINT_NAME(); - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %" PRId32 "\n", - reinterpret_cast(object), key != nullptr ? key : "", value); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetUInt32( - NpUniversalDataSystemEventPropertyObject* object, const char* key, uint32_t value) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %" PRIu32 "\n", - reinterpret_cast(object), key, value); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetInt64( - NpUniversalDataSystemEventPropertyObject* object, const char* key, int64_t value) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %" PRId64 "\n", - reinterpret_cast(object), key, value); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetUInt64( - NpUniversalDataSystemEventPropertyObject* object, const char* key, uint64_t value) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %" PRIu64 "\n", - reinterpret_cast(object), key, value); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetFloat32( - NpUniversalDataSystemEventPropertyObject* object, const char* key, float value) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %f\n", - reinterpret_cast(object), key, static_cast(value)); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetFloat64( - NpUniversalDataSystemEventPropertyObject* object, const char* key, double value) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %f\n", - reinterpret_cast(object), key, value); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetBool( - NpUniversalDataSystemEventPropertyObject* object, const char* key, bool value) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = %d\n", - reinterpret_cast(object), key, value ? 1 : 0); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetBinary( - NpUniversalDataSystemEventPropertyObject* object, const char* key, const void* value, - size_t value_size) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr || (value == nullptr && value_size != 0)) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = 0x%016" PRIx64 "\n" - "\t value_size = %" PRIu64 "\n", - reinterpret_cast(object), key, reinterpret_cast(value), - static_cast(value_size)); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetObject( - NpUniversalDataSystemEventPropertyObject* object, const char* key, - const NpUniversalDataSystemEventPropertyObject* value, - NpUniversalDataSystemEventPropertyObject** value_ptr) { - PRINT_NAME(); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - if (value_ptr != nullptr) { - *value_ptr = - (value != nullptr ? const_cast(value) - : new NpUniversalDataSystemEventPropertyObject); - } - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = 0x%016" PRIx64 "\n" - "\t value_ptr = 0x%016" PRIx64 "\n", - reinterpret_cast(object), key, reinterpret_cast(value), - value_ptr != nullptr ? reinterpret_cast(*value_ptr) : 0); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetArray( - NpUniversalDataSystemEventPropertyObject* object, const char* key, - const NpUniversalDataSystemEventPropertyArray* value, - NpUniversalDataSystemEventPropertyArray** value_ptr) { - PRINT_NAME(); - - LOGF("\t object = 0x%016" PRIx64 "\n" - "\t key = %s\n" - "\t value = 0x%016" PRIx64 "\n" - "\t value_ptr = 0x%016" PRIx64 "\n", - reinterpret_cast(object), key != nullptr ? key : "", - reinterpret_cast(value), reinterpret_cast(value_ptr)); - - if (object == nullptr || key == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - if (value_ptr != nullptr) { - *value_ptr = (value != nullptr ? const_cast(value) - : new NpUniversalDataSystemEventPropertyArray); - } - - return 0; -} - -static int KYTY_SYSV_ABI -NpUniversalDataSystemCreateEventPropertyArray(NpUniversalDataSystemEventPropertyArray** new_array) { - PRINT_NAME(); - - if (new_array == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - *new_array = new NpUniversalDataSystemEventPropertyArray; - - LOGF("\t new_array = 0x%016" PRIx64 "\n", reinterpret_cast(*new_array)); - - return 0; -} - -static int KYTY_SYSV_ABI -NpUniversalDataSystemDestroyEventPropertyArray(NpUniversalDataSystemEventPropertyArray* array) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n", reinterpret_cast(array)); - - delete array; - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetString( - NpUniversalDataSystemEventPropertyArray* array, const char* value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %s\n", - reinterpret_cast(array), value != nullptr ? value : ""); - - if (array == nullptr || value == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetInt32( - NpUniversalDataSystemEventPropertyArray* array, int32_t value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %" PRId32 "\n", - reinterpret_cast(array), value); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetUInt32( - NpUniversalDataSystemEventPropertyArray* array, uint32_t value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %" PRIu32 "\n", - reinterpret_cast(array), value); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetInt64( - NpUniversalDataSystemEventPropertyArray* array, int64_t value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %" PRId64 "\n", - reinterpret_cast(array), value); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetUInt64( - NpUniversalDataSystemEventPropertyArray* array, uint64_t value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %" PRIu64 "\n", - reinterpret_cast(array), value); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetFloat32( - NpUniversalDataSystemEventPropertyArray* array, float value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %f\n", - reinterpret_cast(array), static_cast(value)); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetFloat64( - NpUniversalDataSystemEventPropertyArray* array, double value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %f\n", - reinterpret_cast(array), value); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetBool( - NpUniversalDataSystemEventPropertyArray* array, bool value) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = %d\n", - reinterpret_cast(array), value ? 1 : 0); - - return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetBinary( - NpUniversalDataSystemEventPropertyArray* array, const void* value, size_t value_size) { - PRINT_NAME(); - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = 0x%016" PRIx64 "\n" - "\t value_size = %" PRIu64 "\n", - reinterpret_cast(array), reinterpret_cast(value), - static_cast(value_size)); - - if (array == nullptr || (value == nullptr && value_size != 0)) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetObject( - NpUniversalDataSystemEventPropertyArray* array, - const NpUniversalDataSystemEventPropertyObject* value, - NpUniversalDataSystemEventPropertyObject** value_ptr) { - PRINT_NAME(); - - if (array == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - if (value_ptr != nullptr) { - *value_ptr = - (value != nullptr ? const_cast(value) - : new NpUniversalDataSystemEventPropertyObject); - } - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = 0x%016" PRIx64 "\n" - "\t value_ptr = 0x%016" PRIx64 "\n", - reinterpret_cast(array), reinterpret_cast(value), - value_ptr != nullptr ? reinterpret_cast(*value_ptr) : 0); - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetArray( - NpUniversalDataSystemEventPropertyArray* array, - const NpUniversalDataSystemEventPropertyArray* value, - NpUniversalDataSystemEventPropertyArray** value_ptr) { - PRINT_NAME(); - - if (array == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - if (value_ptr != nullptr) { - *value_ptr = (value != nullptr ? const_cast(value) - : new NpUniversalDataSystemEventPropertyArray); - } - - LOGF("\t array = 0x%016" PRIx64 "\n" - "\t value = 0x%016" PRIx64 "\n" - "\t value_ptr = 0x%016" PRIx64 "\n", - reinterpret_cast(array), reinterpret_cast(value), - value_ptr != nullptr ? reinterpret_cast(*value_ptr) : 0); - - return 0; -} - -static int KYTY_SYSV_ABI -NpUniversalDataSystemGetStorageStat(int context, NpUniversalDataSystemStorageStat* stat) { - PRINT_NAME(); - - LOGF("\t context = %d\n" - "\t stat = 0x%016" PRIx64 "\n", - context, reinterpret_cast(stat)); - - if (stat == nullptr) { - return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; - } - - *stat = {}; - - return 0; -} - -static int KYTY_SYSV_ABI NpUniversalDataSystemTerminate() { - PRINT_NAME(); - - return 0; -} - -LIB_DEFINE(InitNet_1_NpUniversalDataSystem) { - LIB_FUNC("sjaobBgqeB4", LibNpUniversalDataSystem::NpUniversalDataSystemInitialize); - LIB_FUNC("5zBnau1uIEo", LibNpUniversalDataSystem::NpUniversalDataSystemCreateContext); - LIB_FUNC("hT0IAEvN+M0", LibNpUniversalDataSystem::NpUniversalDataSystemCreateHandle); - LIB_FUNC("p+GcLqwpL9M", LibNpUniversalDataSystem::NpUniversalDataSystemCreateEvent); - LIB_FUNC("CzkKf7ahIyU", LibNpUniversalDataSystem::NpUniversalDataSystemPostEvent); - LIB_FUNC("AUIHb7jUX3I", LibNpUniversalDataSystem::NpUniversalDataSystemDestroyHandle); - LIB_FUNC("jZCqWFgMehE", LibNpUniversalDataSystem::NpUniversalDataSystemAbortHandle); - LIB_FUNC("wB7IWzGp2v0", LibNpUniversalDataSystem::NpUniversalDataSystemDestroyContext); - LIB_FUNC("su7jW3VDDb4", LibNpUniversalDataSystem::NpUniversalDataSystemGetMemoryStat); - LIB_FUNC("+s14jq-KGYw", LibNpUniversalDataSystem::NpUniversalDataSystemEventEstimateSize); - LIB_FUNC("vj6CQGWtEBg", LibNpUniversalDataSystem::NpUniversalDataSystemEventToString); - LIB_FUNC("wG+84pnNIuo", LibNpUniversalDataSystem::NpUniversalDataSystemDestroyEvent); - LIB_FUNC("tpFJ8LIKvPw", LibNpUniversalDataSystem::NpUniversalDataSystemRegisterContext); - LIB_FUNC("s6W4Zl4Slgk", - LibNpUniversalDataSystem::NpUniversalDataSystemCreateEventPropertyObject); - LIB_FUNC("kKUH0Viib3c", - LibNpUniversalDataSystem::NpUniversalDataSystemDestroyEventPropertyObject); - LIB_FUNC("MfDb+4Nln64", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetString); - LIB_FUNC("YE4dbtbz6OE", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetInt32); - LIB_FUNC("AzD4irAcKE4", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetUInt32); - LIB_FUNC("56QLTqx911s", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetInt64); - LIB_FUNC("xvsP5Yz6FmY", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetUInt64); - LIB_FUNC("lbPlT4+QVcE", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetFloat32); - LIB_FUNC("4Fu8tHW+u-k", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetFloat64); - LIB_FUNC("Fidd8vWgyVE", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetBool); - LIB_FUNC("wAcxBDLHj1M", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetBinary); - LIB_FUNC("74ASEqxSnkM", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetObject); - LIB_FUNC("Wxbg5x3pTXA", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetArray); - LIB_FUNC("Hm7qubT3b70", - LibNpUniversalDataSystem::NpUniversalDataSystemCreateEventPropertyArray); - LIB_FUNC("W-0xwY0ZMjw", - LibNpUniversalDataSystem::NpUniversalDataSystemDestroyEventPropertyArray); - LIB_FUNC("4llLk7YJRTE", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetString); - LIB_FUNC("BypQuF113-k", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetInt32); - LIB_FUNC("yMi0xAOpmXM", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetUInt32); - LIB_FUNC("viVXAwmmYrY", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetInt64); - LIB_FUNC("Qo9qR7v5zO4", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetUInt64); - LIB_FUNC("JmgwKm96Lq4", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetFloat32); - LIB_FUNC("sbSYZLR5AiE", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetFloat64); - LIB_FUNC("0+l4QSWCM4E", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetBool); - LIB_FUNC("IEdUCV9j2Cw", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetBinary); - LIB_FUNC("XY14n3jNIpE", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetObject); - LIB_FUNC("rdi9BAfDLq8", - LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetArray); - LIB_FUNC("KmN62tT4U8A", LibNpUniversalDataSystem::NpUniversalDataSystemGetStorageStat); - LIB_FUNC("47UAEuQl+iI", LibNpUniversalDataSystem::NpUniversalDataSystemTerminate); -} - -} // namespace LibNpUniversalDataSystem - namespace LibNpGameIntent { LIB_VERSION("NpGameIntent", 1, "NpGameIntent", 1, 1); diff --git a/src/libs/libTrophy.cpp b/src/libs/libTrophy.cpp new file mode 100644 index 000000000..d06441c92 --- /dev/null +++ b/src/libs/libTrophy.cpp @@ -0,0 +1,1288 @@ +#include "common/emulatorConfig.h" +#include "common/trophies.h" +#include "graphics/presentation/systemOverlay.h" +#include "kernel/fileSystem.h" +#include "libs/libs.h" +#include "loader/symbolDatabase.h" +#include "loader/systemContent.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Libs { + +namespace LibNpTrophy2 { + +LIB_VERSION("NpTrophy2", 1, "NpTrophy2", 1, 1); + +constexpr int NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND = -2141898479; /* 0x80553911 */ + +struct NpTrophy2Progress { + int32_t type; + uint8_t reserved[4]; + uint64_t value; +}; + +struct NpTrophy2GameDetails { + uint32_t num_groups; + uint32_t num_trophies; + uint32_t num_platinum; + uint32_t num_gold; + uint32_t num_silver; + uint32_t num_bronze; + char title[128]; +}; + +struct NpTrophy2GameData { + uint32_t unlocked_trophies; + uint32_t unlocked_platinum; + uint32_t unlocked_gold; + uint32_t unlocked_silver; + uint32_t unlocked_bronze; + uint32_t progress_percentage; +}; + +struct NpTrophy2GroupDetails { + int32_t group_id; + uint32_t num_trophies; + uint32_t num_platinum; + uint32_t num_gold; + uint32_t num_silver; + uint32_t num_bronze; + char title[128]; +}; + +struct NpTrophy2GroupData { + int32_t group_id; + uint32_t unlocked_trophies; + uint32_t unlocked_platinum; + uint32_t unlocked_gold; + uint32_t unlocked_silver; + uint32_t unlocked_bronze; + uint32_t progress_percentage; + uint8_t reserved[4]; +}; + +struct NpTrophy2Details { + int32_t trophy_id; + int32_t trophy_grade; + int32_t group_id; + bool hidden; + bool has_reward; + uint8_t reserved2[2]; + NpTrophy2Progress target; + char name[128]; + char description[1024]; + char reward[128]; +}; + +struct NpTrophy2Data { + int32_t trophy_id; + bool unlocked; + uint8_t reserved[3]; + NpTrophy2Progress progress; + uint64_t timestamp_tick; +}; + +static_assert(sizeof(NpTrophy2GameDetails) == 152); +static_assert(sizeof(NpTrophy2GameData) == 24); +static_assert(sizeof(NpTrophy2GroupDetails) == 152); +static_assert(sizeof(NpTrophy2GroupData) == 32); +static_assert(sizeof(NpTrophy2Details) == 1312); +static_assert(sizeof(NpTrophy2Data) == 32); + +namespace Trophies = Common::Trophies; +using TrophyKey = std::pair; + +struct TrophyState { + const Trophies::Package* package = nullptr; + std::set unlocked; + std::filesystem::path path; +}; + +struct TrophyContext { + TrophyKey key; + TrophyState* state = nullptr; +}; + +static std::mutex g_trophy_mutex; +static std::map g_packages; +static std::map g_states; +static std::map g_contexts; +static int g_next_context = 1; + +constexpr int NP_TROPHY2_ERROR_INVALID_ARGUMENT = static_cast(0x80553904); +constexpr int NP_TROPHY2_ERROR_INVALID_CONTEXT = static_cast(0x80553909); +constexpr int NP_TROPHY2_ERROR_INVALID_TROPHY_ID = static_cast(0x8055390a); +constexpr int NP_TROPHY2_ERROR_INVALID_GROUP_ID = static_cast(0x8055390b); +constexpr int NP_TROPHY2_ERROR_NOT_REGISTERED = static_cast(0x80553920); + +// Caller holds g_trophy_mutex. Both NpTrophy2 and UDS use the same user/service record. +static TrophyState* LoadTrophyState(TrophyKey key) { + if (const auto it = g_states.find(key); it != g_states.end()) { + return &it->second; + } + auto& package = g_packages[key.second]; + if (package.trophies.empty()) { + const auto filename = "/app0/" + Trophies::PackagePath(key.second).generic_string(); + package = Trophies::LoadPackage(LibKernel::FileSystem::GetRealFilename(filename), + Config::GetConsoleLanguage()); + if (package.trophies.empty()) { + return nullptr; + } + } + std::string title_id; + Loader::SystemContentParamSfoGetString("TITLE_ID", &title_id); + auto path = Trophies::UnlocksPath({}, title_id, key.first, key.second); + auto unlocked = Trophies::LoadUnlocks(path); + return &g_states.emplace(key, TrophyState {&package, std::move(unlocked), std::move(path)}) + .first->second; +} + +static int GetTrophyState(int context, TrophyState** state) { + const auto it = g_contexts.find(context); + if (it == g_contexts.end()) { + return NP_TROPHY2_ERROR_INVALID_CONTEXT; + } + *state = it->second.state; + return *state == nullptr ? NP_TROPHY2_ERROR_NOT_REGISTERED : 0; +} + +static void FillTrophyInfo(const TrophyState& state, const Trophies::Trophy& trophy, + NpTrophy2Details* details, NpTrophy2Data* data) { + if (details != nullptr) { + *details = {}; + details->trophy_id = trophy.id; + details->trophy_grade = trophy.grade; + details->group_id = trophy.group_id; + details->hidden = trophy.hidden; + details->has_reward = trophy.has_reward; + if (trophy.target) { + details->target.type = 1; + details->target.value = *trophy.target; + } + std::snprintf(details->name, sizeof(details->name), "%s", trophy.name.c_str()); + std::snprintf(details->description, sizeof(details->description), "%s", + trophy.description.c_str()); + std::snprintf(details->reward, sizeof(details->reward), "%s", trophy.reward.c_str()); + } + if (data != nullptr) { + *data = {}; + data->trophy_id = trophy.id; + data->unlocked = state.unlocked.contains(trophy.id); + if (trophy.target) { + data->progress.type = 1; + data->progress.value = data->unlocked ? *trophy.target : 0; + } + } +} + +// Game and group structures share the same count fields. +template +static void FillTrophyCounts(const TrophyState& state, int group, Details* details, Data* data) { + std::array total {}, unlocked {}; + for (const auto& [id, trophy]: state.package->trophies) { + if (group != -2 && trophy.group_id != group) { + continue; + } + ++total[trophy.grade]; + if (state.unlocked.contains(id)) { + ++unlocked[trophy.grade]; + } + } + if (details != nullptr) { + *details = {}; + details->num_trophies = total[1] + total[2] + total[3] + total[4]; + details->num_platinum = total[1]; + details->num_gold = total[2]; + details->num_silver = total[3]; + details->num_bronze = total[4]; + } + if (data != nullptr) { + *data = {}; + data->unlocked_trophies = unlocked[1] + unlocked[2] + unlocked[3] + unlocked[4]; + data->unlocked_platinum = unlocked[1]; + data->unlocked_gold = unlocked[2]; + data->unlocked_silver = unlocked[3]; + data->unlocked_bronze = unlocked[4]; + const auto points = total[2] * 6 + total[3] * 2 + total[4]; + const auto earned = unlocked[2] * 6 + unlocked[3] * 2 + unlocked[4]; + data->progress_percentage = points == 0 ? 0 : earned * 100 / points; + } +} + +static void FillGroupInfo(const TrophyState& state, int group_id, const std::string& title, + NpTrophy2GroupDetails* details, NpTrophy2GroupData* data) { + FillTrophyCounts(state, group_id, details, data); + if (details != nullptr) { + details->group_id = group_id; + std::snprintf(details->title, sizeof(details->title), "%s", title.c_str()); + } + if (data != nullptr) { + data->group_id = group_id; + } +} + +static void RecordTrophyUnlock(TrophyState& state, int trophy_id) { + const auto found = state.package->trophies.find(trophy_id); + if (found == state.package->trophies.end() || found->second.grade == 1 || + found->second.target || !state.unlocked.insert(trophy_id).second) { + return; + } + std::vector earned {trophy_id}; + const auto platinum_id = found->second.platinum_id; + if (platinum_id >= 0 && state.package->trophies.contains(platinum_id) && + std::all_of(state.package->trophies.begin(), state.package->trophies.end(), + [&](const auto& entry) { + return entry.second.platinum_id != platinum_id || + state.unlocked.contains(entry.first); + }) && + state.unlocked.insert(platinum_id).second) { + earned.push_back(platinum_id); + } + if (!Trophies::SaveUnlocks(state.path, state.unlocked)) { + LOGF("[Trophy] could not save unlocks to %s\n", state.path.string().c_str()); + } + if (Config::TrophyEnabled()) { + for (const auto id: earned) { + const auto& trophy = state.package->trophies.at(id); + Graphics::NotifyTrophyUnlocked(trophy.name, trophy.grade, trophy.icon_png); + } + } +} + +static int KYTY_SYSV_ABI NpTrophy2CreateHandle(int* handle) { + PRINT_NAME(); + if (handle == nullptr) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + *handle = 1; + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2CreateContext(int* context, int user_id, uint32_t service_label, + uint64_t options) { + PRINT_NAME(); + if (context == nullptr || options != 0 || user_id < 0) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(g_trophy_mutex); + const TrophyKey key {user_id, service_label}; + for (const auto& [id, value]: g_contexts) { + if (value.key == key) { + return static_cast(0x80553910); // CONTEXT_ALREADY_EXISTS + } + } + if (g_contexts.size() == 8) { + return static_cast(0x8055391b); // CONTEXT_EXCEEDS_MAX + } + *context = g_next_context++; + g_contexts.emplace(*context, TrophyContext {key}); + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2RegisterContext(int context, int handle, uint64_t options) { + PRINT_NAME(); + std::scoped_lock lock(g_trophy_mutex); + const auto it = g_contexts.find(context); + if (it == g_contexts.end()) { + return NP_TROPHY2_ERROR_INVALID_CONTEXT; + } + if (options != 0) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + if (it->second.state != nullptr) { + return static_cast(0x80553921); // ALREADY_REGISTERED + } + it->second.state = LoadTrophyState(it->second.key); + return it->second.state != nullptr ? 0 + : static_cast(0x8055391e); // TITLE_CONF_NOT_INSTALLED +} + +static int KYTY_SYSV_ABI NpTrophy2GetGameInfo(int context, int handle, + NpTrophy2GameDetails* details, + NpTrophy2GameData* data) { + PRINT_NAME(); + if (details == nullptr && data == nullptr) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(g_trophy_mutex); + TrophyState* state = nullptr; + if (const int error = GetTrophyState(context, &state); error != 0) { + return error; + } + FillTrophyCounts(*state, -2, details, data); + if (details != nullptr) { + details->num_groups = state->package->groups.size(); + std::snprintf(details->title, sizeof(details->title), "%s", state->package->title.c_str()); + } + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2GetGroupInfo(int context, int handle, int group_id, + NpTrophy2GroupDetails* details, + NpTrophy2GroupData* data) { + PRINT_NAME(); + if (details == nullptr && data == nullptr) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(g_trophy_mutex); + TrophyState* state = nullptr; + if (const int error = GetTrophyState(context, &state); error != 0) { + return error; + } + const auto group = state->package->groups.find(group_id); + if (group == state->package->groups.end()) { + return NP_TROPHY2_ERROR_INVALID_GROUP_ID; + } + FillGroupInfo(*state, group_id, group->second, details, data); + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2GetGroupInfoArray(int context, int handle, uint32_t offset, + uint32_t limit, + NpTrophy2GroupDetails* details_array, + NpTrophy2GroupData* data_array, + uint32_t* count) { + PRINT_NAME(); + if (count == nullptr || (details_array == nullptr && data_array == nullptr)) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(g_trophy_mutex); + TrophyState* state = nullptr; + if (const int error = GetTrophyState(context, &state); error != 0) { + return error; + } + const auto& groups = state->package->groups; + auto it = groups.begin(); + std::advance(it, std::min(offset, groups.size())); + *count = 0; + for (; it != groups.end() && *count < limit; ++it, ++*count) { + FillGroupInfo(*state, it->first, it->second, + details_array != nullptr ? &details_array[*count] : nullptr, + data_array != nullptr ? &data_array[*count] : nullptr); + } + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2GetTrophyInfo(int context, int handle, int trophy_id, + NpTrophy2Details* details, NpTrophy2Data* data) { + PRINT_NAME(); + if (details == nullptr && data == nullptr) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(g_trophy_mutex); + TrophyState* state = nullptr; + if (const int error = GetTrophyState(context, &state); error != 0) { + return error; + } + const auto trophy = state->package->trophies.find(trophy_id); + if (trophy == state->package->trophies.end()) { + return NP_TROPHY2_ERROR_INVALID_TROPHY_ID; + } + FillTrophyInfo(*state, trophy->second, details, data); + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2GetTrophyInfoArray(int context, int handle, uint32_t offset, + uint32_t limit, + NpTrophy2Details* details_array, + NpTrophy2Data* data_array, uint32_t* count) { + PRINT_NAME(); + if (count == nullptr || (details_array == nullptr && data_array == nullptr)) { + return NP_TROPHY2_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(g_trophy_mutex); + TrophyState* state = nullptr; + if (const int error = GetTrophyState(context, &state); error != 0) { + return error; + } + const auto& trophies = state->package->trophies; + auto it = trophies.begin(); + std::advance(it, std::min(offset, trophies.size())); + *count = 0; + for (; it != trophies.end() && *count < limit; ++it, ++*count) { + FillTrophyInfo(*state, it->second, + details_array != nullptr ? &details_array[*count] : nullptr, + data_array != nullptr ? &data_array[*count] : nullptr); + } + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2GetGameIcon(int context, int handle, void* buffer, size_t* size) { + PRINT_NAME(); + + LOGF("\t context = %d\n" + "\t handle = %d\n" + "\t buffer = 0x%016" PRIx64 "\n" + "\t size = 0x%016" PRIx64 "\n", + context, handle, reinterpret_cast(buffer), reinterpret_cast(size)); + + if (size != nullptr) { + *size = 0; + } + + return NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND; +} + +static int KYTY_SYSV_ABI NpTrophy2GetGroupIcon(int context, int handle, int group_id, void* buffer, + size_t* size) { + PRINT_NAME(); + + LOGF("\t context = %d\n" + "\t handle = %d\n" + "\t group_id = %d\n" + "\t buffer = 0x%016" PRIx64 "\n" + "\t size = 0x%016" PRIx64 "\n", + context, handle, group_id, reinterpret_cast(buffer), + reinterpret_cast(size)); + + if (size != nullptr) { + *size = 0; + } + + return NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND; +} + +static int KYTY_SYSV_ABI NpTrophy2GetTrophyIcon(int context, int handle, int trophy_id, + void* buffer, size_t* size) { + PRINT_NAME(); + + LOGF("\t context = %d\n" + "\t handle = %d\n" + "\t trophy_id = %d\n" + "\t buffer = 0x%016" PRIx64 "\n" + "\t size = 0x%016" PRIx64 "\n", + context, handle, trophy_id, reinterpret_cast(buffer), + reinterpret_cast(size)); + + if (size != nullptr) { + *size = 0; + } + + return NP_TROPHY2_ERROR_ICON_FILE_NOT_FOUND; +} + +static int KYTY_SYSV_ABI NpTrophy2RegisterUnlockCallback(void* callback, void* userdata) { + PRINT_NAME(); + + LOGF("\t callback = 0x%016" PRIx64 "\n" + "\t userdata = 0x%016" PRIx64 "\n", + reinterpret_cast(callback), reinterpret_cast(userdata)); + + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2AbortHandle(int handle) { + PRINT_NAME(); + + LOGF("\t handle = %d\n", handle); + + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2DestroyHandle(int handle) { + PRINT_NAME(); + + LOGF("\t handle = %d\n", handle); + + return 0; +} + +static int KYTY_SYSV_ABI NpTrophy2DestroyContext(int context) { + PRINT_NAME(); + std::scoped_lock lock(g_trophy_mutex); + return g_contexts.erase(context) != 0 ? 0 : NP_TROPHY2_ERROR_INVALID_CONTEXT; +} + +LIB_DEFINE(InitNet_1_NpTrophy2) { + LIB_FUNC("Bagshr7OQ6Q", LibNpTrophy2::NpTrophy2CreateContext); + LIB_FUNC("Gz1rmUZpROM", LibNpTrophy2::NpTrophy2CreateHandle); + LIB_FUNC("bIDov3wBu5Q", LibNpTrophy2::NpTrophy2RegisterContext); + LIB_FUNC("4IzqhhUQ3nk", LibNpTrophy2::NpTrophy2GetGameInfo); + LIB_FUNC("DoZWauG8mu0", LibNpTrophy2::NpTrophy2GetGroupInfo); + LIB_FUNC("+PDSI6WgPRc", LibNpTrophy2::NpTrophy2GetGroupInfoArray); + LIB_FUNC("EwNylPdWUTM", LibNpTrophy2::NpTrophy2GetTrophyInfo); + LIB_FUNC("y3zHpdZO6ME", LibNpTrophy2::NpTrophy2GetTrophyInfoArray); + LIB_FUNC("2QgUy+xJqS0", LibNpTrophy2::NpTrophy2GetGameIcon); + LIB_FUNC("6IjXJUy6ZnA", LibNpTrophy2::NpTrophy2GetGroupIcon); + LIB_FUNC("-9LLVU0uvs8", LibNpTrophy2::NpTrophy2GetTrophyIcon); + LIB_FUNC("sUXGfNMalIo", LibNpTrophy2::NpTrophy2RegisterUnlockCallback); + LIB_FUNC("fYapWA9xVmA", LibNpTrophy2::NpTrophy2AbortHandle); + LIB_FUNC("d8P11CI40KE", LibNpTrophy2::NpTrophy2DestroyHandle); + LIB_FUNC("sysY2FHYff4", LibNpTrophy2::NpTrophy2DestroyContext); +} + +} // namespace LibNpTrophy2 + +namespace LibNpUniversalDataSystem { + +LIB_VERSION("NpUniversalDataSystem", 1, "NpUniversalDataSystem", 1, 1); + +constexpr int NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT = -2141900542; /* 0x80553102 */ + +struct NpUniversalDataSystemInitParam { + size_t size; + size_t pool_size; +}; + +struct NpUniversalDataSystemMemoryStat { + size_t pool_size; + size_t max_inuse_size; + size_t current_inuse_size; +}; + +struct NpUniversalDataSystemEventPropertyObject { + std::optional trophy_id; + + void SetTrophyId(const char* key, std::optional value) { + if (std::strcmp(key, "_trophy_id") == 0) { + trophy_id = value; + } + } +}; + +struct NpUniversalDataSystemEvent { + std::string name; + NpUniversalDataSystemEventPropertyObject properties; +}; + +struct UdsContext { + LibNpTrophy2::TrophyKey key; + bool registered = false; +}; +static std::map g_contexts; +static int g_next_context = 1; + +struct NpUniversalDataSystemEventPropertyArray {}; + +struct NpUniversalDataSystemStorageStat { + size_t in_events; + size_t out_events; + size_t lost_events; + size_t max_inuse_size; + size_t current_events; + size_t current_inuse_size; + size_t current_free_size; +}; + +static int KYTY_SYSV_ABI +NpUniversalDataSystemInitialize(const NpUniversalDataSystemInitParam* param) { + PRINT_NAME(); + + if (param == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + LOGF("\t size = %" PRIu64 "\n" + "\t pool_size = %" PRIu64 "\n", + static_cast(param->size), static_cast(param->pool_size)); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemCreateContext(int* context, int user_id, + uint32_t service_label, + uint64_t options) { + PRINT_NAME(); + if (context == nullptr || options != 0) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + if (user_id < 0) { + return static_cast(0x8055310a); // INVALID_USER + } + std::scoped_lock lock(LibNpTrophy2::g_trophy_mutex); + if (g_contexts.size() == 8) { + return static_cast(0x80553105); // CONTEXT_EXCEEDS_MAX + } + *context = g_next_context++; + g_contexts.emplace(*context, UdsContext {{user_id, service_label}}); + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemCreateHandle(int* handle) { + PRINT_NAME(); + + if (handle == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + if (handle != nullptr) { + *handle = 1; + } + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemDestroyHandle(int handle) { + PRINT_NAME(); + + LOGF("\t handle = %d\n", handle); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemAbortHandle(int handle) { + PRINT_NAME(); + + LOGF("\t handle = %d\n", handle); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemCreateEvent( + const char* event_name, const NpUniversalDataSystemEventPropertyObject* prop, + NpUniversalDataSystemEvent** new_event, NpUniversalDataSystemEventPropertyObject** prop_ptr) { + PRINT_NAME(); + if (event_name == nullptr || new_event == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + *new_event = new NpUniversalDataSystemEvent { + event_name, prop != nullptr ? *prop : NpUniversalDataSystemEventPropertyObject {}}; + if (prop_ptr != nullptr) { + *prop_ptr = &(*new_event)->properties; + } + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemPostEvent(int context, int handle, const void* event, + uint64_t options) { + PRINT_NAME(); + if (event == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + std::scoped_lock lock(LibNpTrophy2::g_trophy_mutex); + const auto it = g_contexts.find(context); + if (it == g_contexts.end()) { + return static_cast(0x80553104); // INVALID_CONTEXT + } + if (!it->second.registered) { + return static_cast(0x80553120); // NOT_REGISTERED + } + const auto& uds_event = *static_cast(event); + if (uds_event.name == "_UnlockTrophy") { + const auto trophy_id = uds_event.properties.trophy_id; + if (!trophy_id || *trophy_id < 0) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + if (auto* state = LibNpTrophy2::LoadTrophyState(it->second.key); state != nullptr) { + LibNpTrophy2::RecordTrophyUnlock(*state, *trophy_id); + } + } + return 0; +} + +static int KYTY_SYSV_ABI +NpUniversalDataSystemEventEstimateSize(const NpUniversalDataSystemEvent* event, size_t* size) { + PRINT_NAME(); + + LOGF("\t event = 0x%016" PRIx64 "\n" + "\t size = 0x%016" PRIx64 "\n", + reinterpret_cast(event), reinterpret_cast(size)); + + if (event == nullptr || size == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + *size = 3; + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventToString(const NpUniversalDataSystemEvent* event, + char* buf, size_t buf_size, + size_t* string_size) { + PRINT_NAME(); + + LOGF("\t event = 0x%016" PRIx64 "\n" + "\t buf = 0x%016" PRIx64 "\n" + "\t buf_size = %" PRIu64 "\n" + "\t string_size = 0x%016" PRIx64 "\n", + reinterpret_cast(event), reinterpret_cast(buf), + static_cast(buf_size), reinterpret_cast(string_size)); + + if (event == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + const char* json = "{}"; + if (string_size != nullptr) { + *string_size = std::strlen(json) + 1; + } + if (buf != nullptr && buf_size > 0) { + std::snprintf(buf, buf_size, "%s", json); + } + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemDestroyEvent(NpUniversalDataSystemEvent* event) { + PRINT_NAME(); + + LOGF("\t event = 0x%016" PRIx64 "\n", reinterpret_cast(event)); + + delete event; + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemRegisterContext(int context, int handle, + uint64_t options) { + PRINT_NAME(); + std::scoped_lock lock(LibNpTrophy2::g_trophy_mutex); + const auto it = g_contexts.find(context); + if (it == g_contexts.end()) { + return static_cast(0x80553104); // INVALID_CONTEXT + } + if (options != 0) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + if (it->second.registered) { + return static_cast(0x80553121); // ALREADY_REGISTERED + } + it->second.registered = true; + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemDestroyContext(int context) { + PRINT_NAME(); + std::scoped_lock lock(LibNpTrophy2::g_trophy_mutex); + return g_contexts.erase(context) != 0 ? 0 : static_cast(0x80553104); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemGetMemoryStat(NpUniversalDataSystemMemoryStat* stat) { + PRINT_NAME(); + + if (stat == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + *stat = {}; + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemCreateEventPropertyObject( + NpUniversalDataSystemEventPropertyObject** new_object) { + PRINT_NAME(); + + if (new_object == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + *new_object = new NpUniversalDataSystemEventPropertyObject; + + LOGF("\t new_object = 0x%016" PRIx64 "\n", reinterpret_cast(*new_object)); + + return 0; +} + +static int KYTY_SYSV_ABI +NpUniversalDataSystemDestroyEventPropertyObject(NpUniversalDataSystemEventPropertyObject* object) { + PRINT_NAME(); + + LOGF("\t object = 0x%016" PRIx64 "\n", reinterpret_cast(object)); + + delete object; + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetString( + NpUniversalDataSystemEventPropertyObject* object, const char* key, const char* value) { + PRINT_NAME(); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %s\n", + reinterpret_cast(object), key != nullptr ? key : "", + value != nullptr ? value : ""); + + if (object == nullptr || key == nullptr || value == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetInt32( + NpUniversalDataSystemEventPropertyObject* object, const char* key, int32_t value) { + PRINT_NAME(); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %" PRId32 "\n", + reinterpret_cast(object), key != nullptr ? key : "", value); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, value); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetUInt32( + NpUniversalDataSystemEventPropertyObject* object, const char* key, uint32_t value) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %" PRIu32 "\n", + reinterpret_cast(object), key, value); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetInt64( + NpUniversalDataSystemEventPropertyObject* object, const char* key, int64_t value) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %" PRId64 "\n", + reinterpret_cast(object), key, value); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetUInt64( + NpUniversalDataSystemEventPropertyObject* object, const char* key, uint64_t value) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %" PRIu64 "\n", + reinterpret_cast(object), key, value); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetFloat32( + NpUniversalDataSystemEventPropertyObject* object, const char* key, float value) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %f\n", + reinterpret_cast(object), key, static_cast(value)); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetFloat64( + NpUniversalDataSystemEventPropertyObject* object, const char* key, double value) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %f\n", + reinterpret_cast(object), key, value); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetBool( + NpUniversalDataSystemEventPropertyObject* object, const char* key, bool value) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = %d\n", + reinterpret_cast(object), key, value ? 1 : 0); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetBinary( + NpUniversalDataSystemEventPropertyObject* object, const char* key, const void* value, + size_t value_size) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr || (value == nullptr && value_size != 0)) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = 0x%016" PRIx64 "\n" + "\t value_size = %" PRIu64 "\n", + reinterpret_cast(object), key, reinterpret_cast(value), + static_cast(value_size)); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetObject( + NpUniversalDataSystemEventPropertyObject* object, const char* key, + const NpUniversalDataSystemEventPropertyObject* value, + NpUniversalDataSystemEventPropertyObject** value_ptr) { + PRINT_NAME(); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + if (value_ptr != nullptr) { + *value_ptr = + (value != nullptr ? const_cast(value) + : new NpUniversalDataSystemEventPropertyObject); + } + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = 0x%016" PRIx64 "\n" + "\t value_ptr = 0x%016" PRIx64 "\n", + reinterpret_cast(object), key, reinterpret_cast(value), + value_ptr != nullptr ? reinterpret_cast(*value_ptr) : 0); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyObjectSetArray( + NpUniversalDataSystemEventPropertyObject* object, const char* key, + const NpUniversalDataSystemEventPropertyArray* value, + NpUniversalDataSystemEventPropertyArray** value_ptr) { + PRINT_NAME(); + + LOGF("\t object = 0x%016" PRIx64 "\n" + "\t key = %s\n" + "\t value = 0x%016" PRIx64 "\n" + "\t value_ptr = 0x%016" PRIx64 "\n", + reinterpret_cast(object), key != nullptr ? key : "", + reinterpret_cast(value), reinterpret_cast(value_ptr)); + + if (object == nullptr || key == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + object->SetTrophyId(key, std::nullopt); + + if (value_ptr != nullptr) { + *value_ptr = (value != nullptr ? const_cast(value) + : new NpUniversalDataSystemEventPropertyArray); + } + + return 0; +} + +static int KYTY_SYSV_ABI +NpUniversalDataSystemCreateEventPropertyArray(NpUniversalDataSystemEventPropertyArray** new_array) { + PRINT_NAME(); + + if (new_array == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + *new_array = new NpUniversalDataSystemEventPropertyArray; + + LOGF("\t new_array = 0x%016" PRIx64 "\n", reinterpret_cast(*new_array)); + + return 0; +} + +static int KYTY_SYSV_ABI +NpUniversalDataSystemDestroyEventPropertyArray(NpUniversalDataSystemEventPropertyArray* array) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n", reinterpret_cast(array)); + + delete array; + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetString( + NpUniversalDataSystemEventPropertyArray* array, const char* value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %s\n", + reinterpret_cast(array), value != nullptr ? value : ""); + + if (array == nullptr || value == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetInt32( + NpUniversalDataSystemEventPropertyArray* array, int32_t value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %" PRId32 "\n", + reinterpret_cast(array), value); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetUInt32( + NpUniversalDataSystemEventPropertyArray* array, uint32_t value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %" PRIu32 "\n", + reinterpret_cast(array), value); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetInt64( + NpUniversalDataSystemEventPropertyArray* array, int64_t value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %" PRId64 "\n", + reinterpret_cast(array), value); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetUInt64( + NpUniversalDataSystemEventPropertyArray* array, uint64_t value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %" PRIu64 "\n", + reinterpret_cast(array), value); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetFloat32( + NpUniversalDataSystemEventPropertyArray* array, float value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %f\n", + reinterpret_cast(array), static_cast(value)); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetFloat64( + NpUniversalDataSystemEventPropertyArray* array, double value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %f\n", + reinterpret_cast(array), value); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetBool( + NpUniversalDataSystemEventPropertyArray* array, bool value) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = %d\n", + reinterpret_cast(array), value ? 1 : 0); + + return (array != nullptr ? 0 : NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT); +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetBinary( + NpUniversalDataSystemEventPropertyArray* array, const void* value, size_t value_size) { + PRINT_NAME(); + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = 0x%016" PRIx64 "\n" + "\t value_size = %" PRIu64 "\n", + reinterpret_cast(array), reinterpret_cast(value), + static_cast(value_size)); + + if (array == nullptr || (value == nullptr && value_size != 0)) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetObject( + NpUniversalDataSystemEventPropertyArray* array, + const NpUniversalDataSystemEventPropertyObject* value, + NpUniversalDataSystemEventPropertyObject** value_ptr) { + PRINT_NAME(); + + if (array == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + if (value_ptr != nullptr) { + *value_ptr = + (value != nullptr ? const_cast(value) + : new NpUniversalDataSystemEventPropertyObject); + } + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = 0x%016" PRIx64 "\n" + "\t value_ptr = 0x%016" PRIx64 "\n", + reinterpret_cast(array), reinterpret_cast(value), + value_ptr != nullptr ? reinterpret_cast(*value_ptr) : 0); + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemEventPropertyArraySetArray( + NpUniversalDataSystemEventPropertyArray* array, + const NpUniversalDataSystemEventPropertyArray* value, + NpUniversalDataSystemEventPropertyArray** value_ptr) { + PRINT_NAME(); + + if (array == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + if (value_ptr != nullptr) { + *value_ptr = (value != nullptr ? const_cast(value) + : new NpUniversalDataSystemEventPropertyArray); + } + + LOGF("\t array = 0x%016" PRIx64 "\n" + "\t value = 0x%016" PRIx64 "\n" + "\t value_ptr = 0x%016" PRIx64 "\n", + reinterpret_cast(array), reinterpret_cast(value), + value_ptr != nullptr ? reinterpret_cast(*value_ptr) : 0); + + return 0; +} + +static int KYTY_SYSV_ABI +NpUniversalDataSystemGetStorageStat(int context, NpUniversalDataSystemStorageStat* stat) { + PRINT_NAME(); + + LOGF("\t context = %d\n" + "\t stat = 0x%016" PRIx64 "\n", + context, reinterpret_cast(stat)); + + if (stat == nullptr) { + return NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT; + } + + *stat = {}; + + return 0; +} + +static int KYTY_SYSV_ABI NpUniversalDataSystemTerminate() { + PRINT_NAME(); + + return 0; +} + +LIB_DEFINE(InitNet_1_NpUniversalDataSystem) { + LIB_FUNC("sjaobBgqeB4", LibNpUniversalDataSystem::NpUniversalDataSystemInitialize); + LIB_FUNC("5zBnau1uIEo", LibNpUniversalDataSystem::NpUniversalDataSystemCreateContext); + LIB_FUNC("hT0IAEvN+M0", LibNpUniversalDataSystem::NpUniversalDataSystemCreateHandle); + LIB_FUNC("p+GcLqwpL9M", LibNpUniversalDataSystem::NpUniversalDataSystemCreateEvent); + LIB_FUNC("CzkKf7ahIyU", LibNpUniversalDataSystem::NpUniversalDataSystemPostEvent); + LIB_FUNC("AUIHb7jUX3I", LibNpUniversalDataSystem::NpUniversalDataSystemDestroyHandle); + LIB_FUNC("jZCqWFgMehE", LibNpUniversalDataSystem::NpUniversalDataSystemAbortHandle); + LIB_FUNC("wB7IWzGp2v0", LibNpUniversalDataSystem::NpUniversalDataSystemDestroyContext); + LIB_FUNC("su7jW3VDDb4", LibNpUniversalDataSystem::NpUniversalDataSystemGetMemoryStat); + LIB_FUNC("+s14jq-KGYw", LibNpUniversalDataSystem::NpUniversalDataSystemEventEstimateSize); + LIB_FUNC("vj6CQGWtEBg", LibNpUniversalDataSystem::NpUniversalDataSystemEventToString); + LIB_FUNC("wG+84pnNIuo", LibNpUniversalDataSystem::NpUniversalDataSystemDestroyEvent); + LIB_FUNC("tpFJ8LIKvPw", LibNpUniversalDataSystem::NpUniversalDataSystemRegisterContext); + LIB_FUNC("s6W4Zl4Slgk", + LibNpUniversalDataSystem::NpUniversalDataSystemCreateEventPropertyObject); + LIB_FUNC("kKUH0Viib3c", + LibNpUniversalDataSystem::NpUniversalDataSystemDestroyEventPropertyObject); + LIB_FUNC("MfDb+4Nln64", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetString); + LIB_FUNC("YE4dbtbz6OE", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetInt32); + LIB_FUNC("AzD4irAcKE4", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetUInt32); + LIB_FUNC("56QLTqx911s", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetInt64); + LIB_FUNC("xvsP5Yz6FmY", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetUInt64); + LIB_FUNC("lbPlT4+QVcE", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetFloat32); + LIB_FUNC("4Fu8tHW+u-k", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetFloat64); + LIB_FUNC("Fidd8vWgyVE", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetBool); + LIB_FUNC("wAcxBDLHj1M", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetBinary); + LIB_FUNC("74ASEqxSnkM", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetObject); + LIB_FUNC("Wxbg5x3pTXA", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyObjectSetArray); + LIB_FUNC("Hm7qubT3b70", + LibNpUniversalDataSystem::NpUniversalDataSystemCreateEventPropertyArray); + LIB_FUNC("W-0xwY0ZMjw", + LibNpUniversalDataSystem::NpUniversalDataSystemDestroyEventPropertyArray); + LIB_FUNC("4llLk7YJRTE", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetString); + LIB_FUNC("BypQuF113-k", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetInt32); + LIB_FUNC("yMi0xAOpmXM", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetUInt32); + LIB_FUNC("viVXAwmmYrY", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetInt64); + LIB_FUNC("Qo9qR7v5zO4", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetUInt64); + LIB_FUNC("JmgwKm96Lq4", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetFloat32); + LIB_FUNC("sbSYZLR5AiE", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetFloat64); + LIB_FUNC("0+l4QSWCM4E", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetBool); + LIB_FUNC("IEdUCV9j2Cw", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetBinary); + LIB_FUNC("XY14n3jNIpE", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetObject); + LIB_FUNC("rdi9BAfDLq8", + LibNpUniversalDataSystem::NpUniversalDataSystemEventPropertyArraySetArray); + LIB_FUNC("KmN62tT4U8A", LibNpUniversalDataSystem::NpUniversalDataSystemGetStorageStat); + LIB_FUNC("47UAEuQl+iI", LibNpUniversalDataSystem::NpUniversalDataSystemTerminate); +} + +} // namespace LibNpUniversalDataSystem + +} // namespace Libs diff --git a/src/main.cpp b/src/main.cpp index ac3ff6c4d..eb4b2942e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,6 +84,8 @@ static void PrintUsage() { ::printf(" --spirv-debug-printf Enable SPIR-V debug printf.\n"); ::printf( " --readback-linear-images Read back writable linear images on submit.\n"); + ::printf( + " --trophy-notifications Show trophy unlock toasts and play their sound.\n"); ::printf(" --playgo-hack Use the supplied PlayGo stub fallback.\n"); #if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS ::printf(" --redzone Protect the guest SysV red zone.\n"); @@ -421,6 +423,11 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he ::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str()); return false; } + } else if (arg == "--trophy-notifications") { + if (!ParseBool(value, options.config.trophy_enabled)) { + ::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str()); + return false; + } } else if (arg == "--keymap") { const auto split = value.find('='); if (split == std::string::npos || split == 0 || split + 1 == value.size()) {