From 646b2f4679e1f694d6c4266d09cb2df80981a41b Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Sun, 22 Sep 2024 04:59:49 -0300 Subject: [PATCH] Add ElfInfo to track current game info in a singleton --- CMakeLists.txt | 1 + src/common/elf_info.h | 72 +++++++++++++++++++ src/core/libraries/kernel/libkernel.cpp | 4 +- .../save_data/dialog/savedatadialog_ui.cpp | 5 +- src/core/libraries/save_data/savedata.cpp | 7 +- src/emulator.cpp | 14 +++- 6 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 src/common/elf_info.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1980b3689..30a029c8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,6 +360,7 @@ set(COMMON src/common/logging/backend.cpp src/common/debug.h src/common/disassembler.cpp src/common/disassembler.h + src/common/elf_info.h src/common/endian.h src/common/enum.h src/common/io_file.cpp diff --git a/src/common/elf_info.h b/src/common/elf_info.h new file mode 100644 index 000000000..5a2c914e0 --- /dev/null +++ b/src/common/elf_info.h @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "assert.h" +#include "singleton.h" +#include "types.h" + +namespace Core { +class Emulator; +} + +namespace Common { + +class ElfInfo { + friend class Core::Emulator; + + bool initialized = false; + + std::string game_serial{}; + std::string title{}; + std::string app_ver{}; + u32 firmware_ver = 0; + u32 raw_firmware_ver = 0; + +public: + static constexpr u32 FW_15 = 0x1500000; + static constexpr u32 FW_16 = 0x1600000; + static constexpr u32 FW_17 = 0x1700000; + static constexpr u32 FW_20 = 0x2000000; + static constexpr u32 FW_25 = 0x2500000; + static constexpr u32 FW_30 = 0x3000000; + static constexpr u32 FW_40 = 0x4000000; + static constexpr u32 FW_45 = 0x4500000; + static constexpr u32 FW_50 = 0x5000000; + static constexpr u32 FW_80 = 0x8000000; + + static ElfInfo& Instance() { + return *Singleton::Instance(); + } + + [[nodiscard]] std::string_view GameSerial() const { + ASSERT(initialized); + return Instance().game_serial; + } + + [[nodiscard]] std::string_view Title() const { + ASSERT(initialized); + return title; + } + + [[nodiscard]] std::string_view AppVer() const { + ASSERT(initialized); + return app_ver; + } + + [[nodiscard]] u32 FirmwareVer() const { + ASSERT(initialized); + return firmware_ver; + } + + [[nodiscard]] u32 RawFirmwareVer() const { + ASSERT(initialized); + return raw_firmware_ver; + } +}; + +} // namespace Common diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index 41ca726ba..65d3dde14 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -8,6 +8,7 @@ #include "common/assert.h" #include "common/debug.h" +#include "common/elf_info.h" #include "common/logging/log.h" #include "common/polyfill_thread.h" #include "common/singleton.h" @@ -243,8 +244,7 @@ int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, } int PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(int* ver) { - auto* param_sfo = Common::Singleton::Instance(); - int version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); + int version = Common::ElfInfo::Instance().RawFirmwareVer(); LOG_INFO(Kernel, "returned system version = {:#x}", version); *ver = version; return (version > 0) ? ORBIS_OK : ORBIS_KERNEL_ERROR_EINVAL; diff --git a/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp b/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp index 79fc1b589..9cfdba52c 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp +++ b/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp @@ -5,6 +5,7 @@ #include #include +#include "common/elf_info.h" #include "common/singleton.h" #include "common/string_util.h" #include "core/file_sys/fs.h" @@ -66,9 +67,7 @@ SaveDialogState::SaveDialogState(const OrbisSaveDataDialogParam& param) { this->enable_back = {param.optionParam->back == OptionBack::ENABLE}; } - const auto content_id = Common::Singleton::Instance()->GetString("CONTENT_ID"); - ASSERT_MSG(content_id.has_value(), "Failed to get CONTENT_ID"); - static std::string game_serial{*content_id, 7, 9}; + const auto& game_serial = Common::ElfInfo::Instance().GameSerial(); const auto item = param.items; this->user_id = item->userId; diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index efe8c673c..ca94d96fb 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -9,10 +9,10 @@ #include "common/assert.h" #include "common/cstring.h" +#include "common/elf_info.h" #include "common/enum.h" #include "common/logging/log.h" #include "common/path_util.h" -#include "common/singleton.h" #include "common/string_util.h" #include "core/file_format/psf.h" #include "core/file_sys/fs.h" @@ -307,10 +307,7 @@ static std::array, 16> g_mount_slots; static void initialize() { g_initialized = true; - static auto* param_sfo = Common::Singleton::Instance(); - const auto content_id = param_sfo->GetString("CONTENT_ID"); - ASSERT_MSG(content_id.has_value(), "Failed to get CONTENT_ID"); - g_game_serial = std::string(*content_id, 7, 9); + g_game_serial = Common::ElfInfo::Instance().GameSerial(); } // game_00other | game*other diff --git a/src/emulator.cpp b/src/emulator.cpp index d920e77c0..4a2e38ff8 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -11,6 +11,7 @@ #include "common/memory_patcher.h" #endif #include "common/assert.h" +#include "common/elf_info.h" #include "common/ntapi.h" #include "common/path_util.h" #include "common/polyfill_thread.h" @@ -91,10 +92,14 @@ void Emulator::Run(const std::filesystem::path& file) { // Certain games may use /hostapp as well such as CUSA001100 mnt->Mount(file.parent_path(), "/hostapp"); + auto& game_info = Common::ElfInfo::Instance(); + // Loading param.sfo file if exists std::string id; std::string title; std::string app_version; + u32 fw_version; + std::filesystem::path sce_sys_folder = file.parent_path() / "sce_sys"; if (std::filesystem::is_directory(sce_sys_folder)) { for (const auto& entry : std::filesystem::directory_iterator(sce_sys_folder)) { @@ -119,7 +124,7 @@ void Emulator::Run(const std::filesystem::path& file) { #endif title = param_sfo->GetString("TITLE").value_or("Unknown title"); LOG_INFO(Loader, "Game id: {} Title: {}", id, title); - u32 fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); + fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); } else if (entry.path().filename() == "playgo-chunk.dat") { @@ -141,6 +146,13 @@ void Emulator::Run(const std::filesystem::path& file) { } } + game_info.initialized = true; + game_info.game_serial = id; + game_info.title = title; + game_info.app_ver = app_version; + game_info.firmware_ver = fw_version & 0xFFF00000; + game_info.raw_firmware_ver = fw_version; + std::string game_title = fmt::format("{} - {} <{}>", id, title, app_version); std::string window_title = ""; if (Common::isRelease) {