From f7a473b3917dc5eb0fad0a8289d56e1ccde90b87 Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Fri, 9 Jan 2026 18:29:09 +0300 Subject: [PATCH 1/2] read compiled SDK version from eboot (#3905) --- src/core/libraries/kernel/process.cpp | 8 +++++--- src/core/linker.cpp | 4 ++-- src/emulator.cpp | 29 +++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/core/libraries/kernel/process.cpp b/src/core/libraries/kernel/process.cpp index e88446e02..4ea7fa062 100644 --- a/src/core/libraries/kernel/process.cpp +++ b/src/core/libraries/kernel/process.cpp @@ -36,9 +36,11 @@ s32 PS4_SYSV_ABI sceKernelGetMainSocId() { } s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver) { - s32 version = Common::ElfInfo::Instance().CompiledSdkVer(); - *ver = version; - return (version >= 0) ? ORBIS_OK : ORBIS_KERNEL_ERROR_EINVAL; + if (!ver) { + return ORBIS_KERNEL_ERROR_EINVAL; + } + *ver = Common::ElfInfo::Instance().CompiledSdkVer(); + return ORBIS_OK; } s32 PS4_SYSV_ABI sceKernelGetCpumode() { diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 8d7f9207e..97d766a38 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -180,8 +180,8 @@ s32 Linker::LoadAndStartModule(const std::filesystem::path& path, u64 args, cons } // Retrieve and verify proc param according to libkernel. - u64* param = module->GetProcParam(); - ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]); + auto* param = module->GetProcParam(); + ASSERT_MSG(!param || param->size >= 0x18, "Invalid module param size: {}", param->size); s32 ret = module->Start(args, argp, param); if (pRes) { *pRes = ret; diff --git a/src/emulator.cpp b/src/emulator.cpp index 6f199649f..4947beeb8 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -74,6 +74,25 @@ Emulator::Emulator() { Emulator::~Emulator() {} +s32 ReadCompiledSdkVersion(const std::filesystem::path& file) { + Core::Loader::Elf elf; + elf.Open(file); + if (!elf.IsElfFile()) { + return 0; + } + const auto elf_pheader = elf.GetProgramHeader(); + auto i_procparam = std::find_if(elf_pheader.begin(), elf_pheader.end(), [](const auto& entry) { + return entry.p_type == PT_SCE_PROCPARAM; + }); + + if (i_procparam != elf_pheader.end()) { + Core::OrbisProcParam param{}; + elf.LoadSegment(u64(¶m), i_procparam->p_offset, i_procparam->p_filesz); + return param.sdk_version; + } + return 0; +} + void Emulator::Run(std::filesystem::path file, std::vector args, std::optional p_game_folder) { Common::SetCurrentThreadName("Main Thread"); @@ -162,6 +181,9 @@ void Emulator::Run(std::filesystem::path file, std::vector args, } } + auto guest_eboot_path = "/app0/" + eboot_name.generic_string(); + const auto eboot_path = mnt->GetHostPath(guest_eboot_path); + auto& game_info = Common::ElfInfo::Instance(); game_info.initialized = true; game_info.game_serial = id; @@ -169,7 +191,7 @@ void Emulator::Run(std::filesystem::path file, std::vector args, game_info.app_ver = app_version; game_info.firmware_ver = fw_version & 0xFFF00000; game_info.raw_firmware_ver = fw_version; - game_info.sdk_ver = sdk_version; + game_info.sdk_ver = ReadCompiledSdkVersion(eboot_path); game_info.psf_attributes = psf_attributes; const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png"); @@ -241,7 +263,8 @@ void Emulator::Run(std::filesystem::path file, std::vector args, if (param_sfo_exists) { LOG_INFO(Loader, "Game id: {} Title: {}", id, title); LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); - LOG_INFO(Loader, "Compiled SDK version: {:#x}", sdk_version); + LOG_INFO(Loader, "param.sfo SDK version: {:#x}", sdk_version); + LOG_INFO(Loader, "eboot SDK version: {:#x}", game_info.sdk_ver); LOG_INFO(Loader, "PSVR Supported: {}", (bool)psf_attributes.support_ps_vr.Value()); LOG_INFO(Loader, "PSVR Required: {}", (bool)psf_attributes.require_ps_vr.Value()); } @@ -339,8 +362,6 @@ void Emulator::Run(std::filesystem::path file, std::vector args, Libraries::InitHLELibs(&linker->GetHLESymbols()); // Load the module with the linker - auto guest_eboot_path = "/app0/" + eboot_name.generic_string(); - const auto eboot_path = mnt->GetHostPath(guest_eboot_path); if (linker->LoadModule(eboot_path) == -1) { LOG_CRITICAL(Loader, "Failed to load game's eboot.bin: {}", Common::FS::PathToUTF8String(std::filesystem::absolute(eboot_path))); From be99cb4d5bfd386eeb0df0af033c99f8ef5deb71 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 9 Jan 2026 19:42:05 +0200 Subject: [PATCH 2/2] Emulator state (#3906) * moved getShowFpsCounter to emu state * more state variables * fps counter is back * removed fpscolor --- CMakeLists.txt | 2 ++ src/common/config.cpp | 25 ----------------------- src/common/config.h | 3 --- src/common/memory_patcher.cpp | 5 +++-- src/core/devtools/layer.cpp | 15 ++++++-------- src/core/emulator_state.cpp | 37 +++++++++++++++++++++++++++++++++++ src/core/emulator_state.h | 29 +++++++++++++++++++++++++++ src/core/ipc/ipc.cpp | 5 +++-- src/main.cpp | 7 +++++-- 9 files changed, 85 insertions(+), 43 deletions(-) create mode 100644 src/core/emulator_state.cpp create mode 100644 src/core/emulator_state.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e3ac31f17..ef5e935a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -840,6 +840,8 @@ set(CORE src/core/aerolib/stubs.cpp src/core/thread.h src/core/tls.cpp src/core/tls.h + src/core/emulator_state.cpp + src/core/emulator_state.h ) if (ARCHITECTURE STREQUAL "x86_64") diff --git a/src/common/config.cpp b/src/common/config.cpp index 1af326af7..eac463d0a 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -198,7 +198,6 @@ static ConfigEntry pipelineCacheArchive(false); static ConfigEntry isDebugDump(false); static ConfigEntry isShaderDebug(false); static ConfigEntry isSeparateLogFilesEnabled(false); -static ConfigEntry isFpsColor(true); static ConfigEntry showFpsCounter(false); static ConfigEntry logEnabled(true); @@ -223,16 +222,6 @@ static string config_version = Common::g_scm_rev; // These entries aren't stored in the config static bool overrideControllerColor = false; static int controllerCustomColorRGB[3] = {0, 0, 255}; -static bool isGameRunning = false; -static bool load_auto_patches = true; - -bool getGameRunning() { - return isGameRunning; -} - -void setGameRunning(bool running) { - isGameRunning = running; -} std::filesystem::path getSysModulesPath() { if (sys_modules_path.empty()) { @@ -463,10 +452,6 @@ bool isPipelineCacheArchived() { return pipelineCacheArchive.get(); } -bool fpsColor() { - return isFpsColor.get(); -} - bool getShowFpsCounter() { return showFpsCounter.get(); } @@ -855,13 +840,6 @@ void setUsbDeviceBackend(int value, bool is_game_specific) { usbDeviceBackend.set(value, is_game_specific); } -bool getLoadAutoPatches() { - return load_auto_patches; -} -void setLoadAutoPatches(bool enable) { - load_auto_patches = enable; -} - void load(const std::filesystem::path& path, bool is_game_specific) { // If the configuration file does not exist, create it and return, unless it is game specific std::error_code error; @@ -977,7 +955,6 @@ void load(const std::filesystem::path& path, bool is_game_specific) { isDebugDump.setFromToml(debug, "DebugDump", is_game_specific); isSeparateLogFilesEnabled.setFromToml(debug, "isSeparateLogFilesEnabled", is_game_specific); isShaderDebug.setFromToml(debug, "CollectShader", is_game_specific); - isFpsColor.setFromToml(debug, "FPSColor", is_game_specific); showFpsCounter.setFromToml(debug, "showFpsCounter", is_game_specific); logEnabled.setFromToml(debug, "logEnabled", is_game_specific); current_version = toml::find_or(debug, "ConfigVersion", current_version); @@ -1197,7 +1174,6 @@ void save(const std::filesystem::path& path, bool is_game_specific) { data["GPU"]["internalScreenWidth"] = internalScreenWidth.base_value; data["GPU"]["internalScreenHeight"] = internalScreenHeight.base_value; data["GPU"]["patchShaders"] = shouldPatchShaders.base_value; - data["Debug"]["FPSColor"] = isFpsColor.base_value; data["Debug"]["showFpsCounter"] = showFpsCounter.base_value; } @@ -1306,7 +1282,6 @@ void setDefaultValues(bool is_game_specific) { internalScreenHeight.base_value = 720; // Debug - isFpsColor.base_value = true; showFpsCounter.base_value = false; } } diff --git a/src/common/config.h b/src/common/config.h index 2bd65b783..2a95e6cf0 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -125,7 +125,6 @@ int getSpecialPadClass(); bool getPSNSignedIn(); void setPSNSignedIn(bool sign, bool is_game_specific = false); bool patchShaders(); // no set -bool fpsColor(); // no set bool getShowFpsCounter(); void setShowFpsCounter(bool enable, bool is_game_specific = false); bool isNeoModeConsole(); @@ -154,8 +153,6 @@ void setConnectedToNetwork(bool enable, bool is_game_specific = false); void setUserName(const std::string& name, bool is_game_specific = false); std::filesystem::path getSysModulesPath(); void setSysModulesPath(const std::filesystem::path& path); -bool getLoadAutoPatches(); -void setLoadAutoPatches(bool enable); enum UsbBackendType : int { Real, SkylandersPortal, InfinityBase, DimensionsToypad }; int getUsbDeviceBackend(); diff --git a/src/common/memory_patcher.cpp b/src/common/memory_patcher.cpp index ad737dab4..a7c020246 100644 --- a/src/common/memory_patcher.cpp +++ b/src/common/memory_patcher.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -12,6 +12,7 @@ #include "common/elf_info.h" #include "common/logging/log.h" #include "common/path_util.h" +#include "core/emulator_state.h" #include "core/file_format/psf.h" #include "memory_patcher.h" @@ -192,7 +193,7 @@ void OnGameLoaded() { } else { ApplyPatchesFromXML(file_path); } - } else if (Config::getLoadAutoPatches()) { + } else if (EmulatorState::GetInstance()->IsAutoPatchesLoadEnabled()) { for (auto const& repo : std::filesystem::directory_iterator(patch_dir)) { if (!repo.is_directory()) { continue; diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index cfa950568..928040fec 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "layer.h" @@ -11,6 +11,7 @@ #include "common/singleton.h" #include "common/types.h" #include "core/debug_state.h" +#include "core/emulator_state.h" #include "imgui/imgui_std.h" #include "imgui_internal.h" #include "options.h" @@ -273,14 +274,10 @@ void L::DrawAdvanced() { void L::DrawSimple() { const float frameRate = DebugState.Framerate; - if (Config::fpsColor()) { - if (frameRate < 10) { - PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // Red - } else if (frameRate >= 10 && frameRate < 20) { - PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.5f, 0.0f, 1.0f)); // Orange - } else { - PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); // White - } + if (frameRate < 10) { + PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // Red + } else if (frameRate >= 10 && frameRate < 20) { + PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.5f, 0.0f, 1.0f)); // Orange } else { PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); // White } diff --git a/src/core/emulator_state.cpp b/src/core/emulator_state.cpp new file mode 100644 index 000000000..1f02043a3 --- /dev/null +++ b/src/core/emulator_state.cpp @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadLauncher4 Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "emulator_state.h" + +std::shared_ptr EmulatorState::s_instance = nullptr; +std::mutex EmulatorState::s_mutex; + +EmulatorState::EmulatorState() {} + +EmulatorState::~EmulatorState() {} + +std::shared_ptr EmulatorState::GetInstance() { + std::lock_guard lock(s_mutex); + if (!s_instance) + s_instance = std::make_shared(); + return s_instance; +} + +void EmulatorState::SetInstance(std::shared_ptr instance) { + std::lock_guard lock(s_mutex); + s_instance = instance; +} + +bool EmulatorState::IsGameRunning() const { + return m_running; +} +void EmulatorState::SetGameRunning(bool running) { + m_running = running; +} + +bool EmulatorState::IsAutoPatchesLoadEnabled() const { + return m_load_patches_auto; +} +void EmulatorState::SetAutoPatchesLoadEnabled(bool enable) { + m_load_patches_auto = enable; +} diff --git a/src/core/emulator_state.h b/src/core/emulator_state.h new file mode 100644 index 000000000..c12af5401 --- /dev/null +++ b/src/core/emulator_state.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadLauncher4 Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +class EmulatorState { +public: + EmulatorState(); + ~EmulatorState(); + + static std::shared_ptr GetInstance(); + static void SetInstance(std::shared_ptr instance); + + bool IsGameRunning() const; + void SetGameRunning(bool running); + bool IsAutoPatchesLoadEnabled() const; + void SetAutoPatchesLoadEnabled(bool enable); + +private: + static std::shared_ptr s_instance; + static std::mutex s_mutex; + + // state variables + bool m_running = false; + bool m_load_patches_auto = true; +}; \ No newline at end of file diff --git a/src/core/ipc/ipc.cpp b/src/core/ipc/ipc.cpp index 08cf3bbb2..ea7cd38b4 100644 --- a/src/core/ipc/ipc.cpp +++ b/src/core/ipc/ipc.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "ipc.h" @@ -14,6 +14,7 @@ #include "common/types.h" #include "core/debug_state.h" #include "core/debugger.h" +#include "core/emulator_state.h" #include "core/libraries/audio/audioout.h" #include "input/input_handler.h" #include "sdl_window.h" @@ -71,7 +72,7 @@ void IPC::Init() { return; } - Config::setLoadAutoPatches(false); + EmulatorState::GetInstance()->SetAutoPatchesLoadEnabled(false); input_thread = std::jthread([this] { Common::SetCurrentThreadName("IPC Read thread"); diff --git a/src/main.cpp b/src/main.cpp index e19e8a938..aa3f4de45 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -8,6 +8,7 @@ #include "system_error" #include "unordered_map" +#include #include #include "common/config.h" #include "common/logging/backend.h" @@ -27,7 +28,9 @@ int main(int argc, char* argv[]) { SetConsoleOutputCP(CP_UTF8); #endif IPC::Instance().Init(); - + // Init emulator state + std::shared_ptr m_emu_state = std::make_shared(); + EmulatorState::SetInstance(m_emu_state); // Load configurations const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); Config::load(user_dir / "config.toml");