diff --git a/.gitmodules b/.gitmodules index 55ae48ea3cc..e717b4cb51e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -133,3 +133,8 @@ [submodule "externals/openal-soft"] path = externals/openal-soft url = https://github.com/shadexternals/openal-soft.git +[submodule "externals/spdlog"] + path = externals/spdlog + url = https://github.com/gabime/spdlog + shallow = true + branch = v1.x diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf373e5707..e31eedbe99a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -699,16 +699,9 @@ set(DEV_TOOLS src/core/devtools/layer.cpp src/core/devtools/widget/text_editor.h ) -set(COMMON src/common/logging/backend.cpp - src/common/logging/backend.h - src/common/logging/filter.cpp - src/common/logging/filter.h - src/common/logging/formatter.h - src/common/logging/log_entry.h +set(COMMON src/common/logging/classes.h + src/common/logging/log.cpp src/common/logging/log.h - src/common/logging/text_formatter.cpp - src/common/logging/text_formatter.h - src/common/logging/types.h src/common/aes.h src/common/alignment.h src/common/arch.h @@ -1113,6 +1106,7 @@ set(EMULATOR src/emulator.cpp src/emulator.h src/sdl_window.h src/sdl_window.cpp + src/shadps4_app.h ) if(NOT ENABLE_TESTS) @@ -1127,17 +1121,13 @@ add_executable(shadps4 ${VIDEO_CORE} ${EMULATOR} src/main.cpp - src/emulator.cpp - src/emulator.h - src/sdl_window.h - src/sdl_window.cpp ) create_target_directory_groups(shadps4) target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG) target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 SDL3_mixer::SDL3_mixer pugixml::pugixml) -target_link_libraries(shadps4 PRIVATE stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json miniz::miniz fdk-aac CLI11::CLI11 OpenAL::OpenAL Cpp_Httplib) +target_link_libraries(shadps4 PRIVATE stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json miniz::miniz fdk-aac CLI11::CLI11 OpenAL::OpenAL Cpp_Httplib spdlog::spdlog) target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h") target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h") diff --git a/documents/Debugging/Debugging.md b/documents/Debugging/Debugging.md index 013ca15fb82..096b71e03d7 100644 --- a/documents/Debugging/Debugging.md +++ b/documents/Debugging/Debugging.md @@ -58,30 +58,39 @@ You can configure the emulator by editing the `config.toml` file found in the `u
Some configuration entries worth changing -- `[General]` - - - `logType`: Configures logging synchronization (`sync`/`async`) - - By default, the emulator logs messages asynchronously for better performance. Some log messages may end up being received out-of-order. - - It can be beneficial to set this to `sync` in order for the log to accurately maintain message order, at the cost of performance. - - When communicating about issues with games and the log messages aren't clear due to potentially confusing order, set this to `sync` and send that log as well. - - `logFilter`: Sets the logging category for various logging classes. - - Format: `: ...` - - Multiple classes can be set by separating them with a space. (example: `Render:Warning Debug:Critical Lib.Pad:Error`) +- `[Log]` + - `sync`: Log synchronously (`true`/`false`) + - By default `true`, the emulator logs messages synchronously to respect the order. + - It can be beneficial to set this to `false` for better performance. + - When communicating about issues with games and the log messages aren't clear due to potentially confusing order, set this to `true` and send that log instead. + - `filter`: Sets the logging category for various logging classes. + - Format: `=,...` + - Multiple classes can be set by separating them with a comma. (example: `Render=warning,Debug=critical,Lib.Pad=error`) - Sub-classes can be specified in the same format as seen in the console/log (such as `Core.Linker`). - - All classes and sub-classes can be set by specifying a `*` symbol. (example: `Kernel.*:Critical`) - - Valid log levels: `Trace, Debug, Info, Warning, Error, Critical` - in this order, setting a level silences all levels preceding it and logs every level after it. + - Valid log levels: `trace, debug, info, warning, error, critical` - in this order, setting a level silences all levels preceding it and logs every level after it. - Examples: - - If the log is being spammed with messages coming from Lib.Pad, you can use `Lib.Pad:Critical` to only log critical-level messages. - - If you'd like to mute everything, but still want to receive messages from Vulkan rendering: `*:Critical Render.Vulkan:Info` - - `isIdenticalLogGrouped`: Group same logs in one line with a counter (`true`/`false`) - - By default, the emulator will not rewrite the same line, and instead add a counter. + - If the log is being spammed with messages coming from Lib.Pad, you can use `Lib.Pad=critical` to only log critical-level messages. + - If you'd like to mute everything, but still want to receive messages from Vulkan rendering: `off,Render.Vulkan=info` (if you want critical at least `critical,Render.Vulkan=info`) + - this option is evaluated after the environment variable `SPDLOG_LEVEL` but before the command line argument (their syntax are `SPDLOG_LEVEL="..."`, `"SPDLOG_LEVEL=..."` respectively) + - `skipDuplicate`: Skip same lines with a `Skipped N duplicate messages..` message (`true`/`false`) + - By default, the emulator will skip same lines for `maxSkipDuration` milliseconds. + - `append`: Append log to the existing file (`true`/`false`) + - By default, the emulator will overwrite the log file. (it can also be by-passed with CLI `--log-append`) + - `separate`: Write log to `log/{GAME ID}.log` instead of `log/shad_log.txt` (`true`/`false`) + - By default, the emulator use `log/shad_log.txt`. + - `maxSkipDuration`: Amount of time in which identical lines will not be logged (milliseconds). + - By default, 5'000 milliseconds. + - `sizeLimit`: Size limit for log files (bytes). + - By default, 100 MB. + - `type`: Choose between `wincolor` (WriteConsole*) and `msvc` (OutputDebugString*) - only for Windows. + - By default, `wincolor`. - - `Fullscreen`: Display the game in a full screen borderless window. - `[GPU]` - `dumpShaders`: Dump shaders that are loaded by the emulator. Dump path: `../user/shader/dumps` - `nullGpu`: Disables rendering. - `screenWidth` and `screenHeight`: Configures the game window width and height. + - `Fullscreen`: Display the game in a full screen borderless window. - `[Vulkan]` - `validation`-related settings: Use when debugging Vulkan. diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 41a0f71c71d..93fbb7017e3 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -317,3 +317,8 @@ endif() add_library(Cpp_Httplib INTERFACE) target_include_directories(Cpp_Httplib INTERFACE cpp-httplib/) +# spdlog +set(SPDLOG_NO_EXCEPTIONS ON) +set(SPDLOG_FMT_EXTERNAL ON) +set(SPDLOG_DISABLE_DEFAULT_LOGGER ON) +add_subdirectory(spdlog EXCLUDE_FROM_ALL SYSTEM) diff --git a/externals/spdlog b/externals/spdlog new file mode 160000 index 00000000000..45b67eee668 --- /dev/null +++ b/externals/spdlog @@ -0,0 +1 @@ +Subproject commit 45b67eee668507813743f84f1b1b9ab674ea221e diff --git a/src/common/assert.cpp b/src/common/assert.cpp index be0feb71dac..c891b1ed011 100644 --- a/src/common/assert.cpp +++ b/src/common/assert.cpp @@ -3,7 +3,7 @@ #include "common/arch.h" #include "common/assert.h" -#include "common/logging/backend.h" +#include "common/logging/log.h" #if defined(ARCH_X86_64) #define Crash() __asm__ __volatile__("int $3") @@ -14,14 +14,12 @@ #endif void assert_fail_impl() { - Common::Log::Stop(); - std::fflush(stdout); + Common::Log::Shutdown(); Crash(); } [[noreturn]] void unreachable_impl() { - Common::Log::Stop(); - std::fflush(stdout); + Common::Log::Shutdown(); Crash(); throw std::runtime_error("Unreachable code"); } diff --git a/src/common/config.cpp b/src/common/config.cpp index 79d3f799f37..107a941dc26 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -11,7 +11,6 @@ #include "common/assert.h" #include "common/config.h" -#include "common/logging/formatter.h" #include "common/path_util.h" #include "common/scm_rev.h" @@ -55,6 +54,10 @@ std::optional get_optional(const toml::value& v, const std::string& key) { if (it->second.is_integer()) { return static_cast(toml::get(it->second)); } + } else if constexpr (std::is_same_v) { + if (it->second.is_integer()) { + return static_cast(toml::get(it->second)); + } } else if constexpr (std::is_same_v) { if (it->second.is_floating()) { return toml::get(it->second); @@ -139,9 +142,6 @@ static ConfigEntry extraDmemInMbytes(0); static ConfigEntry isPSNSignedIn(false); static ConfigEntry isTrophyPopupDisabled(false); static ConfigEntry trophyNotificationDuration(6.0); -static ConfigEntry logFilter(""); -static ConfigEntry logType("sync"); -static ConfigEntry isIdenticalLogGrouped(true); static ConfigEntry userName("shadPS4"); static ConfigEntry isShowSplash(false); static ConfigEntry isSideTrophy("right"); @@ -150,6 +150,19 @@ static bool enableDiscordRPC = false; static std::filesystem::path sys_modules_path = {}; static std::filesystem::path fonts_path = {}; +// Log +static ConfigEntry logAppend(false); +static ConfigEntry logEnable(true); +static ConfigEntry logFilter(""); +static ConfigEntry logMaxSkipDuration(5'000); +static ConfigEntry logSeparate(false); +static ConfigEntry logSizeLimit(100_MB); +static ConfigEntry logSkipDuplicate(true); +static ConfigEntry logSync(true); +#ifdef _WIN32 +static ConfigEntry logType("wincolor"); +#endif + // Input static ConfigEntry cursorState(HideCursorState::Idle); static ConfigEntry cursorHideTimeout(5); // 5 seconds (default) @@ -202,9 +215,7 @@ static ConfigEntry pipelineCacheArchive(false); // Debug static ConfigEntry isDebugDump(false); static ConfigEntry isShaderDebug(false); -static ConfigEntry isSeparateLogFilesEnabled(false); static ConfigEntry showFpsCounter(false); -static ConfigEntry logEnabled(true); // GUI static std::vector settings_install_dirs = {}; @@ -219,7 +230,7 @@ ConfigEntry m_language(1); // english static ConfigEntry usbDeviceBackend(UsbBackendType::Real); // Keys -static string trophyKey = ""; +static ConfigEntry trophyKey{}; // Config version, used to determine if a user's config file is outdated. static string config_version = Common::g_scm_rev; @@ -278,7 +289,7 @@ int* GetControllerCustomColor() { } bool getLoggingEnabled() { - return logEnabled.get(); + return logEnable.get(); } void SetControllerCustomColor(int r, int b, int g) { @@ -288,7 +299,7 @@ void SetControllerCustomColor(int r, int b, int g) { } string getTrophyKey() { - return trophyKey; + return trophyKey.get(); } void setTrophyKey(string key) { @@ -392,12 +403,30 @@ string getLogFilter() { return logFilter.get(); } +bool isLogSync() { + return logSync.get(); +} + +#ifdef _WIN32 string getLogType() { return logType.get(); } +#endif -bool groupIdenticalLogs() { - return isIdenticalLogGrouped.get(); +bool getLogSkipDuplicate() { + return logSkipDuplicate.get(); +} + +bool isLogAppend() { + return logAppend.get(); +} + +u32 getMaxSkipDuration() { + return logMaxSkipDuration.get(); +} + +unsigned long long getLogSizeLimit() { + return logSizeLimit.get(); } string getUserName() { @@ -481,7 +510,7 @@ void setShowFpsCounter(bool enable, bool is_game_specific) { } bool isLoggingEnabled() { - return logEnabled.get(); + return logEnable.get(); } u32 vblankFreq() { @@ -564,7 +593,7 @@ void setDebugDump(bool enable, bool is_game_specific) { } void setLoggingEnabled(bool enable, bool is_game_specific) { - logEnabled.set(enable, is_game_specific); + logEnable.set(enable, is_game_specific); } void setCollectShaderForDebug(bool enable, bool is_game_specific) { @@ -695,12 +724,30 @@ void setDevKitConsole(bool enable, bool is_game_specific) { isDevKit.set(enable, is_game_specific); } +void setLogSync(bool sync, bool is_game_specific) { + logSync.set(sync, is_game_specific); +} + +#ifdef _WIN32 void setLogType(const string& type, bool is_game_specific) { logType.set(type, is_game_specific); } +#endif -void setIdenticalLogGrouped(bool enable, bool is_game_specific) { - isIdenticalLogGrouped.set(enable, is_game_specific); +void setLogSkipDuplicate(bool enable, bool is_game_specific) { + logSkipDuplicate.set(enable, is_game_specific); +} + +void setMaxSkipDuration(u32 duration, bool is_game_specific) { + logMaxSkipDuration.set(duration, is_game_specific); +} + +void setLogSizeLimit(unsigned long long size, bool is_game_specific) { + logSizeLimit.set(size, is_game_specific); +} + +void setLogAppend(bool enable, bool is_game_specific) { + logAppend.set(enable, is_game_specific); } void setLogFilter(const string& type, bool is_game_specific) { @@ -708,7 +755,7 @@ void setLogFilter(const string& type, bool is_game_specific) { } void setSeparateLogFilesEnabled(bool enabled, bool is_game_specific) { - isSeparateLogFilesEnabled.set(enabled, is_game_specific); + logSeparate.set(enabled, is_game_specific); } void setUserName(const string& name, bool is_game_specific) { @@ -805,7 +852,7 @@ u32 GetLanguage() { } bool getSeparateLogFilesEnabled() { - return isSeparateLogFilesEnabled.get(); + return logSeparate.get(); } bool getPSNSignedIn() { @@ -880,7 +927,7 @@ void load(const std::filesystem::path& path, bool is_game_specific) { std::ifstream ifs; ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.open(path, std::ios_base::binary); - data = toml::parse(ifs, string{fmt::UTF(path.filename().u8string()).data}); + data = toml::parse(ifs, path.filename().string()); } catch (std::exception& ex) { fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); return; @@ -900,9 +947,6 @@ void load(const std::filesystem::path& path, bool is_game_specific) { trophyNotificationDuration.setFromToml(general, "trophyNotificationDuration", is_game_specific); enableDiscordRPC = toml::find_or(general, "enableDiscordRPC", enableDiscordRPC); - logFilter.setFromToml(general, "logFilter", is_game_specific); - logType.setFromToml(general, "logType", is_game_specific); - isIdenticalLogGrouped.setFromToml(general, "isIdenticalLogGrouped", is_game_specific); userName.setFromToml(general, "userName", is_game_specific); isShowSplash.setFromToml(general, "showSplash", is_game_specific); isSideTrophy.setFromToml(general, "sideTrophy", is_game_specific); @@ -913,6 +957,22 @@ void load(const std::filesystem::path& path, bool is_game_specific) { fonts_path = toml::find_fs_path_or(general, "fontsPath", fonts_path); } + if (data.contains("Log")) { + const toml::value& log = data.at("Log"); + + logFilter.setFromToml(log, "filter", is_game_specific); + logSkipDuplicate.setFromToml(log, "skipDuplicate", is_game_specific); + logSync.setFromToml(log, "sync", is_game_specific); +#ifdef _WIN32 + logType.setFromToml(log, "type", is_game_specific); +#endif + logAppend.setFromToml(log, "append", is_game_specific); + logSeparate.setFromToml(log, "separate", is_game_specific); + logEnable.setFromToml(log, "enable", is_game_specific); + logMaxSkipDuration.setFromToml(log, "maxSkipDuration", is_game_specific); + logSizeLimit.setFromToml(log, "sizeLimit", is_game_specific); + } + if (data.contains("Input")) { const toml::value& input = data.at("Input"); @@ -979,10 +1039,8 @@ void load(const std::filesystem::path& path, bool is_game_specific) { const toml::value& debug = data.at("Debug"); isDebugDump.setFromToml(debug, "DebugDump", is_game_specific); - isSeparateLogFilesEnabled.setFromToml(debug, "isSeparateLogFilesEnabled", is_game_specific); isShaderDebug.setFromToml(debug, "CollectShader", 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); } @@ -1022,7 +1080,7 @@ void load(const std::filesystem::path& path, bool is_game_specific) { if (data.contains("Keys")) { const toml::value& keys = data.at("Keys"); - trophyKey = toml::find_or(keys, "TrophyKey", trophyKey); + trophyKey = toml::find_or(keys, "TrophyKey", trophyKey.get()); } // Run save after loading to generate any missing fields with default values. @@ -1033,8 +1091,9 @@ void load(const std::filesystem::path& path, bool is_game_specific) { void sortTomlSections(toml::ordered_value& data) { toml::ordered_value ordered_data; - std::vector section_order = {"General", "Input", "Audio", "GPU", "Vulkan", - "Debug", "Keys", "GUI", "Settings"}; + std::vector section_order = {"General", "Log", "Input", "Audio", "GPU", + "Vulkan", "Debug", "Keys", "GUI", "Settings", + "keys"}; for (const auto& section : section_order) { if (data.contains(section)) { @@ -1071,8 +1130,7 @@ void save(const std::filesystem::path& path, bool is_game_specific) { std::ifstream ifs; ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.open(path, std::ios_base::binary); - data = toml::parse( - ifs, string{fmt::UTF(path.filename().u8string()).data}); + data = toml::parse(ifs, path.filename().string()); } catch (const std::exception& ex) { fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what()); return; @@ -1081,7 +1139,7 @@ void save(const std::filesystem::path& path, bool is_game_specific) { if (error) { fmt::print("Filesystem error: {}\n", error.message()); } - fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string())); + fmt::print("Saving new configuration file {}\n", path.string()); } // Entries saved by the game-specific settings GUI @@ -1089,9 +1147,6 @@ void save(const std::filesystem::path& path, bool is_game_specific) { isTrophyPopupDisabled.setTomlValue(data, "General", "isTrophyPopupDisabled", is_game_specific); trophyNotificationDuration.setTomlValue(data, "General", "trophyNotificationDuration", is_game_specific); - logFilter.setTomlValue(data, "General", "logFilter", is_game_specific); - logType.setTomlValue(data, "General", "logType", is_game_specific); - isIdenticalLogGrouped.setTomlValue(data, "General", "isIdenticalLogGrouped", is_game_specific); userName.setTomlValue(data, "General", "userName", is_game_specific); isShowSplash.setTomlValue(data, "General", "showSplash", is_game_specific); isSideTrophy.setTomlValue(data, "General", "sideTrophy", is_game_specific); @@ -1103,6 +1158,18 @@ void save(const std::filesystem::path& path, bool is_game_specific) { isPSNSignedIn.setTomlValue(data, "General", "isPSNSignedIn", is_game_specific); isConnectedToNetwork.setTomlValue(data, "General", "isConnectedToNetwork", is_game_specific); + logAppend.setTomlValue(data, "Log", "append", is_game_specific); + logEnable.setTomlValue(data, "Log", "enable", is_game_specific); + logFilter.setTomlValue(data, "Log", "filter", is_game_specific); + logMaxSkipDuration.setTomlValue(data, "Log", "maxSkipDuration", is_game_specific); + logSeparate.setTomlValue(data, "Log", "separate", is_game_specific); + logSizeLimit.setTomlValue(data, "Log", "sizeLimit", is_game_specific); + logSkipDuplicate.setTomlValue(data, "Log", "skipDuplicate", is_game_specific); + logSync.setTomlValue(data, "Log", "sync", is_game_specific); +#ifdef _WIN32 + logType.setTomlValue(data, "Log", "type", is_game_specific); +#endif + cursorState.setTomlValue(data, "Input", "cursorState", is_game_specific); cursorHideTimeout.setTomlValue(data, "Input", "cursorHideTimeout", is_game_specific); isMotionControlsEnabled.setTomlValue(data, "Input", "isMotionControlsEnabled", @@ -1146,12 +1213,11 @@ void save(const std::filesystem::path& path, bool is_game_specific) { isDebugDump.setTomlValue(data, "Debug", "DebugDump", is_game_specific); isShaderDebug.setTomlValue(data, "Debug", "CollectShader", is_game_specific); - isSeparateLogFilesEnabled.setTomlValue(data, "Debug", "isSeparateLogFilesEnabled", - is_game_specific); - logEnabled.setTomlValue(data, "Debug", "logEnabled", is_game_specific); m_language.setTomlValue(data, "Settings", "consoleLanguage", is_game_specific); + trophyKey.setTomlValue(data, "Keys", "TrophyKey", is_game_specific); + if (!is_game_specific) { std::vector install_dirs; std::vector install_dirs_enabled; @@ -1164,8 +1230,7 @@ void save(const std::filesystem::path& path, bool is_game_specific) { std::vector sorted_dirs; for (const auto& dirInfo : settings_install_dirs) { - sorted_dirs.push_back( - {string{fmt::UTF(dirInfo.path.u8string()).data}, dirInfo.enabled}); + sorted_dirs.push_back({dirInfo.path.string(), dirInfo.enabled}); } // Sort directories alphabetically @@ -1184,15 +1249,14 @@ void save(const std::filesystem::path& path, bool is_game_specific) { // Non game-specific entries data["General"]["enableDiscordRPC"] = enableDiscordRPC; - data["General"]["sysModulesPath"] = string{fmt::UTF(sys_modules_path.u8string()).data}; - data["General"]["fontsPath"] = string{fmt::UTF(fonts_path.u8string()).data}; + data["General"]["sysModulesPath"] = sys_modules_path.string(); + data["General"]["fontsPath"] = fonts_path.string(); data["GUI"]["installDirs"] = install_dirs; data["GUI"]["installDirsEnabled"] = install_dirs_enabled; - data["GUI"]["saveDataPath"] = string{fmt::UTF(save_data_path.u8string()).data}; - data["GUI"]["addonInstallDir"] = - string{fmt::UTF(settings_addon_install_dir.u8string()).data}; + data["GUI"]["saveDataPath"] = save_data_path.string(); + data["GUI"]["addonInstallDir"] = settings_addon_install_dir.string(); data["Debug"]["ConfigVersion"] = config_version; - data["Keys"]["TrophyKey"] = trophyKey; + data["Keys"]["TrophyKey"] = trophyKey.get(); // Do not save these entries in the game-specific dialog since they are not in the GUI data["General"]["defaultControllerID"] = defaultControllerID.base_value; @@ -1233,13 +1297,23 @@ void setDefaultValues(bool is_game_specific) { volumeSlider.set(100, is_game_specific); isTrophyPopupDisabled.set(false, is_game_specific); trophyNotificationDuration.set(6.0, is_game_specific); - logFilter.set("", is_game_specific); - logType.set("sync", is_game_specific); - isIdenticalLogGrouped.set("isIdenticalLogGrouped", is_game_specific); userName.set("shadPS4", is_game_specific); isShowSplash.set(false, is_game_specific); isSideTrophy.set("right", is_game_specific); + // GS - Log + logFilter.set("", is_game_specific); + logSync.set(true, is_game_specific); +#ifdef _WIN32 + logType.set("wincolor", is_game_specific); +#endif + logSkipDuplicate.set(true, is_game_specific); + logAppend.set(false, is_game_specific); + logSeparate.set(false, is_game_specific); + logEnable.set(true, is_game_specific); + logMaxSkipDuration.set(5'000, is_game_specific); + logSizeLimit.set(100_MB, is_game_specific); + // GS - Input cursorState.set(HideCursorState::Idle, is_game_specific); cursorHideTimeout.set(5, is_game_specific); @@ -1281,8 +1355,6 @@ void setDefaultValues(bool is_game_specific) { // GS - Debug isDebugDump.set(false, is_game_specific); isShaderDebug.set(false, is_game_specific); - isSeparateLogFilesEnabled.set(false, is_game_specific); - logEnabled.set(true, is_game_specific); // GS - Settings m_language.set(1, is_game_specific); diff --git a/src/common/config.h b/src/common/config.h index b341030e09a..41bd3732674 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -105,10 +105,20 @@ bool isPipelineCacheArchived(); void setRdocEnabled(bool enable, bool is_game_specific = false); void setPipelineCacheEnabled(bool enable, bool is_game_specific = false); void setPipelineCacheArchived(bool enable, bool is_game_specific = false); +bool isLogSync(); +void setLogSync(bool sync, bool is_game_specific = false); +#ifdef _WIN32 std::string getLogType(); void setLogType(const std::string& type, bool is_game_specific = false); -bool groupIdenticalLogs(); -void setGroupIdenticalLogs(bool enable, bool is_game_specific = false); +#endif +bool getLogSkipDuplicate(); +void setLogSkipDuplicate(bool enable, bool is_game_specific = false); +u32 getMaxSkipDuration(); +void setMaxSkipDuration(u32 duration, bool is_game_specific = false); +unsigned long long getLogSizeLimit(); +void setLogSizeLimit(unsigned long long size, bool is_game_specific = false); +bool isLogAppend(); +void setLogAppend(bool enable, bool is_game_specific = false); std::string getLogFilter(); void setLogFilter(const std::string& type, bool is_game_specific = false); double getTrophyNotificationDuration(); diff --git a/src/common/key_manager.cpp b/src/common/key_manager.cpp index cd0f668bf85..b03bfe3f518 100644 --- a/src/common/key_manager.cpp +++ b/src/common/key_manager.cpp @@ -20,18 +20,6 @@ KeyManager::~KeyManager() { SaveToFile(); } -std::shared_ptr KeyManager::GetInstance() { - std::lock_guard lock(s_mutex); - if (!s_instance) - s_instance = std::make_shared(); - return s_instance; -} - -void KeyManager::SetInstance(std::shared_ptr instance) { - std::lock_guard lock(s_mutex); - s_instance = instance; -} - // ------------------- Load / Save ------------------- bool KeyManager::LoadFromFile() { try { diff --git a/src/common/key_manager.h b/src/common/key_manager.h index 8925ccbd0ad..79dc16d3dfd 100644 --- a/src/common/key_manager.h +++ b/src/common/key_manager.h @@ -29,10 +29,6 @@ class KeyManager { KeyManager(); ~KeyManager(); - // ------------------- Singleton ------------------- - static std::shared_ptr GetInstance(); - static void SetInstance(std::shared_ptr instance); - // ------------------- File operations ------------------- bool LoadFromFile(); bool SaveToFile(); diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp deleted file mode 100644 index 5de4f64a08a..00000000000 --- a/src/common/logging/backend.cpp +++ /dev/null @@ -1,396 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include - -#include - -#ifdef _WIN32 -#include // For OutputDebugStringW -#endif - -#include "common/bounded_threadsafe_queue.h" -#include "common/debug.h" -#include "common/io_file.h" -#include "common/logging/backend.h" -#include "common/logging/log.h" -#include "common/logging/log_entry.h" -#include "common/logging/text_formatter.h" -#include "common/path_util.h" -#include "common/string_util.h" -#include "common/thread.h" -#include "core/emulator_settings.h" - -namespace Common::Log { - -using namespace Common::FS; - -namespace { - -/** - * Backend that writes to stderr and with color - */ -class ColorConsoleBackend { -public: - explicit ColorConsoleBackend() = default; - - ~ColorConsoleBackend() = default; - - void Write(const Entry& entry) { - if (enabled.load(std::memory_order_relaxed)) { - PrintColoredMessage(entry); - } - } - - void Flush() { - // stderr shouldn't be buffered - } - - void SetEnabled(bool enabled_) { - enabled = enabled_; - } - -private: - std::atomic_bool enabled{true}; -}; - -/** - * Backend that writes to a file passed into the constructor - */ -class FileBackend { -public: - explicit FileBackend(const std::filesystem::path& filename, bool should_append = false) - : file{filename, should_append ? FS::FileAccessMode::Append : FS::FileAccessMode::Create, - FS::FileType::TextFile} {} - - ~FileBackend() = default; - - void Write(const Entry& entry) { - if (!enabled && entry.log_level != Level::Critical) { - return; - } - - bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n')); - - // Prevent logs from exceeding a set maximum size in the event that log entries are spammed. - const auto write_limit = 100_MB; - const bool write_limit_exceeded = bytes_written > write_limit; - if (entry.log_level >= Level::Error || write_limit_exceeded) { - if (write_limit_exceeded) { - // Stop writing after the write limit is exceeded. - // Don't close the file so we can print a stacktrace if necessary - enabled = false; - } - file.Flush(); - } - } - - void Flush() { - file.Flush(); - } - -private: - Common::FS::IOFile file; - bool enabled = true; - std::size_t bytes_written = 0; -}; - -#ifdef _WIN32 -/** - * Backend that writes to Visual Studio's output window - */ -class DebuggerBackend { -public: - explicit DebuggerBackend() = default; - - ~DebuggerBackend() = default; - - void Write(const Entry& entry) { - ::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str()); - } - - void Flush() {} - - void EnableForStacktrace() {} -}; -#endif - -bool initialization_in_progress_suppress_logging = true; - -/** - * Static state as a singleton. - */ -class Impl { -public: - static Impl& Instance() { - if (!instance) { - throw std::runtime_error("Using Logging instance before its initialization"); - } - return *instance; - } - - static void Initialize(std::string_view log_file) { - if (instance) { - LOG_WARNING(Log, "Reinitializing logging backend"); - return; - } - const auto& log_dir = GetUserPath(PathType::LogDir); - std::filesystem::create_directory(log_dir); - Filter filter; - filter.ParseFilterString(EmulatorSettings.GetLogFilter()); - const auto& log_file_path = log_file.empty() ? LOG_FILE : log_file; - instance = std::unique_ptr( - new Impl(log_dir / log_file_path, filter), Deleter); - initialization_in_progress_suppress_logging = false; - } - - static void ResetInstance() { - initialization_in_progress_suppress_logging = true; - instance.reset(); - } - - static bool IsActive() { - return instance != nullptr; - } - - static void Start() { - instance->StartBackendThread(); - } - - static void Stop() { - instance->StopBackendThread(); - } - - static void SetAppend() { - should_append = true; - } - - Impl(const Impl&) = delete; - Impl& operator=(const Impl&) = delete; - - Impl(Impl&&) = delete; - Impl& operator=(Impl&&) = delete; - - void SetGlobalFilter(const Filter& f) { - filter = f; - } - - void SetColorConsoleBackendEnabled(bool enabled) { - color_console_backend.SetEnabled(enabled); - } - - void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, - const char* function, const char* format, const fmt::format_args& args) { - if (!filter.CheckMessage(log_class, log_level) || !EmulatorSettings.IsLogEnabled()) { - return; - } - - const auto message = fmt::vformat(format, args); - - // Propagate important log messages to the profiler - if (IsProfilerConnected()) { - const auto& msg_str = fmt::format("[{}] {}", GetLogClassName(log_class), message); - switch (log_level) { - case Level::Warning: - TRACE_WARN(msg_str); - break; - case Level::Error: - TRACE_ERROR(msg_str); - break; - case Level::Critical: - TRACE_CRIT(msg_str); - break; - default: - break; - } - } - - using std::chrono::duration_cast; - using std::chrono::microseconds; - using std::chrono::steady_clock; - - if (EmulatorSettings.IsIdenticalLogGrouped()) { - std::unique_lock entry_loc(_mutex); - - if (_last_entry.message == message) { - ++_last_entry.counter; - return; - } - - if (_last_entry.counter >= 2) { - _last_entry.message += " x" + std::to_string(_last_entry.counter); - } - - if (_last_entry.counter >= 1) { - if (EmulatorSettings.GetLogType() == "async") { - message_queue.EmplaceWait(_last_entry); - } else { - ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); }); - std::fflush(stdout); - } - } - - this->_last_entry = { - .timestamp = duration_cast(steady_clock::now() - time_origin), - .log_class = log_class, - .log_level = log_level, - .filename = filename, - .line_num = line_num, - .function = function, - .message = message, - .thread = Common::GetCurrentThreadName(), - .counter = 1, - }; - } else { - const Entry entry = { - .timestamp = duration_cast(steady_clock::now() - time_origin), - .log_class = log_class, - .log_level = log_level, - .filename = filename, - .line_num = line_num, - .function = function, - .message = message, - .thread = Common::GetCurrentThreadName(), - .counter = 1, - }; - - if (EmulatorSettings.GetLogType() == "async") { - message_queue.EmplaceWait(entry); - } else { - ForEachBackend([&entry](auto& backend) { backend.Write(entry); }); - std::fflush(stdout); - } - } - } - -private: - Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) - : filter{filter_}, file_backend{file_backend_filename, should_append} {} - - ~Impl() = default; - - void StartBackendThread() { - backend_thread = std::jthread([this](std::stop_token stop_token) { - Common::SetCurrentThreadName("shadPS4:Log"); - Entry entry; - const auto write_logs = [this, &entry]() { - ForEachBackend([&entry](auto& backend) { backend.Write(entry); }); - }; - while (!stop_token.stop_requested()) { - message_queue.PopWait(entry, stop_token); - if (entry.filename != nullptr) { - write_logs(); - } - } - // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a - // case where a system is repeatedly spamming logs even on close. - int max_logs_to_write = filter.IsDebug() ? std::numeric_limits::max() : 100; - while (max_logs_to_write-- && message_queue.TryPop(entry)) { - write_logs(); - } - }); - } - - void StopBackendThread() { - if (EmulatorSettings.IsIdenticalLogGrouped()) { - // log last message - if (_last_entry.counter >= 2) { - _last_entry.message += " x" + std::to_string(_last_entry.counter); - } - - if (_last_entry.counter >= 1) { - if (EmulatorSettings.GetLogType() == "async") { - message_queue.EmplaceWait(_last_entry); - } else { - ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); }); - std::fflush(stdout); - } - } - - this->_last_entry = {}; - } - - backend_thread.request_stop(); - if (backend_thread.joinable()) { - backend_thread.join(); - } - - ForEachBackend([](auto& backend) { backend.Flush(); }); - } - - void ForEachBackend(auto lambda) { -#ifdef _WIN32 - lambda(debugger_backend); -#endif - lambda(color_console_backend); - lambda(file_backend); - } - - static void Deleter(Impl* ptr) { - delete ptr; - } - - static inline std::unique_ptr instance{nullptr, Deleter}; - static inline bool should_append{false}; - - Filter filter; -#ifdef _WIN32 - DebuggerBackend debugger_backend{}; -#endif - ColorConsoleBackend color_console_backend{}; - FileBackend file_backend; - - MPSCQueue message_queue{}; - std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; - std::jthread backend_thread; - Entry _last_entry; - std::mutex _mutex; -}; -} // namespace - -void Initialize(std::string_view log_file) { - Impl::Initialize(log_file.empty() ? LOG_FILE : log_file); -} - -bool IsActive() { - return Impl::IsActive(); -} - -void Start() { - Impl::Start(); -} - -void Stop() { - Impl::Stop(); -} - -void Denitializer() { - Impl::Stop(); - Impl::ResetInstance(); -} - -void SetGlobalFilter(const Filter& filter) { - Impl::Instance().SetGlobalFilter(filter); -} - -void SetColorConsoleBackendEnabled(bool enabled) { - Impl::Instance().SetColorConsoleBackendEnabled(enabled); -} - -void SetAppend() { - Impl::SetAppend(); -} - -void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, - unsigned int line_num, const char* function, const char* format, - const fmt::format_args& args) { - if (!initialization_in_progress_suppress_logging) [[likely]] { - Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, format, - args); - } -} -} // namespace Common::Log diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h deleted file mode 100644 index 3003d1eaeb9..00000000000 --- a/src/common/logging/backend.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "common/logging/filter.h" - -namespace Common::Log { - -class Filter; - -/// Initializes the logging system. This should be the first thing called in main. -void Initialize(std::string_view log_file = ""); - -bool IsActive(); - -/// Starts the logging threads. -void Start(); - -/// Explictily stops the logger thread and flushes the buffers -void Stop(); - -/// Closes log files and stops the logger -void Denitializer(); - -/// The global filter will prevent any messages from even being processed if they are filtered. -void SetGlobalFilter(const Filter& filter); - -void SetColorConsoleBackendEnabled(bool enabled); - -void SetAppend(); - -} // namespace Common::Log diff --git a/src/common/logging/classes.h b/src/common/logging/classes.h new file mode 100644 index 00000000000..c068a50a63e --- /dev/null +++ b/src/common/logging/classes.h @@ -0,0 +1,219 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +namespace Common::Log { +// clang-format off +/// Llisting all log classes, if you add here, dont forget ALL_LOG_CLASSES +constexpr auto Log = "Log"; +constexpr auto Common = "Common"; +constexpr auto Common_Filesystem = "Common.Filesystem"; +constexpr auto Common_Memory = "Common.Memory"; +constexpr auto Core = "Core"; +constexpr auto Core_Linker = "Core.Linker"; +constexpr auto Core_Devices = "Core.Devices"; +constexpr auto Config = "Config"; +constexpr auto Debug = "Debug"; +constexpr auto Kernel = "Kernel"; +constexpr auto Kernel_Pthread = "Kernel.Pthread"; +constexpr auto Kernel_Vmm = "Kernel.Vmm"; +constexpr auto Kernel_Fs = "Kernel.Fs"; +constexpr auto Kernel_Event = "Kernel.Event"; +constexpr auto Kernel_Sce = "Kernel.Sce"; +constexpr auto Lib = "Lib"; +constexpr auto Lib_LibC = "Lib.LibC"; +constexpr auto Lib_LibcInternal = "Lib.LibcInternal"; +constexpr auto Lib_Kernel = "Lib.Kernel"; +constexpr auto Lib_Pad = "Lib.Pad"; +constexpr auto Lib_SystemGesture = "Lib.SystemGesture"; +constexpr auto Lib_GnmDriver = "Lib.GnmDriver"; +constexpr auto Lib_SystemService = "Lib.SystemService"; +constexpr auto Lib_UserService = "Lib.UserService"; +constexpr auto Lib_VideoOut = "Lib.VideoOut"; +constexpr auto Lib_CommonDlg = "Lib.CommonDlg"; +constexpr auto Lib_MsgDlg = "Lib.MsgDlg"; +constexpr auto Lib_AudioOut = "Lib.AudioOut"; +constexpr auto Lib_AudioIn = "Lib.AudioIn"; +constexpr auto Lib_Net = "Lib.Net"; +constexpr auto Lib_NetCtl = "Lib.NetCtl"; +constexpr auto Lib_SaveData = "Lib.SaveData"; +constexpr auto Lib_SaveDataDialog = "Lib.SaveDataDialog"; +constexpr auto Lib_Http = "Lib.Http"; +constexpr auto Lib_Http2 = "Lib.Http2"; +constexpr auto Lib_Ssl = "Lib.Ssl"; +constexpr auto Lib_Ssl2 = "Lib.Ssl2"; +constexpr auto Lib_SysModule = "Lib.SysModule"; +constexpr auto Lib_Move = "Lib.Move"; +constexpr auto Lib_NpAuth = "Lib.NpAuth"; +constexpr auto Lib_NpCommon = "Lib.NpCommon"; +constexpr auto Lib_NpCommerce = "Lib.NpCommerce"; +constexpr auto Lib_NpManager = "Lib.NpManager"; +constexpr auto Lib_NpMatching2 = "Lib.NpMatching2"; +constexpr auto Lib_NpScore = "Lib.NpScore"; +constexpr auto Lib_NpTrophy = "Lib.NpTrophy"; +constexpr auto Lib_NpTus = "Lib.NpTus"; +constexpr auto Lib_NpWebApi = "Lib.NpWebApi"; +constexpr auto Lib_NpWebApi2 = "Lib.NpWebApi2"; +constexpr auto Lib_NpProfileDialog = "Lib.NpProfileDialog"; +constexpr auto Lib_NpSnsFacebookDialog = "Lib.NpSnsFacebookDialog"; +constexpr auto Lib_NpPartner = "Lib.NpPartner"; +constexpr auto Lib_Screenshot = "Lib.Screenshot"; +constexpr auto Lib_LibCInternal = "Lib.LibCInternal"; +constexpr auto Lib_AppContent = "Lib.AppContent"; +constexpr auto Lib_Rtc = "Lib.Rtc"; +constexpr auto Lib_Rudp = "Lib.Rudp"; +constexpr auto Lib_DiscMap = "Lib.DiscMap"; +constexpr auto Lib_Png = "Lib.Png"; +constexpr auto Lib_Jpeg = "Lib.Jpeg"; +constexpr auto Lib_PlayGo = "Lib.PlayGo"; +constexpr auto Lib_PlayGoDialog = "Lib.PlayGoDialog"; +constexpr auto Lib_Random = "Lib.Random"; +constexpr auto Lib_Usbd = "Lib.Usbd"; +constexpr auto Lib_Ajm = "Lib.Ajm"; +constexpr auto Lib_ErrorDialog = "Lib.ErrorDialog"; +constexpr auto Lib_ImeDialog = "Lib.ImeDialog"; +constexpr auto Lib_AvPlayer = "Lib.AvPlayer"; +constexpr auto Lib_Ngs2 = "Lib.Ngs2"; +constexpr auto Lib_Audio3d = "Lib.Audio3d"; +constexpr auto Lib_Ime = "Lib.Ime"; +constexpr auto Lib_GameLiveStreaming = "Lib.GameLiveStreaming"; +constexpr auto Lib_Remoteplay = "Lib.Remoteplay"; +constexpr auto Lib_SharePlay = "Lib.SharePlay"; +constexpr auto Lib_Fiber = "Lib.Fiber"; +constexpr auto Lib_Vdec2 = "Lib.Vdec2"; +constexpr auto Lib_Videodec = "Lib.Videodec"; +constexpr auto Lib_RazorCpu = "Lib.RazorCpu"; +constexpr auto Lib_Mouse = "Lib.Mouse"; +constexpr auto Lib_WebBrowserDialog = "Lib.WebBrowserDialog"; +constexpr auto Lib_NpParty = "Lib.NpParty"; +constexpr auto Lib_Zlib = "Lib.Zlib"; +constexpr auto Lib_Hmd = "Lib.Hmd"; +constexpr auto Lib_Font = "Lib.Font"; +constexpr auto Lib_FontFt = "Lib.FontFt"; +constexpr auto Lib_HmdSetupDialog = "Lib.HmdSetupDialog"; +constexpr auto Lib_SigninDialog = "Lib.SigninDialog"; +constexpr auto Lib_Camera = "Lib.Camera"; +constexpr auto Lib_CompanionHttpd = "Lib.CompanionHttpd"; +constexpr auto Lib_CompanionUtil = "Lib.CompanionUtil"; +constexpr auto Lib_Voice = "Lib.Voice"; +constexpr auto Lib_VrTracker = "Lib.VrTracker"; +constexpr auto Frontend = "Frontend"; +constexpr auto Render = "Render"; +constexpr auto Render_Vulkan = "Render.Vulkan"; +constexpr auto Render_Recompiler = "Render.Recompiler"; +constexpr auto ImGui = "ImGui"; +constexpr auto Input = "Input"; +constexpr auto Tty = "Tty"; +constexpr auto IPC = "IPC"; +constexpr auto KeyManager = "KeyManager"; +constexpr auto Loader = "Loader"; +// clang-format on + +constexpr std::array ALL_LOG_CLASSES{ + Log, + Common, + Common_Filesystem, + Common_Memory, + Core, + Core_Linker, + Core_Devices, + Config, + Debug, + Kernel, + Kernel_Pthread, + Kernel_Vmm, + Kernel_Fs, + Kernel_Event, + Kernel_Sce, + Lib, + Lib_LibC, + Lib_LibcInternal, + Lib_Kernel, + Lib_Pad, + Lib_SystemGesture, + Lib_GnmDriver, + Lib_SystemService, + Lib_UserService, + Lib_VideoOut, + Lib_CommonDlg, + Lib_MsgDlg, + Lib_AudioOut, + Lib_AudioIn, + Lib_Net, + Lib_NetCtl, + Lib_SaveData, + Lib_SaveDataDialog, + Lib_Http, + Lib_Http2, + Lib_Ssl, + Lib_Ssl2, + Lib_SysModule, + Lib_Move, + Lib_NpAuth, + Lib_NpCommon, + Lib_NpCommerce, + Lib_NpManager, + Lib_NpMatching2, + Lib_NpScore, + Lib_NpTrophy, + Lib_NpTus, + Lib_NpWebApi, + Lib_NpWebApi2, + Lib_NpProfileDialog, + Lib_NpSnsFacebookDialog, + Lib_NpPartner, + Lib_Screenshot, + Lib_LibCInternal, + Lib_AppContent, + Lib_Rtc, + Lib_Rudp, + Lib_DiscMap, + Lib_Png, + Lib_Jpeg, + Lib_PlayGo, + Lib_PlayGoDialog, + Lib_Random, + Lib_Usbd, + Lib_Ajm, + Lib_ErrorDialog, + Lib_ImeDialog, + Lib_AvPlayer, + Lib_Ngs2, + Lib_Audio3d, + Lib_Ime, + Lib_GameLiveStreaming, + Lib_Remoteplay, + Lib_SharePlay, + Lib_Fiber, + Lib_Vdec2, + Lib_Videodec, + Lib_RazorCpu, + Lib_Mouse, + Lib_WebBrowserDialog, + Lib_NpParty, + Lib_Zlib, + Lib_Hmd, + Lib_Font, + Lib_FontFt, + Lib_HmdSetupDialog, + Lib_SigninDialog, + Lib_Camera, + Lib_CompanionHttpd, + Lib_CompanionUtil, + Lib_Voice, + Lib_VrTracker, + Frontend, + Render, + Render_Vulkan, + Render_Recompiler, + ImGui, + Input, + Tty, + IPC, + KeyManager, + Loader, +}; +} // namespace Common::Log diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp deleted file mode 100644 index fd48faf72aa..00000000000 --- a/src/common/logging/filter.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#include "common/assert.h" -#include "common/logging/filter.h" - -namespace Common::Log { -namespace { -template -Level GetLevelByName(const It begin, const It end) { - for (u8 i = 0; i < static_cast(Level::Count); ++i) { - const char* level_name = GetLevelName(static_cast(i)); - if (std::string_view(begin, end).compare(level_name) == 0) { - return static_cast(i); - } - } - return Level::Count; -} - -template -Class GetClassByName(const It begin, const It end) { - for (u8 i = 0; i < static_cast(Class::Count); ++i) { - const char* level_name = GetLogClassName(static_cast(i)); - if (std::string_view(begin, end).compare(level_name) == 0) { - return static_cast(i); - } - } - return Class::Count; -} - -template -bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { - auto level_separator = std::find(begin, end, ':'); - if (level_separator == end) { - LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}", - std::string_view(begin, end)); - return false; - } - - const Level level = GetLevelByName(level_separator + 1, end); - if (level == Level::Count) { - LOG_ERROR(Log, "Unknown log level in filter: {}", std::string_view(begin, end)); - return false; - } - - if (std::string_view(begin, level_separator).compare("*") == 0) { - instance.ResetAll(level); - return true; - } - - const Class log_class = GetClassByName(begin, level_separator); - if (log_class == Class::Count) { - LOG_ERROR(Log, "Unknown log class in filter: {}", std::string(begin, end)); - return false; - } - - instance.SetClassLevel(log_class, level); - return true; -} -} // Anonymous namespace - -/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. -#define ALL_LOG_CLASSES() \ - CLS(Log) \ - CLS(Common) \ - SUB(Common, Filesystem) \ - SUB(Common, Memory) \ - CLS(KeyManager) \ - CLS(Core) \ - SUB(Core, Linker) \ - SUB(Core, Devices) \ - CLS(Config) \ - CLS(Debug) \ - CLS(Kernel) \ - SUB(Kernel, Pthread) \ - SUB(Kernel, Vmm) \ - SUB(Kernel, Fs) \ - SUB(Kernel, Event) \ - SUB(Kernel, Sce) \ - CLS(Lib) \ - SUB(Lib, LibcInternal) \ - SUB(Lib, Kernel) \ - SUB(Lib, Pad) \ - SUB(Lib, SystemGesture) \ - SUB(Lib, GnmDriver) \ - SUB(Lib, SystemService) \ - SUB(Lib, UserService) \ - SUB(Lib, VideoOut) \ - SUB(Lib, CommonDlg) \ - SUB(Lib, MsgDlg) \ - SUB(Lib, AudioOut) \ - SUB(Lib, AudioIn) \ - SUB(Lib, Net) \ - SUB(Lib, NetCtl) \ - SUB(Lib, SaveData) \ - SUB(Lib, SaveDataDialog) \ - SUB(Lib, Http) \ - SUB(Lib, Http2) \ - SUB(Lib, Ssl) \ - SUB(Lib, Ssl2) \ - SUB(Lib, SysModule) \ - SUB(Lib, Move) \ - SUB(Lib, NpAuth) \ - SUB(Lib, NpCommon) \ - SUB(Lib, NpCommerce) \ - SUB(Lib, NpManager) \ - SUB(Lib, NpMatching2) \ - SUB(Lib, NpScore) \ - SUB(Lib, NpTrophy) \ - SUB(Lib, NpTus) \ - SUB(Lib, NpWebApi) \ - SUB(Lib, NpWebApi2) \ - SUB(Lib, NpProfileDialog) \ - SUB(Lib, NpSnsFacebookDialog) \ - SUB(Lib, NpPartner) \ - SUB(Lib, Screenshot) \ - SUB(Lib, AppContent) \ - SUB(Lib, Rtc) \ - SUB(Lib, Rudp) \ - SUB(Lib, DiscMap) \ - SUB(Lib, Png) \ - SUB(Lib, Jpeg) \ - SUB(Lib, PlayGo) \ - SUB(Lib, PlayGoDialog) \ - SUB(Lib, Random) \ - SUB(Lib, Usbd) \ - SUB(Lib, Ajm) \ - SUB(Lib, ErrorDialog) \ - SUB(Lib, ImeDialog) \ - SUB(Lib, AvPlayer) \ - SUB(Lib, Ngs2) \ - SUB(Lib, Audio3d) \ - SUB(Lib, Ime) \ - SUB(Lib, GameLiveStreaming) \ - SUB(Lib, Remoteplay) \ - SUB(Lib, SharePlay) \ - SUB(Lib, Fiber) \ - SUB(Lib, Vdec2) \ - SUB(Lib, Videodec) \ - SUB(Lib, RazorCpu) \ - SUB(Lib, Mouse) \ - SUB(Lib, WebBrowserDialog) \ - SUB(Lib, NpParty) \ - SUB(Lib, Zlib) \ - SUB(Lib, Hmd) \ - SUB(Lib, Font) \ - SUB(Lib, FontFt) \ - SUB(Lib, HmdSetupDialog) \ - SUB(Lib, SigninDialog) \ - SUB(Lib, Camera) \ - SUB(Lib, CompanionHttpd) \ - SUB(Lib, CompanionUtil) \ - SUB(Lib, Voice) \ - SUB(Lib, VrTracker) \ - CLS(Frontend) \ - CLS(Render) \ - SUB(Render, Vulkan) \ - SUB(Render, Recompiler) \ - CLS(ImGui) \ - CLS(Input) \ - CLS(Tty) \ - CLS(Loader) - -// GetClassName is a macro defined by Windows.h, grrr... -const char* GetLogClassName(Class log_class) { - switch (log_class) { -#define CLS(x) \ - case Class::x: \ - return #x; -#define SUB(x, y) \ - case Class::x##_##y: \ - return #x "." #y; - ALL_LOG_CLASSES() -#undef CLS -#undef SUB - case Class::Count: - default: - break; - } - UNREACHABLE(); -} - -const char* GetLevelName(Level log_level) { -#define LVL(x) \ - case Level::x: \ - return #x - switch (log_level) { - LVL(Trace); - LVL(Debug); - LVL(Info); - LVL(Warning); - LVL(Error); - LVL(Critical); - case Level::Count: - default: - break; - } -#undef LVL - UNREACHABLE(); -} - -Filter::Filter(Level default_level) { - ResetAll(default_level); -} - -void Filter::ResetAll(Level level) { - class_levels.fill(level); -} - -void Filter::SetClassLevel(Class log_class, Level level) { - class_levels[static_cast(log_class)] = level; -} - -void Filter::ParseFilterString(std::string_view filter_view) { - auto clause_begin = filter_view.cbegin(); - while (clause_begin != filter_view.cend()) { - auto clause_end = std::find(clause_begin, filter_view.cend(), ' '); - - // If clause isn't empty - if (clause_end != clause_begin) { - ParseFilterRule(*this, clause_begin, clause_end); - } - - if (clause_end != filter_view.cend()) { - // Skip over the whitespace - ++clause_end; - } - clause_begin = clause_end; - } -} - -bool Filter::CheckMessage(Class log_class, Level level) const { - return static_cast(level) >= - static_cast(class_levels[static_cast(log_class)]); -} - -bool Filter::IsDebug() const { - return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) { - return static_cast(l) <= static_cast(Level::Debug); - }); -} - -} // namespace Common::Log diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h deleted file mode 100644 index 7c46fd8221f..00000000000 --- a/src/common/logging/filter.h +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include "common/logging/types.h" - -namespace Common::Log { - -/** - * Returns the name of the passed log class as a C-string. Subclasses are separated by periods - * instead of underscores as in the enumeration. - */ -const char* GetLogClassName(Class log_class); - -/** - * Returns the name of the passed log level as a C-string. - */ -const char* GetLevelName(Level log_level); - -/** - * Implements a log message filter which allows different log classes to have different minimum - * severity levels. The filter can be changed at runtime and can be parsed from a string to allow - * editing via the interface or loading from a configuration file. - */ -class Filter { -public: - /// Initializes the filter with all classes having `default_level` as the minimum level. - explicit Filter(Level default_level = Level::Info); - - /// Resets the filter so that all classes have `level` as the minimum displayed level. - void ResetAll(Level level); - - /// Sets the minimum level of `log_class` (and not of its subclasses) to `level`. - void SetClassLevel(Class log_class, Level level); - - /** - * Parses a filter string and applies it to this filter. - * - * A filter string consists of a space-separated list of filter rules, each of the format - * `:`. `` is a log class name, with subclasses separated using periods. - * `*` is allowed as a class name and will reset all filters to the specified level. `` - * a severity level name which will be set as the minimum logging level of the matched classes. - * Rules are applied left to right, with each rule overriding previous ones in the sequence. - * - * A few examples of filter rules: - * - `*:Info` -- Resets the level of all classes to Info. - * - `Service:Info` -- Sets the level of Service to Info. - * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. - */ - void ParseFilterString(std::string_view filter_view); - - /// Matches class/level combination against the filter, returning true if it passed. - bool CheckMessage(Class log_class, Level level) const; - - /// Returns true if any logging classes are set to debug - bool IsDebug() const; - -private: - std::array(Class::Count)> class_levels; -}; - -} // namespace Common::Log diff --git a/src/common/logging/formatter.h b/src/common/logging/formatter.h deleted file mode 100644 index fad8451e9bb..00000000000 --- a/src/common/logging/formatter.h +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -// Adapted from https://github.com/fmtlib/fmt/issues/2704 -// a generic formatter for enum classes -#if FMT_VERSION >= 80100 -template -struct fmt::formatter, char>> - : formatter> { - template - auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) { - return fmt::formatter>::format( - static_cast>(value), ctx); - } -}; -#endif - -namespace fmt { -template -struct UTF { - T data; - - explicit UTF(const std::u8string_view view) { - data = view.empty() ? T{} : T{(const char*)&view.front(), (const char*)&view.back() + 1}; - } - - explicit UTF(const std::u8string& str) : UTF(std::u8string_view{str}) {} -}; -} // namespace fmt - -template <> -struct fmt::formatter, char> : formatter { - template - auto format(const UTF& wrapper, FormatContext& ctx) const { - return formatter::format(wrapper.data, ctx); - } -}; \ No newline at end of file diff --git a/src/common/logging/log.cpp b/src/common/logging/log.cpp new file mode 100644 index 00000000000..3b7430d409b --- /dev/null +++ b/src/common/logging/log.cpp @@ -0,0 +1,112 @@ +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "log.h" +#include "common/config.h" +#include "core/emulator_settings.h" +#include "common/types.h" +#include "shadps4_app.h" + +#include +#include + +namespace Common::Log { +std::shared_ptr g_console_sink; +std::shared_ptr g_shad_file_sink; +std::shared_ptr g_game_file_sink; +bool g_should_append = false; + +void Setup(int argc, char* argv[]) { + if (EmulatorSettings.IsLogEnable()) { + spdlog::cfg::load_env_levels(); + spdlog::cfg::helpers::load_levels(EmulatorSettings.GetLogFilter()); + spdlog::cfg::load_argv_levels(argc, argv); + } else { + spdlog::cfg::helpers::load_levels("off"); + } + + if (!EmulatorSettings.IsLogSync()) { + spdlog::init_thread_pool(8192, 1); + } + + std::atexit(Shutdown); + std::at_quick_exit(Shutdown); + + spdlog::set_formatter(std::make_unique(UNLIMITED_SIZE)); + +#ifdef _WIN32 + if (EmulatorSettings.GetLogType() == "wincolor") { + g_console_sink = std::make_shared(); + } else { + g_console_sink = std::make_shared(); + } +#else + g_console_sink = std::make_shared(); +#endif + + g_shad_file_sink = std::make_shared( + (GetUserPath(Common::FS::PathType::LogDir) / "shad_log.txt").string()); + g_shad_file_sink->set_formatter( + std::make_unique(EmulatorSettings.GetLogSizeLimit())); + + std::shared_ptr dup_filter; + + if (EmulatorSettings.IsLogSkipDuplicate()) { + dup_filter = std::make_shared( + std::chrono::milliseconds(EmulatorSettings.GetLogMaxSkipDuration())); + dup_filter->set_sinks( + {g_console_sink, g_shad_file_sink, + std::make_shared< + spdlog::sinks::null_sink_mt>() /*for POSITON_GAME_LOG id + ".log" */}); + } + + for (const auto& name : Common::Log::ALL_LOG_CLASSES) { + if (EmulatorSettings.IsLogSkipDuplicate()) { + spdlog::initialize_logger(EmulatorSettings.IsLogSync() + ? std::make_shared(name, dup_filter) + : std::make_shared( + name, dup_filter, spdlog::thread_pool())); + } else { + spdlog::initialize_logger( + EmulatorSettings.IsLogSync() + ? std::make_shared( + name, + std::initializer_list{ + g_console_sink, g_shad_file_sink, + std::make_shared< + spdlog::sinks:: + null_sink_mt>() /*for POSITON_GAME_LOG id + ".log" */}) + : std::make_shared( + name, + std::initializer_list{ + g_console_sink, g_shad_file_sink, + std::make_shared< + spdlog::sinks:: + null_sink_mt>() /*for POSITON_GAME_LOG id + ".log" */}, + spdlog::thread_pool())); + } + } +} + +void Redirect(const std::string& name) { + g_game_file_sink = std::make_shared( + (GetUserPath(Common::FS::PathType::LogDir) / name).string(), !g_should_append); + g_game_file_sink->set_formatter( + std::make_unique(EmulatorSettings.GetLogSizeLimit())); + + for (const auto& name : Common::Log::ALL_LOG_CLASSES) { + auto l = spdlog::get(name); + auto& sinks = EmulatorSettings.IsLogSkipDuplicate() + ? std::dynamic_pointer_cast( + l->sinks()[POSITON_DUPLICATE_SINK]) + ->sinks() + : l->sinks(); + + if (sinks.size() == 3) { + sinks[POSITON_GAME_LOG] = g_game_file_sink; + } + } + + g_shad_file_sink->set_level(spdlog::level::off); +} +} // namespace Common::Log diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 5fa430348a8..096f3eff42e 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -1,70 +1,145 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "common/logging/formatter.h" -#include "common/logging/types.h" +#ifdef _WIN32 +#include +#include +using spdlog_stdout = spdlog::sinks::sink; +#else +using spdlog_stdout = spdlog::sinks::stdout_color_sink_mt; +#endif +#include + +#include "common/logging/classes.h" +#include "common/path_util.h" +#include "common/thread.h" namespace Common::Log { +static constexpr unsigned long long UNLIMITED_SIZE = 0; + +struct thread_name_formatter : spdlog::formatter { + ~thread_name_formatter() override = default; + + thread_name_formatter(unsigned long long size_limit) : _size_limit(size_limit) {} + + void format(const spdlog::details::log_msg& msg, spdlog::memory_buf_t& dest) override { + if (_size_limit != UNLIMITED_SIZE && _current_size >= _size_limit) { + return; + } + + msg.color_range_start = dest.size(); + + dest.push_back('['); + spdlog::details::fmt_helper::append_string_view(msg.logger_name, dest); + dest.push_back(']'); + dest.push_back(' '); + dest.push_back('<'); + spdlog::details::fmt_helper::append_string_view(spdlog::level::to_string_view(msg.level), + dest); + dest.push_back('>'); + dest.push_back(' '); + dest.push_back('('); + spdlog::details::fmt_helper::append_string_view(GetCurrentThreadName(), dest); + dest.push_back(')'); + dest.push_back(' '); + spdlog::details::fmt_helper::append_string_view( + std::filesystem::path(msg.source.filename).filename().string(), dest); + dest.push_back(':'); + spdlog::details::fmt_helper::append_int(msg.source.line, dest); + dest.push_back(' '); + spdlog::details::fmt_helper::append_string_view( + std::string_view(msg.source.funcname).contains("(anonymous class)::operator()") + ? "lambda" + : msg.source.funcname, + dest); + dest.push_back(':'); + dest.push_back(' '); + spdlog::details::fmt_helper::append_string_view(msg.payload, dest); + spdlog::details::fmt_helper::append_string_view(spdlog::details::os::default_eol, dest); + + msg.color_range_end = dest.size(); -constexpr const char* TrimSourcePath(std::string_view source) { - const auto rfind = [source](const std::string_view match) { - return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size()); - }; - auto idx = std::max({rfind("/"), rfind("\\")}); - return source.data() + idx; + _current_size += dest.size(); + } + + std::unique_ptr clone() const override { + return std::make_unique(_size_limit); + } + + const unsigned long long _size_limit; + unsigned long long _current_size = 0; +}; + +static constexpr auto POSITON_CONSOLE_LOG = 0; +static constexpr auto POSITON_SHAD_LOG = 1; +static constexpr auto POSITON_GAME_LOG = 2; + +static constexpr auto POSITON_DUPLICATE_SINK = 0; + +extern std::shared_ptr g_console_sink; +extern std::shared_ptr g_shad_file_sink; +extern std::shared_ptr g_game_file_sink; +extern bool g_should_append; + +static void Shutdown() { + g_game_file_sink.reset(); + g_shad_file_sink.reset(); + g_console_sink.reset(); + spdlog::shutdown(); } -/// Logs a message to the global logger, using fmt -void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, - unsigned int line_num, const char* function, const char* format, - const fmt::format_args& args); +void Setup(int argc, char* argv[]); -template -void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, - const char* function, const char* format, const Args&... args) { - FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, - fmt::make_format_args(args...)); +void Redirect(const std::string& name); + +static void StopRedirection() { + g_game_file_sink->flush(); + g_game_file_sink->set_level(spdlog::level::off); + g_shad_file_sink->set_level(spdlog::level::trace); } +static void Truncate() { + if (g_game_file_sink != nullptr) { + g_game_file_sink->truncate(); + } + if (g_shad_file_sink != nullptr) { + g_shad_file_sink->truncate(); + } +} } // namespace Common::Log // Define the fmt lib macros #define LOG_GENERIC(log_class, log_level, ...) \ - Common::Log::FmtLogMessage(log_class, log_level, Common::Log::TrimSourcePath(__FILE__), \ - __LINE__, __func__, __VA_ARGS__) + SPDLOG_LOGGER_CALL(spdlog::get(log_class), log_level, __VA_ARGS__) #ifdef _DEBUG #define LOG_TRACE(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) + LOG_GENERIC(Common::Log::log_class, spdlog::level::trace, __VA_ARGS__) #else -#define LOG_TRACE(log_class, fmt, ...) (void(0)) +#define LOG_TRACE(log_class, ...) (void(0)) #endif #define LOG_DEBUG(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) + LOG_GENERIC(Common::Log::log_class, spdlog::level::debug, __VA_ARGS__) #define LOG_INFO(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) + LOG_GENERIC(Common::Log::log_class, spdlog::level::info, __VA_ARGS__) #define LOG_WARNING(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) + LOG_GENERIC(Common::Log::log_class, spdlog::level::warn, __VA_ARGS__) #define LOG_ERROR(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) + LOG_GENERIC(Common::Log::log_class, spdlog::level::err, __VA_ARGS__) #define LOG_CRITICAL(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) + LOG_GENERIC(Common::Log::log_class, spdlog::level::critical, __VA_ARGS__) diff --git a/src/common/logging/log_entry.h b/src/common/logging/log_entry.h deleted file mode 100644 index 7b52ad7e12e..00000000000 --- a/src/common/logging/log_entry.h +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -#include "common/logging/types.h" - -namespace Common::Log { - -/** - * A log entry. Log entries are store in a structured format to permit more varied output - * formatting on different frontends, as well as facilitating filtering and aggregation. - */ -struct Entry { - std::chrono::microseconds timestamp; - Class log_class{}; - Level log_level{}; - const char* filename = nullptr; - u32 line_num = 0; - std::string function; - std::string message; - std::string thread; - u32 counter = 0; -}; - -} // namespace Common::Log diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp deleted file mode 100644 index e8c5f49799f..00000000000 --- a/src/common/logging/text_formatter.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -#ifdef _WIN32 -#include -#endif - -#include "common/assert.h" -#include "common/logging/filter.h" -#include "common/logging/log.h" -#include "common/logging/log_entry.h" -#include "common/logging/text_formatter.h" - -namespace Common::Log { - -std::string FormatLogMessage(const Entry& entry) { - const u32 time_seconds = static_cast(entry.timestamp.count() / 1000000); - const u32 time_fractional = static_cast(entry.timestamp.count() % 1000000); - - const char* class_name = GetLogClassName(entry.log_class); - const char* level_name = GetLevelName(entry.log_level); - - return fmt::format("[{}] <{}> ({}) {}:{} {}: {}", class_name, level_name, entry.thread, - entry.filename, entry.line_num, entry.function, entry.message); -} - -void PrintMessage(const Entry& entry) { - const auto str = FormatLogMessage(entry).append(1, '\n'); - fputs(str.c_str(), stdout); -} - -void PrintColoredMessage(const Entry& entry) { -#ifdef _WIN32 - HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE); - if (console_handle == INVALID_HANDLE_VALUE) { - return; - } - - CONSOLE_SCREEN_BUFFER_INFO original_info{}; - GetConsoleScreenBufferInfo(console_handle, &original_info); - - WORD color = 0; - switch (entry.log_level) { - case Level::Trace: // Grey - color = FOREGROUND_INTENSITY; - break; - case Level::Debug: // Cyan - color = FOREGROUND_GREEN | FOREGROUND_BLUE; - break; - case Level::Info: // Bright gray - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - break; - case Level::Warning: // Bright yellow - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - break; - case Level::Error: // Bright red - color = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; - case Level::Critical: // Bright magenta - color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - case Level::Count: - UNREACHABLE(); - } - - SetConsoleTextAttribute(console_handle, color); -#else -#define ESC "\x1b" - const char* color = ""; - switch (entry.log_level) { - case Level::Trace: // Grey - color = ESC "[1;30m"; - break; - case Level::Debug: // Cyan - color = ESC "[0;36m"; - break; - case Level::Info: // Bright gray - color = ESC "[0;37m"; - break; - case Level::Warning: // Bright yellow - color = ESC "[1;33m"; - break; - case Level::Error: // Bright red - color = ESC "[1;31m"; - break; - case Level::Critical: // Bright magenta - color = ESC "[1;35m"; - break; - case Level::Count: - UNREACHABLE(); - } - - fputs(color, stdout); -#endif - - PrintMessage(entry); - -#ifdef _WIN32 - SetConsoleTextAttribute(console_handle, original_info.wAttributes); -#else - fputs(ESC "[0m", stdout); -#undef ESC -#endif -} - -} // namespace Common::Log diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h deleted file mode 100644 index 504d8639b67..00000000000 --- a/src/common/logging/text_formatter.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -namespace Common::Log { - -struct Entry; - -/// Formats a log entry into the provided text buffer. -std::string FormatLogMessage(const Entry& entry); - -/// Formats and prints a log entry to stderr. -void PrintMessage(const Entry& entry); - -/// Prints the same message as `PrintMessage`, but colored according to the severity level. -void PrintColoredMessage(const Entry& entry); - -} // namespace Common::Log diff --git a/src/common/logging/types.h b/src/common/logging/types.h deleted file mode 100644 index 2c6edef3bac..00000000000 --- a/src/common/logging/types.h +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 Citra Emulator Project -// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/types.h" - -namespace Common::Log { - -/// Specifies the severity or level of detail of the log message. -enum class Level : u8 { - Trace, ///< Extremely detailed and repetitive debugging information that is likely to - ///< pollute logs. - Debug, ///< Less detailed debugging information. - Info, ///< Status information from important points during execution. - Warning, ///< Minor or potential problems found during execution of a task. - Error, ///< Major problems found during execution of a task that prevent it from being - ///< completed. - Critical, ///< Major problems during execution that threaten the stability of the entire - ///< application. - - Count, ///< Total number of logging levels -}; - -/** - * Specifies the sub-system that generated the log message. - * - * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in - * filter.cpp. - */ -enum class Class : u8 { - Log, ///< Messages about the log system itself - Common, ///< Library routines - Common_Filesystem, ///< Filesystem interface library - Common_Memory, ///< Memory mapping and management functions - KeyManager, ///< Key management system - Core, ///< LLE emulation core - Core_Linker, ///< The module linker - Core_Devices, ///< Devices emulation - Config, ///< Emulator configuration (including commandline) - Debug, ///< Debugging tools - Kernel, ///< The HLE implementation of the PS4 kernel. - Kernel_Pthread, ///< The pthread implementation of the kernel. - Kernel_Fs, ///< The filesystem implementation of the kernel. - Kernel_Vmm, ///< The virtual memory implementation of the kernel. - Kernel_Event, ///< The event management implementation of the kernel. - Kernel_Sce, ///< The Sony-specific interfaces provided by the kernel. - Lib, ///< HLE implementation of system library. Each major library - ///< should have its own subclass. - Lib_LibcInternal, ///< The LibcInternal implementation. - Lib_Kernel, ///< The LibKernel implementation. - Lib_Pad, ///< The LibScePad implementation. - Lib_SystemGesture, ///< The LibSceSystemGesture implementation. - Lib_GnmDriver, ///< The LibSceGnmDriver implementation. - Lib_SystemService, ///< The LibSceSystemService implementation. - Lib_UserService, ///< The LibSceUserService implementation. - Lib_VideoOut, ///< The LibSceVideoOut implementation. - Lib_CommonDlg, ///< The LibSceCommonDialog implementation. - Lib_MsgDlg, ///< The LibSceMsgDialog implementation. - Lib_AudioOut, ///< The LibSceAudioOut implementation. - Lib_AudioIn, ///< The LibSceAudioIn implementation. - Lib_Move, ///< The LibSceMove implementation. - Lib_Net, ///< The LibSceNet implementation. - Lib_NetCtl, ///< The LibSceNetCtl implementation. - Lib_SaveData, ///< The LibSceSaveData implementation. - Lib_SaveDataDialog, ///< The LibSceSaveDataDialog implementation. - Lib_Ssl, ///< The LibSceSsl implementation. - Lib_Ssl2, ///< The LibSceSsl2 implementation. - Lib_Http, ///< The LibSceHttp implementation. - Lib_Http2, ///< The LibSceHttp2 implementation. - Lib_SysModule, ///< The LibSceSysModule implementation - Lib_NpCommon, ///< The LibSceNpCommon implementation - Lib_NpCommerce, ///< The LibSceNpCommerce implementation - Lib_NpAuth, ///< The LibSceNpAuth implementation - Lib_NpManager, ///< The LibSceNpManager implementation - Lib_NpMatching2, ///< The LibSceNpMatching2 implementation - Lib_NpScore, ///< The LibSceNpScore implementation - Lib_NpTrophy, ///< The LibSceNpTrophy implementation - Lib_NpTus, ///< The LibSceNpTus implementation - Lib_NpWebApi, ///< The LibSceWebApi implementation - Lib_NpWebApi2, ///< The LibSceWebApi2 implementation - Lib_NpProfileDialog, ///< The LibSceNpProfileDialog implementation - Lib_NpSnsFacebookDialog, ///< The LibSceNpSnsFacebookDialog implementation - Lib_Screenshot, ///< The LibSceScreenshot implementation - Lib_AppContent, ///< The LibSceAppContent implementation. - Lib_Rtc, ///< The LibSceRtc implementation. - Lib_Rudp, ///< The LibSceRudp implementation. - Lib_DiscMap, ///< The LibSceDiscMap implementation. - Lib_Png, ///< The LibScePng implementation. - Lib_Jpeg, ///< The LibSceJpeg implementation. - Lib_PlayGo, ///< The LibScePlayGo implementation. - Lib_PlayGoDialog, ///< The LibScePlayGoDialog implementation. - Lib_Random, ///< The LibSceRandom implementation. - Lib_Usbd, ///< The LibSceUsbd implementation. - Lib_Ajm, ///< The LibSceAjm implementation. - Lib_ErrorDialog, ///< The LibSceErrorDialog implementation. - Lib_ImeDialog, ///< The LibSceImeDialog implementation. - Lib_AvPlayer, ///< The LibSceAvPlayer implementation. - Lib_Ngs2, ///< The LibSceNgs2 implementation. - Lib_Audio3d, ///< The LibSceAudio3d implementation. - Lib_Ime, ///< The LibSceIme implementation - Lib_GameLiveStreaming, ///< The LibSceGameLiveStreaming implementation - Lib_Remoteplay, ///< The LibSceRemotePlay implementation - Lib_SharePlay, ///< The LibSceSharePlay implemenation - Lib_Fiber, ///< The LibSceFiber implementation. - Lib_Vdec2, ///< The LibSceVideodec2 implementation. - Lib_Videodec, ///< The LibSceVideodec implementation. - Lib_Voice, ///< The LibSceVoice implementation. - Lib_RazorCpu, ///< The LibRazorCpu implementation. - Lib_Mouse, ///< The LibSceMouse implementation - Lib_WebBrowserDialog, ///< The LibSceWebBrowserDialog implementation - Lib_NpParty, ///< The LibSceNpParty implementation - Lib_NpPartner, ///< The LibSceNpPartner implementation - Lib_Zlib, ///< The LibSceZlib implementation. - Lib_Hmd, ///< The LibSceHmd implementation. - Lib_HmdSetupDialog, ///< The LibSceHmdSetupDialog implementation. - Lib_SigninDialog, ///< The LibSigninDialog implementation. - Lib_Camera, ///< The LibCamera implementation. - Lib_CompanionHttpd, ///< The LibCompanionHttpd implementation. - Lib_CompanionUtil, ///< The LibCompanionUtil implementation. - Lib_VrTracker, ///< The LibSceVrTracker implementation. - Lib_Font, ///< The libSceFont implementation. - Lib_FontFt, ///< The libSceFontFt implementation. - Frontend, ///< Emulator UI - Render, ///< Video Core - Render_Vulkan, ///< Vulkan backend - Render_Recompiler, ///< Shader recompiler - ImGui, ///< ImGui - Loader, ///< ROM loader - Input, ///< Input emulation - Tty, ///< Debug output from emu - Count ///< Total number of logging classes -}; - -} // namespace Common::Log diff --git a/src/common/memory_patcher.cpp b/src/common/memory_patcher.cpp index 2517e3f2263..73911941c3f 100644 --- a/src/common/memory_patcher.cpp +++ b/src/common/memory_patcher.cpp @@ -14,6 +14,7 @@ #include "core/emulator_state.h" #include "core/file_format/psf.h" #include "memory_patcher.h" +#include "shadps4_app.h" namespace MemoryPatcher { @@ -192,7 +193,7 @@ void OnGameLoaded() { } else { ApplyPatchesFromXML(file_path); } - } else if (EmulatorState::GetInstance()->IsAutoPatchesLoadEnabled()) { + } else if (ShadPs4App::GetInstance()->m_emulator_state.IsAutoPatchesLoadEnabled()) { for (auto const& repo : std::filesystem::directory_iterator(patch_dir)) { if (!repo.is_directory()) { continue; diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index ca3d520429e..96ececb94ad 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -12,6 +12,7 @@ #include "core/libraries/kernel/memory.h" #include "core/memory.h" #include "libraries/error_codes.h" +#include "shadps4_app.h" #ifdef _WIN32 #include diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index 10e5f911c9f..e070f052dfb 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -12,6 +12,7 @@ #include "core/debug_state.h" #include "core/emulator_settings.h" #include "core/emulator_state.h" +#include "core/libraries/libs.h" #include "imgui/imgui_std.h" #include "imgui_internal.h" #include "options.h" @@ -22,8 +23,6 @@ #include "widget/module_list.h" #include "widget/shader_list.h" -extern std::unique_ptr presenter; - using namespace ImGui; using namespace ::Core::Devtools; using L = ::Core::Devtools::Layer; @@ -90,13 +89,13 @@ void L::DrawMenuBar() { ImGui::EndMenu(); } if (BeginMenu("Display")) { - auto& pp_settings = presenter->GetPPSettingsRef(); + auto& pp_settings = ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetPPSettingsRef(); if (BeginMenu("Brightness")) { SliderFloat("Gamma", &pp_settings.gamma, 0.1f, 2.0f); ImGui::EndMenu(); } if (BeginMenu("FSR")) { - auto& fsr = presenter->GetFsrSettingsRef(); + auto& fsr = ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetFsrSettingsRef(); Checkbox("FSR Enabled", &fsr.enable); BeginDisabled(!fsr.enable); { diff --git a/src/core/devtools/widget/frame_graph.cpp b/src/core/devtools/widget/frame_graph.cpp index 6d44520740c..2cd953e32c4 100644 --- a/src/core/devtools/widget/frame_graph.cpp +++ b/src/core/devtools/widget/frame_graph.cpp @@ -8,6 +8,7 @@ #include "core/emulator_settings.h" #include "imgui.h" #include "imgui_internal.h" +#include "shadps4_app.h" using namespace ImGui; diff --git a/src/core/devtools/widget/module_list.h b/src/core/devtools/widget/module_list.h index 4eed5444d2f..8d3047c73af 100644 --- a/src/core/devtools/widget/module_list.h +++ b/src/core/devtools/widget/module_list.h @@ -11,6 +11,7 @@ #include "common/elf_info.h" #include "common/path_util.h" #include "core/emulator_settings.h" +#include "shadps4_app.h" namespace Core::Devtools::Widget { diff --git a/src/core/devtools/widget/shader_list.cpp b/src/core/devtools/widget/shader_list.cpp index 243e2355f7e..e0850ee4b72 100644 --- a/src/core/devtools/widget/shader_list.cpp +++ b/src/core/devtools/widget/shader_list.cpp @@ -13,13 +13,13 @@ #include "core/debug_state.h" #include "core/devtools/options.h" #include "core/emulator_settings.h" +#include "core/libraries/libs.h" #include "imgui/imgui_std.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "video_core/renderer_vulkan/vk_presenter.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" -extern std::unique_ptr presenter; - using namespace ImGui; namespace Core::Devtools::Widget { @@ -31,12 +31,12 @@ ShaderList::Selection::Selection(int index) isa_editor->SetReadOnly(true); glsl_editor->SetPalette(TextEditor::GetDarkPalette()); glsl_editor->SetLanguageDefinition(TextEditor::LanguageDefinition::GLSL()); - presenter->GetWindow().RequestKeyboard(); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetWindow().RequestKeyboard(); } ShaderList::Selection::~Selection() { if (index >= 0) { - presenter->GetWindow().ReleaseKeyboard(); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetWindow().ReleaseKeyboard(); } } @@ -58,7 +58,7 @@ void ShaderList::Selection::ReloadShader(DebugStateType::ShaderDump& value) { if (spv.empty()) { return; } - auto& cache = presenter->GetRasterizer().GetPipelineCache(); + auto& cache = ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetRasterizer().GetPipelineCache(); if (const auto m = cache.ReplaceShader(value.module, spv); m) { value.module = *m; } diff --git a/src/core/devtools/widget/text_editor.cpp b/src/core/devtools/widget/text_editor.cpp index 12031d1efa0..460b4bfd2ad 100644 --- a/src/core/devtools/widget/text_editor.cpp +++ b/src/core/devtools/widget/text_editor.cpp @@ -12,6 +12,7 @@ #include "text_editor.h" #define IMGUI_DEFINE_MATH_OPERATORS +#include "common/types.h" #include "imgui.h" // for imGui::GetCurrentWindow() // TODO diff --git a/src/core/emulator_settings.cpp b/src/core/emulator_settings.cpp index 066c23af829..014d9b1d5a9 100644 --- a/src/core/emulator_settings.cpp +++ b/src/core/emulator_settings.cpp @@ -5,14 +5,15 @@ #include #include #include -#include -#include #include +#include + +#include "common/path_util.h" +#include "common/scm_rev.h" #include "common/logging/log.h" #include "emulator_settings.h" #include "emulator_state.h" - -#include +#include "shadps4_app.h" using json = nlohmann::json; @@ -25,13 +26,10 @@ namespace nlohmann { template <> struct adl_serializer { static void to_json(json& j, const std::filesystem::path& p) { - const auto u8 = p.u8string(); - j = std::string(reinterpret_cast(u8.data()), u8.size()); + j = p.string(); } static void from_json(const json& j, std::filesystem::path& p) { - const std::string s = j.get(); - p = std::filesystem::path( - std::u8string_view(reinterpret_cast(s.data()), s.size())); + p = j.get(); } }; } // namespace nlohmann @@ -55,6 +53,10 @@ std::optional get_optional(const toml::value& v, const std::string& key) { if (it->second.is_integer()) { return static_cast(toml::get(it->second)); } + } else if constexpr (std::is_same_v) { + if (it->second.is_integer()) { + return static_cast(toml::get(it->second)); + } } else if constexpr (std::is_same_v) { if (it->second.is_floating()) { return toml::get(it->second); @@ -100,18 +102,6 @@ EmulatorSettingsImpl::~EmulatorSettingsImpl() { Save(); } -std::shared_ptr EmulatorSettingsImpl::GetInstance() { - std::lock_guard lock(s_mutex); - if (!s_instance) - s_instance = std::make_shared(); - return s_instance; -} - -void EmulatorSettingsImpl::SetInstance(std::shared_ptr instance) { - std::lock_guard lock(s_mutex); - s_instance = std::move(instance); -} - // -------------------- // General helpers // -------------------- @@ -210,11 +200,13 @@ void EmulatorSettingsImpl::SetFontsDir(const std::filesystem::path& dir) { // ── Game-specific override management ──────────────────────────────── void EmulatorSettingsImpl::ClearGameSpecificOverrides() { ClearGroupOverrides(m_general); + ClearGroupOverrides(m_log); ClearGroupOverrides(m_debug); ClearGroupOverrides(m_input); ClearGroupOverrides(m_audio); ClearGroupOverrides(m_gpu); ClearGroupOverrides(m_vulkan); + ClearGroupOverrides(m_keys); LOG_DEBUG(Config, "All game-specific overrides cleared"); } @@ -231,6 +223,8 @@ void EmulatorSettingsImpl::ResetGameSpecificValue(const std::string& key) { }; if (tryGroup(m_general)) return; + if (tryGroup(m_log)) + return; if (tryGroup(m_debug)) return; if (tryGroup(m_input)) @@ -241,6 +235,8 @@ void EmulatorSettingsImpl::ResetGameSpecificValue(const std::string& key) { return; if (tryGroup(m_vulkan)) return; + if (tryGroup(m_keys)) + return; LOG_WARNING(Config, "ResetGameSpecificValue: key '{}' not found", key); } @@ -257,6 +253,10 @@ bool EmulatorSettingsImpl::Save(const std::string& serial) { SaveGroupGameSpecific(m_general, generalObj); j["General"] = generalObj; + json logObj = json::object(); + SaveGroupGameSpecific(m_log, logObj); + j["Log"] = logObj; + json debugObj = json::object(); SaveGroupGameSpecific(m_debug, debugObj); j["Debug"] = debugObj; @@ -277,6 +277,10 @@ bool EmulatorSettingsImpl::Save(const std::string& serial) { SaveGroupGameSpecific(m_vulkan, vulkanObj); j["Vulkan"] = vulkanObj; + json keysObj = json::object(); + SaveGroupGameSpecific(m_keys, keysObj); + j["Keys"] = keysObj; + std::ofstream out(path); if (!out) { LOG_ERROR(Config, "Failed to open game config for writing: {}", path.string()); @@ -294,11 +298,13 @@ bool EmulatorSettingsImpl::Save(const std::string& serial) { json j; j["General"] = m_general; + j["Log"] = m_log; j["Debug"] = m_debug; j["Input"] = m_input; j["Audio"] = m_audio; j["GPU"] = m_gpu; j["Vulkan"] = m_vulkan; + j["Keys"] = m_keys; // Read the existing file so we can preserve keys unknown to this build json existing = json::object(); @@ -355,11 +361,13 @@ bool EmulatorSettingsImpl::Load(const std::string& serial) { }; mergeGroup(m_general, "General"); + mergeGroup(m_log, "Log"); mergeGroup(m_debug, "Debug"); mergeGroup(m_input, "Input"); mergeGroup(m_audio, "Audio"); mergeGroup(m_gpu, "GPU"); mergeGroup(m_vulkan, "Vulkan"); + mergeGroup(m_keys, "Keys"); LOG_DEBUG(Config, "Global config loaded successfully"); } else { @@ -435,6 +443,8 @@ bool EmulatorSettingsImpl::Load(const std::string& serial) { // time without ever touching the base values. if (gj.contains("General")) ApplyGroupOverrides(m_general, gj.at("General"), changed); + if (gj.contains("Log")) + ApplyGroupOverrides(m_log, gj.at("Log"), changed); if (gj.contains("Debug")) ApplyGroupOverrides(m_debug, gj.at("Debug"), changed); if (gj.contains("Input")) @@ -445,9 +455,11 @@ bool EmulatorSettingsImpl::Load(const std::string& serial) { ApplyGroupOverrides(m_gpu, gj.at("GPU"), changed); if (gj.contains("Vulkan")) ApplyGroupOverrides(m_vulkan, gj.at("Vulkan"), changed); + if (gj.contains("Keys")) + ApplyGroupOverrides(m_keys, gj.at("Keys"), changed); PrintChangedSummary(changed); - EmulatorState::GetInstance()->SetGameSpecifigConfigUsed(true); + ShadPs4App::GetInstance()->m_emulator_state.SetGameSpecifigConfigUsed(true); return true; } } catch (const std::exception& e) { @@ -458,11 +470,13 @@ bool EmulatorSettingsImpl::Load(const std::string& serial) { void EmulatorSettingsImpl::SetDefaultValues() { m_general = GeneralSettings{}; + m_log = LogSettings{}; m_debug = DebugSettings{}; m_input = InputSettings{}; m_audio = AudioSettings{}; m_gpu = GPUSettings{}; m_vulkan = VulkanSettings{}; + m_keys = KeysSettings{}; } bool EmulatorSettingsImpl::TransferSettings() { @@ -473,7 +487,7 @@ bool EmulatorSettingsImpl::TransferSettings() { std::ifstream ifs; ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.open(path, std::ios_base::binary); - og_data = toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data}); + og_data = toml::parse(ifs, path.filename().string()); } catch (std::exception& ex) { fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); return false; @@ -492,9 +506,6 @@ bool EmulatorSettingsImpl::TransferSettings() { setFromToml(s.trophy_popup_disabled, general, "isTrophyPopupDisabled"); setFromToml(s.trophy_notification_duration, general, "trophyNotificationDuration"); setFromToml(s.discord_rpc_enabled, general, "enableDiscordRPC"); - setFromToml(s.log_filter, general, "logFilter"); - setFromToml(s.log_type, general, "logType"); - setFromToml(s.identical_log_grouped, general, "isIdenticalLogGrouped"); setFromToml(s.show_splash, general, "showSplash"); setFromToml(s.trophy_notification_side, general, "sideTrophy"); setFromToml(s.connected_to_network, general, "isConnectedToNetwork"); @@ -504,6 +515,23 @@ bool EmulatorSettingsImpl::TransferSettings() { // setFromToml(s.defaultControllerID, general, "defaultControllerID"); } + if (og_data.contains("Log")) { + const toml::value& log = og_data.at("Log"); + auto& s = m_log; + + setFromToml(s.append, log, "append"); + setFromToml(s.enable, log, "enable"); + setFromToml(s.filter, log, "filter"); + setFromToml(s.max_skip_duration, log, "maxSkipDuration"); + setFromToml(s.separate, log, "separate"); + setFromToml(s.size_limit, log, "sizeLimit"); + setFromToml(s.skip_duplicate, log, "skipDuplicate"); + setFromToml(s.sync, log, "sync"); +#ifdef _WIN32 + setFromToml(s.type, log, "type"); +#endif + } + if (og_data.contains("Input")) { const toml::value& input = og_data.at("Input"); auto& s = m_input; @@ -574,9 +602,7 @@ bool EmulatorSettingsImpl::TransferSettings() { auto& s = m_debug; setFromToml(s.debug_dump, debug, "DebugDump"); - setFromToml(s.separate_logging_enabled, debug, "isSeparateLogFilesEnabled"); setFromToml(s.shader_collect, debug, "CollectShader"); - setFromToml(s.log_enabled, debug, "logEnabled"); setFromToml(m_general.show_fps_counter, debug, "showFpsCounter"); } @@ -669,6 +695,12 @@ bool EmulatorSettingsImpl::TransferSettings() { } } + if (og_data.contains("Keys")) { + const toml::value& keys = og_data.at("Keys"); + auto& s = m_keys; + setFromToml(s.trophy_key, keys, "TrophyKey"); + } + return true; } @@ -679,10 +711,11 @@ std::vector EmulatorSettingsImpl::GetAllOverrideableKeys() const { keys.push_back(item.key); }; addGroup(m_general.GetOverrideableFields()); + addGroup(m_log.GetOverrideableFields()); addGroup(m_debug.GetOverrideableFields()); addGroup(m_input.GetOverrideableFields()); addGroup(m_audio.GetOverrideableFields()); addGroup(m_gpu.GetOverrideableFields()); addGroup(m_vulkan.GetOverrideableFields()); return keys; -} +} \ No newline at end of file diff --git a/src/core/emulator_settings.h b/src/core/emulator_settings.h index 370fb0ab022..c020128d021 100644 --- a/src/core/emulator_settings.h +++ b/src/core/emulator_settings.h @@ -13,8 +13,10 @@ #include #include "common/logging/log.h" #include "common/types.h" +#include +#include -#define EmulatorSettings (*EmulatorSettingsImpl::GetInstance()) +#define EmulatorSettings ShadPs4App::GetInstance()->m_emulator_settings enum HideCursorState : int { Never, @@ -122,7 +124,27 @@ inline OverrideItem make_override(const char* key, Setting Struct::* member) LOG_DEBUG(Config, "[make_override] Current value: {}", dst.value); if (dst.value != newValue) { std::ostringstream oss; - oss << key << " ( " << dst.value << " → " << newValue << " )"; + oss << key << " ( " << key; + + constexpr bool iterable = requires(const T& t) { + t.operator[](0); + }; + + if constexpr (iterable) { + for (const auto v : dst.value) { + oss << v; + } + + oss << " → "; + + for (const auto v : newValue) { + oss << v; + } + } else { + oss << dst.value << " → " << newValue; + } + + oss << " )"; changed.push_back(oss.str()); LOG_DEBUG(Config, "[make_override] Recorded change: {}", oss.str()); } @@ -170,6 +192,7 @@ struct GeneralSettings { Setting home_dir; Setting sys_modules_dir; Setting font_dir; + Setting save_data_path; Setting volume_slider{100}; Setting neo_mode{false}; @@ -179,10 +202,7 @@ struct GeneralSettings { Setting trophy_popup_disabled{false}; Setting trophy_notification_duration{6.0}; Setting trophy_notification_side{"right"}; - Setting log_filter{""}; - Setting log_type{"sync"}; Setting show_splash{false}; - Setting identical_log_grouped{true}; Setting connected_to_network{false}; Setting discord_rpc_enabled{false}; Setting show_fps_counter{false}; @@ -201,10 +221,6 @@ struct GeneralSettings { &GeneralSettings::trophy_popup_disabled), make_override("trophy_notification_duration", &GeneralSettings::trophy_notification_duration), - make_override("log_filter", &GeneralSettings::log_filter), - make_override("log_type", &GeneralSettings::log_type), - make_override("identical_log_grouped", - &GeneralSettings::identical_log_grouped), make_override("show_splash", &GeneralSettings::show_splash), make_override("trophy_notification_side", &GeneralSettings::trophy_notification_side), @@ -215,32 +231,66 @@ struct GeneralSettings { NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GeneralSettings, install_dirs, addon_install_dir, home_dir, sys_modules_dir, font_dir, volume_slider, neo_mode, dev_kit_mode, extra_dmem_in_mbytes, psn_signed_in, trophy_popup_disabled, - trophy_notification_duration, log_filter, log_type, show_splash, - identical_log_grouped, trophy_notification_side, - connected_to_network, discord_rpc_enabled, show_fps_counter, - console_language) + trophy_notification_duration, show_splash, + trophy_notification_side, connected_to_network, + discord_rpc_enabled, show_fps_counter, console_language) + +// ------------------------------- +// Log settings +// ------------------------------- +struct LogSettings { + Setting append{false}; // specific + Setting enable{true}; // specific + Setting filter{""}; + Setting max_skip_duration{5'000}; + Setting separate{false}; // specific + Setting size_limit{100_MB}; + Setting skip_duplicate{true}; + Setting sync{true}; +#ifdef _WIN32 + Setting type{"wincolor"}; +#endif + + // return a vector of override descriptors (runtime, but tiny) + std::vector GetOverrideableFields() const { + return std::vector{ + make_override("append", &LogSettings::append), + make_override("enable", &LogSettings::enable), + make_override("filter", &LogSettings::filter), + make_override("max_skip_duration", &LogSettings::max_skip_duration), + make_override("separate", &LogSettings::separate), + make_override("size_limit", &LogSettings::size_limit), + make_override("skip_duplicate", &LogSettings::skip_duplicate), + make_override("sync", &LogSettings::sync), +#ifdef _WIN32 + make_override("type", &LogSettings::type) +#endif + }; + } +}; +#ifdef _WIN32 +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(LogSettings, append, enable, filter, max_skip_duration, separate, + size_limit, skip_duplicate, sync, type) +#else +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(LogSettings, append, enable, filter, max_skip_duration, separate, + size_limit, skip_duplicate, sync) +#endif // ------------------------------- // Debug settings // ------------------------------- struct DebugSettings { - Setting separate_logging_enabled{false}; // specific - Setting debug_dump{false}; // specific - Setting shader_collect{false}; // specific - Setting log_enabled{true}; // specific - Setting config_version{""}; // specific + Setting debug_dump{false}; // specific + Setting shader_collect{false}; // specific + Setting config_version{""}; // specific std::vector GetOverrideableFields() const { return std::vector{ make_override("debug_dump", &DebugSettings::debug_dump), - make_override("shader_collect", &DebugSettings::shader_collect), - make_override("separate_logging_enabled", - &DebugSettings::separate_logging_enabled), - make_override("log_enabled", &DebugSettings::log_enabled)}; + make_override("shader_collect", &DebugSettings::shader_collect)}; } }; -NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(DebugSettings, separate_logging_enabled, debug_dump, - shader_collect, log_enabled, config_version) +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(DebugSettings, debug_dump, shader_collect, config_version) // ------------------------------- // Input settings @@ -257,6 +307,8 @@ struct InputSettings { Setting default_controller_id{""}; Setting background_controller_input{false}; // specific Setting camera_id{-1}; + Setting override_controller_color{false}; + Setting> controller_custom_color_rgb{{0, 0, 255}}; std::vector GetOverrideableFields() const { return std::vector{ @@ -268,7 +320,8 @@ struct InputSettings { &InputSettings::motion_controls_enabled), make_override("background_controller_input", &InputSettings::background_controller_input), - make_override("camera_id", &InputSettings::camera_id)}; + make_override("camera_id", &InputSettings::camera_id), + make_override("controller_custom_color_rgb", &InputSettings::controller_custom_color_rgb)}; } }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(InputSettings, cursor_state, cursor_hide_timeout, @@ -406,6 +459,21 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(VulkanSettings, gpu_id, renderdoc_enabled, vk vkhost_markers, vkguest_markers, pipeline_cache_enabled, pipeline_cache_archived) +// ------------------------------- +// Keys settings +// ------------------------------- +struct KeysSettings { + Setting trophy_key{}; + + std::vector GetOverrideableFields() const { + return std::vector{ + make_override("trophy_key", + &KeysSettings::trophy_key), + }; + } +}; +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(KeysSettings, trophy_key) + // ------------------------------- // Main manager // ------------------------------- @@ -414,9 +482,6 @@ class EmulatorSettingsImpl { EmulatorSettingsImpl(); ~EmulatorSettingsImpl(); - static std::shared_ptr GetInstance(); - static void SetInstance(std::shared_ptr instance); - bool Save(const std::string& serial = ""); bool Load(const std::string& serial = ""); void SetDefaultValues(); @@ -455,14 +520,18 @@ class EmulatorSettingsImpl { void SetSysModulesDir(const std::filesystem::path& dir); std::filesystem::path GetFontsDir(); void SetFontsDir(const std::filesystem::path& dir); + std::filesystem::path GetSaveDataPath(); + void SetSaveDataPath(const std::filesystem::path& dir); private: GeneralSettings m_general{}; + LogSettings m_log{}; DebugSettings m_debug{}; InputSettings m_input{}; AudioSettings m_audio{}; GPUSettings m_gpu{}; VulkanSettings m_vulkan{}; + KeysSettings m_keys{}; ConfigMode m_configMode{ConfigMode::Default}; bool m_loaded{false}; @@ -548,15 +617,25 @@ class EmulatorSettingsImpl { SETTING_FORWARD(m_general, TrophyNotificationDuration, trophy_notification_duration) SETTING_FORWARD(m_general, TrophyNotificationSide, trophy_notification_side) SETTING_FORWARD_BOOL(m_general, ShowSplash, show_splash) - SETTING_FORWARD_BOOL(m_general, IdenticalLogGrouped, identical_log_grouped) SETTING_FORWARD(m_general, AddonInstallDir, addon_install_dir) - SETTING_FORWARD(m_general, LogFilter, log_filter) - SETTING_FORWARD(m_general, LogType, log_type) SETTING_FORWARD_BOOL(m_general, ConnectedToNetwork, connected_to_network) SETTING_FORWARD_BOOL(m_general, DiscordRPCEnabled, discord_rpc_enabled) SETTING_FORWARD_BOOL(m_general, ShowFpsCounter, show_fps_counter) SETTING_FORWARD(m_general, ConsoleLanguage, console_language) + // Log settings + SETTING_FORWARD_BOOL(m_log, LogAppend, append) + SETTING_FORWARD_BOOL(m_log, LogEnable, enable) + SETTING_FORWARD(m_log, LogFilter, filter) + SETTING_FORWARD(m_log, LogMaxSkipDuration, max_skip_duration) + SETTING_FORWARD_BOOL(m_log, LogSeparate, separate) + SETTING_FORWARD(m_log, LogSizeLimit, size_limit) + SETTING_FORWARD_BOOL(m_log, LogSkipDuplicate, skip_duplicate) + SETTING_FORWARD_BOOL(m_log, LogSync, sync) +#ifdef _WIN32 + SETTING_FORWARD(m_log, LogType, type) +#endif + // Audio settings SETTING_FORWARD(m_audio, AudioBackend, audio_backend) SETTING_FORWARD(m_audio, SDLMicDevice, sdl_mic_device) @@ -567,10 +646,8 @@ class EmulatorSettingsImpl { SETTING_FORWARD(m_audio, OpenALPadSpkOutputDevice, openal_padSpk_output_device) // Debug settings - SETTING_FORWARD_BOOL(m_debug, SeparateLoggingEnabled, separate_logging_enabled) SETTING_FORWARD_BOOL(m_debug, DebugDump, debug_dump) SETTING_FORWARD_BOOL(m_debug, ShaderCollect, shader_collect) - SETTING_FORWARD_BOOL(m_debug, LogEnabled, log_enabled) SETTING_FORWARD(m_debug, ConfigVersion, config_version) // GPU Settings @@ -619,6 +696,8 @@ class EmulatorSettingsImpl { SETTING_FORWARD(m_input, SpecialPadClass, special_pad_class) SETTING_FORWARD_BOOL(m_input, UseUnifiedInputConfig, use_unified_input_config) SETTING_FORWARD(m_input, CameraId, camera_id) + SETTING_FORWARD(m_input, OverrideControllerColor, override_controller_color) + SETTING_FORWARD(m_input, ControllerCustomColor, controller_custom_color_rgb) // Vulkan settings SETTING_FORWARD(m_vulkan, GpuId, gpu_id) @@ -633,6 +712,9 @@ class EmulatorSettingsImpl { SETTING_FORWARD_BOOL(m_vulkan, PipelineCacheEnabled, pipeline_cache_enabled) SETTING_FORWARD_BOOL(m_vulkan, PipelineCacheArchived, pipeline_cache_archived) + // Keys settings + SETTING_FORWARD(m_keys, TrophyKey, trophy_key) + #undef SETTING_FORWARD #undef SETTING_FORWARD_BOOL #undef SETTING_FORWARD_BOOL_READONLY diff --git a/src/core/emulator_state.cpp b/src/core/emulator_state.cpp index 20cffe53cfa..a909de718b2 100644 --- a/src/core/emulator_state.cpp +++ b/src/core/emulator_state.cpp @@ -10,18 +10,6 @@ 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; } diff --git a/src/core/emulator_state.h b/src/core/emulator_state.h index 0764b8a8106..e246d7bb86b 100644 --- a/src/core/emulator_state.h +++ b/src/core/emulator_state.h @@ -11,9 +11,6 @@ class EmulatorState { EmulatorState(); ~EmulatorState(); - static std::shared_ptr GetInstance(); - static void SetInstance(std::shared_ptr instance); - bool IsGameRunning() const; void SetGameRunning(bool running); bool IsAutoPatchesLoadEnabled() const; diff --git a/src/core/entry_params.h b/src/core/entry_params.h new file mode 100644 index 00000000000..50fd2fd5f38 --- /dev/null +++ b/src/core/entry_params.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Core { + +struct EntryParams { + int argc; + u32 padding; + const char* argv[33]; + VAddr entry_addr; +}; + +} // namespace Core diff --git a/src/core/file_format/trp.cpp b/src/core/file_format/trp.cpp index 6269fc6c7ef..73ceaaf39ea 100644 --- a/src/core/file_format/trp.cpp +++ b/src/core/file_format/trp.cpp @@ -6,6 +6,7 @@ #include "common/logging/log.h" #include "common/path_util.h" #include "core/file_format/trp.h" +#include "shadps4_app.h" static void DecryptEFSM(std::span trophyKey, std::span NPcommID, std::span efsmIv, std::span ciphertext, @@ -52,7 +53,7 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, int index, std::strin } const auto& user_key_vec = - KeyManager::GetInstance()->GetAllKeys().TrophyKeySet.ReleaseTrophyKey; + ShadPs4App::GetInstance()->m_key_manager.GetAllKeys().TrophyKeySet.ReleaseTrophyKey; if (user_key_vec.size() != 16) { LOG_INFO(Common_Filesystem, "Trophy decryption key is not specified"); diff --git a/src/core/file_sys/fs.h b/src/core/file_sys/fs.h index 0522c3d8a5d..0c7856b6bbb 100644 --- a/src/core/file_sys/fs.h +++ b/src/core/file_sys/fs.h @@ -10,7 +10,6 @@ #include #include #include "common/io_file.h" -#include "common/logging/formatter.h" #include "core/file_sys/devices/base_device.h" #include "core/file_sys/directories/base_directory.h" @@ -54,7 +53,7 @@ class MntPoints { const MntPair* GetMountFromHostPath(const std::string& host_path) { std::scoped_lock lock{m_mutex}; const auto it = std::ranges::find_if(m_mnt_pairs, [&](const MntPair& mount) { - return host_path.starts_with(std::string{fmt::UTF(mount.host_path.u8string()).data}); + return host_path.starts_with(mount.host_path.string()); }); return it == m_mnt_pairs.end() ? nullptr : &*it; } diff --git a/src/core/ipc/ipc.cpp b/src/core/ipc/ipc.cpp index 70180d3bfc7..f37dbaf4063 100644 --- a/src/core/ipc/ipc.cpp +++ b/src/core/ipc/ipc.cpp @@ -16,13 +16,13 @@ #include "core/emulator_settings.h" #include "core/emulator_state.h" #include "core/libraries/audio/audioout.h" +#include "core/libraries/libs.h" #include "input/input_handler.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "src/core/libraries/usbd/usbd.h" #include "video_core/renderer_vulkan/vk_presenter.h" -extern std::unique_ptr presenter; - /** * Protocol summary: * - IPC is enabled by setting the SHADPS4_ENABLE_IPC environment variable to "true" @@ -65,14 +65,14 @@ extern std::unique_ptr presenter; * - RESTART(argn: number, argv: ...string): Request restart of the emulator, must call STOP **/ -void IPC::Init() { +void IPC::Init(EmulatorState& emulator_state) { const char* enabledEnv = std::getenv("SHADPS4_ENABLE_IPC"); enabled = enabledEnv && strcmp(enabledEnv, "true") == 0; if (!enabled) { return; } - EmulatorState::GetInstance()->SetAutoPatchesLoadEnabled(false); + emulator_state.SetAutoPatchesLoadEnabled(false); input_thread = std::jthread([this] { Common::SetCurrentThreadName("IPC Read thread"); @@ -157,18 +157,18 @@ void IPC::InputLoop() { Libraries::AudioOut::AdjustVol(); } else if (cmd == "SET_FSR") { bool use_fsr = next_u64() != 0; - if (presenter) { - presenter->GetFsrSettingsRef().enable = use_fsr; + if (ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter) { + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetFsrSettingsRef().enable = use_fsr; } } else if (cmd == "SET_RCAS") { bool use_rcas = next_u64() != 0; - if (presenter) { - presenter->GetFsrSettingsRef().use_rcas = use_rcas; + if (ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter) { + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetFsrSettingsRef().use_rcas = use_rcas; } } else if (cmd == "SET_RCAS_ATTENUATION") { int value = static_cast(next_u64()); - if (presenter) { - presenter->GetFsrSettingsRef().rcas_attenuation = + if (ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter) { + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetFsrSettingsRef().rcas_attenuation = static_cast(value / 1000.0f); } } else if (cmd == "USB_LOAD_FIGURE") { diff --git a/src/core/ipc/ipc.h b/src/core/ipc/ipc.h index 933afa897d7..67a8b5efe71 100644 --- a/src/core/ipc/ipc.h +++ b/src/core/ipc/ipc.h @@ -10,6 +10,8 @@ #include #include +class EmulatorState; + class IPC { bool enabled{false}; std::jthread input_thread{}; @@ -18,11 +20,7 @@ class IPC { std::binary_semaphore start_semaphore{0}; public: - static IPC& Instance() { - return *Common::Singleton::Instance(); - } - - void Init(); + void Init(EmulatorState& emulator_state); operator bool() const { return enabled; diff --git a/src/core/libraries/ajm/ajm.cpp b/src/core/libraries/ajm/ajm.cpp index 2bec1bf0f60..df3b7362ac9 100644 --- a/src/core/libraries/ajm/ajm.cpp +++ b/src/core/libraries/ajm/ajm.cpp @@ -218,7 +218,7 @@ int PS4_SYSV_ABI sceAjmStrError() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("NVDXiUesSbA", "libSceAjm", 1, "libSceAjm", sceAjmBatchCancel); LIB_FUNCTION("WfAiBW8Wcek", "libSceAjm", 1, "libSceAjm", sceAjmBatchErrorDump); LIB_FUNCTION("dmDybN--Fn8", "libSceAjm", 1, "libSceAjm", sceAjmBatchJobControlBufferRa); diff --git a/src/core/libraries/ajm/ajm.h b/src/core/libraries/ajm/ajm.h index 1bfd88351ab..ac9ef054c45 100644 --- a/src/core/libraries/ajm/ajm.h +++ b/src/core/libraries/ajm/ajm.h @@ -227,5 +227,8 @@ int PS4_SYSV_ABI sceAjmModuleRegister(u32 context, AjmCodecType codec_type, s64 int PS4_SYSV_ABI sceAjmModuleUnregister(); int PS4_SYSV_ABI sceAjmStrError(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Ajm diff --git a/src/core/libraries/ajm/ajm_batch.cpp b/src/core/libraries/ajm/ajm_batch.cpp index 3ab2ed4ab0e..5a4d4ec17f2 100644 --- a/src/core/libraries/ajm/ajm_batch.cpp +++ b/src/core/libraries/ajm/ajm_batch.cpp @@ -158,7 +158,7 @@ AjmJob AjmStatisticsJobFromBatchBuffer(u32 instance_id, AjmBatchBuffer batch_buf break; } default: - UNREACHABLE_MSG("Unknown chunk: {}", header.ident); + UNREACHABLE_MSG("Unknown chunk: {}", +header.ident); } } @@ -257,7 +257,7 @@ AjmJob AjmJobFromBatchBuffer(u32 instance_id, AjmBatchBuffer batch_buffer) { break; } default: - UNREACHABLE_MSG("Unknown chunk: {}", header.ident); + UNREACHABLE_MSG("Unknown chunk: {}", +header.ident); } } diff --git a/src/core/libraries/app_content/app_content.cpp b/src/core/libraries/app_content/app_content.cpp index bf2b72b07af..4ef6852baa9 100644 --- a/src/core/libraries/app_content/app_content.cpp +++ b/src/core/libraries/app_content/app_content.cpp @@ -13,6 +13,7 @@ #include "core/libraries/app_content/app_content_error.h" #include "core/libraries/libs.h" #include "core/libraries/system/systemservice.h" +#include "shadps4_app.h" namespace Libraries::AppContent { @@ -447,7 +448,7 @@ int PS4_SYSV_ABI sceAppContentGetDownloadedStoreCountry() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("AS45QoYHjc4", "libSceAppContent", 1, "libSceAppContentUtil", _Z5dummyv); LIB_FUNCTION("ZiATpP9gEkA", "libSceAppContent", 1, "libSceAppContentUtil", sceAppContentAddcontDelete); diff --git a/src/core/libraries/app_content/app_content.h b/src/core/libraries/app_content/app_content.h index dd8455dcc7f..9c0ddf92b62 100644 --- a/src/core/libraries/app_content/app_content.h +++ b/src/core/libraries/app_content/app_content.h @@ -120,5 +120,8 @@ int PS4_SYSV_ABI sceAppContentGetAddcontInfoByEntitlementId(); int PS4_SYSV_ABI sceAppContentGetAddcontInfoListByIroTag(); int PS4_SYSV_ABI sceAppContentGetDownloadedStoreCountry(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::AppContent diff --git a/src/core/libraries/audio/audioin.cpp b/src/core/libraries/audio/audioin.cpp index 55c2891b2c1..6c32f6fa268 100644 --- a/src/core/libraries/audio/audioin.cpp +++ b/src/core/libraries/audio/audioin.cpp @@ -442,7 +442,7 @@ int PS4_SYSV_ABI sceAudioInVmicWrite() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("IQtWgnrw6v8", "libSceAudioIn", 1, "libSceAudioIn", sceAudioInChangeAppModuleState); LIB_FUNCTION("Jh6WbHhnI68", "libSceAudioIn", 1, "libSceAudioIn", sceAudioInClose); diff --git a/src/core/libraries/audio/audioin.h b/src/core/libraries/audio/audioin.h index be43315e094..6ee5b2451a8 100644 --- a/src/core/libraries/audio/audioin.h +++ b/src/core/libraries/audio/audioin.h @@ -84,5 +84,8 @@ int PS4_SYSV_ABI sceAudioInVmicCreate(); int PS4_SYSV_ABI sceAudioInVmicDestroy(); int PS4_SYSV_ABI sceAudioInVmicWrite(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::AudioIn diff --git a/src/core/libraries/audio/audioout.cpp b/src/core/libraries/audio/audioout.cpp index e009f1f39d3..3d32f45ebc6 100644 --- a/src/core/libraries/audio/audioout.cpp +++ b/src/core/libraries/audio/audioout.cpp @@ -16,6 +16,7 @@ #include "core/libraries/audio/audioout_error.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" +#include "shadps4_app.h" namespace Libraries::AudioOut { @@ -1096,7 +1097,7 @@ s32 PS4_SYSV_ABI sceAudioOutSetSystemDebugState() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("cx2dYFbzIAg", "libSceAudioOutDeviceService", 1, "libSceAudioOut", sceAudioOutDeviceIdOpen); LIB_FUNCTION("tKumjQSzhys", "libSceAudioDeviceControl", 1, "libSceAudioOut", diff --git a/src/core/libraries/audio/audioout.h b/src/core/libraries/audio/audioout.h index ffc1f9eb1f9..2a3e16d4963 100644 --- a/src/core/libraries/audio/audioout.h +++ b/src/core/libraries/audio/audioout.h @@ -217,5 +217,9 @@ s32 PS4_SYSV_ABI sceAudioOutSparkControlSetEqCoef(); s32 PS4_SYSV_ABI sceAudioOutSetSystemDebugState(); void AdjustVol(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); + +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::AudioOut diff --git a/src/core/libraries/audio/openal_audio_out.cpp b/src/core/libraries/audio/openal_audio_out.cpp index d40f01588f9..8b15bc6ecb7 100644 --- a/src/core/libraries/audio/openal_audio_out.cpp +++ b/src/core/libraries/audio/openal_audio_out.cpp @@ -17,6 +17,7 @@ #include "core/libraries/audio/audioout_backend.h" #include "core/libraries/audio/openal_manager.h" #include "core/libraries/kernel/threads.h" +#include "shadps4_app.h" // SIMD support detection #if defined(__x86_64__) || defined(_M_X64) diff --git a/src/core/libraries/audio/sdl_audio_in.cpp b/src/core/libraries/audio/sdl_audio_in.cpp index 6e7a7bdbd30..71689401687 100644 --- a/src/core/libraries/audio/sdl_audio_in.cpp +++ b/src/core/libraries/audio/sdl_audio_in.cpp @@ -7,6 +7,7 @@ #include #include "audioin.h" #include "audioin_backend.h" +#include "shadps4_app.h" namespace Libraries::AudioIn { diff --git a/src/core/libraries/audio/sdl_audio_out.cpp b/src/core/libraries/audio/sdl_audio_out.cpp index b6706eff7f3..e8d25079631 100644 --- a/src/core/libraries/audio/sdl_audio_out.cpp +++ b/src/core/libraries/audio/sdl_audio_out.cpp @@ -14,6 +14,7 @@ #include "core/libraries/audio/audioout.h" #include "core/libraries/audio/audioout_backend.h" #include "core/libraries/kernel/threads.h" +#include "shadps4_app.h" // SIMD support detection #if defined(__x86_64__) || defined(_M_X64) diff --git a/src/core/libraries/audio3d/audio3d.cpp b/src/core/libraries/audio3d/audio3d.cpp index 98967910702..30f80fbb47a 100644 --- a/src/core/libraries/audio3d/audio3d.cpp +++ b/src/core/libraries/audio3d/audio3d.cpp @@ -946,7 +946,7 @@ s32 PS4_SYSV_ABI sceAudio3dTerminate() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", sceAudio3dAudioOutClose); LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", sceAudio3dAudioOutOpen); LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", sceAudio3dAudioOutOutput); diff --git a/src/core/libraries/audio3d/audio3d.h b/src/core/libraries/audio3d/audio3d.h index 0db7fa83b0c..349a6484a9c 100644 --- a/src/core/libraries/audio3d/audio3d.h +++ b/src/core/libraries/audio3d/audio3d.h @@ -179,5 +179,8 @@ s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer(); s32 PS4_SYSV_ABI sceAudio3dStrError(); s32 PS4_SYSV_ABI sceAudio3dTerminate(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Audio3d diff --git a/src/core/libraries/audio3d/audio3d_openal.cpp b/src/core/libraries/audio3d/audio3d_openal.cpp index 53bbb8b24ea..e2e19f740dc 100644 --- a/src/core/libraries/audio3d/audio3d_openal.cpp +++ b/src/core/libraries/audio3d/audio3d_openal.cpp @@ -946,7 +946,7 @@ s32 PS4_SYSV_ABI sceAudio3dTerminate() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", sceAudio3dAudioOutClose); LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", sceAudio3dAudioOutOpen); LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", sceAudio3dAudioOutOutput); diff --git a/src/core/libraries/audio3d/audio3d_openal.h b/src/core/libraries/audio3d/audio3d_openal.h index 75be72066c0..4835aee72c7 100644 --- a/src/core/libraries/audio3d/audio3d_openal.h +++ b/src/core/libraries/audio3d/audio3d_openal.h @@ -177,5 +177,8 @@ s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer(); s32 PS4_SYSV_ABI sceAudio3dStrError(); s32 PS4_SYSV_ABI sceAudio3dTerminate(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Audio3dOpenAL diff --git a/src/core/libraries/avplayer/avplayer.cpp b/src/core/libraries/avplayer/avplayer.cpp index e4d30af21c3..57aa2e420cf 100644 --- a/src/core/libraries/avplayer/avplayer.cpp +++ b/src/core/libraries/avplayer/avplayer.cpp @@ -248,7 +248,7 @@ s32 PS4_SYSV_ABI sceAvPlayerVprintf(const char* format, va_list args) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("KMcEa+rHsIo", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerAddSource); LIB_FUNCTION("x8uvuFOPZhU", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerAddSourceEx); LIB_FUNCTION("buMCiJftcfw", "libSceAvPlayer", 1, "libSceAvPlayer", sceAvPlayerChangeStream); diff --git a/src/core/libraries/avplayer/avplayer.h b/src/core/libraries/avplayer/avplayer.h index eebce8965c6..7d88263daf3 100644 --- a/src/core/libraries/avplayer/avplayer.h +++ b/src/core/libraries/avplayer/avplayer.h @@ -290,6 +290,9 @@ enum class AvPlayerAvSyncMode { using AvPlayerLogCallback = int PS4_SYSV_ABI (*)(void* p, const char* format, va_list args); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::AvPlayer diff --git a/src/core/libraries/camera/camera.cpp b/src/core/libraries/camera/camera.cpp index 14aad8e84dc..139344c45af 100644 --- a/src/core/libraries/camera/camera.cpp +++ b/src/core/libraries/camera/camera.cpp @@ -9,11 +9,11 @@ #include "core/libraries/error_codes.h" #include "core/libraries/kernel/process.h" #include "core/libraries/libs.h" +#include "shadps4_app.h" #include - #include -#include "SDL3/SDL_camera.h" +#include namespace Libraries::Camera { @@ -1125,7 +1125,7 @@ s32 PS4_SYSV_ABI sceCameraStopByHandle(s32 handle) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { Libraries::Kernel::sceKernelGetCompiledSdkVersion(&g_firmware_version); LIB_FUNCTION("QhjrPkRPUZQ", "libSceCamera", 1, "libSceCamera", sceCameraAccGetData); diff --git a/src/core/libraries/camera/camera.h b/src/core/libraries/camera/camera.h index eba7f4720d5..281a22218d8 100644 --- a/src/core/libraries/camera/camera.h +++ b/src/core/libraries/camera/camera.h @@ -455,5 +455,8 @@ s32 PS4_SYSV_ABI sceCameraStartByHandle(s32 handle, OrbisCameraStartParameter* p s32 PS4_SYSV_ABI sceCameraStop(s32 handle); s32 PS4_SYSV_ABI sceCameraStopByHandle(s32 handle); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Camera \ No newline at end of file diff --git a/src/core/libraries/companion/companion_httpd.cpp b/src/core/libraries/companion/companion_httpd.cpp index 6ffc8c05266..7a2f36c560b 100644 --- a/src/core/libraries/companion/companion_httpd.cpp +++ b/src/core/libraries/companion/companion_httpd.cpp @@ -102,7 +102,7 @@ s32 PS4_SYSV_ABI sceCompanionHttpdUnregisterRequestCallback() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("8pWltDG7h6A", "libSceCompanionHttpd", 1, "libSceCompanionHttpd", sceCompanionHttpdAddHeader); LIB_FUNCTION("B-QBMeFdNgY", "libSceCompanionHttpd", 1, "libSceCompanionHttpd", diff --git a/src/core/libraries/companion/companion_httpd.h b/src/core/libraries/companion/companion_httpd.h index bc6807fbcaa..18d9f60154d 100644 --- a/src/core/libraries/companion/companion_httpd.h +++ b/src/core/libraries/companion/companion_httpd.h @@ -87,5 +87,8 @@ s32 PS4_SYSV_ABI sceCompanionHttpdTerminate(); s32 PS4_SYSV_ABI sceCompanionHttpdUnregisterRequestBodyReceptionCallback(); s32 PS4_SYSV_ABI sceCompanionHttpdUnregisterRequestCallback(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::CompanionHttpd \ No newline at end of file diff --git a/src/core/libraries/companion/companion_util.cpp b/src/core/libraries/companion/companion_util.cpp index 2794c49af86..44f14a02d99 100644 --- a/src/core/libraries/companion/companion_util.cpp +++ b/src/core/libraries/companion/companion_util.cpp @@ -55,7 +55,7 @@ s32 PS4_SYSV_ABI sceCompanionUtilTerminate() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("cE5Msy11WhU", "libSceCompanionUtil", 1, "libSceCompanionUtil", sceCompanionUtilGetEvent); LIB_FUNCTION("MaVrz79mT5o", "libSceCompanionUtil", 1, "libSceCompanionUtil", diff --git a/src/core/libraries/companion/companion_util.h b/src/core/libraries/companion/companion_util.h index e44b095ee87..540fad4ae4f 100644 --- a/src/core/libraries/companion/companion_util.h +++ b/src/core/libraries/companion/companion_util.h @@ -29,5 +29,8 @@ s32 PS4_SYSV_ABI sceCompanionUtilInitialize(); s32 PS4_SYSV_ABI sceCompanionUtilOptParamInitialize(); s32 PS4_SYSV_ABI sceCompanionUtilTerminate(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::CompanionUtil \ No newline at end of file diff --git a/src/core/libraries/disc_map/disc_map.cpp b/src/core/libraries/disc_map/disc_map.cpp index 27295fda260..7847fbb7b6a 100644 --- a/src/core/libraries/disc_map/disc_map.cpp +++ b/src/core/libraries/disc_map/disc_map.cpp @@ -34,7 +34,7 @@ int PS4_SYSV_ABI Func_E7EBCE96E92F91F8() { return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("fl1eoDnwQ4s", "libSceDiscMap", 1, "libSceDiscMap", sceDiscMapGetPackageSize); LIB_FUNCTION("lbQKqsERhtE", "libSceDiscMap", 1, "libSceDiscMap", sceDiscMapIsRequestOnHDD); LIB_FUNCTION("fJgP+wqifno", "libSceDiscMap", 1, "libSceDiscMap", Func_7C980FFB0AA27E7A); diff --git a/src/core/libraries/disc_map/disc_map.h b/src/core/libraries/disc_map/disc_map.h index df6c25aa043..594672c9c9d 100644 --- a/src/core/libraries/disc_map/disc_map.h +++ b/src/core/libraries/disc_map/disc_map.h @@ -18,5 +18,8 @@ int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9(char* path, s64 offset, s64 nbytes, int* int* ret2); int PS4_SYSV_ABI Func_E7EBCE96E92F91F8(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::DiscMap \ No newline at end of file diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 2ebfbd24491..2721e6343ff 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -545,7 +545,7 @@ s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_o return sceFiberSwitchImpl(fiber, nullptr, 0, arg_on_run_to, arg_on_run); } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", sceFiberInitialize); LIB_FUNCTION("7+OJIpko9RY", "libSceFiber", 1, "libSceFiber", sceFiberInitializeImpl); // _sceFiberInitializeWithInternalOptionImpl diff --git a/src/core/libraries/fiber/fiber.h b/src/core/libraries/fiber/fiber.h index f52a751b186..d1673381894 100644 --- a/src/core/libraries/fiber/fiber.h +++ b/src/core/libraries/fiber/fiber.h @@ -116,5 +116,8 @@ s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name); s32 PS4_SYSV_ABI sceFiberGetThreadFramePointerAddress(u64* addr_frame_pointer); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Fiber \ No newline at end of file diff --git a/src/core/libraries/font/font.cpp b/src/core/libraries/font/font.cpp index 1454004aaab..7054e676a57 100644 --- a/src/core/libraries/font/font.cpp +++ b/src/core/libraries/font/font.cpp @@ -1364,7 +1364,7 @@ s32 PS4_SYSV_ABI Func_FE7E5AE95D3058F5() { return ORBIS_OK; } -void RegisterlibSceFont(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("CUKn5pX-NVY", "libSceFont", 1, "libSceFont", sceFontAttachDeviceCacheBuffer); LIB_FUNCTION("3OdRkSjOcog", "libSceFont", 1, "libSceFont", sceFontBindRenderer); LIB_FUNCTION("6DFUkCwQLa8", "libSceFont", 1, "libSceFont", sceFontCharacterGetBidiLevel); diff --git a/src/core/libraries/font/font.h b/src/core/libraries/font/font.h index a8e239126e9..baee3c9d097 100644 --- a/src/core/libraries/font/font.h +++ b/src/core/libraries/font/font.h @@ -295,5 +295,8 @@ s32 PS4_SYSV_ABI Func_EAC96B2186B71E14(); s32 PS4_SYSV_ABI Func_FE4788A96EF46256(); s32 PS4_SYSV_ABI Func_FE7E5AE95D3058F5(); -void RegisterlibSceFont(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Font \ No newline at end of file diff --git a/src/core/libraries/font/fontft.cpp b/src/core/libraries/font/fontft.cpp index 4a1dbb98919..1b98b2b21bc 100644 --- a/src/core/libraries/font/fontft.cpp +++ b/src/core/libraries/font/fontft.cpp @@ -113,7 +113,7 @@ s32 PS4_SYSV_ABI sceFontSelectRendererFt() { return ORBIS_OK; } -void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("e60aorDdpB8", "libSceFontFt", 1, "libSceFontFt", sceFontFtInitAliases); LIB_FUNCTION("BxcmiMc3UaA", "libSceFontFt", 1, "libSceFontFt", sceFontFtSetAliasFont); LIB_FUNCTION("MEWjebIzDEI", "libSceFontFt", 1, "libSceFontFt", sceFontFtSetAliasPath); diff --git a/src/core/libraries/font/fontft.h b/src/core/libraries/font/fontft.h index cec6d78725d..03b999a6355 100644 --- a/src/core/libraries/font/fontft.h +++ b/src/core/libraries/font/fontft.h @@ -33,5 +33,8 @@ s32 PS4_SYSV_ABI sceFontSelectGlyphsFt(); s32 PS4_SYSV_ABI sceFontSelectLibraryFt(); s32 PS4_SYSV_ABI sceFontSelectRendererFt(); -void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::FontFt \ No newline at end of file diff --git a/src/core/libraries/game_live_streaming/gamelivestreaming.cpp b/src/core/libraries/game_live_streaming/gamelivestreaming.cpp index 374eb4c9da9..8e98a3c9a0e 100644 --- a/src/core/libraries/game_live_streaming/gamelivestreaming.cpp +++ b/src/core/libraries/game_live_streaming/gamelivestreaming.cpp @@ -246,7 +246,7 @@ int PS4_SYSV_ABI sceGameLiveStreamingUnregisterCallback() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("caqgDl+V9qA", "libSceGameLiveStreaming_debug", 1, "libSceGameLiveStreaming", sceGameLiveStreamingStartDebugBroadcast); LIB_FUNCTION("0i8Lrllxwow", "libSceGameLiveStreaming_debug", 1, "libSceGameLiveStreaming", diff --git a/src/core/libraries/game_live_streaming/gamelivestreaming.h b/src/core/libraries/game_live_streaming/gamelivestreaming.h index 5ceee8ff515..1b61b909a02 100644 --- a/src/core/libraries/game_live_streaming/gamelivestreaming.h +++ b/src/core/libraries/game_live_streaming/gamelivestreaming.h @@ -78,5 +78,8 @@ int PS4_SYSV_ABI sceGameLiveStreamingStopSocialFeedbackMessageFiltering(); int PS4_SYSV_ABI sceGameLiveStreamingTerminate(); int PS4_SYSV_ABI sceGameLiveStreamingUnregisterCallback(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::GameLiveStreaming \ No newline at end of file diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index f8886e3fff5..638d96ae171 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -20,13 +20,12 @@ #include "core/libraries/videoout/video_out.h" #include "core/memory.h" #include "core/platform.h" +#include "shadps4_app.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/amdgpu/pm4_cmds.h" #include "video_core/renderer_vulkan/vk_presenter.h" extern Frontend::WindowSDL* g_window; -std::unique_ptr presenter; -std::unique_ptr liverpool; namespace Libraries::GnmDriver { @@ -304,15 +303,17 @@ void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) { } auto vqid = gnm_vqid - 1; - auto& asc_queue = liverpool->asc_queues[{vqid}]; + auto& asc_queue = + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->asc_queues[{vqid}]; auto& offs_dw = asc_next_offs_dw[vqid]; if (next_offs_dw < offs_dw && next_offs_dw != 0) { // For cases if a submission is split at the end of the ring buffer, we need to submit it in // two parts to handle the wrap - liverpool->SubmitAsc(gnm_vqid, {reinterpret_cast(asc_queue.map_addr) + offs_dw, - asc_queue.ring_size_dw - offs_dw}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitAsc( + gnm_vqid, {reinterpret_cast(asc_queue.map_addr) + offs_dw, + asc_queue.ring_size_dw - offs_dw}); offs_dw = 0; } @@ -354,7 +355,7 @@ void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) { .base_addr = base_addr, }); } - liverpool->SubmitAsc(gnm_vqid, acb_span); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitAsc(gnm_vqid, acb_span); } void PS4_SYSV_ABI sceGnmDingDongForWorkload(u32 gnm_vqid, u32 next_offs_dw, u64 workload_id) { @@ -1212,13 +1213,15 @@ int PS4_SYSV_ABI sceGnmMapComputeQueue(u32 pipe_id, u32 queue_id, VAddr ring_bas } const auto vqid = - liverpool->asc_queues.insert(VAddr(ring_base_addr), read_ptr_addr, ring_size_dw, pipe_id); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->asc_queues.insert( + VAddr(ring_base_addr), read_ptr_addr, ring_size_dw, pipe_id); // We need to offset index as `dingDong` assumes it to be from the range [1..64] const auto gnm_vqid = vqid.index + 1; LOG_INFO(Lib_GnmDriver, "ASC pipe {} queue {} mapped to vqueue {}", pipe_id, queue_id, gnm_vqid); - const auto& queue = liverpool->asc_queues[vqid]; + const auto& queue = + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->asc_queues[vqid]; *queue.read_addr = 0u; return gnm_vqid; @@ -2226,26 +2229,33 @@ int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload(u32 workload, u32 count, if (send_init_packet) { if (sdk_version < Common::ElfInfo::FW_20) { - liverpool->SubmitGfx(InitSequence, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx(InitSequence, + {}); } else if (sdk_version < Common::ElfInfo::FW_40) { if (sceKernelIsNeoMode()) { if (!UseNeoCompatSequences) { - liverpool->SubmitGfx(InitSequence200Neo, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx( + InitSequence200Neo, {}); } else { - liverpool->SubmitGfx(InitSequence200NeoCompat, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx( + InitSequence200NeoCompat, {}); } } else { - liverpool->SubmitGfx(InitSequence200, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx( + InitSequence200, {}); } } else { if (sceKernelIsNeoMode()) { if (!UseNeoCompatSequences) { - liverpool->SubmitGfx(InitSequence350Neo, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx( + InitSequence350Neo, {}); } else { - liverpool->SubmitGfx(InitSequence350NeoCompat, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx( + InitSequence350NeoCompat, {}); } } else { - liverpool->SubmitGfx(InitSequence350, {}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx( + InitSequence350, {}); } } send_init_packet = false; @@ -2288,7 +2298,8 @@ int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload(u32 workload, u32 count, .base_addr = reinterpret_cast(ccb), }); } - liverpool->SubmitGfx(dcb_span, ccb_span); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitGfx(dcb_span, + ccb_span); } return ORBIS_OK; @@ -2305,10 +2316,10 @@ int PS4_SYSV_ABI sceGnmSubmitDone() { HLE_TRACE; LOG_DEBUG(Lib_GnmDriver, "called"); WaitGpuIdle(); - if (!liverpool->IsGpuIdle()) { + if (!ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->IsGpuIdle()) { submission_lock = true; } - liverpool->SubmitDone(); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SubmitDone(); send_init_packet = true; ++frames_submitted; DebugState.IncGnmFrameNum(); @@ -2316,7 +2327,8 @@ int PS4_SYSV_ABI sceGnmSubmitDone() { } int PS4_SYSV_ABI sceGnmUnmapComputeQueue(u32 vqid) { - liverpool->asc_queues.erase(Common::SlotId{vqid - 1}); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->asc_queues.erase( + Common::SlotId{vqid - 1}); return ORBIS_OK; } @@ -2865,11 +2877,9 @@ int PS4_SYSV_ABI Func_F916890425496553() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { - LOG_INFO(Lib_GnmDriver, "Initializing presenter"); - liverpool = std::make_unique(); - presenter = std::make_unique(*g_window, liverpool.get()); - +Engine::Engine(Core::Loader::SymbolsResolver* sym) + : liverpool(std::make_unique()), + presenter(std::make_unique(*g_window, liverpool.get())) { const s32 result = sceKernelGetCompiledSdkVersion(&sdk_version); if (result != ORBIS_OK) { sdk_version = 0; diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index 2208ca05de0..a4bd69d800c 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -5,6 +5,8 @@ #include "common/types.h" #include "core/libraries/kernel/equeue.h" +#include "video_core/amdgpu/liverpool.h" +#include "video_core/renderer_vulkan/vk_presenter.h" namespace Core::Loader { class SymbolsResolver; @@ -299,5 +301,17 @@ int PS4_SYSV_ABI Func_BFB41C057478F0BF(); int PS4_SYSV_ABI Func_E51D44DB8151238C(); int PS4_SYSV_ABI Func_F916890425496553(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Context { + Context() { + LOG_INFO(Lib_GnmDriver, "Initializing presenter"); + } +}; + +struct Engine : Context { + std::unique_ptr liverpool; + std::unique_ptr presenter; + + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::GnmDriver diff --git a/src/core/libraries/hmd/hmd.cpp b/src/core/libraries/hmd/hmd.cpp index cddfc2ecc07..42fec4d4864 100644 --- a/src/core/libraries/hmd/hmd.cpp +++ b/src/core/libraries/hmd/hmd.cpp @@ -863,7 +863,8 @@ s32 PS4_SYSV_ABI Func_FF2E0E53015FE231() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) + : m_distortion_engine(sym), m_reprojection_engine(sym) { Libraries::Kernel::sceKernelGetCompiledSdkVersion(&g_firmware_version); LIB_FUNCTION("6biw1XHTSqQ", "libSceHmd", 1, "libSceHmd", sceHmdClose); LIB_FUNCTION("BWY-qKM5hxE", "libSceHmd", 1, "libSceHmd", sceHmdGet2DEyeOffset); @@ -1021,9 +1022,6 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("sWZSZB-mnw4", "libSceHmd", 1, "libSceHmd", Func_B16652641FE69F0E); LIB_FUNCTION("-Bk71lPyry4", "libSceHmd", 1, "libSceHmd", Func_FC193BD653F2AF2E); LIB_FUNCTION("-y4OUwFf4jE", "libSceHmd", 1, "libSceHmd", Func_FF2E0E53015FE231); - - RegisterDistortion(sym); - RegisterReprojection(sym); }; } // namespace Libraries::Hmd \ No newline at end of file diff --git a/src/core/libraries/hmd/hmd.h b/src/core/libraries/hmd/hmd.h index 67ee6c1d8ea..85593318e9f 100644 --- a/src/core/libraries/hmd/hmd.h +++ b/src/core/libraries/hmd/hmd.h @@ -261,7 +261,19 @@ s32 PS4_SYSV_ABI Func_B9A6FA0735EC7E49(); s32 PS4_SYSV_ABI Func_FC193BD653F2AF2E(); s32 PS4_SYSV_ABI Func_FF2E0E53015FE231(); -void RegisterDistortion(Core::Loader::SymbolsResolver* sym); -void RegisterReprojection(Core::Loader::SymbolsResolver* sym); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct DistortionEngine { + DistortionEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct ReprojectionEngine { + ReprojectionEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct Engine { + DistortionEngine m_distortion_engine; + ReprojectionEngine m_reprojection_engine; + + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Hmd \ No newline at end of file diff --git a/src/core/libraries/hmd/hmd_distortion.cpp b/src/core/libraries/hmd/hmd_distortion.cpp index 3f454f7d2de..a6a4ca18ef8 100644 --- a/src/core/libraries/hmd/hmd_distortion.cpp +++ b/src/core/libraries/hmd/hmd_distortion.cpp @@ -74,7 +74,7 @@ s32 PS4_SYSV_ABI Func_B614F290B67FB59B() { return ORBIS_OK; } -void RegisterDistortion(Core::Loader::SymbolsResolver* sym) { +DistortionEngine::DistortionEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("gEokC+OGI8g", "libSceHmdDistortion", 1, "libSceHmd", sceHmdDistortionGet2dVrCommand); LIB_FUNCTION("za4xJfzCBcM", "libSceHmd", 1, "libSceHmd", sceHmdDistortionGet2dVrCommand); diff --git a/src/core/libraries/hmd/hmd_reprojection.cpp b/src/core/libraries/hmd/hmd_reprojection.cpp index b94f72c89f9..4a9243acfd2 100644 --- a/src/core/libraries/hmd/hmd_reprojection.cpp +++ b/src/core/libraries/hmd/hmd_reprojection.cpp @@ -175,7 +175,7 @@ s32 PS4_SYSV_ABI Func_B9A6FA0735EC7E49() { return ORBIS_OK; } -void RegisterReprojection(Core::Loader::SymbolsResolver* sym) { +ReprojectionEngine::ReprojectionEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("8gH1aLgty5I", "libsceHmdReprojectionMultilayer", 1, "libSceHmd", sceHmdReprojectionStartMultilayer); LIB_FUNCTION("NTIbBpSH9ik", "libSceHmd", 1, "libSceHmd", sceHmdReprojectionAddDisplayBuffer); diff --git a/src/core/libraries/hmd/hmd_setup_dialog.cpp b/src/core/libraries/hmd/hmd_setup_dialog.cpp index 6af312624ac..2e25e5ac087 100644 --- a/src/core/libraries/hmd/hmd_setup_dialog.cpp +++ b/src/core/libraries/hmd/hmd_setup_dialog.cpp @@ -48,7 +48,7 @@ s32 PS4_SYSV_ABI sceHmdSetupDialogTerminate() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("nmHzU4Gh0xs", "libSceHmdSetupDialog", 1, "libSceHmdSetupDialog", sceHmdSetupDialogClose); LIB_FUNCTION("6lVRHMV5LY0", "libSceHmdSetupDialog", 1, "libSceHmdSetupDialog", diff --git a/src/core/libraries/hmd/hmd_setup_dialog.h b/src/core/libraries/hmd/hmd_setup_dialog.h index b5de5253104..74aa4d54751 100644 --- a/src/core/libraries/hmd/hmd_setup_dialog.h +++ b/src/core/libraries/hmd/hmd_setup_dialog.h @@ -34,5 +34,8 @@ s32 PS4_SYSV_ABI sceHmdSetupDialogOpen(const OrbisHmdSetupDialogParam* param); s32 PS4_SYSV_ABI sceHmdSetupDialogTerminate(); Libraries::CommonDialog::Status PS4_SYSV_ABI sceHmdSetupDialogUpdateStatus(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::HmdSetupDialog \ No newline at end of file diff --git a/src/core/libraries/ime/error_dialog.cpp b/src/core/libraries/ime/error_dialog.cpp index 09a192534b5..2202723228a 100644 --- a/src/core/libraries/ime/error_dialog.cpp +++ b/src/core/libraries/ime/error_dialog.cpp @@ -190,7 +190,7 @@ Status PS4_SYSV_ABI sceErrorDialogUpdateStatus() { return g_status; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("ekXHb1kDBl0", "libSceErrorDialog", 1, "libSceErrorDialog", sceErrorDialogClose); LIB_FUNCTION("t2FvHRXzgqk", "libSceErrorDialog", 1, "libSceErrorDialog", sceErrorDialogGetStatus); diff --git a/src/core/libraries/ime/error_dialog.h b/src/core/libraries/ime/error_dialog.h index 75643b1db64..62bdf203de2 100644 --- a/src/core/libraries/ime/error_dialog.h +++ b/src/core/libraries/ime/error_dialog.h @@ -24,5 +24,8 @@ int PS4_SYSV_ABI sceErrorDialogOpenWithReport(); CommonDialog::Error PS4_SYSV_ABI sceErrorDialogTerminate(); CommonDialog::Status PS4_SYSV_ABI sceErrorDialogUpdateStatus(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::ErrorDialog \ No newline at end of file diff --git a/src/core/libraries/ime/ime.cpp b/src/core/libraries/ime/ime.cpp index 96ae446fa00..1687fa6af75 100644 --- a/src/core/libraries/ime/ime.cpp +++ b/src/core/libraries/ime/ime.cpp @@ -12,8 +12,8 @@ namespace Libraries::Ime { static std::queue g_ime_events; -static ImeState g_ime_state{}; -static ImeUi g_ime_ui; +static std::unique_ptr g_ime_state{}; +static std::unique_ptr g_ime_ui; class ImeHandler { public: @@ -67,14 +67,14 @@ class ImeHandler { }*/ if (ime_mode) { - g_ime_state = ImeState(&m_param.ime, &m_param.ime_ext); - g_ime_ui = ImeUi(&g_ime_state, &m_param.ime, &m_param.ime_ext); + g_ime_state = std::make_unique(&m_param.ime, &m_param.ime_ext); + g_ime_ui = std::make_unique(g_ime_state.get(), &m_param.ime, &m_param.ime_ext); // Queue the Open event so it is delivered on next sceImeUpdate LOG_DEBUG(Lib_Ime, "IME Event queued: Open rect x={}, y={}, w={}, h={}", openEvent.param.rect.x, openEvent.param.rect.y, openEvent.param.rect.width, openEvent.param.rect.height); - g_ime_state.SendEvent(&openEvent); + g_ime_state->SendEvent(&openEvent); } } @@ -84,11 +84,11 @@ class ImeHandler { return Error::OK; } - std::unique_lock lock{g_ime_state.queue_mutex}; + std::unique_lock lock{g_ime_state->queue_mutex}; - while (!g_ime_state.event_queue.empty()) { - OrbisImeEvent event = g_ime_state.event_queue.front(); - g_ime_state.event_queue.pop(); + while (!g_ime_state->event_queue.empty()) { + OrbisImeEvent event = g_ime_state->event_queue.front(); + g_ime_state->event_queue.pop(); Execute(handler, &event, false); } @@ -118,7 +118,7 @@ class ImeHandler { LOG_WARNING(Lib_Ime, "ImeHandler::SetText received null text pointer"); return Error::INVALID_ADDRESS; } - g_ime_state.SetText(text, length); + g_ime_state->SetText(text, length); return Error::OK; } @@ -127,7 +127,7 @@ class ImeHandler { LOG_WARNING(Lib_Ime, "ImeHandler::SetCaret received null caret pointer"); return Error::INVALID_ADDRESS; } - g_ime_state.SetCaret(caret->index); + g_ime_state->SetCaret(caret->index); return Error::OK; } @@ -185,8 +185,8 @@ Error PS4_SYSV_ABI sceImeClose() { LOG_ERROR(Lib_Ime, "Failed to close IME handler, it is still open"); return Error::INTERNAL; } - g_ime_ui = ImeUi(); - g_ime_state = ImeState(); + g_ime_ui = std::make_unique(); + g_ime_state = std::make_unique(); LOG_DEBUG(Lib_Ime, "IME closed successfully"); return Error::OK; @@ -831,7 +831,7 @@ int PS4_SYSV_ABI sceImeVshUpdateContext2() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("mN+ZoSN-8hQ", "libSceIme", 1, "libSceIme", FinalizeImeModule); LIB_FUNCTION("uTW+63goeJs", "libSceIme", 1, "libSceIme", InitializeImeModule); LIB_FUNCTION("Lf3DeGWC6xg", "libSceIme", 1, "libSceIme", sceImeCheckFilterText); diff --git a/src/core/libraries/ime/ime.h b/src/core/libraries/ime/ime.h index b2b4a51ad4d..06a308f506e 100644 --- a/src/core/libraries/ime/ime.h +++ b/src/core/libraries/ime/ime.h @@ -71,6 +71,9 @@ int PS4_SYSV_ABI sceImeVshUpdate(); int PS4_SYSV_ABI sceImeVshUpdateContext(); int PS4_SYSV_ABI sceImeVshUpdateContext2(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Ime diff --git a/src/core/libraries/ime/ime_dialog.cpp b/src/core/libraries/ime/ime_dialog.cpp index 226570bd6b4..bf272368319 100644 --- a/src/core/libraries/ime/ime_dialog.cpp +++ b/src/core/libraries/ime/ime_dialog.cpp @@ -533,7 +533,7 @@ Error PS4_SYSV_ABI sceImeDialogTerm() { return Error::OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("oBmw4xrmfKs", "libSceImeDialog", 1, "libSceImeDialog", sceImeDialogAbort); LIB_FUNCTION("bX4H+sxPI-o", "libSceImeDialog", 1, "libSceImeDialog", sceImeDialogForceClose); LIB_FUNCTION("UFcyYDf+e88", "libSceImeDialog", 1, "libSceImeDialog", diff --git a/src/core/libraries/ime/ime_dialog.h b/src/core/libraries/ime/ime_dialog.h index 532762ccc61..a83005e2590 100644 --- a/src/core/libraries/ime/ime_dialog.h +++ b/src/core/libraries/ime/ime_dialog.h @@ -49,5 +49,8 @@ int PS4_SYSV_ABI sceImeDialogInitInternal3(); int PS4_SYSV_ABI sceImeDialogSetPanelPosition(); Error PS4_SYSV_ABI sceImeDialogTerm(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::ImeDialog diff --git a/src/core/libraries/jpeg/jpegenc.cpp b/src/core/libraries/jpeg/jpegenc.cpp index 1d22d7e85d9..0c921f7d2c1 100644 --- a/src/core/libraries/jpeg/jpegenc.cpp +++ b/src/core/libraries/jpeg/jpegenc.cpp @@ -197,7 +197,7 @@ s32 PS4_SYSV_ABI sceJpegEncQueryMemorySize(const OrbisJpegEncCreateParam* param) return ORBIS_JPEG_ENC_MINIMUM_MEMORY_SIZE; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("K+rocojkr-I", "libSceJpegEnc", 1, "libSceJpegEnc", sceJpegEncCreate); LIB_FUNCTION("j1LyMdaM+C0", "libSceJpegEnc", 1, "libSceJpegEnc", sceJpegEncDelete); LIB_FUNCTION("QbrU0cUghEM", "libSceJpegEnc", 1, "libSceJpegEnc", sceJpegEncEncode); diff --git a/src/core/libraries/jpeg/jpegenc.h b/src/core/libraries/jpeg/jpegenc.h index e0c39c58d79..bf8fe548d90 100644 --- a/src/core/libraries/jpeg/jpegenc.h +++ b/src/core/libraries/jpeg/jpegenc.h @@ -80,5 +80,8 @@ s32 PS4_SYSV_ABI sceJpegEncEncode(OrbisJpegEncHandle handle, const OrbisJpegEncE OrbisJpegEncOutputInfo* output_info); s32 PS4_SYSV_ABI sceJpegEncQueryMemorySize(const OrbisJpegEncCreateParam* param); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::JpegEnc diff --git a/src/core/libraries/kernel/aio.cpp b/src/core/libraries/kernel/aio.cpp index ee518030e72..8f66b457a0b 100644 --- a/src/core/libraries/kernel/aio.cpp +++ b/src/core/libraries/kernel/aio.cpp @@ -312,7 +312,7 @@ s32 PS4_SYSV_ABI sceKernelAioInitializeParam() { return ORBIS_OK; } -void RegisterAio(Core::Loader::SymbolsResolver* sym) { +AioEngine::AioEngine(Core::Loader::SymbolsResolver* sym) { id_index = 1; id_state = (int*)malloc(sizeof(int) * MAX_QUEUE); memset(id_state, 0, sizeof(sizeof(int) * MAX_QUEUE)); diff --git a/src/core/libraries/kernel/aio.h b/src/core/libraries/kernel/aio.h index 0ad21e93811..1779dd0e9a1 100644 --- a/src/core/libraries/kernel/aio.h +++ b/src/core/libraries/kernel/aio.h @@ -39,5 +39,8 @@ struct OrbisKernelAioRWRequest { s32 fd; }; -void RegisterAio(Core::Loader::SymbolsResolver* sym); +struct AioEngine { + AioEngine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Kernel \ No newline at end of file diff --git a/src/core/libraries/kernel/debug.cpp b/src/core/libraries/kernel/debug.cpp index 5e3b98b7ced..4ab54356fb9 100644 --- a/src/core/libraries/kernel/debug.cpp +++ b/src/core/libraries/kernel/debug.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/assert.h" +#include "core/libraries/kernel/debug.h" #include "core/libraries/kernel/file_system.h" #include "core/libraries/kernel/orbis_error.h" #include "core/libraries/libs.h" @@ -13,7 +14,7 @@ void PS4_SYSV_ABI sceKernelDebugOutText(void* unk, char* text) { return; } -void RegisterDebug(Core::Loader::SymbolsResolver* sym) { +DebugEngine::DebugEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("9JYNqN6jAKI", "libkernel", 1, "libkernel", sceKernelDebugOutText); } diff --git a/src/core/libraries/kernel/debug.h b/src/core/libraries/kernel/debug.h index 177046862bd..ff33fca3b98 100644 --- a/src/core/libraries/kernel/debug.h +++ b/src/core/libraries/kernel/debug.h @@ -9,6 +9,8 @@ class SymbolsResolver; namespace Libraries::Kernel { -void RegisterDebug(Core::Loader::SymbolsResolver* sym); +struct DebugEngine { + DebugEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel \ No newline at end of file diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index 68a6dae2494..301089e6df2 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -15,12 +15,10 @@ #include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" +#include "shadps4_app.h" namespace Libraries::Kernel { -extern boost::asio::io_context io_context; -extern void KernelSignalRequest(); - static std::unordered_map kqueues; static constexpr auto HrTimerSpinlockThresholdNs = 1200000u; @@ -133,7 +131,7 @@ bool EqueueInternal::ScheduleEvent(u64 id, s16 filter, event.event.filter == OrbisKernelEvent::Filter::HrTimer); if (!it->timer) { - it->timer = std::make_unique(io_context, event.timer_interval); + it->timer = std::make_unique(ShadPs4App::GetInstance()->m_hle_layer->m_kernel.io_context, event.timer_interval); } else { // If the timer already exists we are scheduling a reoccurrence after the next period. // Set the expiration time to the previous occurrence plus the period. @@ -153,7 +151,8 @@ bool EqueueInternal::ScheduleEvent(u64 id, s16 filter, } callback(this->m_handle, event_data); }); - KernelSignalRequest(); + + ShadPs4App::GetInstance()->m_hle_layer->m_kernel.KernelSignalRequest(); return true; } @@ -641,7 +640,7 @@ u64 PS4_SYSV_ABI sceKernelGetEventData(const OrbisKernelEvent* ev) { return ev->data; } -void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) { +EventQueueEngine::EventQueueEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("nh2IFMgKTv8", "libScePosix", 1, "libkernel", posix_kqueue); LIB_FUNCTION("RW-GEfpnsqg", "libScePosix", 1, "libkernel", posix_kevent); LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", sceKernelCreateEqueue); diff --git a/src/core/libraries/kernel/equeue.h b/src/core/libraries/kernel/equeue.h index 9b3c73c19bb..bc99fa6ccdf 100644 --- a/src/core/libraries/kernel/equeue.h +++ b/src/core/libraries/kernel/equeue.h @@ -192,6 +192,8 @@ class EqueueInternal { EqueueInternal* GetEqueue(OrbisKernelEqueue eq); u64 PS4_SYSV_ABI sceKernelGetEventData(const OrbisKernelEvent* ev); -void RegisterEventQueue(Core::Loader::SymbolsResolver* sym); +struct EventQueueEngine { + EventQueueEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 085e18b9f51..043e7eff35c 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -1512,7 +1512,7 @@ s32 PS4_SYSV_ABI posix_select(s32 nfds, fd_set* readfds, fd_set* writefds, fd_se } #endif -void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) { +FileSystemEngine::FileSystemEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", open); LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", posix_open); LIB_FUNCTION("wuCroIGjt2g", "libkernel", 1, "libkernel", posix_open); diff --git a/src/core/libraries/kernel/file_system.h b/src/core/libraries/kernel/file_system.h index d8989828a7e..625d8e25a24 100644 --- a/src/core/libraries/kernel/file_system.h +++ b/src/core/libraries/kernel/file_system.h @@ -72,6 +72,9 @@ s64 PS4_SYSV_ABI sceKernelWrite(s32 fd, const void* buf, u64 nbytes); s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, u64 nbytes); s64 PS4_SYSV_ABI sceKernelPread(s32 fd, void* buf, u64 nbytes, s64 offset); s64 PS4_SYSV_ABI sceKernelPwrite(s32 fd, void* buf, u64 nbytes, s64 offset); -void RegisterFileSystem(Core::Loader::SymbolsResolver* sym); + +struct FileSystemEngine { + FileSystemEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index 6594bfab27f..54f2772fa65 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -27,6 +27,7 @@ #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" #include "core/libraries/network/sys_net.h" +#include "core/linker.h" #ifdef _WIN64 #include @@ -41,42 +42,6 @@ namespace Libraries::Kernel { -static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return - -boost::asio::io_context io_context; -static std::mutex m_asio_req; -static std::condition_variable_any cv_asio_req; -static std::atomic asio_requests; -static std::jthread service_thread; - -Core::EntryParams entry_params{}; - -void KernelSignalRequest() { - std::unique_lock lock{m_asio_req}; - ++asio_requests; - cv_asio_req.notify_one(); -} - -static void KernelServiceThread(std::stop_token stoken) { - Common::SetCurrentThreadName("shadPS4:KernelServiceThread"); - - while (!stoken.stop_requested()) { - HLE_TRACE; - { - std::unique_lock lock{m_asio_req}; - Common::CondvarWait(cv_asio_req, lock, stoken, [] { return asio_requests != 0; }); - } - if (stoken.stop_requested()) { - break; - } - - io_context.run(); - io_context.restart(); - - asio_requests = 0; - } -} - static PS4_SYSV_ABI void stack_chk_fail() { UNREACHABLE(); } @@ -144,6 +109,12 @@ void SetPosixErrno(s32 e) { } } +void Engine::KernelSignalRequest() { + std::unique_lock lock{m_asio_req}; + ++asio_requests; + cv_asio_req.notify_one(); +} + static u64 g_mspace_atomic_id_mask = 0; static u64 g_mstate_table[64] = {0}; @@ -259,11 +230,11 @@ s32 PS4_SYSV_ABI sceKernelGetSystemSwVersion(SwVersionStruct* ret) { } s32 PS4_SYSV_ABI getargc() { - return entry_params.argc; + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.entry_params.argc; } const char** PS4_SYSV_ABI getargv() { - return entry_params.argv; + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.entry_params.argv; } s32 PS4_SYSV_ABI get_authinfo(s32 pid, AuthInfoData* p2) { @@ -298,20 +269,31 @@ s32 PS4_SYSV_ABI sceKernelGetAppInfo(s32 pid, OrbisKernelAppInfo* app_info) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { - service_thread = std::jthread{KernelServiceThread}; +void Engine::KernelServiceThread(const std::stop_token& stoken) { + Common::SetCurrentThreadName("shadPS4:KernelServiceThread"); + + while (!stoken.stop_requested()) { + HLE_TRACE; + { + std::unique_lock lock{m_asio_req}; + Common::CondvarWait(cv_asio_req, lock, stoken, [this] { return asio_requests != 0; }); + } + if (stoken.stop_requested()) { + break; + } + + io_context.run(); + io_context.restart(); - Libraries::Kernel::RegisterFileSystem(sym); - Libraries::Kernel::RegisterTime(sym); - Libraries::Kernel::RegisterThreads(sym); - Libraries::Kernel::RegisterKernelEventFlag(sym); - Libraries::Kernel::RegisterMemory(sym); - Libraries::Kernel::RegisterEventQueue(sym); - Libraries::Kernel::RegisterProcess(sym); - Libraries::Kernel::RegisterException(sym); - Libraries::Kernel::RegisterAio(sym); - Libraries::Kernel::RegisterDebug(sym); + asio_requests = 0; + } +} +Engine::Engine(Core::Loader::SymbolsResolver* sym) + : m_file_system_engine(sym), m_time_engine(sym), m_threads_engine(sym), + m_kernel_event_flag_engine(sym), m_memory_engine(sym), m_event_queue_engine(sym), + m_process_engine(sym), m_exception_engine(sym), m_aio_engine(sym), m_debug_engine(sym), + service_thread{[this](const std::stop_token& stoken) { KernelServiceThread(stoken); }} { LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", &g_stack_chk_guard); LIB_FUNCTION("D4yla3vx4tY", "libkernel", 1, "libkernel", sceKernelError); LIB_FUNCTION("YeU23Szo3BM", "libkernel", 1, "libkernel", sceKernelGetAllowedSdkVersionOnSystem); @@ -375,4 +357,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("FJmglmTMdr4", "libkernel", 1, "libkernel", getargv); } +Engine::~Engine() { + service_thread.request_stop(); +} + } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/kernel.h b/src/core/libraries/kernel/kernel.h index 315af6b0603..f05056a58c1 100644 --- a/src/core/libraries/kernel/kernel.h +++ b/src/core/libraries/kernel/kernel.h @@ -3,9 +3,25 @@ #pragma once +#include +#include +#include + #include "common/types.h" +#include "core/entry_params.h" +#include "core/libraries/kernel/aio.h" +#include "core/libraries/kernel/debug.h" +#include "core/libraries/kernel/equeue.h" +#include "core/libraries/kernel/file_system.h" +#include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/memory.h" #include "core/libraries/kernel/orbis_error.h" -#include "core/linker.h" +#include "core/libraries/kernel/posix_error.h" +#include "core/libraries/kernel/process.h" +#include "core/libraries/kernel/threads.h" +#include "core/libraries/kernel/threads/exception.h" +#include "core/libraries/kernel/threads/pthread.h" +#include "core/libraries/kernel/time.h" namespace Core::Loader { class SymbolsResolver; @@ -19,7 +35,36 @@ void SetPosixErrno(s32 e); s32* PS4_SYSV_ABI __Error(); const char* PS4_SYSV_ABI sceKernelGetFsSandboxRandomWord(); -extern Core::EntryParams entry_params; +struct Engine { + FileSystemEngine m_file_system_engine; + TimeEngine m_time_engine; + ThreadsEngine m_threads_engine; + KernelEventFlagEngine m_kernel_event_flag_engine; + MemoryEngine m_memory_engine; + EventQueueEngine m_event_queue_engine; + ProcessEngine m_process_engine; + ExceptionEngine m_exception_engine; + AioEngine m_aio_engine; + DebugEngine m_debug_engine; + + Engine(Core::Loader::SymbolsResolver* sym); + ~Engine(); + + static constexpr u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return + + boost::asio::io_context io_context; + std::mutex m_asio_req; + std::condition_variable_any cv_asio_req; + std::atomic asio_requests; + std::jthread service_thread; + + Core::EntryParams entry_params{}; + + void KernelServiceThread(const std::stop_token& stoken); + + void KernelSignalRequest(); +}; + template struct OrbisWrapperImpl; @@ -39,8 +84,6 @@ struct OrbisWrapperImpl { #define CURRENT_FIRMWARE_VERSION 0x13500011 -s32* PS4_SYSV_ABI __Error(); - struct SwVersionStruct { u64 struct_size; char text_representation[0x1c]; @@ -78,6 +121,4 @@ struct OrbisKernelAppInfo { OrbisKernelTitleWorkaround title_workaround; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); - -} // namespace Libraries::Kernel +} // namespace Libraries diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index 378064e44d3..7a6ca008c52 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -807,7 +807,7 @@ s32 PS4_SYSV_ABI sceKernelGetPrtAperture(s32 id, VAddr* address, u64* size) { return ORBIS_OK; } -void RegisterMemory(Core::Loader::SymbolsResolver* sym) { +MemoryEngine::MemoryEngine(Core::Loader::SymbolsResolver* sym) { ASSERT_MSG(sceKernelGetCompiledSdkVersion(&g_sdk_version) == ORBIS_OK, "Failed to get compiled SDK verision."); diff --git a/src/core/libraries/kernel/memory.h b/src/core/libraries/kernel/memory.h index 9f78eb84faa..93d84cac902 100644 --- a/src/core/libraries/kernel/memory.h +++ b/src/core/libraries/kernel/memory.h @@ -186,6 +186,8 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolGetBlockStats(OrbisKernelMemoryPoolBlockStat s32 PS4_SYSV_ABI sceKernelMunmap(void* addr, u64 len); -void RegisterMemory(Core::Loader::SymbolsResolver* sym); +struct MemoryEngine { + MemoryEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/process.cpp b/src/core/libraries/kernel/process.cpp index 2af5aa1bfd0..5b7b74badf1 100644 --- a/src/core/libraries/kernel/process.cpp +++ b/src/core/libraries/kernel/process.cpp @@ -284,7 +284,7 @@ s32 PS4_SYSV_ABI exit(s32 status) { return 0; } -void RegisterProcess(Core::Loader::SymbolsResolver* sym) { +ProcessEngine::ProcessEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("xeu-pV8wkKs", "libkernel", 1, "libkernel", sceKernelIsInSandbox); LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", sceKernelGetCompiledSdkVersion); LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", sceKernelIsNeoMode); diff --git a/src/core/libraries/kernel/process.h b/src/core/libraries/kernel/process.h index 6296fe404fe..901020dbf7e 100644 --- a/src/core/libraries/kernel/process.h +++ b/src/core/libraries/kernel/process.h @@ -30,6 +30,8 @@ s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver); s32 PS4_SYSV_ABI sceKernelGetModuleInfoForUnwind(VAddr addr, s32 flags, OrbisModuleInfoForUnwind* info); -void RegisterProcess(Core::Loader::SymbolsResolver* sym); +struct ProcessEngine { + ProcessEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads.cpp b/src/core/libraries/kernel/threads.cpp index 083dc8ee16c..1bf28d08632 100644 --- a/src/core/libraries/kernel/threads.cpp +++ b/src/core/libraries/kernel/threads.cpp @@ -18,16 +18,9 @@ void PS4_SYSV_ABI ClearStack() { sp = nullptr; } -void RegisterThreads(Core::Loader::SymbolsResolver* sym) { - RegisterMutex(sym); - RegisterCond(sym); - RegisterRwlock(sym); - RegisterSemaphore(sym); - RegisterSpec(sym); - RegisterThreadAttr(sym); - RegisterThread(sym); - RegisterRtld(sym); - RegisterPthreadClean(sym); -} +ThreadsEngine::ThreadsEngine(Core::Loader::SymbolsResolver* sym) + : m_mutex_engine(sym), m_cond_engine(sym), m_rwlock_engine(sym), m_semaphore_engine(sym), + m_spec_engine(sym), m_thread_attr_engine(sym), m_thread_engine(sym), m_rtld_engine(sym), + m_pthread_clean_engine(sym) {} } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads.h b/src/core/libraries/kernel/threads.h index 81535352c2c..16c0e3eaf0a 100644 --- a/src/core/libraries/kernel/threads.h +++ b/src/core/libraries/kernel/threads.h @@ -39,7 +39,19 @@ int PS4_SYSV_ABI posix_pthread_mutex_lock(PthreadMutexT* mutex); int PS4_SYSV_ABI posix_pthread_mutex_unlock(PthreadMutexT* mutex); int PS4_SYSV_ABI posix_pthread_mutex_destroy(PthreadMutexT* mutex); -void RegisterThreads(Core::Loader::SymbolsResolver* sym); +struct ThreadsEngine { + MutexEngine m_mutex_engine; + CondEngine m_cond_engine; + RwlockEngine m_rwlock_engine; + SemaphoreEngine m_semaphore_engine; + SpecEngine m_spec_engine; + ThreadAttrEngine m_thread_attr_engine; + ThreadEngine m_thread_engine; + RtldEngine m_rtld_engine; + PthreadCleanEngine m_pthread_clean_engine; + + ThreadsEngine(Core::Loader::SymbolsResolver* sym); +}; void PS4_SYSV_ABI ClearStack(); diff --git a/src/core/libraries/kernel/threads/condvar.cpp b/src/core/libraries/kernel/threads/condvar.cpp index 9d429ed7d34..34218b9a9a4 100644 --- a/src/core/libraries/kernel/threads/condvar.cpp +++ b/src/core/libraries/kernel/threads/condvar.cpp @@ -336,7 +336,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_setpshared(PthreadCondAttrT* attr, int p return 0; } -void RegisterCond(Core::Loader::SymbolsResolver* sym) { +CondEngine::CondEngine(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", posix_pthread_condattr_init); LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", posix_pthread_condattr_destroy); diff --git a/src/core/libraries/kernel/threads/event_flag.cpp b/src/core/libraries/kernel/threads/event_flag.cpp index 7f2fdb16339..7d972578921 100644 --- a/src/core/libraries/kernel/threads/event_flag.cpp +++ b/src/core/libraries/kernel/threads/event_flag.cpp @@ -371,7 +371,7 @@ int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, return result; } -void RegisterKernelEventFlag(Core::Loader::SymbolsResolver* sym) { +KernelEventFlagEngine::KernelEventFlagEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("PZku4ZrXJqg", "libkernel", 1, "libkernel", sceKernelCancelEventFlag); LIB_FUNCTION("7uhBFWRAS60", "libkernel", 1, "libkernel", sceKernelClearEventFlag); LIB_FUNCTION("s9-RaxukuzQ", "libkernel", 1, "libkernel", sceKernelCloseEventFlag); diff --git a/src/core/libraries/kernel/threads/exception.cpp b/src/core/libraries/kernel/threads/exception.cpp index e2fd032f5ec..360f2be86e1 100644 --- a/src/core/libraries/kernel/threads/exception.cpp +++ b/src/core/libraries/kernel/threads/exception.cpp @@ -459,7 +459,7 @@ s32 PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode(s32 error, s64 unk) { return ORBIS_OK; } -void RegisterException(Core::Loader::SymbolsResolver* sym) { +ExceptionEngine::ExceptionEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("il03nluKfMk", "libkernel_unity", 1, "libkernel", sceKernelRaiseException); LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel", sceKernelInstallExceptionHandler); diff --git a/src/core/libraries/kernel/threads/exception.h b/src/core/libraries/kernel/threads/exception.h index c07242c1d73..14a50fcbc99 100644 --- a/src/core/libraries/kernel/threads/exception.h +++ b/src/core/libraries/kernel/threads/exception.h @@ -186,6 +186,8 @@ struct Ucontext { s32 NativeToOrbisSignal(s32 s); s32 OrbisToNativeSignal(s32 s); -void RegisterException(Core::Loader::SymbolsResolver* sym); +struct ExceptionEngine { + ExceptionEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/mutex.cpp b/src/core/libraries/kernel/threads/mutex.cpp index 51d2d3bcd12..66ec10aa6f3 100644 --- a/src/core/libraries/kernel/threads/mutex.cpp +++ b/src/core/libraries/kernel/threads/mutex.cpp @@ -431,7 +431,7 @@ s32 PS4_SYSV_ABI posix_pthread_mutexattr_setpshared(PthreadMutexAttrT* attr, s32 return ORBIS_OK; } -void RegisterMutex(Core::Loader::SymbolsResolver* sym) { +MutexEngine::MutexEngine(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", posix_pthread_mutex_init); LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", posix_pthread_mutex_lock); diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index 3742db5cf0a..8d84cdd8295 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -35,7 +35,9 @@ static void ExitThread() { } auto* thread_state = ThrState::Instance(); - ASSERT(thread_state->active_threads.fetch_sub(1) != 1); + if (thread_state->active_threads.fetch_sub(1) == 1) { + LOG_WARNING(Kernel_Pthread, "Exiting last thread."); + } curthread->lock.lock(); curthread->state = PthreadState::Dead; @@ -127,7 +129,9 @@ static int JoinThread(PthreadT pthread, void** thread_return, const OrbisKernelT }; PthreadCleanup cup{backout_join, pthread, 0}; - curthread->cleanup.push_front(&cup); + if (curthread != nullptr) { + curthread->cleanup.push_front(&cup); + } //_thr_cancel_enter(curthread); @@ -139,7 +143,9 @@ static int JoinThread(PthreadT pthread, void** thread_return, const OrbisKernelT } //_thr_cancel_leave(curthread, 0); - curthread->cleanup.pop_front(); + if (curthread != nullptr) { + curthread->cleanup.pop_front(); + } if (ret == POSIX_ETIMEDOUT) { backout_join(pthread); @@ -640,7 +646,7 @@ int PS4_SYSV_ABI scePthreadSetaffinity(PthreadT thread, const u64 mask) { return posix_pthread_setaffinity_np(thread, sizeof(Cpuset), &cpuset); } -void RegisterThread(Core::Loader::SymbolsResolver* sym) { +ThreadEngine::ThreadEngine(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("Z4QosVuAsA0", "libScePosix", 1, "libkernel", posix_pthread_once); LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", posix_pthread_equal); diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index fed3b96fe6b..042ae40bf8b 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -352,15 +352,44 @@ using PthreadT = Pthread*; extern thread_local Pthread* g_curthread; -void RegisterMutex(Core::Loader::SymbolsResolver* sym); -void RegisterCond(Core::Loader::SymbolsResolver* sym); -void RegisterRwlock(Core::Loader::SymbolsResolver* sym); -void RegisterSemaphore(Core::Loader::SymbolsResolver* sym); -void RegisterSpec(Core::Loader::SymbolsResolver* sym); -void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym); -void RegisterThread(Core::Loader::SymbolsResolver* sym); -void RegisterRtld(Core::Loader::SymbolsResolver* sym); -void RegisterKernelEventFlag(Core::Loader::SymbolsResolver* sym); -void RegisterPthreadClean(Core::Loader::SymbolsResolver* sym); +struct MutexEngine { + MutexEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct CondEngine { + CondEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct RwlockEngine { + RwlockEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct SemaphoreEngine { + SemaphoreEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct SpecEngine { + SpecEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct ThreadAttrEngine { + ThreadAttrEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct ThreadEngine { + ThreadEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct RtldEngine { + RtldEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct KernelEventFlagEngine { + KernelEventFlagEngine(Core::Loader::SymbolsResolver* sym); +}; + +struct PthreadCleanEngine { + PthreadCleanEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/pthread_attr.cpp b/src/core/libraries/kernel/threads/pthread_attr.cpp index 2f3f2604959..6f71605f54c 100644 --- a/src/core/libraries/kernel/threads/pthread_attr.cpp +++ b/src/core/libraries/kernel/threads/pthread_attr.cpp @@ -284,7 +284,7 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(PthreadAttrT* attr, const u64 mask) { return posix_pthread_attr_setaffinity_np(attr, sizeof(Cpuset), &cpuset); } -void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) { +ThreadAttrEngine::ThreadAttrEngine(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", posix_pthread_attr_init); LIB_FUNCTION("vQm4fDEsWi8", "libScePosix", 1, "libkernel", posix_pthread_attr_getstack); diff --git a/src/core/libraries/kernel/threads/pthread_clean.cpp b/src/core/libraries/kernel/threads/pthread_clean.cpp index 45a134b70af..7012e11285d 100644 --- a/src/core/libraries/kernel/threads/pthread_clean.cpp +++ b/src/core/libraries/kernel/threads/pthread_clean.cpp @@ -41,7 +41,7 @@ void PS4_SYSV_ABI posix_pthread_cleanup_pop(int execute) { } } -void RegisterPthreadClean(Core::Loader::SymbolsResolver* sym) { +PthreadCleanEngine::PthreadCleanEngine(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("4ZeZWcMsAV0", "libScePosix", 1, "libkernel", posix_pthread_cleanup_push); LIB_FUNCTION("RVxb0Ssa5t0", "libScePosix", 1, "libkernel", posix_pthread_cleanup_pop); diff --git a/src/core/libraries/kernel/threads/pthread_spec.cpp b/src/core/libraries/kernel/threads/pthread_spec.cpp index 38032f1742e..363c41cd37e 100644 --- a/src/core/libraries/kernel/threads/pthread_spec.cpp +++ b/src/core/libraries/kernel/threads/pthread_spec.cpp @@ -139,7 +139,7 @@ const void* PS4_SYSV_ABI posix_pthread_getspecific(PthreadKeyT key) { return nullptr; } -void RegisterSpec(Core::Loader::SymbolsResolver* sym) { +SpecEngine::SpecEngine(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("mqULNdimTn0", "libScePosix", 1, "libkernel", posix_pthread_key_create); LIB_FUNCTION("6BpEZuDT7YI", "libScePosix", 1, "libkernel", posix_pthread_key_delete); diff --git a/src/core/libraries/kernel/threads/rwlock.cpp b/src/core/libraries/kernel/threads/rwlock.cpp index 52109b58d87..0a2fa15ad6c 100644 --- a/src/core/libraries/kernel/threads/rwlock.cpp +++ b/src/core/libraries/kernel/threads/rwlock.cpp @@ -233,7 +233,7 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_setpshared(PthreadRwlockAttrT* rwlocka return 0; } -void RegisterRwlock(Core::Loader::SymbolsResolver* sym) { +RwlockEngine::RwlockEngine(Core::Loader::SymbolsResolver* sym) { // Posix-Kernel LIB_FUNCTION("1471ajPzxh0", "libkernel", 1, "libkernel", posix_pthread_rwlock_destroy); LIB_FUNCTION("ytQULN-nhL4", "libkernel", 1, "libkernel", posix_pthread_rwlock_init); diff --git a/src/core/libraries/kernel/threads/semaphore.cpp b/src/core/libraries/kernel/threads/semaphore.cpp index 721b2c21a88..e4db979e8d6 100644 --- a/src/core/libraries/kernel/threads/semaphore.cpp +++ b/src/core/libraries/kernel/threads/semaphore.cpp @@ -397,7 +397,7 @@ s32 PS4_SYSV_ABI scePthreadSemGetvalue(PthreadSem** sem, s32* sval) { return ORBIS_OK; } -void RegisterSemaphore(Core::Loader::SymbolsResolver* sym) { +SemaphoreEngine::SemaphoreEngine(Core::Loader::SymbolsResolver* sym) { // Orbis LIB_FUNCTION("188x57JYp0g", "libkernel", 1, "libkernel", sceKernelCreateSema); LIB_FUNCTION("Zxa0VhQVTsk", "libkernel", 1, "libkernel", sceKernelWaitSema); diff --git a/src/core/libraries/kernel/threads/tcb.cpp b/src/core/libraries/kernel/threads/tcb.cpp index 043d11e4ec4..47956c1f201 100644 --- a/src/core/libraries/kernel/threads/tcb.cpp +++ b/src/core/libraries/kernel/threads/tcb.cpp @@ -90,7 +90,7 @@ void* PS4_SYSV_ABI __tls_get_addr(TlsIndex* index) { return linker->TlsGetAddr(index->ti_module, index->ti_offset); } -void RegisterRtld(Core::Loader::SymbolsResolver* sym) { +RtldEngine::RtldEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("vNe1w4diLCs", "libkernel", 1, "libkernel", __tls_get_addr); } diff --git a/src/core/libraries/kernel/time.cpp b/src/core/libraries/kernel/time.cpp index 3e1648b98f5..b0b7d6a3dcb 100644 --- a/src/core/libraries/kernel/time.cpp +++ b/src/core/libraries/kernel/time.cpp @@ -28,28 +28,27 @@ namespace Libraries::Kernel { -static u64 initial_ptc; -static std::unique_ptr clock; - u64 PS4_SYSV_ABI sceKernelGetTscFrequency() { - return clock->GetTscFrequency(); + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.clock->GetTscFrequency(); } u64 PS4_SYSV_ABI sceKernelGetProcessTime() { // TODO: this timer should support suspends, so initial ptc needs to be updated on wake up - return clock->GetTimeUS(initial_ptc); + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.clock->GetTimeUS( + ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.initial_ptc); } u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() { - return clock->GetUptime() - initial_ptc; + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.clock->GetUptime() - + ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.initial_ptc; } u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency() { - return clock->GetTscFrequency(); + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.clock->GetTscFrequency(); } u64 PS4_SYSV_ABI sceKernelReadTsc() { - return clock->GetUptime(); + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.clock->GetUptime(); } static s32 posix_nanosleep_impl(const OrbisKernelTimespec* rqtp, OrbisKernelTimespec* rmtp, @@ -474,11 +473,11 @@ s32 PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, namespace Dev { u64& GetInitialPtc() { - return initial_ptc; + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.initial_ptc; } Common::NativeClock* GetClock() { - return clock.get(); + return ShadPs4App::GetInstance()->m_hle_layer->m_kernel.m_time_engine.clock.get(); } } // namespace Dev @@ -543,10 +542,8 @@ s32 PS4_SYSV_ABI sceKernelSettimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimez return ret; } -void RegisterTime(Core::Loader::SymbolsResolver* sym) { - clock = std::make_unique(); - initial_ptc = clock->GetUptime(); - +TimeEngine::TimeEngine(Core::Loader::SymbolsResolver* sym) + : clock(std::make_unique()), initial_ptc(clock->GetUptime()) { // POSIX LIB_FUNCTION("NhpspxdjEKU", "libkernel", 1, "libkernel", posix_nanosleep); LIB_FUNCTION("NhpspxdjEKU", "libScePosix", 1, "libkernel", posix_nanosleep); diff --git a/src/core/libraries/kernel/time.h b/src/core/libraries/kernel/time.h index 583d138b8bc..d12789ecc26 100644 --- a/src/core/libraries/kernel/time.h +++ b/src/core/libraries/kernel/time.h @@ -6,6 +6,7 @@ #include #include #include "common/types.h" +#include "common/native_clock.h" namespace Common { class NativeClock; @@ -87,6 +88,11 @@ s32 PS4_SYSV_ABI posix_clock_settime(s32 clock_id, OrbisKernelTimespec* tp); s32 PS4_SYSV_ABI posix_settimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz); s32 PS4_SYSV_ABI sceKernelSettimeofday(OrbisKernelTimeval* _tv, OrbisKernelTimezone* _tz); -void RegisterTime(Core::Loader::SymbolsResolver* sym); +struct TimeEngine { + std::unique_ptr clock; + u64 initial_ptc; + + TimeEngine(Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries::Kernel diff --git a/src/core/libraries/libc_internal/libc_internal.cpp b/src/core/libraries/libc_internal/libc_internal.cpp index 6a92d2317b9..1932c61145a 100644 --- a/src/core/libraries/libc_internal/libc_internal.cpp +++ b/src/core/libraries/libc_internal/libc_internal.cpp @@ -16,16 +16,11 @@ namespace Libraries::LibcInternal { -void RegisterLib(Core::Loader::SymbolsResolver* sym) { - RegisterlibSceLibcInternalMath(sym); - RegisterlibSceLibcInternalStr(sym); - RegisterlibSceLibcInternalMemory(sym); - RegisterlibSceLibcInternalIo(sym); - RegisterlibSceLibcInternalThreads(sym); -} +EngineV1::EngineV1(Core::Loader::SymbolsResolver* sym) + : m_math_engine(sym), m_str_engine(sym), m_memory_engine(sym), m_io_engine(sym), + m_threads_engine(sym) {} + +// Used to forcibly enable HLEs for broken LLE functions. +EngineV2::EngineV2(Core::Loader::SymbolsResolver* sym) : m_io_engine(sym) {} -void ForceRegisterLib(Core::Loader::SymbolsResolver* sym) { - // Used to forcibly enable HLEs for broken LLE functions. - ForceRegisterlibSceLibcInternalIo(sym); -} } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal.h b/src/core/libraries/libc_internal/libc_internal.h index 1494a2ab281..59892db0439 100644 --- a/src/core/libraries/libc_internal/libc_internal.h +++ b/src/core/libraries/libc_internal/libc_internal.h @@ -4,6 +4,11 @@ #pragma once #include "common/types.h" +#include "libc_internal_io.h" +#include "libc_internal_math.h" +#include "libc_internal_memory.h" +#include "libc_internal_str.h" +#include "libc_internal_threads.h" namespace Core::Loader { class SymbolsResolver; @@ -14,6 +19,22 @@ namespace Libraries::LibcInternal { // I won't manage definitons of 3000+ functions, and they don't need to be accessed externally, // so everything is just in the .cpp file -void RegisterLib(Core::Loader::SymbolsResolver* sym); -void ForceRegisterLib(Core::Loader::SymbolsResolver* sym); +struct EngineV1 { + MathEngine m_math_engine; + StrEngine m_str_engine; + MemoryEngine m_memory_engine; + IoEngineV1 m_io_engine; + ThreadsEngine m_threads_engine; + + EngineV1(Core::Loader::SymbolsResolver* sym); +}; + +struct EngineV2 { + IoEngineV2 m_io_engine; + + EngineV2(Core::Loader::SymbolsResolver* sym); +}; + +using Engine = EngineV2; + } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal_io.cpp b/src/core/libraries/libc_internal/libc_internal_io.cpp index 0bb23eb78c1..2db90974217 100644 --- a/src/core/libraries/libc_internal/libc_internal_io.cpp +++ b/src/core/libraries/libc_internal/libc_internal_io.cpp @@ -463,7 +463,7 @@ s32 PS4_SYSV_ABI internal_fclose(OrbisFILE* file) { return 0; } -void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) { +IoEngineV1::IoEngineV1(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("eLdDw6l0-bU", "libSceLibcInternal", 1, "libSceLibcInternal", internal_snprintf); LIB_FUNCTION("MUjC4lbHrK4", "libSceLibcInternal", 1, "libSceLibcInternal", internal_fflush); LIB_FUNCTION("xGT4Mc55ViQ", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Fofind); @@ -479,7 +479,7 @@ void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) { internal__Unlockfilelock); } -void ForceRegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) { +IoEngineV2::IoEngineV2(Core::Loader::SymbolsResolver* sym) { // Goal is to be minimally intrusive here to allow LLE for printf/stdout writes. LIB_FUNCTION("xeYO4u7uyJ0", "libSceLibcInternal", 1, "libSceLibcInternal", internal_fopen); LIB_FUNCTION("rQFVBXp-Cxg", "libSceLibcInternal", 1, "libSceLibcInternal", internal_fseek); diff --git a/src/core/libraries/libc_internal/libc_internal_io.h b/src/core/libraries/libc_internal/libc_internal_io.h index 27915d8fa22..1fbb6ccdee3 100644 --- a/src/core/libraries/libc_internal/libc_internal_io.h +++ b/src/core/libraries/libc_internal/libc_internal_io.h @@ -6,6 +6,7 @@ #include #include "common/types.h" #include "core/libraries/kernel/threads.h" +#include "common/va_ctx.h" namespace Core::Loader { class SymbolsResolver; @@ -93,6 +94,12 @@ s32 PS4_SYSV_ABI internal__Frprep(OrbisFILE* file); u64 PS4_SYSV_ABI internal_fread(char* ptr, u64 size, u64 nmemb, OrbisFILE* file); s32 PS4_SYSV_ABI internal_fclose(OrbisFILE* file); -void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym); -void ForceRegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym); +struct IoEngineV1 { + IoEngineV1(Core::Loader::SymbolsResolver* sym); +}; + +struct IoEngineV2 { + IoEngineV2(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal_math.cpp b/src/core/libraries/libc_internal/libc_internal_math.cpp index baeefdf27b2..8d4ed67adae 100644 --- a/src/core/libraries/libc_internal/libc_internal_math.cpp +++ b/src/core/libraries/libc_internal/libc_internal_math.cpp @@ -5,6 +5,7 @@ #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "libc_internal_math.h" namespace Libraries::LibcInternal { @@ -114,7 +115,7 @@ float PS4_SYSV_ABI internal_log10f(float x) { return log10f(x); } -void RegisterlibSceLibcInternalMath(Core::Loader::SymbolsResolver* sym) { +MathEngine::MathEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("H8ya2H00jbI", "libSceLibcInternal", 1, "libSceLibcInternal", internal_sin); LIB_FUNCTION("Q4rRL34CEeE", "libSceLibcInternal", 1, "libSceLibcInternal", internal_sinf); LIB_FUNCTION("2WE3BTYVwKM", "libSceLibcInternal", 1, "libSceLibcInternal", internal_cos); diff --git a/src/core/libraries/libc_internal/libc_internal_math.h b/src/core/libraries/libc_internal/libc_internal_math.h index 89b76520566..c76b4f0563b 100644 --- a/src/core/libraries/libc_internal/libc_internal_math.h +++ b/src/core/libraries/libc_internal/libc_internal_math.h @@ -10,5 +10,9 @@ class SymbolsResolver; } namespace Libraries::LibcInternal { -void RegisterlibSceLibcInternalMath(Core::Loader::SymbolsResolver* sym); + +struct MathEngine { + MathEngine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal_memory.cpp b/src/core/libraries/libc_internal/libc_internal_memory.cpp index b7535cde55f..58c0aa6dbf7 100644 --- a/src/core/libraries/libc_internal/libc_internal_memory.cpp +++ b/src/core/libraries/libc_internal/libc_internal_memory.cpp @@ -30,7 +30,7 @@ s32 PS4_SYSV_ABI internal_memcmp(const void* s1, const void* s2, size_t n) { return std::memcmp(s1, s2, n); } -void RegisterlibSceLibcInternalMemory(Core::Loader::SymbolsResolver* sym) { +MemoryEngine::MemoryEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("NFLs+dRJGNg", "libSceLibcInternal", 1, "libSceLibcInternal", internal_memcpy_s); LIB_FUNCTION("Q3VBxCXhUHs", "libSceLibcInternal", 1, "libSceLibcInternal", internal_memcpy); diff --git a/src/core/libraries/libc_internal/libc_internal_memory.h b/src/core/libraries/libc_internal/libc_internal_memory.h index 995de935bec..d48b6421f87 100644 --- a/src/core/libraries/libc_internal/libc_internal_memory.h +++ b/src/core/libraries/libc_internal/libc_internal_memory.h @@ -10,5 +10,9 @@ class SymbolsResolver; } namespace Libraries::LibcInternal { -void RegisterlibSceLibcInternalMemory(Core::Loader::SymbolsResolver* sym); + +struct MemoryEngine { + MemoryEngine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal_str.cpp b/src/core/libraries/libc_internal/libc_internal_str.cpp index a7997a19348..2804d21ca33 100644 --- a/src/core/libraries/libc_internal/libc_internal_str.cpp +++ b/src/core/libraries/libc_internal/libc_internal_str.cpp @@ -60,7 +60,7 @@ const char* PS4_SYSV_ABI internal_strchr(const char* str, int c) { return std::strchr(str, c); } -void RegisterlibSceLibcInternalStr(Core::Loader::SymbolsResolver* sym) { +StrEngine::StrEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("5Xa2ACNECdo", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcpy_s); LIB_FUNCTION("K+gcnFFJKVc", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcat_s); LIB_FUNCTION("aesyjrHVWy4", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcmp); diff --git a/src/core/libraries/libc_internal/libc_internal_str.h b/src/core/libraries/libc_internal/libc_internal_str.h index 26023c40eff..72e7232d921 100644 --- a/src/core/libraries/libc_internal/libc_internal_str.h +++ b/src/core/libraries/libc_internal/libc_internal_str.h @@ -10,5 +10,9 @@ class SymbolsResolver; } namespace Libraries::LibcInternal { -void RegisterlibSceLibcInternalStr(Core::Loader::SymbolsResolver* sym); + +struct StrEngine { + StrEngine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libc_internal/libc_internal_threads.cpp b/src/core/libraries/libc_internal/libc_internal_threads.cpp index 2d8ddaccbea..ca8a483f9bb 100644 --- a/src/core/libraries/libc_internal/libc_internal_threads.cpp +++ b/src/core/libraries/libc_internal/libc_internal_threads.cpp @@ -55,7 +55,7 @@ s32 PS4_SYSV_ABI internal__Mtxdst(Libraries::Kernel::PthreadMutexT* mtx) { return result != 0; } -void RegisterlibSceLibcInternalThreads(Core::Loader::SymbolsResolver* sym) { +ThreadsEngine::ThreadsEngine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("z7STeF6abuU", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxinit); LIB_FUNCTION("pE4Ot3CffW0", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxlock); LIB_FUNCTION("cMwgSSmpE5o", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Mtxunlock); diff --git a/src/core/libraries/libc_internal/libc_internal_threads.h b/src/core/libraries/libc_internal/libc_internal_threads.h index 74e6d41b178..6a9c96dbccb 100644 --- a/src/core/libraries/libc_internal/libc_internal_threads.h +++ b/src/core/libraries/libc_internal/libc_internal_threads.h @@ -18,5 +18,8 @@ s32 PS4_SYSV_ABI internal__Mtxlock(Libraries::Kernel::PthreadMutexT* mtx); s32 PS4_SYSV_ABI internal__Mtxunlock(Libraries::Kernel::PthreadMutexT* mtx); s32 PS4_SYSV_ABI internal__Mtxdst(Libraries::Kernel::PthreadMutexT* mtx); -void RegisterlibSceLibcInternalThreads(Core::Loader::SymbolsResolver* sym); +struct ThreadsEngine { + ThreadsEngine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::LibcInternal \ No newline at end of file diff --git a/src/core/libraries/libpng/pngdec.cpp b/src/core/libraries/libpng/pngdec.cpp index 9c978df2a07..b5acc87602f 100644 --- a/src/core/libraries/libpng/pngdec.cpp +++ b/src/core/libraries/libpng/pngdec.cpp @@ -261,7 +261,7 @@ s32 PS4_SYSV_ABI scePngDecQueryMemorySize(const OrbisPngDecCreateParam* param) { return sizeof(PngHandler); } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("m0uW+8pFyaw", "libScePngDec", 1, "libScePngDec", scePngDecCreate); LIB_FUNCTION("WC216DD3El4", "libScePngDec", 1, "libScePngDec", scePngDecDecode); LIB_FUNCTION("cJ--1xAbj-I", "libScePngDec", 1, "libScePngDec", scePngDecDecodeWithInputControl); diff --git a/src/core/libraries/libpng/pngdec.h b/src/core/libraries/libpng/pngdec.h index b306d610094..c19414e19ea 100644 --- a/src/core/libraries/libpng/pngdec.h +++ b/src/core/libraries/libpng/pngdec.h @@ -79,5 +79,8 @@ s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param, OrbisPngDecImageInfo* imageInfo); s32 PS4_SYSV_ABI scePngDecQueryMemorySize(const OrbisPngDecCreateParam* param); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::PngDec diff --git a/src/core/libraries/libpng/pngenc.cpp b/src/core/libraries/libpng/pngenc.cpp index a17adbf71d1..0a922037b99 100644 --- a/src/core/libraries/libpng/pngenc.cpp +++ b/src/core/libraries/libpng/pngenc.cpp @@ -256,7 +256,7 @@ s32 PS4_SYSV_ABI scePngEncQueryMemorySize(const OrbisPngEncCreateParam* param) { return sizeof(PngHandler); } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("7aGTPfrqT9s", "libScePngEnc", 1, "libScePngEnc", scePngEncCreate); LIB_FUNCTION("RUrWdwTWZy8", "libScePngEnc", 1, "libScePngEnc", scePngEncDelete); LIB_FUNCTION("xgDjJKpcyHo", "libScePngEnc", 1, "libScePngEnc", scePngEncEncode); diff --git a/src/core/libraries/libpng/pngenc.h b/src/core/libraries/libpng/pngenc.h index 1e654934056..fac87d7d372 100644 --- a/src/core/libraries/libpng/pngenc.h +++ b/src/core/libraries/libpng/pngenc.h @@ -63,5 +63,8 @@ s32 PS4_SYSV_ABI scePngEncEncode(OrbisPngEncHandle, const OrbisPngEncEncodeParam OrbisPngEncOutputInfo* outputInfo); s32 PS4_SYSV_ABI scePngEncQueryMemorySize(const OrbisPngEncCreateParam* param); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::PngEnc \ No newline at end of file diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 6db1ba18de5..6e06c201ba9 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/emulator_settings.h" #include "core/libraries/ajm/ajm.h" #include "core/libraries/app_content/app_content.h" #include "core/libraries/audio/audioin.h" @@ -12,6 +13,7 @@ #include "core/libraries/companion/companion_httpd.h" #include "core/libraries/companion/companion_util.h" #include "core/libraries/disc_map/disc_map.h" +#include "core/libraries/fiber/fiber.h" #include "core/libraries/game_live_streaming/gamelivestreaming.h" #include "core/libraries/gnmdriver/gnmdriver.h" #include "core/libraries/hmd/hmd.h" @@ -31,6 +33,8 @@ #include "core/libraries/network/netctl.h" #include "core/libraries/network/ssl.h" #include "core/libraries/network/ssl2.h" +#include "core/libraries/ngs2/ngs2.h" +#include "core/libraries/ngs2/ngs2_eq.h" #include "core/libraries/np/np_auth.h" #include "core/libraries/np/np_commerce.h" #include "core/libraries/np/np_common.h" @@ -73,89 +77,64 @@ #include "core/libraries/vr_tracker/vr_tracker.h" #include "core/libraries/web_browser_dialog/webbrowserdialog.h" #include "core/libraries/zlib/zlib_sce.h" -#include "fiber/fiber.h" +#include "shadps4_app.h" namespace Libraries { -void InitHLELibs(Core::Loader::SymbolsResolver* sym) { - LOG_INFO(Lib_Kernel, "Initializing HLE libraries"); - Libraries::Kernel::RegisterLib(sym); - Libraries::LibcInternal::ForceRegisterLib(sym); - Libraries::GnmDriver::RegisterLib(sym); - Libraries::VideoOut::RegisterLib(sym); - Libraries::UserService::RegisterLib(sym); - Libraries::SystemService::RegisterLib(sym); - Libraries::CommonDialog::RegisterLib(sym); - Libraries::MsgDialog::RegisterLib(sym); - Libraries::AudioOut::RegisterLib(sym); - Libraries::Http::RegisterLib(sym); - Libraries::Http2::RegisterLib(sym); - Libraries::Net::RegisterLib(sym); - Libraries::NetCtl::RegisterLib(sym); - Libraries::SaveData::RegisterLib(sym); - Libraries::SaveData::Dialog::RegisterLib(sym); - Libraries::Ssl2::RegisterLib(sym); - Libraries::SysModule::RegisterLib(sym); - Libraries::Posix::RegisterLib(sym); - Libraries::AudioIn::RegisterLib(sym); - Libraries::Np::NpCommerce::RegisterLib(sym); - Libraries::Np::NpCommon::RegisterLib(sym); - Libraries::Np::NpManager::RegisterLib(sym); - Libraries::Np::NpMatching2::RegisterLib(sym); - Libraries::Np::NpScore::RegisterLib(sym); - Libraries::Np::NpTrophy::RegisterLib(sym); - Libraries::Np::NpWebApi::RegisterLib(sym); - Libraries::Np::NpWebApi2::RegisterLib(sym); - Libraries::Np::NpProfileDialog::RegisterLib(sym); - Libraries::Np::NpSnsFacebookDialog::RegisterLib(sym); - Libraries::Np::NpAuth::RegisterLib(sym); - Libraries::Np::NpParty::RegisterLib(sym); - Libraries::Np::NpPartner::RegisterLib(sym); - Libraries::Np::NpTus::RegisterLib(sym); - Libraries::ScreenShot::RegisterLib(sym); - Libraries::AppContent::RegisterLib(sym); - Libraries::PngDec::RegisterLib(sym); - Libraries::PlayGo::RegisterLib(sym); - Libraries::PlayGo::Dialog::RegisterLib(sym); - Libraries::Random::RegisterLib(sym); - Libraries::Usbd::RegisterLib(sym); - Libraries::Pad::RegisterLib(sym); - Libraries::SystemGesture::RegisterLib(sym); - Libraries::Ajm::RegisterLib(sym); - Libraries::ErrorDialog::RegisterLib(sym); - Libraries::ImeDialog::RegisterLib(sym); - Libraries::AvPlayer::RegisterLib(sym); - Libraries::Videodec::RegisterLib(sym); - Libraries::Videodec2::RegisterLib(sym); - if (EmulatorSettings.GetAudioBackend() == AudioBackend::OpenAL) { - Libraries::Audio3dOpenAL::RegisterLib(sym); - } else { - Libraries::Audio3d::RegisterLib(sym); - } - Libraries::Ime::RegisterLib(sym); - Libraries::GameLiveStreaming::RegisterLib(sym); - Libraries::SharePlay::RegisterLib(sym); - Libraries::Remoteplay::RegisterLib(sym); - Libraries::RazorCpu::RegisterLib(sym); - Libraries::Move::RegisterLib(sym); - Libraries::Fiber::RegisterLib(sym); - Libraries::Mouse::RegisterLib(sym); - Libraries::WebBrowserDialog::RegisterLib(sym); - Libraries::Zlib::RegisterLib(sym); - Libraries::Hmd::RegisterLib(sym); - Libraries::HmdSetupDialog::RegisterLib(sym); - Libraries::DiscMap::RegisterLib(sym); - Libraries::Ulobjmgr::RegisterLib(sym); - Libraries::SigninDialog::RegisterLib(sym); - Libraries::Camera::RegisterLib(sym); - Libraries::CompanionHttpd::RegisterLib(sym); - Libraries::CompanionUtil::RegisterLib(sym); - Libraries::Voice::RegisterLib(sym); - Libraries::Rudp::RegisterLib(sym); - Libraries::VrTracker::RegisterLib(sym); +HleLayer::HleLayer(Core::Loader::SymbolsResolver* sym) + : m_kernel(sym), m_libc_internal(sym), m_gnm_driver(sym), m_video_out(sym, *m_gnm_driver.presenter), m_user_service(sym), + m_system_service(sym), m_common_dialog(sym), m_msg_dialog(sym), m_audio_out(sym), m_http(sym), + m_http2(sym), m_net(sym), m_net_ctl(sym), m_save_data(sym), m_save_data_dialog(sym), + m_ssl2(sym), m_sys_module(sym), m_posix(sym), m_audio_in(sym), m_np_commerce(sym), + m_np_common(sym), m_np_matching(sym), m_np_matching2(sym), m_np_score(sym), m_np_trophy(sym), + m_np_web_api(sym), m_np_web_api2(sym), m_np_profile_dialog(sym), + m_np_sns_facebook_dialog(sym), m_np_auth(sym), m_np_party(sym), m_np_partner(sym), + m_np_tus(sym), m_screenshot(sym), m_app_content(sym), m_pngdec(sym), m_play_go(sym), + m_play_go_dialog(sym), m_random(sym), m_usbd(sym), m_pad(sym), m_system_gesture(sym), + m_ajm(sym), m_error_dialog(sym), m_ime_dialog(sym), m_avplayer(sym), m_videodec(sym), + m_videodec2(sym), m_audio3d_openal(EmulatorSettings.GetAudioBackend() == AudioBackend::OpenAL + ? std::make_unique(sym) + : nullptr), + m_audio3d(EmulatorSettings.GetAudioBackend() == AudioBackend::SDL + ? std::make_unique(sym) + : nullptr), + m_ime(sym), m_game_live_streaming(sym), m_share_play(sym), m_remote_play(sym), + m_razor_cpu(sym), m_move(sym), m_fiber(sym), m_mouse(sym), m_web_browser_dialog(sym), + m_zlib(sym), m_hmd(sym), m_hmd_setup_dialog(sym), m_disc_map(sym), m_ul_obj_mgr(sym), + m_signin_dialog(sym), m_camera(sym), m_companion_httpd(sym), m_companion_util(sym), + m_voice(sym), m_rudp(sym), m_vr_tracker(sym) {} - // Loading libSceSsl is locked behind a title workaround that currently applies to nothing. - // Libraries::Ssl::RegisterLib(sym); +void HleLayer::load(const std::string_view& module_name, Core::Loader::SymbolsResolver* sym) { + if (module_name == "libSceNgs2.sprx") { + m_ngs2_engine = std::make_unique(sym); + } else if (module_name == "libSceUlt.sprx") { + // TODO m_ult_engine = std::make_unique(sym); + } else if (module_name == "libSceRtc.sprx") { + m_rtc_engine = std::make_unique(sym); + } else if (module_name == "libSceJpegDec.sprx") { + // TODO m_jpeg_dec_engine = std::make_unique(sym); + } else if (module_name == "libSceJpegEnc.sprx") { + m_jpeg_enc_engine = std::make_unique(sym); + } else if (module_name == "libScePngEnc.sprx") { + m_png_enc_engine = std::make_unique(sym); + } else if (module_name == "libSceJson.sprx") { + // TODO m_json_engine = std::make_unique(sym); + } else if (module_name == "libSceJson2.sprx") { + // TODO m_json2_engine = std::make_unique(sym); + } else if (module_name == "libSceLibcInternal.sprx") { + // m_libc_internal = std::make_unique(sym); + m_libc_internal = LibcInternal::Engine(sym); + } else if (module_name == "libSceCesCs.sprx") { + // TODO m_ces_cs_engine = std::make_unique(sym); + } else if (module_name == "libSceAudiodec.sprx") { + // TODO m_audio_dec_engine = std::make_unique(sym); + } else if (module_name == "libSceFont.sprx") { + m_font_engine = std::make_unique(sym); + } else if (module_name == "libSceFontFt.sprx") { + m_font_ft_engine = std::make_unique(sym); + } else if (module_name == "libSceFreeTypeOt.sprx") { + // TODO m_freetype_ot_engine = std::make_unique(sym); + } } } // namespace Libraries diff --git a/src/core/libraries/libs.h b/src/core/libraries/libs.h index 1229e6411d3..f627655663a 100644 --- a/src/core/libraries/libs.h +++ b/src/core/libraries/libs.h @@ -3,9 +3,83 @@ #pragma once +#include "core/libraries/ajm/ajm.h" +#include "core/libraries/app_content/app_content.h" +#include "core/libraries/audio/audioin.h" +#include "core/libraries/audio/audioout.h" +#include "core/libraries/audio3d/audio3d.h" +#include "core/libraries/audio3d/audio3d_openal.h" +#include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/companion//companion_httpd.h" +#include "core/libraries/companion//companion_util.h" +#include "core/libraries/disc_map/disc_map.h" +#include "core/libraries/fiber/fiber.h" +#include "core/libraries/game_live_streaming/gamelivestreaming.h" +#include "core/libraries/gnmdriver/gnmdriver.h" +#include "core/libraries/hmd/hmd.h" +#include "core/libraries/hmd/hmd_setup_dialog.h" +#include "core/libraries/ime/error_dialog.h" +#include "core/libraries/ime/ime.h" +#include "core/libraries/ime/ime_dialog.h" +#include "core/libraries/kernel/kernel.h" +#include "core/libraries/libc_internal/libc_internal.h" +#include "core/libraries/libpng/pngdec.h" +#include "core/libraries/mouse/mouse.h" +#include "core/libraries/move/move.h" +#include "core/libraries/network/http.h" +#include "core/libraries/network/http2.h" +#include "core/libraries/network/net.h" +#include "core/libraries/network/netctl.h" +#include "core/libraries/network/ssl2.h" +#include "core/libraries/ngs2/ngs2.h" +#include "core/libraries/np/np_auth.h" +#include "core/libraries/np/np_commerce.h" +#include "core/libraries/np/np_common.h" +#include "core/libraries/np/np_manager.h" +#include "core/libraries/np/np_matching2.h" +#include "core/libraries/np/np_partner.h" +#include "core/libraries/np/np_party.h" +#include "core/libraries/np/np_profile_dialog.h" +#include "core/libraries/np/np_score.h" +#include "core/libraries/np/np_sns_facebook_dialog.h" +#include "core/libraries/np/np_trophy.h" +#include "core/libraries/np/np_tus.h" +#include "core/libraries/np/np_web_api.h" +#include "core/libraries/np/np_web_api2.h" +#include "core/libraries/pad/pad.h" +#include "core/libraries/playgo/playgo.h" +#include "core/libraries/playgo/playgo_dialog.h" +#include "core/libraries/random/random.h" +#include "core/libraries/razor_cpu/razor_cpu.h" +#include "core/libraries/remote_play/remoteplay.h" +#include "core/libraries/rudp/rudp.h" +#include "core/libraries/save_data/dialog/savedatadialog.h" +#include "core/libraries/save_data/savedata.h" +#include "core/libraries/screenshot/screenshot.h" +#include "core/libraries/share_play/shareplay.h" +#include "core/libraries/signin_dialog/signindialog.h" +#include "core/libraries/sysmodule/sysmodule.h" +#include "core/libraries/system/msgdialog.h" +#include "core/libraries/system/posix.h" +#include "core/libraries/system/systemservice.h" +#include "core/libraries/system_gesture/system_gesture.h" +#include "core/libraries/ulobjmgr/ulobjmgr.h" +#include "core/libraries/usbd/usbd.h" +#include "core/libraries/videodec/videodec.h" +#include "core/libraries/videodec/videodec2.h" +#include "core/libraries/videoout/video_out.h" +#include "core/libraries/voice/voice.h" +#include "core/libraries/vr_tracker/vr_tracker.h" +#include "core/libraries/web_browser_dialog/webbrowserdialog.h" +#include "core/libraries/zlib/zlib_sce.h" +#include "core/linker.h" #include "core/loader/elf.h" #include "core/loader/symbols_resolver.h" #include "core/tls.h" +#include "font/font.h" +#include "font/fontft.h" +#include "jpeg/jpegenc.h" +#include "libpng/pngenc.h" #define LIB_FUNCTION(nid, lib, libversion, mod, function) \ { \ @@ -32,6 +106,99 @@ namespace Libraries { -void InitHLELibs(Core::Loader::SymbolsResolver* sym); +struct Context { + Context() { + LOG_INFO(Lib_Kernel, "Initializing HLE libraries"); + } +}; + +struct HleLayer : public Context { + Kernel::Engine m_kernel; + LibcInternal::Engine m_libc_internal; + GnmDriver::Engine m_gnm_driver; + VideoOut::Engine m_video_out; + UserService::Engine m_user_service; + SystemService::Engine m_system_service; + CommonDialog::Engine m_common_dialog; + MsgDialog::Engine m_msg_dialog; + AudioOut::Engine m_audio_out; + Http::Engine m_http; + Http2::Engine m_http2; + Net::Engine m_net; + NetCtl::Engine m_net_ctl; + SaveData::Engine m_save_data; + SaveData::Dialog::Engine m_save_data_dialog; + Ssl2::Engine m_ssl2; + SysModule::Engine m_sys_module; + Posix::Engine m_posix; + AudioIn::Engine m_audio_in; + Np::NpCommerce::Engine m_np_commerce; + Np::NpCommon::Engine m_np_common; + Np::NpManager::Engine m_np_matching; + Np::NpMatching2::Engine m_np_matching2; + Np::NpScore::Engine m_np_score; + Np::NpTrophy::Engine m_np_trophy; + Np::NpWebApi::Engine m_np_web_api; + Np::NpWebApi2::Engine m_np_web_api2; + Np::NpProfileDialog::Engine m_np_profile_dialog; + Np::NpSnsFacebookDialog::Engine m_np_sns_facebook_dialog; + Np::NpAuth::Engine m_np_auth; + Np::NpParty::Engine m_np_party; + Np::NpPartner::Engine m_np_partner; + Np::NpTus::Engine m_np_tus; + ScreenShot::Engine m_screenshot; + AppContent::Engine m_app_content; + PngDec::Engine m_pngdec; + PlayGo::Engine m_play_go; + PlayGo::Dialog::Engine m_play_go_dialog; + Random::Engine m_random; + Usbd::Engine m_usbd; + Pad::Engine m_pad; + SystemGesture::Engine m_system_gesture; + Ajm::Engine m_ajm; + ErrorDialog::Engine m_error_dialog; + ImeDialog::Engine m_ime_dialog; + AvPlayer::Engine m_avplayer; + Videodec::Engine m_videodec; + Videodec2::Engine m_videodec2; + std::unique_ptr m_audio3d_openal; + std::unique_ptr m_audio3d; + Ime::Engine m_ime; + GameLiveStreaming::Engine m_game_live_streaming; + SharePlay::Engine m_share_play; + Remoteplay::Engine m_remote_play; + RazorCpu::Engine m_razor_cpu; + Move::Engine m_move; + Fiber::Engine m_fiber; + Mouse::Engine m_mouse; + WebBrowserDialog::Engine m_web_browser_dialog; + Zlib::Engine m_zlib; + Hmd::Engine m_hmd; + HmdSetupDialog::Engine m_hmd_setup_dialog; + DiscMap::Engine m_disc_map; + Ulobjmgr::Engine m_ul_obj_mgr; + SigninDialog::Engine m_signin_dialog; + Camera::Engine m_camera; + CompanionHttpd::Engine m_companion_httpd; + CompanionUtil::Engine m_companion_util; + Voice::Engine m_voice; + Rudp::Engine m_rudp; + VrTracker::Engine m_vr_tracker; + + std::unique_ptr m_ngs2_engine; + std::unique_ptr m_rtc_engine; + std::unique_ptr m_jpeg_enc_engine; + std::unique_ptr m_png_enc_engine; + + std::unique_ptr m_font_engine; + std::unique_ptr m_font_ft_engine; + + // Loading libSceSsl is locked behind a title workaround that currently applies to nothing. + // Ssl::Engine m_save_data_dialog; + + HleLayer(Core::Loader::SymbolsResolver* sym); + + void load(const std::string_view& module_name, Core::Loader::SymbolsResolver* sym); +}; } // namespace Libraries diff --git a/src/core/libraries/mouse/mouse.cpp b/src/core/libraries/mouse/mouse.cpp index b2799107bb2..2508835e062 100644 --- a/src/core/libraries/mouse/mouse.cpp +++ b/src/core/libraries/mouse/mouse.cpp @@ -79,7 +79,7 @@ int PS4_SYSV_ABI sceMouseSetProcessPrivilege() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("cAnT0Rw-IwU", "libSceMouse", 1, "libSceMouse", sceMouseClose); LIB_FUNCTION("Ymyy1HSSJLQ", "libSceMouse", 1, "libSceMouse", sceMouseConnectPort); LIB_FUNCTION("BRXOoXQtb+k", "libSceMouse", 1, "libSceMouse", sceMouseDebugGetDeviceId); diff --git a/src/core/libraries/mouse/mouse.h b/src/core/libraries/mouse/mouse.h index 1923434348e..047d807f6a7 100644 --- a/src/core/libraries/mouse/mouse.h +++ b/src/core/libraries/mouse/mouse.h @@ -25,5 +25,8 @@ int PS4_SYSV_ABI sceMouseSetHandType(); int PS4_SYSV_ABI sceMouseSetPointerSpeed(); int PS4_SYSV_ABI sceMouseSetProcessPrivilege(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Mouse \ No newline at end of file diff --git a/src/core/libraries/move/move.cpp b/src/core/libraries/move/move.cpp index b7e86a2d705..ee48f132a0b 100644 --- a/src/core/libraries/move/move.cpp +++ b/src/core/libraries/move/move.cpp @@ -120,7 +120,7 @@ s32 PS4_SYSV_ABI sceMoveTerm() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("j1ITE-EoJmE", "libSceMove", 1, "libSceMove", sceMoveInit); LIB_FUNCTION("HzC60MfjJxU", "libSceMove", 1, "libSceMove", sceMoveOpen); LIB_FUNCTION("GWXTyxs4QbE", "libSceMove", 1, "libSceMove", sceMoveGetDeviceInfo); diff --git a/src/core/libraries/move/move.h b/src/core/libraries/move/move.h index 7300226e389..b7ea1914cb1 100644 --- a/src/core/libraries/move/move.h +++ b/src/core/libraries/move/move.h @@ -43,5 +43,8 @@ struct OrbisMoveData { float temperature; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Move \ No newline at end of file diff --git a/src/core/libraries/network/http.cpp b/src/core/libraries/network/http.cpp index 4d688690838..5e24ac5ba13 100644 --- a/src/core/libraries/network/http.cpp +++ b/src/core/libraries/network/http.cpp @@ -1309,7 +1309,7 @@ int PS4_SYSV_ABI sceHttpWaitRequest() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("hvG6GfBMXg8", "libSceHttp", 1, "libSceHttp", sceHttpAbortRequest); LIB_FUNCTION("JKl06ZIAl6A", "libSceHttp", 1, "libSceHttp", sceHttpAbortRequestForce); LIB_FUNCTION("sWQiqKvYTVA", "libSceHttp", 1, "libSceHttp", sceHttpAbortWaitRequest); diff --git a/src/core/libraries/network/http.h b/src/core/libraries/network/http.h index d373fd2901f..f0d5d9d6918 100644 --- a/src/core/libraries/network/http.h +++ b/src/core/libraries/network/http.h @@ -157,5 +157,8 @@ int PS4_SYSV_ABI sceHttpUriSweepPath(char* dst, const char* src, u64 srcSize); int PS4_SYSV_ABI sceHttpUriUnescape(char* out, u64* require, u64 prepare, const char* in); int PS4_SYSV_ABI sceHttpWaitRequest(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Http diff --git a/src/core/libraries/network/http2.cpp b/src/core/libraries/network/http2.cpp index d71c04aedb6..247578ce651 100644 --- a/src/core/libraries/network/http2.cpp +++ b/src/core/libraries/network/http2.cpp @@ -289,7 +289,7 @@ int PS4_SYSV_ABI sceHttp2WaitAsync() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("AS45QoYHjc4", "libSceHttp2", 1, "libSceHttp2", _Z5dummyv); LIB_FUNCTION("IZ-qjhRqvjk", "libSceHttp2", 1, "libSceHttp2", sceHttp2AbortRequest); LIB_FUNCTION("flPxnowtvWY", "libSceHttp2", 1, "libSceHttp2", sceHttp2AddCookie); diff --git a/src/core/libraries/network/http2.h b/src/core/libraries/network/http2.h index 99359518a33..1573a85ecef 100644 --- a/src/core/libraries/network/http2.h +++ b/src/core/libraries/network/http2.h @@ -68,5 +68,8 @@ int PS4_SYSV_ABI sceHttp2SslEnableOption(); int PS4_SYSV_ABI sceHttp2Term(); int PS4_SYSV_ABI sceHttp2WaitAsync(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Http2 \ No newline at end of file diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 6bf4764c492..3492a9d00f0 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/emulator_settings.h" +#include "shadps4_app.h" #ifdef WIN32 #define _WINSOCK_DEPRECATED_NO_WARNINGS #include @@ -1732,7 +1734,7 @@ int PS4_SYSV_ABI sceNetEmulationSet() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("ZRAJo-A-ukc", "libSceNet", 1, "libSceNet", in6addr_any); LIB_FUNCTION("XCuA-GqjA-k", "libSceNet", 1, "libSceNet", in6addr_loopback); LIB_FUNCTION("VZgoeBxPXUQ", "libSceNet", 1, "libSceNet", sce_net_dummy); diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index 4cb7afdda5c..5b6998b867b 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -491,5 +491,8 @@ int PS4_SYSV_ABI Func_0E707A589F751C68(); int PS4_SYSV_ABI sceNetEmulationGet(); int PS4_SYSV_ABI sceNetEmulationSet(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Net diff --git a/src/core/libraries/network/net_ctl_obj.cpp b/src/core/libraries/network/net_ctl_obj.cpp index 5eb6403c205..34721bba735 100644 --- a/src/core/libraries/network/net_ctl_obj.cpp +++ b/src/core/libraries/network/net_ctl_obj.cpp @@ -7,6 +7,7 @@ #include "core/libraries/network/net_ctl_codes.h" #include "core/libraries/network/net_ctl_obj.h" #include "core/tls.h" +#include "shadps4_app.h" namespace Libraries::NetCtl { diff --git a/src/core/libraries/network/net_resolver.cpp b/src/core/libraries/network/net_resolver.cpp index a66f1519b98..8032b0c4094 100644 --- a/src/core/libraries/network/net_resolver.cpp +++ b/src/core/libraries/network/net_resolver.cpp @@ -9,6 +9,7 @@ #include "net_error.h" #include "net_resolver.h" #include "net_util.h" +#include "shadps4_app.h" namespace Libraries::Net { diff --git a/src/core/libraries/network/netctl.cpp b/src/core/libraries/network/netctl.cpp index 136d6381071..4bf677a2093 100644 --- a/src/core/libraries/network/netctl.cpp +++ b/src/core/libraries/network/netctl.cpp @@ -20,6 +20,7 @@ #include "core/libraries/network/net_ctl_codes.h" #include "core/libraries/network/netctl.h" #include "net_util.h" +#include "shadps4_app.h" namespace Libraries::NetCtl { @@ -598,7 +599,7 @@ int PS4_SYSV_ABI sceNetCtlApRpUnregisterCallback() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("XtClSOC1xcU", "libSceNetBwe", 1, "libSceNetCtl", sceNetBweCheckCallbackIpcInt); LIB_FUNCTION("YALqoY4aeY0", "libSceNetBwe", 1, "libSceNetCtl", sceNetBweClearEventIpcInt); LIB_FUNCTION("ouyROWhGUbM", "libSceNetBwe", 1, "libSceNetCtl", diff --git a/src/core/libraries/network/netctl.h b/src/core/libraries/network/netctl.h index 7f139e8c3e8..7a96d9c96e9 100644 --- a/src/core/libraries/network/netctl.h +++ b/src/core/libraries/network/netctl.h @@ -165,5 +165,8 @@ int PS4_SYSV_ABI sceNetCtlApRpStartWithRetry(); int PS4_SYSV_ABI sceNetCtlApRpStop(); int PS4_SYSV_ABI sceNetCtlApRpUnregisterCallback(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::NetCtl diff --git a/src/core/libraries/network/posix_sockets.cpp b/src/core/libraries/network/posix_sockets.cpp index 164d85896dc..f91ea6a2ea7 100644 --- a/src/core/libraries/network/posix_sockets.cpp +++ b/src/core/libraries/network/posix_sockets.cpp @@ -23,7 +23,7 @@ namespace Libraries::Net { #else #define ERROR_CASE(errname) \ case (errname): \ - *Libraries::Kernel::__Error() = ORBIS_NET_##errname; \ + *Libraries::Kernel::__Error() = ORBIS_NET_##errname; \ return -1; #endif diff --git a/src/core/libraries/network/ssl.cpp b/src/core/libraries/network/ssl.cpp index c3720d788fa..c5f670d2ad1 100644 --- a/src/core/libraries/network/ssl.cpp +++ b/src/core/libraries/network/ssl.cpp @@ -1059,7 +1059,7 @@ int PS4_SYSV_ABI Func_28F8791A771D39C7() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("Pgt0gg14ewU", "libSceSsl", 1, "libSceSsl", CA_MGMT_allocCertDistinguishedName); LIB_FUNCTION("wJ5jCpkCv-c", "libSceSsl", 1, "libSceSsl", CA_MGMT_certDistinguishedNameCompare); LIB_FUNCTION("Vc2tb-mWu78", "libSceSsl", 1, "libSceSsl", CA_MGMT_convertKeyBlobToPKCS8Key); diff --git a/src/core/libraries/network/ssl.h b/src/core/libraries/network/ssl.h index fd55f528e98..8dc5d6d03b3 100644 --- a/src/core/libraries/network/ssl.h +++ b/src/core/libraries/network/ssl.h @@ -227,5 +227,8 @@ int PS4_SYSV_ABI VLONG_freeVlongQueue(); int PS4_SYSV_ABI Func_22E76E60BC0587D7(); int PS4_SYSV_ABI Func_28F8791A771D39C7(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Ssl diff --git a/src/core/libraries/network/ssl2.cpp b/src/core/libraries/network/ssl2.cpp index 3a7fd71e56d..2172ff52dd6 100644 --- a/src/core/libraries/network/ssl2.cpp +++ b/src/core/libraries/network/ssl2.cpp @@ -313,7 +313,7 @@ int PS4_SYSV_ABI Func_28F8791A771D39C7() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("Md+HYkCBZB4", "libSceSsl", 1, "libSceSsl", CA_MGMT_extractKeyBlobEx); LIB_FUNCTION("9bKYzKP6kYU", "libSceSsl", 1, "libSceSsl", CA_MGMT_extractPublicKeyInfo); LIB_FUNCTION("ipLIammTj2Q", "libSceSsl", 1, "libSceSsl", CA_MGMT_freeKeyBlob); diff --git a/src/core/libraries/network/ssl2.h b/src/core/libraries/network/ssl2.h index 18fb205d3a7..6690d36dca3 100644 --- a/src/core/libraries/network/ssl2.h +++ b/src/core/libraries/network/ssl2.h @@ -22,5 +22,8 @@ struct OrbisSslCaCerts { void* pool; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Ssl2 \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2.cpp b/src/core/libraries/ngs2/ngs2.cpp index 97d19c3522d..19504b1c7f6 100644 --- a/src/core/libraries/ngs2/ngs2.cpp +++ b/src/core/libraries/ngs2/ngs2.cpp @@ -519,7 +519,7 @@ int PS4_SYSV_ABI sceNgs2VoiceRunCommands() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("3pCNbVM11UA", "libSceNgs2", 1, "libSceNgs2", sceNgs2CalcWaveformBlock); LIB_FUNCTION("6qN1zaEZuN0", "libSceNgs2", 1, "libSceNgs2", sceNgs2CustomRackGetModuleInfo); LIB_FUNCTION("Kg1MA5j7KFk", "libSceNgs2", 1, "libSceNgs2", sceNgs2FftInit); diff --git a/src/core/libraries/ngs2/ngs2.h b/src/core/libraries/ngs2/ngs2.h index 4a5724d0f47..e4530efcd76 100644 --- a/src/core/libraries/ngs2/ngs2.h +++ b/src/core/libraries/ngs2/ngs2.h @@ -269,6 +269,9 @@ struct OrbisNgs2VoiceState { u32 stateFlags; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Ngs2 diff --git a/src/core/libraries/np/np_auth.cpp b/src/core/libraries/np/np_auth.cpp index a9c2181b9a2..3777e19db6c 100644 --- a/src/core/libraries/np/np_auth.cpp +++ b/src/core/libraries/np/np_auth.cpp @@ -10,6 +10,7 @@ #include "core/libraries/np/np_auth_error.h" #include "core/libraries/np/np_error.h" #include "core/libraries/system/userservice.h" +#include "shadps4_app.h" namespace Libraries::Np::NpAuth { @@ -362,7 +363,7 @@ s32 PS4_SYSV_ABI sceNpAuthDeleteRequest(s32 req_id) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { g_signed_in = EmulatorSettings.IsPSNSignedIn(); LIB_FUNCTION("6bwFkosYRQg", "libSceNpAuth", 1, "libSceNpAuth", sceNpAuthCreateRequest); diff --git a/src/core/libraries/np/np_auth.h b/src/core/libraries/np/np_auth.h index 0894bd85d72..d07f3c24e4a 100644 --- a/src/core/libraries/np/np_auth.h +++ b/src/core/libraries/np/np_auth.h @@ -55,5 +55,8 @@ struct OrbisNpAuthGetIdTokenParameterA { const char* scope; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpAuth \ No newline at end of file diff --git a/src/core/libraries/np/np_commerce.cpp b/src/core/libraries/np/np_commerce.cpp index 99b03384a93..6c889f38c94 100644 --- a/src/core/libraries/np/np_commerce.cpp +++ b/src/core/libraries/np/np_commerce.cpp @@ -102,7 +102,7 @@ s32 PS4_SYSV_ABI sceNpCommerceShowPsStoreIcon(s16 icon) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("NU3ckGHMFXo", "libSceNpCommerce", 1, "libSceNpCommerce", sceNpCommerceDialogClose); LIB_FUNCTION("r42bWcQbtZY", "libSceNpCommerce", 1, "libSceNpCommerce", diff --git a/src/core/libraries/np/np_commerce.h b/src/core/libraries/np/np_commerce.h index 003e85a58b8..85b4a9afe35 100644 --- a/src/core/libraries/np/np_commerce.h +++ b/src/core/libraries/np/np_commerce.h @@ -11,6 +11,9 @@ class SymbolsResolver; namespace Libraries::Np::NpCommerce { -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpCommerce \ No newline at end of file diff --git a/src/core/libraries/np/np_common.cpp b/src/core/libraries/np/np_common.cpp index ce0c3799a11..df6965db621 100644 --- a/src/core/libraries/np/np_common.cpp +++ b/src/core/libraries/np/np_common.cpp @@ -91,7 +91,7 @@ s32 PS4_SYSV_ABI sceNpCmpOnlineId(OrbisNpOnlineId* online_id1, OrbisNpOnlineId* return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("i8UmXTSq7N4", "libSceNpCommonCompat", 1, "libSceNpCommon", sceNpCmpNpId); LIB_FUNCTION("TcwEFnakiSc", "libSceNpCommonCompat", 1, "libSceNpCommon", sceNpCmpNpIdInOrder); LIB_FUNCTION("dj+O5aD2a0Q", "libSceNpCommonCompat", 1, "libSceNpCommon", sceNpCmpOnlineId); diff --git a/src/core/libraries/np/np_common.h b/src/core/libraries/np/np_common.h index a130f9c1dd9..bf0c35994f4 100644 --- a/src/core/libraries/np/np_common.h +++ b/src/core/libraries/np/np_common.h @@ -17,5 +17,8 @@ struct OrbisNpFreeKernelMemoryArgs { void* addr; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpCommon \ No newline at end of file diff --git a/src/core/libraries/np/np_manager.cpp b/src/core/libraries/np/np_manager.cpp index 0ffbb682af6..516818da3bc 100644 --- a/src/core/libraries/np/np_manager.cpp +++ b/src/core/libraries/np/np_manager.cpp @@ -13,6 +13,7 @@ #include "core/libraries/np/np_error.h" #include "core/libraries/np/np_manager.h" #include "core/tls.h" +#include "shadps4_app.h" namespace Libraries::Np::NpManager { @@ -786,7 +787,7 @@ void DeregisterNpCallback(std::string key) { g_np_callbacks.erase(key); } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { g_signed_in = EmulatorSettings.IsPSNSignedIn(); LIB_FUNCTION("GpLQDNKICac", "libSceNpManager", 1, "libSceNpManager", sceNpCreateRequest); diff --git a/src/core/libraries/np/np_manager.h b/src/core/libraries/np/np_manager.h index 49250db031b..3c4321f0e06 100644 --- a/src/core/libraries/np/np_manager.h +++ b/src/core/libraries/np/np_manager.h @@ -98,5 +98,8 @@ s32 PS4_SYSV_ABI sceNpGetNpId(Libraries::UserService::OrbisUserServiceUserId use s32 PS4_SYSV_ABI sceNpGetOnlineId(Libraries::UserService::OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpManager diff --git a/src/core/libraries/np/np_matching2.cpp b/src/core/libraries/np/np_matching2.cpp index dcd2a9c233e..2ca4c110889 100644 --- a/src/core/libraries/np/np_matching2.cpp +++ b/src/core/libraries/np/np_matching2.cpp @@ -12,6 +12,7 @@ #include "core/libraries/np/np_matching2.h" #include "core/libraries/np/np_types.h" #include "core/libraries/system/userservice.h" +#include "shadps4_app.h" namespace Libraries::Np::NpMatching2 { @@ -768,7 +769,7 @@ int PS4_SYSV_ABI sceNpMatching2SetRoomDataInternal(OrbisNpMatching2ContextId ctx return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("10t3e5+JPnU", "libSceNpMatching2", 1, "libSceNpMatching2", sceNpMatching2Initialize); LIB_FUNCTION("Mqp3lJ+sjy4", "libSceNpMatching2", 1, "libSceNpMatching2", diff --git a/src/core/libraries/np/np_matching2.h b/src/core/libraries/np/np_matching2.h index 6f7fca90012..5e0180f2b8a 100644 --- a/src/core/libraries/np/np_matching2.h +++ b/src/core/libraries/np/np_matching2.h @@ -44,5 +44,8 @@ constexpr OrbisNpMatching2Event ORBIS_NP_MATCHING2_CONTEXT_EVENT_STARTED = 0x6F0 constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ERROR = 10; constexpr OrbisNpMatching2EventCause ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION = 11; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpMatching2 \ No newline at end of file diff --git a/src/core/libraries/np/np_partner.cpp b/src/core/libraries/np/np_partner.cpp index 447144344ff..85628b8c650 100644 --- a/src/core/libraries/np/np_partner.cpp +++ b/src/core/libraries/np/np_partner.cpp @@ -69,7 +69,7 @@ s32 PS4_SYSV_ABI Func_F8E9DB52CD425743(UserService::OrbisUserServiceUserId user_ return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("pMxXhNozUX8", "libSceNpPartner001", 1, "libSceNpPartner001", Func_A4CC5784DA33517F); LIB_FUNCTION("pQfYTZHznMc", "libSceNpPartner001", 1, "libSceNpPartner001", diff --git a/src/core/libraries/np/np_partner.h b/src/core/libraries/np/np_partner.h index 4cb2a6f5f7f..ffedcc965c8 100644 --- a/src/core/libraries/np/np_partner.h +++ b/src/core/libraries/np/np_partner.h @@ -11,5 +11,8 @@ class SymbolsResolver; namespace Libraries::Np::NpPartner { -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpPartner \ No newline at end of file diff --git a/src/core/libraries/np/np_party.cpp b/src/core/libraries/np/np_party.cpp index 07667760750..3b4b777e514 100644 --- a/src/core/libraries/np/np_party.cpp +++ b/src/core/libraries/np/np_party.cpp @@ -141,7 +141,7 @@ s32 PS4_SYSV_ABI sceNpPartyUnregisterPrivateHandler() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("3e4k2mzLkmc", "libSceNpParty", 1, "libSceNpParty", sceNpPartyCheckCallback); LIB_FUNCTION("nOZRy-slBoA", "libSceNpParty", 1, "libSceNpParty", sceNpPartyCreate); LIB_FUNCTION("XQSUbbnpPBA", "libSceNpParty", 1, "libSceNpParty", sceNpPartyCreateA); diff --git a/src/core/libraries/np/np_party.h b/src/core/libraries/np/np_party.h index 9cf63321704..b7a9e4f4f53 100644 --- a/src/core/libraries/np/np_party.h +++ b/src/core/libraries/np/np_party.h @@ -43,5 +43,8 @@ s32 PS4_SYSV_ABI sceNpPartyShowInvitationListA(); s32 PS4_SYSV_ABI sceNpPartyTerminate(); s32 PS4_SYSV_ABI sceNpPartyUnregisterPrivateHandler(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpParty \ No newline at end of file diff --git a/src/core/libraries/np/np_profile_dialog.cpp b/src/core/libraries/np/np_profile_dialog.cpp index 6ae1ed26cd5..eb74967d338 100644 --- a/src/core/libraries/np/np_profile_dialog.cpp +++ b/src/core/libraries/np/np_profile_dialog.cpp @@ -48,7 +48,7 @@ s32 PS4_SYSV_ABI sceNpProfileDialogUpdateStatus() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("uj9Cz7Tk0cc", "libSceNpProfileDialogCompat", 1, "libSceNpProfileDialog", sceNpProfileDialogOpen); LIB_FUNCTION("wkwjz0Xdo2A", "libSceNpProfileDialog", 1, "libSceNpProfileDialog", diff --git a/src/core/libraries/np/np_profile_dialog.h b/src/core/libraries/np/np_profile_dialog.h index ca1126d579d..894b93d3289 100644 --- a/src/core/libraries/np/np_profile_dialog.h +++ b/src/core/libraries/np/np_profile_dialog.h @@ -20,5 +20,8 @@ s32 PS4_SYSV_ABI sceNpProfileDialogOpenA(); s32 PS4_SYSV_ABI sceNpProfileDialogTerminate(); s32 PS4_SYSV_ABI sceNpProfileDialogUpdateStatus(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpProfileDialog \ No newline at end of file diff --git a/src/core/libraries/np/np_score.cpp b/src/core/libraries/np/np_score.cpp index 49bb956b207..24b83f9d289 100644 --- a/src/core/libraries/np/np_score.cpp +++ b/src/core/libraries/np/np_score.cpp @@ -263,7 +263,7 @@ int PS4_SYSV_ABI sceNpScoreWaitAsync() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("1i7kmKbX6hk", "libSceNpScore", 1, "libSceNpScore", sceNpScoreAbortRequest); LIB_FUNCTION("2b3TI0mDYiI", "libSceNpScore", 1, "libSceNpScore", sceNpScoreCensorComment); LIB_FUNCTION("4eOvDyN-aZc", "libSceNpScore", 1, "libSceNpScore", sceNpScoreCensorCommentAsync); diff --git a/src/core/libraries/np/np_score.h b/src/core/libraries/np/np_score.h index 01cc25f2ff8..6bef6bc3b48 100644 --- a/src/core/libraries/np/np_score.h +++ b/src/core/libraries/np/np_score.h @@ -63,5 +63,8 @@ int PS4_SYSV_ABI sceNpScoreSetThreadParam(); int PS4_SYSV_ABI sceNpScoreSetTimeout(); int PS4_SYSV_ABI sceNpScoreWaitAsync(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpScore \ No newline at end of file diff --git a/src/core/libraries/np/np_sns_facebook_dialog.cpp b/src/core/libraries/np/np_sns_facebook_dialog.cpp index d0e058e24d3..2604c6ab563 100644 --- a/src/core/libraries/np/np_sns_facebook_dialog.cpp +++ b/src/core/libraries/np/np_sns_facebook_dialog.cpp @@ -14,7 +14,7 @@ Libraries::CommonDialog::Status PS4_SYSV_ABI sceNpSnsFacebookDialogUpdateStatus( return Libraries::CommonDialog::Status::NONE; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("fjV7C8H0Y8k", "libSceNpSnsFacebookDialog", 1, "libSceNpSnsFacebookDialog", sceNpSnsFacebookDialogUpdateStatus); }; diff --git a/src/core/libraries/np/np_sns_facebook_dialog.h b/src/core/libraries/np/np_sns_facebook_dialog.h index 96d8ac25dac..dc36ba406bc 100644 --- a/src/core/libraries/np/np_sns_facebook_dialog.h +++ b/src/core/libraries/np/np_sns_facebook_dialog.h @@ -11,5 +11,8 @@ class SymbolsResolver; namespace Libraries::Np::NpSnsFacebookDialog { -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpSnsFacebookDialog \ No newline at end of file diff --git a/src/core/libraries/np/np_trophy.cpp b/src/core/libraries/np/np_trophy.cpp index 287d8d29591..c73a741dce1 100644 --- a/src/core/libraries/np/np_trophy.cpp +++ b/src/core/libraries/np/np_trophy.cpp @@ -16,6 +16,7 @@ #include "core/libraries/np/trophy_ui.h" #include "core/libraries/system/userservice.h" #include "core/memory.h" +#include "shadps4_app.h" namespace Libraries::Np::NpTrophy { @@ -1367,7 +1368,7 @@ int PS4_SYSV_ABI Func_FA7A2DD770447552() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("aTnHs7W-9Uk", "libSceNpTrophy", 1, "libSceNpTrophy", sceNpTrophyAbortHandle); LIB_FUNCTION("cqGkYAN-gRw", "libSceNpTrophy", 1, "libSceNpTrophy", sceNpTrophyCaptureScreenshot); diff --git a/src/core/libraries/np/np_trophy.h b/src/core/libraries/np/np_trophy.h index 590e58c0d97..2e37ea4bc02 100644 --- a/src/core/libraries/np/np_trophy.h +++ b/src/core/libraries/np/np_trophy.h @@ -225,5 +225,8 @@ int PS4_SYSV_ABI Func_9F80071876FFA5F6(); int PS4_SYSV_ABI Func_F8EF6F5350A91990(); int PS4_SYSV_ABI Func_FA7A2DD770447552(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpTrophy \ No newline at end of file diff --git a/src/core/libraries/np/np_tus.cpp b/src/core/libraries/np/np_tus.cpp index d18cf4ec011..2fba04fc897 100644 --- a/src/core/libraries/np/np_tus.cpp +++ b/src/core/libraries/np/np_tus.cpp @@ -1161,7 +1161,7 @@ s32 PS4_SYSV_ABI sceNpTusWaitAsync(int reqId, int* result) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("sRVb2Cf0GHg", "libSceNpTusCompat", 1, "libSceNpTus", sceNpTssCreateNpTitleCtx); LIB_FUNCTION("cRVmNrJDbG8", "libSceNpTusCompat", 1, "libSceNpTus", sceNpTusAddAndGetVariable); LIB_FUNCTION("Q2UmHdK04c8", "libSceNpTusCompat", 1, "libSceNpTus", diff --git a/src/core/libraries/np/np_tus.h b/src/core/libraries/np/np_tus.h index ef4554ec382..c888e475474 100644 --- a/src/core/libraries/np/np_tus.h +++ b/src/core/libraries/np/np_tus.h @@ -83,5 +83,8 @@ struct OrbisNpTssGetDataOptParam { s32 PS4_SYSV_ABI sceNpTusWaitAsync(int reqId, int* result); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpTus \ No newline at end of file diff --git a/src/core/libraries/np/np_web_api.cpp b/src/core/libraries/np/np_web_api.cpp index 0c633e0d17c..67b32084f8a 100644 --- a/src/core/libraries/np/np_web_api.cpp +++ b/src/core/libraries/np/np_web_api.cpp @@ -812,7 +812,7 @@ s32 PS4_SYSV_ABI Func_F9A32E8685627436() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("x1Y7yiYSk7c", "libSceNpWebApiCompat", 1, "libSceNpWebApi", sceNpWebApiCreateContext); LIB_FUNCTION("y5Ta5JCzQHY", "libSceNpWebApiCompat", 1, "libSceNpWebApi", diff --git a/src/core/libraries/np/np_web_api.h b/src/core/libraries/np/np_web_api.h index 8dd9441e099..020dffeb80e 100644 --- a/src/core/libraries/np/np_web_api.h +++ b/src/core/libraries/np/np_web_api.h @@ -124,5 +124,8 @@ using OrbisNpWebApiInternalServicePushEventCallbackA = PS4_SYSV_ABI void (*)(); using OrbisNpWebApiNotificationCallback = PS4_SYSV_ABI void (*)(); // dummy -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpWebApi \ No newline at end of file diff --git a/src/core/libraries/np/np_web_api2.cpp b/src/core/libraries/np/np_web_api2.cpp index a7c7ee3f3a7..5ea7f5295b4 100644 --- a/src/core/libraries/np/np_web_api2.cpp +++ b/src/core/libraries/np/np_web_api2.cpp @@ -8,6 +8,7 @@ #include "core/libraries/np/np_web_api2.h" #include "core/libraries/np/np_web_api2_error.h" #include "core/libraries/system/userservice.h" +#include "shadps4_app.h" namespace Libraries::Np::NpWebApi2 { @@ -251,7 +252,7 @@ s32 PS4_SYSV_ABI Func_E0DF39A36F087DB9() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("zpiPsH7dbFQ", "libSceNpWebApi2", 1, "libSceNpWebApi2", sceNpWebApi2AbortRequest); LIB_FUNCTION("egOOvrnF6mI", "libSceNpWebApi2", 1, "libSceNpWebApi2", sceNpWebApi2AddHttpRequestHeader); diff --git a/src/core/libraries/np/np_web_api2.h b/src/core/libraries/np/np_web_api2.h index 1e970d08e98..34d99fec575 100644 --- a/src/core/libraries/np/np_web_api2.h +++ b/src/core/libraries/np/np_web_api2.h @@ -36,5 +36,8 @@ struct OrbisNpWebApi2MemoryPoolStats { s32 reserved; }; -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Np::NpWebApi2 \ No newline at end of file diff --git a/src/core/libraries/np/np_web_api_internal.cpp b/src/core/libraries/np/np_web_api_internal.cpp index 66a09b49394..84fa6e020f5 100644 --- a/src/core/libraries/np/np_web_api_internal.cpp +++ b/src/core/libraries/np/np_web_api_internal.cpp @@ -7,6 +7,7 @@ #include "core/libraries/kernel/time.h" #include "core/libraries/network/http.h" #include "np_web_api_internal.h" +#include "shadps4_app.h" #include diff --git a/src/core/libraries/np/trophy_ui.cpp b/src/core/libraries/np/trophy_ui.cpp index a4fd21a33cc..4d42d821007 100644 --- a/src/core/libraries/np/trophy_ui.cpp +++ b/src/core/libraries/np/trophy_ui.cpp @@ -13,6 +13,7 @@ #include "core/emulator_settings.h" #include "core/libraries/np/trophy_ui.h" #include "imgui/imgui_std.h" +#include "shadps4_app.h" CMRC_DECLARE(res); namespace fs = std::filesystem; @@ -38,8 +39,7 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin if (std::filesystem::exists(trophyIconPath)) { trophy_icon = RefCountedTexture::DecodePngFile(trophyIconPath); } else { - LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}", - fmt::UTF(trophyIconPath.u8string())); + LOG_ERROR(Lib_NpTrophy, "Couldnt load trophy icon at {}", trophyIconPath.string()); } std::string pathString = "src/images/"; diff --git a/src/core/libraries/pad/pad.cpp b/src/core/libraries/pad/pad.cpp index f3862119198..e472d2b211a 100644 --- a/src/core/libraries/pad/pad.cpp +++ b/src/core/libraries/pad/pad.cpp @@ -9,6 +9,7 @@ #include "core/user_settings.h" #include "input/controller.h" #include "pad.h" +#include "shadps4_app.h" namespace Libraries::Pad { @@ -776,7 +777,7 @@ int PS4_SYSV_ABI Func_EF103E845B6F0420() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("6ncge5+l5Qs", "libScePad", 1, "libScePad", scePadClose); LIB_FUNCTION("kazv1NzSB8c", "libScePad", 1, "libScePad", scePadConnectPort); LIB_FUNCTION("AcslpN1jHR8", "libScePad", 1, "libScePad", diff --git a/src/core/libraries/pad/pad.h b/src/core/libraries/pad/pad.h index 2f4cbcc6ab9..0d3039c73bc 100644 --- a/src/core/libraries/pad/pad.h +++ b/src/core/libraries/pad/pad.h @@ -352,5 +352,8 @@ int PS4_SYSV_ABI Func_51E514BCD3A05CA5(); int PS4_SYSV_ABI Func_89C9237E393DA243(); int PS4_SYSV_ABI Func_EF103E845B6F0420(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Pad diff --git a/src/core/libraries/playgo/playgo.cpp b/src/core/libraries/playgo/playgo.cpp index 24f8d676111..27b01a1aba3 100644 --- a/src/core/libraries/playgo/playgo.cpp +++ b/src/core/libraries/playgo/playgo.cpp @@ -385,7 +385,7 @@ s32 PS4_SYSV_ABI scePlayGoTerminate() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("uEqMfMITvEI", "libSceDbgPlayGo", 1, "libScePlayGo", sceDbgPlayGoRequestNextChunk); LIB_FUNCTION("vU+FqrH+pEY", "libSceDbgPlayGo", 1, "libScePlayGo", sceDbgPlayGoSnapshot); LIB_FUNCTION("Uco1I0dlDi8", "libScePlayGo", 1, "libScePlayGo", scePlayGoClose); diff --git a/src/core/libraries/playgo/playgo.h b/src/core/libraries/playgo/playgo.h index 68a5f1e8476..e0cd5fdb12f 100644 --- a/src/core/libraries/playgo/playgo.h +++ b/src/core/libraries/playgo/playgo.h @@ -41,5 +41,8 @@ s32 PS4_SYSV_ABI scePlayGoSetToDoList(OrbisPlayGoHandle handle, const OrbisPlayG uint32_t numberOfEntries); s32 PS4_SYSV_ABI scePlayGoTerminate(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::PlayGo \ No newline at end of file diff --git a/src/core/libraries/playgo/playgo_dialog.cpp b/src/core/libraries/playgo/playgo_dialog.cpp index de77d5b5652..f8dde96ac31 100644 --- a/src/core/libraries/playgo/playgo_dialog.cpp +++ b/src/core/libraries/playgo/playgo_dialog.cpp @@ -58,7 +58,7 @@ Status PS4_SYSV_ABI scePlayGoDialogUpdateStatus() { return Status::NONE; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("fbigNQiZpm0", "libScePlayGoDialog", 1, "libScePlayGoDialog", scePlayGoDialogClose); LIB_FUNCTION("wx9TDplJKB4", "libScePlayGoDialog", 1, "libScePlayGoDialog", diff --git a/src/core/libraries/playgo/playgo_dialog.h b/src/core/libraries/playgo/playgo_dialog.h index d9b991f48f1..438062de9dc 100644 --- a/src/core/libraries/playgo/playgo_dialog.h +++ b/src/core/libraries/playgo/playgo_dialog.h @@ -34,5 +34,8 @@ CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogOpen(const OrbisPlayGoDialogPara CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogTerminate(); CommonDialog::Status PS4_SYSV_ABI scePlayGoDialogUpdateStatus(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::PlayGo::Dialog diff --git a/src/core/libraries/random/random.cpp b/src/core/libraries/random/random.cpp index 8549a9b052c..7a879c92de2 100644 --- a/src/core/libraries/random/random.cpp +++ b/src/core/libraries/random/random.cpp @@ -22,7 +22,7 @@ s32 PS4_SYSV_ABI sceRandomGetRandomNumber(u8* buf, std::size_t size) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("PI7jIZj4pcE", "libSceRandom", 1, "libSceRandom", sceRandomGetRandomNumber); }; diff --git a/src/core/libraries/random/random.h b/src/core/libraries/random/random.h index 9f86a900f59..fbfad64fa33 100644 --- a/src/core/libraries/random/random.h +++ b/src/core/libraries/random/random.h @@ -15,6 +15,9 @@ constexpr s32 SCE_RANDOM_MAX_SIZE = 64; s32 PS4_SYSV_ABI sceRandomGetRandomNumber(u8* buf, std::size_t size); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Random diff --git a/src/core/libraries/razor_cpu/razor_cpu.cpp b/src/core/libraries/razor_cpu/razor_cpu.cpp index 7405473d9c6..f2b9f0f92e5 100644 --- a/src/core/libraries/razor_cpu/razor_cpu.cpp +++ b/src/core/libraries/razor_cpu/razor_cpu.cpp @@ -180,7 +180,7 @@ s32 PS4_SYSV_ABI sceRazorCpuWriteBookmark() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("JFzLJBlYIJE", "libSceRazorCpu", 1, "libSceRazorCpu", sceRazorCpuBeginLogicalFileAccess); LIB_FUNCTION("SfRTRZ1Sh+U", "libSceRazorCpu", 1, "libSceRazorCpu", diff --git a/src/core/libraries/razor_cpu/razor_cpu.h b/src/core/libraries/razor_cpu/razor_cpu.h index c8ed3c942fd..175f5bd5dc2 100644 --- a/src/core/libraries/razor_cpu/razor_cpu.h +++ b/src/core/libraries/razor_cpu/razor_cpu.h @@ -13,5 +13,8 @@ class SymbolsResolver; } namespace Libraries::RazorCpu { -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::RazorCpu \ No newline at end of file diff --git a/src/core/libraries/remote_play/remoteplay.cpp b/src/core/libraries/remote_play/remoteplay.cpp index 775450d26c0..96a42c88f82 100644 --- a/src/core/libraries/remote_play/remoteplay.cpp +++ b/src/core/libraries/remote_play/remoteplay.cpp @@ -220,7 +220,7 @@ int PS4_SYSV_ABI Func_1D5EE365ED5FADB3() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("xQeIryTX7dY", "libSceRemoteplay", 1, "libSceRemoteplay", sceRemoteplayApprove); LIB_FUNCTION("IYZ+Mu+8tPo", "libSceRemoteplay", 1, "libSceRemoteplay", sceRemoteplayChangeEnterKey); diff --git a/src/core/libraries/remote_play/remoteplay.h b/src/core/libraries/remote_play/remoteplay.h index b4614dca0f7..1e799a071e5 100644 --- a/src/core/libraries/remote_play/remoteplay.h +++ b/src/core/libraries/remote_play/remoteplay.h @@ -60,5 +60,8 @@ int PS4_SYSV_ABI sceRemoteplaySetRpMode(); int PS4_SYSV_ABI sceRemoteplayTerminate(); int PS4_SYSV_ABI Func_1D5EE365ED5FADB3(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Remoteplay \ No newline at end of file diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index ca63d2f4d8a..b46e8fe443c 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -1181,7 +1181,7 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("lPEBYdVX0XQ", "libSceRtc", 1, "libSceRtc", sceRtcCheckValid); LIB_FUNCTION("fNaZ4DbzHAE", "libSceRtc", 1, "libSceRtc", sceRtcCompareTick); LIB_FUNCTION("8Yr143yEnRo", "libSceRtc", 1, "libSceRtc", sceRtcConvertLocalTimeToUtc); diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index 8ca55a03a09..38c0e033958 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -92,5 +92,8 @@ int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Rtc diff --git a/src/core/libraries/rudp/rudp.cpp b/src/core/libraries/rudp/rudp.cpp index 2dfb66f6471..f45e205e4ed 100644 --- a/src/core/libraries/rudp/rudp.cpp +++ b/src/core/libraries/rudp/rudp.cpp @@ -178,7 +178,7 @@ s32 PS4_SYSV_ABI sceRudpWrite() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("uQiK7fjU6y8", "libSceRudp", 1, "libSceRudp", sceRudpAccept); LIB_FUNCTION("J-6d0WTjzMc", "libSceRudp", 1, "libSceRudp", sceRudpActivate); LIB_FUNCTION("l4SLBpKUDK4", "libSceRudp", 1, "libSceRudp", sceRudpBind); diff --git a/src/core/libraries/rudp/rudp.h b/src/core/libraries/rudp/rudp.h index 22d2576a23f..8a8478133f4 100644 --- a/src/core/libraries/rudp/rudp.h +++ b/src/core/libraries/rudp/rudp.h @@ -46,5 +46,8 @@ s32 PS4_SYSV_ABI sceRudpSetOption(); s32 PS4_SYSV_ABI sceRudpTerminate(); s32 PS4_SYSV_ABI sceRudpWrite(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Rudp \ No newline at end of file diff --git a/src/core/libraries/save_data/dialog/savedatadialog.cpp b/src/core/libraries/save_data/dialog/savedatadialog.cpp index f70800dfd8c..1cc82824d2b 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog.cpp +++ b/src/core/libraries/save_data/dialog/savedatadialog.cpp @@ -139,7 +139,7 @@ Status PS4_SYSV_ABI sceSaveDataDialogUpdateStatus() { return g_status; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("fH46Lag88XY", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", sceSaveDataDialogClose); LIB_FUNCTION("yEiJ-qqr6Cg", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", diff --git a/src/core/libraries/save_data/dialog/savedatadialog.h b/src/core/libraries/save_data/dialog/savedatadialog.h index 39450b36b39..712a1098347 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog.h +++ b/src/core/libraries/save_data/dialog/savedatadialog.h @@ -29,5 +29,8 @@ sceSaveDataDialogProgressBarSetValue(OrbisSaveDataDialogProgressBarTarget target CommonDialog::Error PS4_SYSV_ABI sceSaveDataDialogTerminate(); CommonDialog::Status PS4_SYSV_ABI sceSaveDataDialogUpdateStatus(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SaveData::Dialog diff --git a/src/core/libraries/save_data/save_backup.cpp b/src/core/libraries/save_data/save_backup.cpp index c5f66d883e4..a51d812171e 100644 --- a/src/core/libraries/save_data/save_backup.cpp +++ b/src/core/libraries/save_data/save_backup.cpp @@ -11,7 +11,6 @@ #include "save_instance.h" #include "common/logging/log.h" -#include "common/logging/log_entry.h" #include "common/polyfill_thread.h" #include "common/thread.h" @@ -107,16 +106,14 @@ static void BackupThreadBody() { } g_backup_status = WorkerStatus::Running; - LOG_INFO(Lib_SaveData, "Backing up the following directory: {}", - fmt::UTF(req.save_path.u8string())); + LOG_INFO(Lib_SaveData, "Backing up the following directory: {}", req.save_path.string()); try { backup(req.save_path); } catch (const std::filesystem::filesystem_error& err) { - LOG_ERROR(Lib_SaveData, "Failed to backup {}: {}", fmt::UTF(req.save_path.u8string()), - err.what()); + LOG_ERROR(Lib_SaveData, "Failed to backup {}: {}", req.save_path.string(), err.what()); } LOG_DEBUG(Lib_SaveData, "Backing up the following directory: {} finished", - fmt::UTF(req.save_path.u8string())); + req.save_path.string()); { std::scoped_lock lk{g_backup_queue_mutex}; g_backup_queue.front().done = true; @@ -173,7 +170,7 @@ bool NewRequest(Libraries::UserService::OrbisUserServiceUserId user_id, std::str if (g_backup_status != WorkerStatus::Waiting && g_backup_status != WorkerStatus::Running) { LOG_ERROR(Lib_SaveData, "Called backup while status is {}. Backup request to {} ignored", - magic_enum::enum_name(g_backup_status.load()), fmt::UTF(save_path.u8string())); + magic_enum::enum_name(g_backup_status.load()), save_path.string()); return false; } { @@ -197,7 +194,7 @@ bool NewRequest(Libraries::UserService::OrbisUserServiceUserId user_id, std::str } bool Restore(const std::filesystem::path& save_path) { - LOG_INFO(Lib_SaveData, "Restoring backup for {}", fmt::UTF(save_path.u8string())); + LOG_INFO(Lib_SaveData, "Restoring backup for {}", save_path.string()); std::unique_lock lk{g_backup_running_mutex}; if (!fs::exists(save_path) || !fs::exists(save_path / backup_dir)) { return false; diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 463baa50beb..1bf3e6a6e99 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -12,6 +12,7 @@ #include "core/file_sys/fs.h" #include "save_backup.h" #include "save_instance.h" +#include "shadps4_app.h" constexpr auto OrbisSaveDataBlocksMin2 = 96; // 3MiB constexpr auto OrbisSaveDataBlocksMax = 32768; // 1 GiB diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index 70c66e4cd4f..524270c68b3 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -27,6 +27,7 @@ #include "save_backup.h" #include "save_instance.h" #include "save_memory.h" +#include "shadps4_app.h" namespace fs = std::filesystem; namespace chrono = std::chrono; @@ -619,7 +620,7 @@ Error PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData if (check->param != nullptr) { PSF sfo; if (!sfo.Open(backup_path / "sce_sys" / "param.sfo")) { - LOG_ERROR(Lib_SaveData, "Failed to read SFO at {}", fmt::UTF(backup_path.u8string())); + LOG_ERROR(Lib_SaveData, "Failed to read SFO at {}", backup_path.string()); return Error::INTERNAL; } check->param->FromSFO(sfo); @@ -830,7 +831,7 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond const auto sfo_path = SaveInstance::GetParamSFOPath(dir_path); PSF sfo; if (!sfo.Open(sfo_path)) { - LOG_ERROR(Lib_SaveData, "Failed to read SFO: {}", fmt::UTF(sfo_path.u8string())); + LOG_ERROR(Lib_SaveData, "Failed to read SFO: {}", sfo_path.string()); ASSERT_MSG(false, "Failed to read SFO"); } @@ -1732,7 +1733,7 @@ int PS4_SYSV_ABI Func_02E4C4D201716422() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("dQ2GohUHXzk", "libSceSaveData", 1, "libSceSaveData", sceSaveDataAbort); LIB_FUNCTION("z1JA8-iJt3k", "libSceSaveData", 1, "libSceSaveData", sceSaveDataBackup); LIB_FUNCTION("kLJQ3XioYiU", "libSceSaveData", 1, "libSceSaveData", sceSaveDataBindPsnAccount); diff --git a/src/core/libraries/save_data/savedata.h b/src/core/libraries/save_data/savedata.h index 37a21dbc786..745dc0f106d 100644 --- a/src/core/libraries/save_data/savedata.h +++ b/src/core/libraries/save_data/savedata.h @@ -186,5 +186,8 @@ int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback(); int PS4_SYSV_ABI sceSaveDataUpload(); int PS4_SYSV_ABI Func_02E4C4D201716422(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SaveData diff --git a/src/core/libraries/screenshot/screenshot.cpp b/src/core/libraries/screenshot/screenshot.cpp index 8ae14abc4a2..bea1ba56e22 100644 --- a/src/core/libraries/screenshot/screenshot.cpp +++ b/src/core/libraries/screenshot/screenshot.cpp @@ -78,7 +78,7 @@ int PS4_SYSV_ABI sceScreenShotSetDrcParam() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("AS45QoYHjc4", "libSceScreenShot", 1, "libSceScreenShot", _Z5dummyv); LIB_FUNCTION("JuMLLmmvRgk", "libSceScreenShot", 1, "libSceScreenShot", sceScreenShotCapture); LIB_FUNCTION("tIYf0W5VTi8", "libSceScreenShot", 1, "libSceScreenShot", sceScreenShotDisable); diff --git a/src/core/libraries/screenshot/screenshot.h b/src/core/libraries/screenshot/screenshot.h index 0aee54173fd..49bf195387e 100644 --- a/src/core/libraries/screenshot/screenshot.h +++ b/src/core/libraries/screenshot/screenshot.h @@ -26,5 +26,8 @@ int PS4_SYSV_ABI sceScreenShotSetOverlayImageWithOrigin(); int PS4_SYSV_ABI sceScreenShotSetParam(); int PS4_SYSV_ABI sceScreenShotSetDrcParam(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::ScreenShot \ No newline at end of file diff --git a/src/core/libraries/share_play/shareplay.cpp b/src/core/libraries/share_play/shareplay.cpp index f6865ba70ab..e919c0c8d05 100644 --- a/src/core/libraries/share_play/shareplay.cpp +++ b/src/core/libraries/share_play/shareplay.cpp @@ -131,7 +131,7 @@ int PS4_SYSV_ABI Func_F3DD6199DA15ED44() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("ggnCfalLU-8", "libSceSharePlay", 1, "libSceSharePlay", sceSharePlayCrashDaemon); LIB_FUNCTION("OOrLKB0bSDs", "libSceSharePlay", 1, "libSceSharePlay", sceSharePlayGetCurrentConnectionInfo); diff --git a/src/core/libraries/share_play/shareplay.h b/src/core/libraries/share_play/shareplay.h index b67b01e9349..4ee569ef170 100644 --- a/src/core/libraries/share_play/shareplay.h +++ b/src/core/libraries/share_play/shareplay.h @@ -51,5 +51,8 @@ int PS4_SYSV_ABI Func_C1C236728D88E177(); int PS4_SYSV_ABI Func_E9E80C474781F115(); int PS4_SYSV_ABI Func_F3DD6199DA15ED44(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SharePlay \ No newline at end of file diff --git a/src/core/libraries/signin_dialog/signindialog.cpp b/src/core/libraries/signin_dialog/signindialog.cpp index 9391d819731..f1d94eff997 100644 --- a/src/core/libraries/signin_dialog/signindialog.cpp +++ b/src/core/libraries/signin_dialog/signindialog.cpp @@ -44,7 +44,7 @@ s32 PS4_SYSV_ABI sceSigninDialogTerminate() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("mlYGfmqE3fQ", "libSceSigninDialog", 1, "libSceSigninDialog", sceSigninDialogInitialize); LIB_FUNCTION("JlpJVoRWv7U", "libSceSigninDialog", 1, "libSceSigninDialog", sceSigninDialogOpen); diff --git a/src/core/libraries/signin_dialog/signindialog.h b/src/core/libraries/signin_dialog/signindialog.h index 35740efff98..e9da7d3b536 100644 --- a/src/core/libraries/signin_dialog/signindialog.h +++ b/src/core/libraries/signin_dialog/signindialog.h @@ -25,5 +25,8 @@ s32 PS4_SYSV_ABI sceSigninDialogGetResult(); s32 PS4_SYSV_ABI sceSigninDialogClose(); s32 PS4_SYSV_ABI sceSigninDialogTerminate(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SigninDialog diff --git a/src/core/libraries/sysmodule/sysmodule.cpp b/src/core/libraries/sysmodule/sysmodule.cpp index 1ad9075e7a4..e8b2d936bda 100644 --- a/src/core/libraries/sysmodule/sysmodule.cpp +++ b/src/core/libraries/sysmodule/sysmodule.cpp @@ -169,7 +169,7 @@ s32 PS4_SYSV_ABI sceSysmoduleUnloadModuleInternalWithArg() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("D8cuU4d72xM", "libSceSysmodule", 1, "libSceSysmodule", sceSysmoduleGetModuleHandleInternal); LIB_FUNCTION("4fU5yvOkVG4", "libSceSysmodule", 1, "libSceSysmodule", diff --git a/src/core/libraries/sysmodule/sysmodule.h b/src/core/libraries/sysmodule/sysmodule.h index 17ac3188fef..aa0d82f9672 100644 --- a/src/core/libraries/sysmodule/sysmodule.h +++ b/src/core/libraries/sysmodule/sysmodule.h @@ -34,5 +34,8 @@ s32 PS4_SYSV_ABI sceSysmoduleUnloadModuleByNameInternal(); s32 PS4_SYSV_ABI sceSysmoduleUnloadModuleInternal(); s32 PS4_SYSV_ABI sceSysmoduleUnloadModuleInternalWithArg(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SysModule diff --git a/src/core/libraries/sysmodule/sysmodule_internal.cpp b/src/core/libraries/sysmodule/sysmodule_internal.cpp index 56e13028917..3a6f2f941d2 100644 --- a/src/core/libraries/sysmodule/sysmodule_internal.cpp +++ b/src/core/libraries/sysmodule/sysmodule_internal.cpp @@ -210,20 +210,20 @@ s32 loadModuleInternal(s32 index, s32 argc, const void* argv, s32* res_out) { // First, check if this is a module we allow LLE for. static s32 stub_handle = 100; constexpr auto ModulesToLoad = std::to_array( - {{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterLib}, - {"libSceUlt.sprx", nullptr}, - {"libSceRtc.sprx", &Libraries::Rtc::RegisterLib}, - {"libSceJpegDec.sprx", nullptr}, - {"libSceJpegEnc.sprx", &Libraries::JpegEnc::RegisterLib}, - {"libScePngEnc.sprx", &Libraries::PngEnc::RegisterLib}, - {"libSceJson.sprx", nullptr}, - {"libSceJson2.sprx", nullptr}, - {"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterLib}, - {"libSceCesCs.sprx", nullptr}, - {"libSceAudiodec.sprx", nullptr}, - {"libSceFont.sprx", &Libraries::Font::RegisterlibSceFont}, - {"libSceFontFt.sprx", &Libraries::FontFt::RegisterlibSceFontFt}, - {"libSceFreeTypeOt.sprx", nullptr}}); + {{"libSceNgs2.sprx", true}, + {"libSceUlt.sprx", false}, + {"libSceRtc.sprx", true}, + {"libSceJpegDec.sprx", false}, + {"libSceJpegEnc.sprx", true}, + {"libScePngEnc.sprx", true}, + {"libSceJson.sprx", false}, + {"libSceJson2.sprx", false}, + {"libSceLibcInternal.sprx", true}, + {"libSceCesCs.sprx", false}, + {"libSceAudiodec.sprx", false}, + {"libSceFont.sprx", true}, + {"libSceFontFt.sprx", true}, + {"libSceFreeTypeOt.sprx", false}}); // Iterate through the allowed array const auto it = std::ranges::find_if( @@ -251,7 +251,7 @@ s32 loadModuleInternal(s32 index, s32 argc, const void* argv, s32* res_out) { auto& [name, init_func] = *it; if (init_func) { LOG_INFO(Loader, "Can't Load {} switching to HLE", mod_name); - init_func(&linker->GetHLESymbols()); + ShadPs4App::GetInstance()->m_hle_layer->load(name, &linker->GetHLESymbols()); // When loading HLEs, we need to relocate imports // This ensures later module loads can see our HLE functions. diff --git a/src/core/libraries/system/commondialog.cpp b/src/core/libraries/system/commondialog.cpp index 13df2d2f41a..e2208c4d100 100644 --- a/src/core/libraries/system/commondialog.cpp +++ b/src/core/libraries/system/commondialog.cpp @@ -156,7 +156,7 @@ int PS4_SYSV_ABI Func_F2AEE270605622B0() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("2RdicdHhtGA", "libSceCommonDialog", 1, "libSceCommonDialog", _ZN3sce16CommonDialogUtil12getSelfAppIdEv); LIB_FUNCTION("I+tdxsCap08", "libSceCommonDialog", 1, "libSceCommonDialog", diff --git a/src/core/libraries/system/commondialog.h b/src/core/libraries/system/commondialog.h index cee783e3225..e0156f75a0b 100644 --- a/src/core/libraries/system/commondialog.h +++ b/src/core/libraries/system/commondialog.h @@ -81,5 +81,8 @@ int PS4_SYSV_ABI Func_B71349CF15FACAB0(); int PS4_SYSV_ABI Func_CB18E00EFA946C64(); int PS4_SYSV_ABI Func_F2AEE270605622B0(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::CommonDialog diff --git a/src/core/libraries/system/msgdialog.cpp b/src/core/libraries/system/msgdialog.cpp index d6ed62fb70d..36348c0ae85 100644 --- a/src/core/libraries/system/msgdialog.cpp +++ b/src/core/libraries/system/msgdialog.cpp @@ -149,7 +149,7 @@ Status PS4_SYSV_ABI sceMsgDialogUpdateStatus() { return g_status; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("HTrcDKlFKuM", "libSceMsgDialog", 1, "libSceMsgDialog", sceMsgDialogClose); LIB_FUNCTION("Lr8ovHH9l6A", "libSceMsgDialog", 1, "libSceMsgDialog", sceMsgDialogGetResult); LIB_FUNCTION("CWVW78Qc3fI", "libSceMsgDialog", 1, "libSceMsgDialog", sceMsgDialogGetStatus); diff --git a/src/core/libraries/system/msgdialog.h b/src/core/libraries/system/msgdialog.h index 9f8c065c328..ad9325391ef 100644 --- a/src/core/libraries/system/msgdialog.h +++ b/src/core/libraries/system/msgdialog.h @@ -29,5 +29,8 @@ CommonDialog::Error PS4_SYSV_ABI sceMsgDialogProgressBarSetValue(OrbisMsgDialogP CommonDialog::Error PS4_SYSV_ABI sceMsgDialogTerminate(); CommonDialog::Status PS4_SYSV_ABI sceMsgDialogUpdateStatus(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::MsgDialog diff --git a/src/core/libraries/system/posix.cpp b/src/core/libraries/system/posix.cpp index d09366ca09e..784195e2e88 100644 --- a/src/core/libraries/system/posix.cpp +++ b/src/core/libraries/system/posix.cpp @@ -5,6 +5,6 @@ namespace Libraries::Posix { -void RegisterLib(Core::Loader::SymbolsResolver* sym) {} +Engine::Engine(Core::Loader::SymbolsResolver* sym) {} } // namespace Libraries::Posix diff --git a/src/core/libraries/system/posix.h b/src/core/libraries/system/posix.h index 4d08a2785e5..fdf482ecb35 100644 --- a/src/core/libraries/system/posix.h +++ b/src/core/libraries/system/posix.h @@ -8,5 +8,8 @@ class SymbolsResolver; } namespace Libraries::Posix { -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Posix diff --git a/src/core/libraries/system/systemservice.cpp b/src/core/libraries/system/systemservice.cpp index 0e40c723fa1..79ca2295da5 100644 --- a/src/core/libraries/system/systemservice.cpp +++ b/src/core/libraries/system/systemservice.cpp @@ -9,6 +9,7 @@ #include "core/libraries/system/systemservice.h" #include "core/libraries/system/systemservice_error.h" #include "emulator.h" +#include "shadps4_app.h" namespace Libraries::SystemService { @@ -2446,7 +2447,7 @@ void PushSystemServiceEvent(const OrbisSystemServiceEvent& event) { g_event_queue.push(event); } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("alZfRdr2RP8", "libSceAppMessaging", 1, "libSceSystemService", sceAppMessagingClearEventFlag); LIB_FUNCTION("jKgAUl6cLy0", "libSceAppMessaging", 1, "libSceSystemService", diff --git a/src/core/libraries/system/systemservice.h b/src/core/libraries/system/systemservice.h index e3eeb21dcad..b2fe9285768 100644 --- a/src/core/libraries/system/systemservice.h +++ b/src/core/libraries/system/systemservice.h @@ -608,5 +608,8 @@ int PS4_SYSV_ABI Func_CB5E885E225F69F0(); void PushSystemServiceEvent(const OrbisSystemServiceEvent& event); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SystemService diff --git a/src/core/libraries/system/userservice.cpp b/src/core/libraries/system/userservice.cpp index 029868eb4ef..24f61264985 100644 --- a/src/core/libraries/system/userservice.cpp +++ b/src/core/libraries/system/userservice.cpp @@ -14,6 +14,7 @@ #include "core/libraries/system/userservice_error.h" #include "core/tls.h" #include "input/controller.h" +#include "shadps4_app.h" namespace Libraries::UserService { @@ -2196,7 +2197,7 @@ int PS4_SYSV_ABI Func_D2B814603E7B4477() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("Psl9mfs3duM", "libSceUserServiceForShellCore", 1, "libSceUserService", sceUserServiceInitializeForShellCore); LIB_FUNCTION("CydP+QtA0KI", "libSceUserServiceForShellCore", 1, "libSceUserService", diff --git a/src/core/libraries/system/userservice.h b/src/core/libraries/system/userservice.h index 799bf89ba16..8e3c68d5881 100644 --- a/src/core/libraries/system/userservice.h +++ b/src/core/libraries/system/userservice.h @@ -483,5 +483,8 @@ int PS4_SYSV_ABI Func_A6BDC9DFDAFD02B4(); int PS4_SYSV_ABI Func_BB9491DFE6B4953C(); int PS4_SYSV_ABI Func_D2B814603E7B4477(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::UserService diff --git a/src/core/libraries/system_gesture/system_gesture.cpp b/src/core/libraries/system_gesture/system_gesture.cpp index a6455e05e2b..54159e16c3f 100644 --- a/src/core/libraries/system_gesture/system_gesture.cpp +++ b/src/core/libraries/system_gesture/system_gesture.cpp @@ -123,7 +123,7 @@ int PS4_SYSV_ABI sceSystemGestureUpdateTouchRecognizerRectangle() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("1MMK0W-kMgA", "libSceSystemGesture", 1, "libSceSystemGesture", sceSystemGestureAppendTouchRecognizer); LIB_FUNCTION("j4yXIA2jJ68", "libSceSystemGesture", 1, "libSceSystemGesture", diff --git a/src/core/libraries/system_gesture/system_gesture.h b/src/core/libraries/system_gesture/system_gesture.h index 8150d08c36f..746a3fc700b 100644 --- a/src/core/libraries/system_gesture/system_gesture.h +++ b/src/core/libraries/system_gesture/system_gesture.h @@ -35,5 +35,8 @@ int PS4_SYSV_ABI sceSystemGestureUpdatePrimitiveTouchRecognizer(); int PS4_SYSV_ABI sceSystemGestureUpdateTouchRecognizer(); int PS4_SYSV_ABI sceSystemGestureUpdateTouchRecognizerRectangle(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::SystemGesture diff --git a/src/core/libraries/ulobjmgr/ulobjmgr.cpp b/src/core/libraries/ulobjmgr/ulobjmgr.cpp index ff729b3ec8d..b69b2bfb0c5 100644 --- a/src/core/libraries/ulobjmgr/ulobjmgr.cpp +++ b/src/core/libraries/ulobjmgr/ulobjmgr.cpp @@ -35,7 +35,7 @@ s32 PS4_SYSV_ABI Func_4B07893BBB77A649(u64 arg0) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("BG26hBGiNlw", "ulobjmgr", 1, "ulobjmgr", Func_046DBA8411A2365C); LIB_FUNCTION("HZ9Q2c+4BU4", "ulobjmgr", 1, "ulobjmgr", Func_1D9F50D9CFB8054E); LIB_FUNCTION("Smf+fUNblPc", "ulobjmgr", 1, "ulobjmgr", Func_4A67FE7D435B94F7); diff --git a/src/core/libraries/ulobjmgr/ulobjmgr.h b/src/core/libraries/ulobjmgr/ulobjmgr.h index baf90719cff..54852da0f46 100644 --- a/src/core/libraries/ulobjmgr/ulobjmgr.h +++ b/src/core/libraries/ulobjmgr/ulobjmgr.h @@ -10,5 +10,8 @@ class SymbolsResolver; } namespace Libraries::Ulobjmgr { -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Ulobjmgr \ No newline at end of file diff --git a/src/core/libraries/usbd/usbd.cpp b/src/core/libraries/usbd/usbd.cpp index 52d6aec6623..fe61baa207e 100644 --- a/src/core/libraries/usbd/usbd.cpp +++ b/src/core/libraries/usbd/usbd.cpp @@ -4,13 +4,13 @@ #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "core/emulator_settings.h" +#include "shadps4_app.h" #include "usbd.h" #include #include -#include "core/emulator_settings.h" - namespace Libraries::Usbd { s32 libusb_to_orbis_error(int retVal) { @@ -456,7 +456,7 @@ int PS4_SYSV_ABI Func_D56B43060720B1E0() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { switch (EmulatorSettings.GetUsbDeviceBackend()) { case UsbBackendType::SkylandersPortal: usb_backend = std::make_shared(); diff --git a/src/core/libraries/usbd/usbd.h b/src/core/libraries/usbd/usbd.h index fef9d6871c7..df27fceea8c 100644 --- a/src/core/libraries/usbd/usbd.h +++ b/src/core/libraries/usbd/usbd.h @@ -160,5 +160,8 @@ int PS4_SYSV_ABI Func_97F056BAD90AADE7(); int PS4_SYSV_ABI Func_C55104A33B35B264(); int PS4_SYSV_ABI Func_D56B43060720B1E0(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Usbd \ No newline at end of file diff --git a/src/core/libraries/videodec/videodec.cpp b/src/core/libraries/videodec/videodec.cpp index 80fe7df99e6..b2c464cffbd 100644 --- a/src/core/libraries/videodec/videodec.cpp +++ b/src/core/libraries/videodec/videodec.cpp @@ -131,7 +131,7 @@ int PS4_SYSV_ABI sceVideodecReset(OrbisVideodecCtrl* pCtrlIn) { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("qkgRiwHyheU", "libSceVideodec", 1, "libSceVideodec", sceVideodecCreateDecoder); LIB_FUNCTION("q0W5GJMovMs", "libSceVideodec", 1, "libSceVideodec", sceVideodecDecode); LIB_FUNCTION("U0kpGF1cl90", "libSceVideodec", 1, "libSceVideodec", sceVideodecDeleteDecoder); diff --git a/src/core/libraries/videodec/videodec.h b/src/core/libraries/videodec/videodec.h index ab4bd953199..37a6801d938 100644 --- a/src/core/libraries/videodec/videodec.h +++ b/src/core/libraries/videodec/videodec.h @@ -104,5 +104,8 @@ int PS4_SYSV_ABI sceVideodecQueryResourceInfo(const OrbisVideodecConfigInfo* pCf OrbisVideodecResourceInfo* pRsrcInfoOut); int PS4_SYSV_ABI sceVideodecReset(OrbisVideodecCtrl* pCtrlIn); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Videodec \ No newline at end of file diff --git a/src/core/libraries/videodec/videodec2.cpp b/src/core/libraries/videodec/videodec2.cpp index 121818f398b..38640df0609 100644 --- a/src/core/libraries/videodec/videodec2.cpp +++ b/src/core/libraries/videodec/videodec2.cpp @@ -242,7 +242,7 @@ s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* outp return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("RnDibcGCPKw", "libSceVideodec2", 1, "libSceVideodec2", sceVideodec2QueryComputeMemoryInfo); LIB_FUNCTION("eD+X2SmxUt4", "libSceVideodec2", 1, "libSceVideodec2", diff --git a/src/core/libraries/videodec/videodec2.h b/src/core/libraries/videodec/videodec2.h index 0311e4d27f3..47b9d8f808d 100644 --- a/src/core/libraries/videodec/videodec2.h +++ b/src/core/libraries/videodec/videodec2.h @@ -137,5 +137,8 @@ s32 PS4_SYSV_ABI sceVideodec2Reset(OrbisVideodec2Decoder decoder); s32 PS4_SYSV_ABI sceVideodec2GetPictureInfo(const OrbisVideodec2OutputInfo* outputInfo, void* p1stPictureInfo, void* p2ndPictureInfo); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Videodec2 \ No newline at end of file diff --git a/src/core/libraries/videoout/driver.cpp b/src/core/libraries/videoout/driver.cpp index 9db70569bfe..58de50c0ad0 100644 --- a/src/core/libraries/videoout/driver.cpp +++ b/src/core/libraries/videoout/driver.cpp @@ -7,15 +7,14 @@ #include "core/debug_state.h" #include "core/emulator_settings.h" #include "core/libraries/kernel/time.h" +#include "core/libraries/libs.h" #include "core/libraries/videoout/driver.h" #include "core/libraries/videoout/videoout_error.h" #include "imgui/renderer/imgui_core.h" +#include "shadps4_app.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/renderer_vulkan/vk_presenter.h" -extern std::unique_ptr presenter; -extern std::unique_ptr liverpool; - namespace Libraries::VideoOut { constexpr static bool Is32BppPixelFormat(PixelFormat format) { @@ -40,22 +39,37 @@ constexpr u32 PixelFormatBpp(PixelFormat pixel_format) { } } -VideoOutDriver::VideoOutDriver(u32 width, u32 height) { +VideoOutDriver::VideoOutDriver(u32 width, u32 height, Vulkan::Presenter& presenter) : m_presenter(presenter) { main_port.resolution.full_width = width; main_port.resolution.full_height = height; main_port.resolution.pane_width = width; main_port.resolution.pane_height = height; - present_thread = std::jthread([&](std::stop_token token) { PresentThread(token); }); + present_thread = std::jthread([&](std::stop_token token) { + { + std::unique_lock lk(mutex); + cond_var.wait(lk, []{ return ShadPs4App::GetInstance()->m_hle_layer != nullptr; }); + } + + try { + PresentThread(token); + } + catch (const std::runtime_error& exception) { + LOG_TRACE(Lib_VideoOut, "Thread stop: {}", exception.what()); + } + }); } -VideoOutDriver::~VideoOutDriver() = default; +VideoOutDriver::~VideoOutDriver() { + present_thread.request_stop(); + present_thread.join(); +} int VideoOutDriver::Open(const ServiceThreadParams* params) { if (main_port.is_open) { return ORBIS_VIDEO_OUT_ERROR_RESOURCE_BUSY; } main_port.is_open = true; - liverpool->SetVoPort(&main_port); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SetVoPort(&main_port); return 1; } @@ -139,7 +153,7 @@ int VideoOutDriver::RegisterBuffers(VideoOutPort* port, s32 startIndex, void* co port->buffer_labels[startIndex + i] = 0; port->SignalVoLabel(); - presenter->RegisterVideoOutSurface(group, address); + m_presenter.RegisterVideoOutSurface(group, address); LOG_INFO(Lib_VideoOut, "buffers[{}] = {:#x}", i + startIndex, address); } @@ -167,10 +181,10 @@ int VideoOutDriver::UnregisterBuffers(VideoOutPort* port, s32 attributeIndex) { void VideoOutDriver::Flip(const Request& req) { // Update HDR status before presenting. - presenter->SetHDR(req.port->is_hdr); + m_presenter.SetHDR(req.port->is_hdr); // Present the frame. - presenter->Present(req.frame); + m_presenter.Present(req.frame); // Update flip status. auto* port = req.port; @@ -209,14 +223,14 @@ void VideoOutDriver::Flip(const Request& req) { } void VideoOutDriver::DrawBlankFrame() { - const auto empty_frame = presenter->PrepareBlankFrame(false); - presenter->Present(empty_frame); + const auto empty_frame = m_presenter.PrepareBlankFrame(false); + m_presenter.Present(empty_frame); } void VideoOutDriver::DrawLastFrame() { - const auto frame = presenter->PrepareLastFrame(); + const auto frame = m_presenter.PrepareLastFrame(); if (frame != nullptr) { - presenter->Present(frame, true); + m_presenter.Present(frame, true); } } @@ -238,7 +252,7 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg, if (!is_eop) { // Non EOP flips can arrive from any thread so ask GPU thread to perform them - liverpool->SendCommand([=, this]() { SubmitFlipInternal(port, index, flip_arg, is_eop); }); + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.liverpool->SendCommand([=, this]() { SubmitFlipInternal(port, index, flip_arg, is_eop); }); } else { SubmitFlipInternal(port, index, flip_arg, is_eop); } @@ -249,12 +263,12 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg, void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop) { Vulkan::Frame* frame; if (index == -1) { - frame = presenter->PrepareBlankFrame(false); + frame = m_presenter.PrepareBlankFrame(false); } else { const auto& buffer = port->buffer_slots[index]; ASSERT_MSG(buffer.group_index >= 0, "Trying to flip an unregistered buffer!"); const auto& group = port->groups[buffer.group_index]; - frame = presenter->PrepareFrame(group, buffer.address_left); + frame = m_presenter.PrepareFrame(group, buffer.address_left); } std::scoped_lock lock{mutex}; diff --git a/src/core/libraries/videoout/driver.h b/src/core/libraries/videoout/driver.h index 96bd58500cc..93ec9aa9e33 100644 --- a/src/core/libraries/videoout/driver.h +++ b/src/core/libraries/videoout/driver.h @@ -1,16 +1,23 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include "common/debug.h" #include "common/polyfill_thread.h" -#include "core/libraries/videoout/video_out.h" +//#include "core/libraries/videoout/video_out.h" #include #include #include +#include "core/libraries/kernel/equeue.h" +#include "core/libraries/videoout/buffer.h" +#include "core/libraries/videoout/flip_status.h" +#include "core/libraries/videoout/sce_video_out_resolution_status.h" +#include "core/libraries/videoout/sce_video_out_vblank_status.h" +#include "video_core/renderer_vulkan/vk_presenter.h" + namespace Vulkan { struct Frame; } @@ -76,7 +83,7 @@ struct ServiceThreadParams { class VideoOutDriver { public: - VideoOutDriver(u32 width, u32 height); + VideoOutDriver(u32 width, u32 height, Vulkan::Presenter& presenter); ~VideoOutDriver(); int Open(const ServiceThreadParams* params); @@ -90,6 +97,9 @@ class VideoOutDriver { bool SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop = false); + std::jthread present_thread; + std::condition_variable cond_var; + private: struct Request { Vulkan::Frame* frame; @@ -109,9 +119,9 @@ class VideoOutDriver { void SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop = false); void PresentThread(std::stop_token token); + Vulkan::Presenter& m_presenter; std::mutex mutex; VideoOutPort main_port{}; - std::jthread present_thread; std::queue requests; }; diff --git a/src/core/libraries/videoout/flip_status.h b/src/core/libraries/videoout/flip_status.h new file mode 100644 index 00000000000..9b712c3a34a --- /dev/null +++ b/src/core/libraries/videoout/flip_status.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Libraries::VideoOut { +struct FlipStatus { + u64 count = 0; + u64 process_time = 0; + u64 tsc = 0; + s64 flip_arg = -1; + u64 submit_tsc = 0; + u64 reserved0 = 0; + s32 gc_queue_num = 0; + s32 flip_pending_num = 0; + s32 current_buffer = -1; + u32 reserved1 = 0; +}; +} // namespace Libraries::VideoOut diff --git a/src/core/libraries/videoout/sce_video_out_refresh_rate.h b/src/core/libraries/videoout/sce_video_out_refresh_rate.h new file mode 100644 index 00000000000..4e0bf1c7f09 --- /dev/null +++ b/src/core/libraries/videoout/sce_video_out_refresh_rate.h @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +// SceVideoOutRefreshRate +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_UNKNOWN = 0; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_23_98HZ = 1; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_50HZ = 2; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ = 3; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_119_88HZ = 13; +constexpr int SCE_VIDEO_OUT_REFRESH_RATE_89_91HZ = 35; +constexpr s64 SCE_VIDEO_OUT_REFRESH_RATE_ANY = 0xFFFFFFFFFFFFFFFFUL; diff --git a/src/core/libraries/videoout/sce_video_out_resolution_status.h b/src/core/libraries/videoout/sce_video_out_resolution_status.h new file mode 100644 index 00000000000..986afec1b16 --- /dev/null +++ b/src/core/libraries/videoout/sce_video_out_resolution_status.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "sce_video_out_refresh_rate.h" + +namespace Libraries::VideoOut { +struct SceVideoOutResolutionStatus { + s32 full_width = 1280; + s32 full_height = 720; + s32 pane_width = 1280; + s32 pane_height = 720; + u64 refresh_rate = SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ; + float screen_size_in_inch = 50; + u16 flags = 0; + u16 reserved0 = 0; + u32 reserved1[3] = {0}; +}; +} // namespace Libraries::VideoOut diff --git a/src/core/libraries/videoout/sce_video_out_vblank_status.h b/src/core/libraries/videoout/sce_video_out_vblank_status.h new file mode 100644 index 00000000000..a8e9d9fc482 --- /dev/null +++ b/src/core/libraries/videoout/sce_video_out_vblank_status.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Libraries::VideoOut { +struct SceVideoOutVblankStatus { + u64 count = 0; + u64 process_time = 0; + u64 tsc = 0; + u64 reserved[1] = {0}; + u8 flags = 0; + u8 pad1[7] = {}; +}; +} // namespace Libraries::VideoOut diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index 7714eb2b5f0..7442e6b0265 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -11,14 +11,11 @@ #include "core/libraries/videoout/video_out.h" #include "core/libraries/videoout/videoout_error.h" #include "core/platform.h" +#include "shadps4_app.h" #include "video_core/renderer_vulkan/vk_presenter.h" -extern std::unique_ptr presenter; - namespace Libraries::VideoOut { -static std::unique_ptr driver; - void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, u32 height, u32 pitchInPixel) { @@ -41,7 +38,7 @@ void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, Pixe s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::OrbisKernelEqueue eq, s32 handle, void* udata) { LOG_INFO(Lib_VideoOut, "handle = {}", handle); - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (port == nullptr) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -66,7 +63,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::OrbisKernelEqueue eq, s32 handl } s32 PS4_SYSV_ABI sceVideoOutDeleteFlipEvent(Kernel::OrbisKernelEqueue eq, s32 handle) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (port == nullptr) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -83,7 +80,7 @@ s32 PS4_SYSV_ABI sceVideoOutDeleteFlipEvent(Kernel::OrbisKernelEqueue eq, s32 ha s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::OrbisKernelEqueue eq, s32 handle, void* udata) { LOG_INFO(Lib_VideoOut, "handle = {}", handle); - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (port == nullptr) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -108,7 +105,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::OrbisKernelEqueue eq, s32 han } s32 PS4_SYSV_ABI sceVideoOutDeleteVblankEvent(Kernel::OrbisKernelEqueue eq, s32 handle) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (port == nullptr) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -129,31 +126,32 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port || !port->is_open) { LOG_ERROR(Lib_VideoOut, "Invalid handle = {}", handle); return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } - return driver->RegisterBuffers(port, startIndex, addresses, bufferNum, attribute); + return ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->RegisterBuffers( + port, startIndex, addresses, bufferNum, attribute); } s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate) { LOG_TRACE(Lib_VideoOut, "called"); - driver->GetPort(handle)->flip_rate = rate; + ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle)->flip_rate = rate; return ORBIS_OK; } s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) { LOG_TRACE(Lib_VideoOut, "called"); - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); std::unique_lock lock{port->port_mutex}; s32 pending = port->flip_status.flip_pending_num; return pending; } s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { LOG_ERROR(Lib_VideoOut, "Invalid handle = {}", handle); return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; @@ -176,7 +174,8 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode LOG_DEBUG(Lib_VideoOut, "bufferIndex = {}, flipMode = {}, flipArg = {}", bufferIndex, flipMode, flipArg); - if (!driver->SubmitFlip(port, bufferIndex, flipArg)) { + if (!ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->SubmitFlip(port, bufferIndex, + flipArg)) { LOG_ERROR(Lib_VideoOut, "Flip queue is full"); return ORBIS_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL; } @@ -247,7 +246,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) { return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { LOG_ERROR(Lib_VideoOut, "Invalid port handle = {}", handle); return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; @@ -273,7 +272,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetVblankStatus(int handle, SceVideoOutVblankStatus* return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { LOG_ERROR(Lib_VideoOut, "Invalid port handle = {}", handle); return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; @@ -286,7 +285,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetVblankStatus(int handle, SceVideoOutVblankStatus* s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutionStatus* status) { LOG_INFO(Lib_VideoOut, "called"); - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port || !port->is_open) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -306,7 +305,7 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(Libraries::UserService::OrbisUserServiceUserId } auto* params = reinterpret_cast(param); - int handle = driver->Open(params); + int handle = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->Open(params); if (handle < 0) { LOG_ERROR(Lib_VideoOut, "All available handles are open"); @@ -317,24 +316,25 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(Libraries::UserService::OrbisUserServiceUserId } s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle) { - driver->Close(handle); + ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->Close(handle); return ORBIS_OK; } s32 PS4_SYSV_ABI sceVideoOutUnregisterBuffers(s32 handle, s32 attributeIndex) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port || !port->is_open) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } - return driver->UnregisterBuffers(port, attributeIndex); + return ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->UnregisterBuffers( + port, attributeIndex); } s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr) { if (label_addr == nullptr) { return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -343,7 +343,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_a } s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, void** unk) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -352,7 +352,9 @@ s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, voi Platform::InterruptId::GfxFlip, [=](Platform::InterruptId irq) { ASSERT_MSG(irq == Platform::InterruptId::GfxFlip, "An unexpected IRQ occured"); ASSERT_MSG(port->buffer_labels[buf_id] == 1, "Out of order flip IRQ"); - const auto result = driver->SubmitFlip(port, buf_id, flip_arg, true); + const auto result = + ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->SubmitFlip( + port, buf_id, flip_arg, true); ASSERT_MSG(result, "EOP flip submission failed"); }); @@ -362,7 +364,7 @@ s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, voi s32 PS4_SYSV_ABI sceVideoOutGetDeviceCapabilityInfo( s32 handle, SceVideoOutDeviceCapabilityInfo* pDeviceCapabilityInfo) { pDeviceCapabilityInfo->capability = 0; - if (presenter->IsHDRSupported()) { + if (ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->IsHDRSupported()) { auto& game_info = Common::ElfInfo::Instance(); if (game_info.GetPSFAttributes().support_hdr) { pDeviceCapabilityInfo->capability |= ORBIS_VIDEO_OUT_DEVICE_CAPABILITY_BT2020_PQ; @@ -372,7 +374,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetDeviceCapabilityInfo( } s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -396,12 +398,13 @@ s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettin return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } - presenter->GetPPSettingsRef().gamma = settings->gamma; + ShadPs4App::GetInstance()->m_hle_layer->m_gnm_driver.presenter->GetPPSettingsRef().gamma = + settings->gamma; return ORBIS_OK; } @@ -424,7 +427,7 @@ void PS4_SYSV_ABI sceVideoOutModeSetAny_(Mode* mode, u32 size) { s32 PS4_SYSV_ABI sceVideoOutConfigureOutputMode_(s32 handle, u32 reserved, const Mode* mode, const void* options, u32 size_mode, u32 size_options) { - auto* port = driver->GetPort(handle); + auto* port = ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->GetPort(handle); if (!port) { return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; } @@ -454,10 +457,10 @@ s32 PS4_SYSV_ABI sceVideoOutSetWindowModeMargins(s32 handle, s32 top, s32 bottom return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { - driver = std::make_unique(EmulatorSettings.GetInternalScreenWidth(), - EmulatorSettings.GetInternalScreenHeight()); - +Engine::Engine(Core::Loader::SymbolsResolver* sym, Vulkan::Presenter& presenter) + : driver(std::make_unique(EmulatorSettings.GetInternalScreenWidth(), + EmulatorSettings.GetInternalScreenHeight(), + presenter)) { LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutGetFlipStatus); LIB_FUNCTION("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutSubmitFlip); LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", sceVideoOutRegisterBuffers); diff --git a/src/core/libraries/videoout/video_out.h b/src/core/libraries/videoout/video_out.h index 09b79e85d8c..fdff30f0b72 100644 --- a/src/core/libraries/videoout/video_out.h +++ b/src/core/libraries/videoout/video_out.h @@ -4,29 +4,25 @@ #pragma once #include + #include "core/libraries/kernel/equeue.h" #include "core/libraries/videoout/buffer.h" +#include "core/libraries/videoout/driver.h" +#include "core/libraries/videoout/flip_status.h" +#include "core/libraries/videoout/sce_video_out_resolution_status.h" namespace Core::Loader { class SymbolsResolver; } namespace Libraries::VideoOut { +//class VideoOutDriver; // SceVideoOutBusType constexpr int SCE_VIDEO_OUT_BUS_TYPE_MAIN = 0; // Main output constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_SOCIAL_SCREEN = 5; // Aux output for social constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_GAME_LIVE_STREAMING = 6; // Aux output for screaming -// SceVideoOutRefreshRate -constexpr int SCE_VIDEO_OUT_REFRESH_RATE_UNKNOWN = 0; -constexpr int SCE_VIDEO_OUT_REFRESH_RATE_23_98HZ = 1; -constexpr int SCE_VIDEO_OUT_REFRESH_RATE_50HZ = 2; -constexpr int SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ = 3; -constexpr int SCE_VIDEO_OUT_REFRESH_RATE_119_88HZ = 13; -constexpr int SCE_VIDEO_OUT_REFRESH_RATE_89_91HZ = 35; -constexpr s64 SCE_VIDEO_OUT_REFRESH_RATE_ANY = 0xFFFFFFFFFFFFFFFFUL; - constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB = 0x80000000; constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB = 0x80002200; constexpr int SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10 = 0x88060000; @@ -67,40 +63,6 @@ enum class AspectRatioMode : s32 { Ratio16_9 = 0, }; -struct FlipStatus { - u64 count = 0; - u64 process_time = 0; - u64 tsc = 0; - s64 flip_arg = -1; - u64 submit_tsc = 0; - u64 reserved0 = 0; - s32 gc_queue_num = 0; - s32 flip_pending_num = 0; - s32 current_buffer = -1; - u32 reserved1 = 0; -}; - -struct SceVideoOutResolutionStatus { - s32 full_width = 1280; - s32 full_height = 720; - s32 pane_width = 1280; - s32 pane_height = 720; - u64 refresh_rate = SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ; - float screen_size_in_inch = 50; - u16 flags = 0; - u16 reserved0 = 0; - u32 reserved1[3] = {0}; -}; - -struct SceVideoOutVblankStatus { - u64 count = 0; - u64 process_time = 0; - u64 tsc = 0; - u64 reserved[1] = {0}; - u8 flags = 0; - u8 pad1[7] = {}; -}; - struct SceVideoOutDeviceCapabilityInfo { u64 capability; }; @@ -141,6 +103,10 @@ s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettin // Internal system functions s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, void** unk); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + std::unique_ptr driver; + + Engine(Core::Loader::SymbolsResolver* sym, Vulkan::Presenter& presenter); +}; } // namespace Libraries::VideoOut diff --git a/src/core/libraries/voice/voice.cpp b/src/core/libraries/voice/voice.cpp index 9379cadc5aa..b08c272ee6a 100644 --- a/src/core/libraries/voice/voice.cpp +++ b/src/core/libraries/voice/voice.cpp @@ -166,7 +166,7 @@ s32 PS4_SYSV_ABI sceVoiceWriteToIPort() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("oV9GAdJ23Gw", "libSceVoice", 1, "libSceVoice", sceVoiceConnectIPortToOPort); LIB_FUNCTION("nXpje5yNpaE", "libSceVoice", 1, "libSceVoice", sceVoiceCreatePort); LIB_FUNCTION("b7kJI+nx2hg", "libSceVoice", 1, "libSceVoice", sceVoiceDeletePort); diff --git a/src/core/libraries/voice/voice.h b/src/core/libraries/voice/voice.h index 89467c83ce8..95277c25a04 100644 --- a/src/core/libraries/voice/voice.h +++ b/src/core/libraries/voice/voice.h @@ -52,5 +52,8 @@ s32 PS4_SYSV_ABI sceVoiceVADAdjustment(); s32 PS4_SYSV_ABI sceVoiceVADSetVersion(); s32 PS4_SYSV_ABI sceVoiceWriteToIPort(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Voice \ No newline at end of file diff --git a/src/core/libraries/vr_tracker/vr_tracker.cpp b/src/core/libraries/vr_tracker/vr_tracker.cpp index 41989aaa1a4..955d2954a8b 100644 --- a/src/core/libraries/vr_tracker/vr_tracker.cpp +++ b/src/core/libraries/vr_tracker/vr_tracker.cpp @@ -475,7 +475,7 @@ s32 PS4_SYSV_ABI sceVrTrackerTerm() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("24kDA+A0Ox0", "libSceVrTrackerFourDeviceAllowed", 1, "libSceVrTracker", sceVrTrackerRegisterDevice2); LIB_FUNCTION("5IFOAYv-62g", "libSceVrTracker", 1, "libSceVrTracker", sceVrTrackerCpuProcess); diff --git a/src/core/libraries/vr_tracker/vr_tracker.h b/src/core/libraries/vr_tracker/vr_tracker.h index 6a052c5fb6a..be34af74efb 100644 --- a/src/core/libraries/vr_tracker/vr_tracker.h +++ b/src/core/libraries/vr_tracker/vr_tracker.h @@ -403,5 +403,8 @@ s32 PS4_SYSV_ABI sceVrTrackerStopLiveCapture(); s32 PS4_SYSV_ABI sceVrTrackerUnregisterDevice(const s32 handle); s32 PS4_SYSV_ABI sceVrTrackerTerm(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::VrTracker \ No newline at end of file diff --git a/src/core/libraries/web_browser_dialog/webbrowserdialog.cpp b/src/core/libraries/web_browser_dialog/webbrowserdialog.cpp index 5844affa2e5..f80f6705b75 100644 --- a/src/core/libraries/web_browser_dialog/webbrowserdialog.cpp +++ b/src/core/libraries/web_browser_dialog/webbrowserdialog.cpp @@ -94,7 +94,7 @@ s32 PS4_SYSV_ABI Func_F2BE042771625F8C() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("PSK+Eik919Q", "libSceWebBrowserDialog", 1, "libSceWebBrowserDialog", sceWebBrowserDialogClose); LIB_FUNCTION("Wit4LjeoeX4", "libSceWebBrowserDialog", 1, "libSceWebBrowserDialog", diff --git a/src/core/libraries/web_browser_dialog/webbrowserdialog.h b/src/core/libraries/web_browser_dialog/webbrowserdialog.h index 3dad7e1e914..c8073e6ac64 100644 --- a/src/core/libraries/web_browser_dialog/webbrowserdialog.h +++ b/src/core/libraries/web_browser_dialog/webbrowserdialog.h @@ -27,5 +27,8 @@ Libraries::CommonDialog::Error PS4_SYSV_ABI sceWebBrowserDialogTerminate(); Libraries::CommonDialog::Status PS4_SYSV_ABI sceWebBrowserDialogUpdateStatus(); s32 PS4_SYSV_ABI Func_F2BE042771625F8C(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::WebBrowserDialog \ No newline at end of file diff --git a/src/core/libraries/zlib/zlib.cpp b/src/core/libraries/zlib/zlib.cpp index 57b67460fb6..1dd8db2b3f4 100644 --- a/src/core/libraries/zlib/zlib.cpp +++ b/src/core/libraries/zlib/zlib.cpp @@ -172,7 +172,7 @@ s32 PS4_SYSV_ABI sceZlibFinalize() { return ORBIS_OK; } -void RegisterLib(Core::Loader::SymbolsResolver* sym) { +Engine::Engine(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("m1YErdIXCp4", "libSceZlib", 1, "libSceZlib", sceZlibInitialize); LIB_FUNCTION("6na+Sa-B83w", "libSceZlib", 1, "libSceZlib", sceZlibFinalize); LIB_FUNCTION("TLar1HULv1Q", "libSceZlib", 1, "libSceZlib", sceZlibInflate); diff --git a/src/core/libraries/zlib/zlib_sce.h b/src/core/libraries/zlib/zlib_sce.h index 32d738f48dd..2030de9ec77 100644 --- a/src/core/libraries/zlib/zlib_sce.h +++ b/src/core/libraries/zlib/zlib_sce.h @@ -17,5 +17,8 @@ s32 PS4_SYSV_ABI sceZlibWaitForDone(u64* request_id, const u32* timeout); s32 PS4_SYSV_ABI sceZlibGetResult(u64 request_id, u32* dst_length, s32* status); s32 PS4_SYSV_ABI sceZlibFinalize(); -void RegisterLib(Core::Loader::SymbolsResolver* sym); +struct Engine { + Engine(Core::Loader::SymbolsResolver* sym); +}; + } // namespace Libraries::Zlib \ No newline at end of file diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 889f3a298c3..863ce7c210f 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -21,6 +21,8 @@ #include "core/memory.h" #include "core/tls.h" #include "ipc/ipc.h" +#include "libraries/libs.h" +#include "shadps4_app.h" #ifndef _WIN32 #include @@ -109,14 +111,14 @@ void Linker::Execute(const std::vector& args) { memory->SetupMemoryRegions(fmem_size, use_extended_mem1, use_extended_mem2); - main_thread.Run([this, module, &args](std::stop_token) { + main_thread.Run([this, module, &args](std::stop_token stop_token) { Common::SetCurrentThreadName("Game:Main"); #ifndef _WIN32 // Clear any existing signal mask for game threads. sigset_t emptyset; sigemptyset(&emptyset); pthread_sigmask(SIG_SETMASK, &emptyset, nullptr); #endif - if (auto& ipc = IPC::Instance()) { + if (auto& ipc = ShadPs4App::GetInstance()->m_ipc) { ipc.WaitForStart(); } @@ -136,7 +138,7 @@ void Linker::Execute(const std::vector& args) { ASSERT_MSG(result == 0, "Unable to emulate libSceGnmDriver initialization"); // Start main module. - EntryParams& params = Libraries::Kernel::entry_params; + auto& params = ShadPs4App::GetInstance()->m_hle_layer->m_kernel.entry_params; params.argc = 1; params.argv[0] = "eboot.bin"; if (!args.empty()) { @@ -147,6 +149,11 @@ void Linker::Execute(const std::vector& args) { } params.entry_addr = module->GetEntryAddress(); Libraries::Kernel::ClearStack(); + static bool stop_requested = false; + if (stop_token.stop_requested() || stop_requested) { + stop_requested = true; + return; + } RunMainEntry(¶ms); }); } diff --git a/src/core/linker.h b/src/core/linker.h index 895901f0861..8f8849c50cd 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -8,6 +8,7 @@ #include #include "core/libraries/kernel/threads.h" #include "core/module.h" +#include "core/entry_params.h" namespace Core { @@ -44,15 +45,6 @@ struct OrbisProcParam { using ExitFunc = PS4_SYSV_ABI void (*)(); -class Linker; - -struct EntryParams { - int argc; - u32 padding; - const char* argv[33]; - VAddr entry_addr; -}; - struct HeapAPI { PS4_SYSV_ABI void* (*heap_malloc)(u64); PS4_SYSV_ABI void (*heap_free)(void*); @@ -154,11 +146,12 @@ class Linker { void Execute(const std::vector& args = {}); void DebugDump(); + Libraries::Kernel::Thread main_thread; + private: const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l); MemoryManager* memory; - Libraries::Kernel::Thread main_thread; std::mutex mutex; u32 dtv_generation_counter{1}; size_t static_tls_size{}; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a340c3643c4..4620e801ae2 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -11,6 +11,7 @@ #include "core/libraries/kernel/orbis_error.h" #include "core/libraries/kernel/process.h" #include "core/memory.h" +#include "shadps4_app.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" namespace Core { diff --git a/src/core/module.h b/src/core/module.h index 8dde0f4677b..5cdd55bcff5 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -9,6 +9,7 @@ #include "core/emulator_settings.h" #include "core/loader/elf.h" #include "core/loader/symbols_resolver.h" +#include "shadps4_app.h" namespace Core { diff --git a/src/core/thread.cpp b/src/core/thread.cpp index 0015f40b995..8edb9e8c959 100644 --- a/src/core/thread.cpp +++ b/src/core/thread.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/alignment.h" +#include "common/assert.h" #include "core/libraries/kernel/threads/pthread.h" #include "thread.h" #ifdef _WIN64 diff --git a/src/core/user_manager.cpp b/src/core/user_manager.cpp index 73e881e8ea4..1054297a88d 100644 --- a/src/core/user_manager.cpp +++ b/src/core/user_manager.cpp @@ -6,6 +6,7 @@ #include #include "emulator_settings.h" #include "libraries/system/userservice.h" +#include "shadps4_app.h" #include "user_manager.h" #include "user_settings.h" diff --git a/src/core/user_settings.cpp b/src/core/user_settings.cpp index cf569a68a33..f983ceeed42 100644 --- a/src/core/user_settings.cpp +++ b/src/core/user_settings.cpp @@ -23,18 +23,6 @@ UserSettingsImpl::~UserSettingsImpl() { Save(); } -std::shared_ptr UserSettingsImpl::GetInstance() { - std::lock_guard lock(s_mutex); - if (!s_instance) - s_instance = std::make_shared(); - return s_instance; -} - -void UserSettingsImpl::SetInstance(std::shared_ptr instance) { - std::lock_guard lock(s_mutex); - s_instance = std::move(instance); -} - bool UserSettingsImpl::Save() const { const auto path = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "users.json"; try { diff --git a/src/core/user_settings.h b/src/core/user_settings.h index 45cfa91ddcf..52511f7ff1f 100644 --- a/src/core/user_settings.h +++ b/src/core/user_settings.h @@ -15,7 +15,7 @@ #include "common/types.h" #include "core/user_manager.h" -#define UserSettings (*UserSettingsImpl::GetInstance()) +#define UserSettings ShadPs4App::GetInstance()->m_user_settings #define UserManagement UserSettings.GetUserManager() @@ -35,9 +35,6 @@ class UserSettingsImpl { bool Save() const; bool Load(); - static std::shared_ptr GetInstance(); - static void SetInstance(std::shared_ptr instance); - private: UserManager m_userManager; diff --git a/src/emulator.cpp b/src/emulator.cpp index 034d30ed8d9..851870c4693 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -11,7 +11,6 @@ #include #include "common/debug.h" -#include "common/logging/backend.h" #include "common/logging/log.h" #include "common/thread.h" #include "core/emulator_settings.h" @@ -41,6 +40,7 @@ #include "core/memory.h" #include "core/user_settings.h" #include "emulator.h" +#include "shadps4_app.h" #include "video_core/cache_storage.h" #include "video_core/renderdoc.h" @@ -215,12 +215,10 @@ void Emulator::Run(std::filesystem::path file, std::vector args, EmulatorSettings.Load(id); // Initialize logging as soon as possible - if (!id.empty() && EmulatorSettings.IsSeparateLoggingEnabled()) { - Common::Log::Initialize(id + ".log"); - } else { - Common::Log::Initialize(); + if (!id.empty() && EmulatorSettings.IsLogSeparate()) { + Common::Log::Redirect(id + ".log"); } - Common::Log::Start(); + if (!std::filesystem::exists(file)) { LOG_CRITICAL(Loader, "eboot.bin does not exist: {}", std::filesystem::absolute(file).string()); @@ -234,14 +232,18 @@ void Emulator::Run(std::filesystem::path file, std::vector args, LOG_INFO(Loader, "Remote {}", Common::g_scm_remote_url); LOG_INFO(Config, "Game-specific config used: {}", - EmulatorState::GetInstance()->IsGameSpecifigConfigUsed()); + ShadPs4App::GetInstance()->m_emulator_state.IsGameSpecifigConfigUsed()); - LOG_INFO(Config, "General LogType: {}", EmulatorSettings.GetLogType()); - LOG_INFO(Config, "General isIdenticalLogGrouped: {}", EmulatorSettings.IsIdenticalLogGrouped()); LOG_INFO(Config, "General isNeo: {}", EmulatorSettings.IsNeo()); LOG_INFO(Config, "General isDevKit: {}", EmulatorSettings.IsDevKit()); LOG_INFO(Config, "General isConnectedToNetwork: {}", EmulatorSettings.IsConnectedToNetwork()); LOG_INFO(Config, "General isPsnSignedIn: {}", EmulatorSettings.IsPSNSignedIn()); + LOG_INFO(Config, "Log sync: {}", EmulatorSettings.IsLogSync()); + LOG_INFO(Config, "Log skipDuplicate: {}", EmulatorSettings.IsLogSkipDuplicate()); + LOG_INFO(Config, "Log filter: {}", EmulatorSettings.GetLogFilter()); +#ifdef _WIN32 + LOG_INFO(Config, "Log type: {}", EmulatorSettings.GetLogType()); +#endif LOG_INFO(Config, "GPU isNullGpu: {}", EmulatorSettings.IsNullGPU()); LOG_INFO(Config, "GPU readbacksMode: {}", EmulatorSettings.GetReadbacksMode()); LOG_INFO(Config, "GPU readbackLinearImages: {}", @@ -412,7 +414,8 @@ void Emulator::Run(std::filesystem::path file, std::vector args, } // Initialize kernel and library facilities. - Libraries::InitHLELibs(&linker->GetHLESymbols()); + ShadPs4App::GetInstance()->m_hle_layer = std::make_unique(&linker->GetHLESymbols()); + ShadPs4App::GetInstance()->m_hle_layer->m_video_out.driver->cond_var.notify_all(); // Load the module with the linker if (linker->LoadModule(eboot_path) == -1) { @@ -432,16 +435,19 @@ void Emulator::Run(std::filesystem::path file, std::vector args, } #endif + std::unique_ptr play_time_thread; + if (!id.empty()) { start_time = std::chrono::steady_clock::now(); - std::thread([this, id]() { - while (true) { - std::this_thread::sleep_for(std::chrono::seconds(60)); + play_time_thread = std::make_unique([this, id](std::stop_token token) { + Common::SetCurrentThreadName("shadPS4:UpdatePlayTime"); + while (!token.stop_requested()) { + std::this_thread::sleep_for(std::chrono::seconds(1)); UpdatePlayTime(id); start_time = std::chrono::steady_clock::now(); } - }).detach(); + }); } args.insert(args.begin(), eboot_name.generic_string()); @@ -455,7 +461,14 @@ void Emulator::Run(std::filesystem::path file, std::vector args, UpdatePlayTime(id); Storage::DataBase::Instance().Close(); - std::quick_exit(0); + //ShadPs4App::GetInstance()->m_hle_layer.reset(); + linker->main_thread.Stop(); + + if (play_time_thread != nullptr) { + play_time_thread->request_stop(); + } + + //std::quick_exit(0); } void Emulator::Restart(std::filesystem::path eboot_path, @@ -497,9 +510,9 @@ void Emulator::Restart(std::filesystem::path eboot_path, LOG_INFO(Common, "Restarting the emulator with args: {}", fmt::join(args, " ")); Libraries::SaveData::Backup::StopThread(); - Common::Log::Denitializer(); + Common::Log::Shutdown(); - auto& ipc = IPC::Instance(); + auto& ipc = ShadPs4App::GetInstance()->m_ipc; if (ipc.IsEnabled()) { ipc.SendRestart(args); @@ -527,7 +540,7 @@ void Emulator::Restart(std::filesystem::path eboot_path, nullptr, &si, &pi); if (!success) { - std::cerr << "Failed to restart game: {}" << GetLastError() << std::endl; + std::cerr << "Failed to restart game: " << GetLastError() << std::endl; std::quick_exit(1); } diff --git a/src/emulator.h b/src/emulator.h index d350ce16c69..11deb8e3e3c 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -7,18 +7,17 @@ #include #include -#include "common/singleton.h" -#include "core/linker.h" #include "input/controller.h" #include "sdl_window.h" namespace Core { -using HLEInitDef = void (*)(Core::Loader::SymbolsResolver* sym); +class Linker; +class MemoryManager; struct SysModules { std::string_view module_name; - HLEInitDef callback; + bool should_init; }; class Emulator { diff --git a/src/imgui/renderer/imgui_core.cpp b/src/imgui/renderer/imgui_core.cpp index b52a68d22f5..235ad8369de 100644 --- a/src/imgui/renderer/imgui_core.cpp +++ b/src/imgui/renderer/imgui_core.cpp @@ -14,6 +14,7 @@ #include "imgui_impl_vulkan.h" #include "imgui_internal.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "texture_manager.h" #include "video_core/renderer_vulkan/vk_presenter.h" diff --git a/src/imgui/renderer/imgui_impl_sdl3.cpp b/src/imgui/renderer/imgui_impl_sdl3.cpp index 679aeb8c071..ffcd72eb603 100644 --- a/src/imgui/renderer/imgui_impl_sdl3.cpp +++ b/src/imgui/renderer/imgui_impl_sdl3.cpp @@ -11,6 +11,7 @@ #include "input/controller.h" #include "input/input_handler.h" #include "sdl_window.h" +#include "shadps4_app.h" // SDL #include diff --git a/src/imgui/renderer/imgui_impl_vulkan.cpp b/src/imgui/renderer/imgui_impl_vulkan.cpp index 97f44c31804..0ef1d263d34 100644 --- a/src/imgui/renderer/imgui_impl_vulkan.cpp +++ b/src/imgui/renderer/imgui_impl_vulkan.cpp @@ -1219,6 +1219,10 @@ void ImGuiImplVulkanDestroyDeviceObjects() { v.device.destroyDescriptorSetLayout(bd->descriptor_set_layout, v.allocator); bd->descriptor_set_layout = VK_NULL_HANDLE; } + if (bd->descriptor_pool) { + v.device.destroyDescriptorPool(bd->descriptor_pool, v.allocator); + bd->descriptor_pool = VK_NULL_HANDLE; + } if (bd->pipeline_layout) { v.device.destroyPipelineLayout(bd->pipeline_layout, v.allocator); bd->pipeline_layout = VK_NULL_HANDLE; diff --git a/src/imgui/renderer/texture_manager.cpp b/src/imgui/renderer/texture_manager.cpp index f8ac0435235..d982b104966 100644 --- a/src/imgui/renderer/texture_manager.cpp +++ b/src/imgui/renderer/texture_manager.cpp @@ -13,6 +13,7 @@ #include "core/emulator_settings.h" #include "imgui_impl_vulkan.h" #include "texture_manager.h" +#include "shadps4_app.h" namespace ImGui { diff --git a/src/input/controller.cpp b/src/input/controller.cpp index c1ba584e32c..3d2c15913a0 100644 --- a/src/input/controller.cpp +++ b/src/input/controller.cpp @@ -14,6 +14,7 @@ #include "core/libraries/system/userservice.h" #include "core/user_settings.h" #include "input/controller.h" +#include "shadps4_app.h" namespace Input { diff --git a/src/input/input_handler.cpp b/src/input/input_handler.cpp index cf258235d73..10aa266c466 100644 --- a/src/input/input_handler.cpp +++ b/src/input/input_handler.cpp @@ -27,6 +27,7 @@ #include "core/emulator_state.h" #include "input/controller.h" #include "input/input_mouse.h" +#include "shadps4_app.h" namespace Input { /* diff --git a/src/input/input_mouse.cpp b/src/input/input_mouse.cpp index f90c204846a..c787601bdf4 100644 --- a/src/input/input_mouse.cpp +++ b/src/input/input_mouse.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include "common/assert.h" #include "common/types.h" diff --git a/src/main.cpp b/src/main.cpp index fb9ff307844..06ff7d044d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,218 +1,59 @@ // SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "common/config.h" -#include "common/key_manager.h" -#include "common/logging/backend.h" -#include "common/memory_patcher.h" -#include "common/path_util.h" -#include "core/debugger.h" -#include "core/file_sys/fs.h" -#include "core/ipc/ipc.h" -#include "emulator.h" +#include "core/libraries/libs.h"//TODO +#include "shadps4_app.h" #ifdef _WIN32 #include #endif -#include + +std::shared_ptr ShadPs4App::instance = std::make_shared(); + +static void DeleteInstance() { + ShadPs4App::instance.reset(); +} int main(int argc, char* argv[]) { #ifdef _WIN32 SetConsoleOutputCP(CP_UTF8); #endif - IPC::Instance().Init(); - - auto emu_state = std::make_shared(); - EmulatorState::SetInstance(emu_state); - UserSettings.Load(); - - const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); - Config::load(user_dir / "config.toml"); - - // ---- Trophy key migration ---- - auto key_manager = KeyManager::GetInstance(); - key_manager->LoadFromFile(); - if (key_manager->GetAllKeys().TrophyKeySet.ReleaseTrophyKey.empty() && - !Config::getTrophyKey().empty()) { - auto keys = key_manager->GetAllKeys(); - if (keys.TrophyKeySet.ReleaseTrophyKey.empty() && !Config::getTrophyKey().empty()) { - keys.TrophyKeySet.ReleaseTrophyKey = - KeyManager::HexStringToBytes(Config::getTrophyKey()); - key_manager->SetAllKeys(keys); - key_manager->SaveToFile(); - } - } - - // Load configurations - std::shared_ptr emu_settings = std::make_shared(); - EmulatorSettingsImpl::SetInstance(emu_settings); - emu_settings->Load(); - - CLI::App app{"shadPS4 Emulator CLI"}; - - // ---- CLI state ---- - std::optional gamePath; - std::vector gameArgs; - std::optional overrideRoot; - std::optional waitPid; - bool waitForDebugger = false; - - std::optional fullscreenStr; - bool ignoreGamePatch = false; - bool showFps = false; - bool configClean = false; - bool configGlobal = false; - bool logAppend = false; - - std::optional addGameFolder; - std::optional setAddonFolder; - std::optional patchFile; - - // ---- Options ---- - app.add_option("-g,--game", gamePath, "Game path or ID"); - app.add_option("-p,--patch", patchFile, "Patch file to apply"); - app.add_flag("-i,--ignore-game-patch", ignoreGamePatch, - "Disable automatic loading of game patches"); - - // FULLSCREEN: behavior-identical - app.add_option("-f,--fullscreen", fullscreenStr, "Fullscreen mode (true|false)"); - - app.add_option("--override-root", overrideRoot)->check(CLI::ExistingDirectory); - - app.add_flag("--wait-for-debugger", waitForDebugger); - app.add_option("--wait-for-pid", waitPid); - - app.add_flag("--show-fps", showFps); - app.add_flag("--config-clean", configClean); - app.add_flag("--config-global", configGlobal); - app.add_flag("--log-append", logAppend); + auto& shadps4_app = *ShadPs4App::instance; - app.add_option("--add-game-folder", addGameFolder)->check(CLI::ExistingDirectory); - app.add_option("--set-addon-folder", setAddonFolder)->check(CLI::ExistingDirectory); - - // ---- Capture args after `--` verbatim ---- - app.allow_extras(); - app.parse_complete_callback([&]() { - const auto& extras = app.remaining(); - if (!extras.empty()) { - gameArgs = extras; + Common::Log::Setup(argc, argv); + // register Shutdwon to run before registry dtor + static struct LogDestroyer { + ~LogDestroyer() { + Common::Log::Shutdown(); } - }); + } s_log_destroyer; - // ---- No-args behavior ---- - if (argc == 1) { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "shadPS4", - "This is a CLI application. Please use the QTLauncher for a GUI:\n" - "https://github.com/shadps4-emu/shadps4-qtlauncher/releases", - nullptr); - std::cout << app.help(); - return -1; - } + // register instance deleter after log one + //std::atexit(DeleteInstance); + //std::at_quick_exit(DeleteInstance); - try { - app.parse(argc, argv); - } catch (const CLI::ParseError& e) { - return app.exit(e); - } + if (auto code = shadps4_app.parse(argc, argv); code.has_value()) { + //DeleteInstance(); + //Common::Log::Shutdown(); - // ---- Utility commands ---- - if (addGameFolder) { - EmulatorSettings.AddGameInstallDir(*addGameFolder); - EmulatorSettings.Save(); - std::cout << "Game folder successfully saved.\n"; - return 0; + return *code; } - if (setAddonFolder) { - EmulatorSettings.SetAddonInstallDir(*setAddonFolder); - EmulatorSettings.Save(); - std::cout << "Addon folder successfully saved.\n"; - return 0; - } + shadps4_app.init(); - if (!gamePath.has_value()) { - if (!gameArgs.empty()) { - gamePath = gameArgs.front(); - gameArgs.erase(gameArgs.begin()); - } else { - std::cerr << "Error: Please provide a game path or ID.\n"; - return 1; - } - } - if (!gameArgs.empty()) { - if (gameArgs.front() == "--") { - gameArgs.erase(gameArgs.begin()); - } else { - std::cerr << "Error: unhandled flags\n"; - return 1; + // should be the first to be destroyed (in particular before vulkan/log) + static struct AppDestroyer { + ~AppDestroyer() { + //DeleteInstance(); } - } - - // ---- Apply flags ---- - if (patchFile) - MemoryPatcher::patch_file = *patchFile; + } s_app_destroyer; - if (ignoreGamePatch) - Core::FileSys::MntPoints::ignore_game_patches = true; - - if (fullscreenStr) { - if (*fullscreenStr == "true") { - EmulatorSettings.SetFullScreen(true); - } else if (*fullscreenStr == "false") { - EmulatorSettings.SetFullScreen(false); - } else { - std::cerr << "Error: Invalid argument for --fullscreen (use true|false)\n"; - return 1; - } - } - - if (showFps) - EmulatorSettings.SetShowFpsCounter(true); - - if (configClean) - EmulatorSettings.SetConfigMode(ConfigMode::Clean); - - if (configGlobal) - EmulatorSettings.SetConfigMode(ConfigMode::Global); - - if (logAppend) - Common::Log::SetAppend(); - - // ---- Resolve game path or ID ---- - std::filesystem::path ebootPath(*gamePath); - if (!std::filesystem::exists(ebootPath)) { - bool found = false; - constexpr int maxDepth = 5; - for (const auto& installDir : EmulatorSettings.GetGameInstallDirs()) { - if (auto foundPath = Common::FS::FindGameByID(installDir, *gamePath, maxDepth)) { - ebootPath = *foundPath; - found = true; - break; - } - } - if (!found) { - std::cerr << "Error: Game ID or file path not found: " << *gamePath << "\n"; - return 1; - } - } + //if (!Common::Log::g_should_append) + // Common::Log::Truncate(); - if (waitPid) - Core::Debugger::WaitForPid(*waitPid); + auto r = shadps4_app.run(); - auto* emulator = Common::Singleton::Instance(); - emulator->executableName = argv[0]; - emulator->waitForDebuggerBeforeRun = waitForDebugger; - emulator->Run(ebootPath, gameArgs, overrideRoot); + DeleteInstance(); - return 0; + return r; } diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 766a336c236..06522a18bae 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -21,6 +21,7 @@ #include "input/input_handler.h" #include "input/input_mouse.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "video_core/renderdoc.h" #ifdef __APPLE__ @@ -72,11 +73,18 @@ static OrbisPadButtonDataOffset SDLGamepadToOrbisButton(u8 button) { } static Uint32 SDLCALL PollController(void* userdata, SDL_TimerID timer_id, Uint32 interval) { - auto* controller = reinterpret_cast(userdata); - controller->UpdateAxisSmoothing(); - controller->Gyro(0); - controller->Acceleration(0); - return interval; + try { + auto* controller = reinterpret_cast(userdata); + controller->UpdateAxisSmoothing(); + controller->Gyro(0); + controller->Acceleration(0); + return interval; + } + catch (const std::runtime_error& exception) { + LOG_TRACE(Frontend, "Thread stop: {}", exception.what()); + } + //timer is canceled and will be removed. + return 0; } static Uint32 SDLCALL PollControllerLightColour(void* userdata, SDL_TimerID timer_id, diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 81f8d08d7e4..464fbab99a3 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -9,6 +9,7 @@ #include "shader_recompiler/ir/attribute.h" #include "shader_recompiler/ir/patch.h" #include "shader_recompiler/runtime_info.h" +#include "shadps4_app.h" #include diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index de38222967a..dce2898e282 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -13,6 +13,7 @@ #include "shader_recompiler/ir/reinterpret.h" #include "shader_recompiler/profile.h" #include "shader_recompiler/runtime_info.h" +#include "shadps4_app.h" #include "video_core/amdgpu/resource.h" #define MAGIC_ENUM_RANGE_MIN 0 diff --git a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp index a23ee2319f9..616e6de4246 100644 --- a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp +++ b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp @@ -19,6 +19,7 @@ #include "shader_recompiler/ir/reg.h" #include "shader_recompiler/ir/srt_gvn_table.h" #include "shader_recompiler/ir/value.h" +#include "shadps4_app.h" #include "src/common/arch.h" #include "src/common/decoder.h" diff --git a/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp b/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp index e26d3f078e9..c293bbfdf49 100644 --- a/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp +++ b/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp @@ -4,6 +4,7 @@ #include "core/emulator_settings.h" #include "shader_recompiler/ir/program.h" #include "shader_recompiler/profile.h" +#include "shadps4_app.h" #include "video_core/buffer_cache/buffer_cache.h" namespace Shader::Optimization { diff --git a/src/shader_recompiler/ir/program.cpp b/src/shader_recompiler/ir/program.cpp index 926f8f29d22..a3acbaacf96 100644 --- a/src/shader_recompiler/ir/program.cpp +++ b/src/shader_recompiler/ir/program.cpp @@ -13,6 +13,7 @@ #include "shader_recompiler/ir/basic_block.h" #include "shader_recompiler/ir/program.h" #include "shader_recompiler/ir/value.h" +#include "shadps4_app.h" namespace Shader::IR { diff --git a/src/shadps4_app.h b/src/shadps4_app.h new file mode 100644 index 00000000000..6270744bb18 --- /dev/null +++ b/src/shadps4_app.h @@ -0,0 +1,254 @@ +// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "common/config.h" +#include "common/key_manager.h" +#include "common/logging/log.h" +#include "common/memory_patcher.h" +#include "common/path_util.h" +#include "core/debugger.h" +#include "core/emulator_settings.h" +#include "core/emulator_state.h" +#include "core/file_sys/fs.h" +#include "core/ipc/ipc.h" +//#include "core/libraries/libs.h" +#include "core/user_settings.h" +#include "emulator.h" + +namespace Libraries { + +struct HleLayer; + +} + +class ShadPs4App { +public: + static std::shared_ptr instance; + + static auto GetInstance() { + if (instance == nullptr) { + throw std::runtime_error("ShadPs4App instance has been destroyed"); + } + return instance; + } + + std::optional parse(int argc, char* argv[]) { + CLI::App app{"shadPS4 Emulator CLI"}; + + // ---- CLI state ---- + std::optional waitPid; + + std::optional fullscreenStr; + bool ignoreGamePatch = false; + bool showFps = false; + bool configClean = false; + bool configGlobal = false; + std::optional logAppend; + // Common::Log::g_should_append = EmulatorSettings.IsLogAppend(); + + std::optional addGameFolder; + std::optional setAddonFolder; + std::optional patchFile; + + // ---- Options ---- + app.add_option("-g,--game", gamePath, "Game path or ID"); + app.add_option("-p,--patch", patchFile, "Patch file to apply"); + app.add_flag("-i,--ignore-game-patch", ignoreGamePatch, + "Disable automatic loading of game patches"); + + // FULLSCREEN: behavior-identical + app.add_option("-f,--fullscreen", fullscreenStr, "Fullscreen mode (true|false)"); + + app.add_option("--override-root", overrideRoot)->check(CLI::ExistingDirectory); + + app.add_flag("--wait-for-debugger", waitForDebugger); + app.add_option("--wait-for-pid", waitPid); + + app.add_flag("--show-fps", showFps); + app.add_flag("--config-clean", configClean); + app.add_flag("--config-global", configGlobal); + app.add_flag("--log-append", logAppend); + + app.add_option("--add-game-folder", addGameFolder)->check(CLI::ExistingDirectory); + app.add_option("--set-addon-folder", setAddonFolder)->check(CLI::ExistingDirectory); + + // ---- Capture args after `--` verbatim ---- + app.allow_extras(); + app.parse_complete_callback([&]() { + const auto& extras = app.remaining(); + if (!extras.empty()) { + gameArgs = extras; + } + }); + + // ---- No-args behavior ---- + if (argc == 1) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_INFORMATION, "shadPS4", + "This is a CLI application. Please use the QTLauncher for a GUI:\n" + "https://github.com/shadps4-emu/shadps4-qtlauncher/releases", + nullptr); + std::cout << app.help(); + return -1; + } + + try { + app.parse(argc, argv); + } catch (const CLI::ParseError& e) { + return app.exit(e); + } + + executableName = argv[0]; + + if (waitPid) + Core::Debugger::WaitForPid(*waitPid); + + // ---- Apply flags ---- + { + if (patchFile) + MemoryPatcher::patch_file = *patchFile; + + if (ignoreGamePatch) + Core::FileSys::MntPoints::ignore_game_patches = true; + } + + // ---- update settings from CLI ---- + { + if (fullscreenStr) { + if (*fullscreenStr == "true") { + m_emulator_settings.SetFullScreen(true); + } else if (*fullscreenStr == "false") { + m_emulator_settings.SetFullScreen(false); + } else { + std::cerr << "Error: Invalid argument for --fullscreen (use true|false)\n"; + return 1; + } + } + + if (showFps) + m_emulator_settings.SetShowFpsCounter(true); + + if (configClean) + m_emulator_settings.SetConfigMode(ConfigMode::Clean); + + if (configGlobal) + m_emulator_settings.SetConfigMode(ConfigMode::Global); + } + + // ---- Utility commands ---- + { + if (addGameFolder) { + m_emulator_settings.AddGameInstallDir(*addGameFolder); + m_emulator_settings.Save(); + std::cout << "Game folder successfully saved.\n"; + return 0; + } + + if (setAddonFolder) { + m_emulator_settings.SetAddonInstallDir(*setAddonFolder); + m_emulator_settings.Save(); + std::cout << "Addon folder successfully saved.\n"; + return 0; + } + } + + // ---- fix arguments ---- + if (!gamePath.has_value()) { + if (!gameArgs.empty()) { + gamePath = gameArgs.front(); + gameArgs.erase(gameArgs.begin()); + } else { + std::cerr << "Error: Please provide a game path or ID.\n"; + return 1; + } + } + if (!gameArgs.empty()) { + if (gameArgs.front() == "--") { + gameArgs.erase(gameArgs.begin()); + } else { + std::cerr << "Error: unhandled flags\n"; + return 1; + } + } + + return {}; + } + + void init() { + m_ipc.Init(m_emulator_state); + + // Load configurations + m_user_settings.Load(); + + Config::load(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"); + + // ---- Trophy key migration ---- + m_key_manager.LoadFromFile(); + if (m_key_manager.GetAllKeys().TrophyKeySet.ReleaseTrophyKey.empty() && + !Config::getTrophyKey().empty()) { + auto keys = m_key_manager.GetAllKeys(); + if (keys.TrophyKeySet.ReleaseTrophyKey.empty() && !Config::getTrophyKey().empty()) { + keys.TrophyKeySet.ReleaseTrophyKey = + KeyManager::HexStringToBytes(Config::getTrophyKey()); + m_key_manager.SetAllKeys(keys); + m_key_manager.SaveToFile(); + } + } + + m_emulator_settings.Load(); + } + + int run() { + // ---- Resolve game path or ID ---- + std::filesystem::path ebootPath(*gamePath); + + if (!std::filesystem::exists(ebootPath)) { + bool found = false; + constexpr int maxDepth = 5; + for (const auto& installDir : m_emulator_settings.GetGameInstallDirs()) { + if (auto foundPath = Common::FS::FindGameByID(installDir, *gamePath, maxDepth)) { + ebootPath = *foundPath; + found = true; + break; + } + } + if (!found) { + std::cerr << "Error: Game ID or file path not found: " << *gamePath << "\n"; + return 1; + } + } + + auto* emulator = Common::Singleton::Instance(); + emulator->executableName = executableName; + emulator->waitForDebuggerBeforeRun = waitForDebugger; + emulator->Run(ebootPath, gameArgs, overrideRoot); + + return 0; + } + + const char* executableName; + bool waitForDebugger = false; + + std::optional gamePath; + std::vector gameArgs; + std::optional overrideRoot; + + EmulatorState m_emulator_state; + IPC m_ipc; + + UserSettingsImpl m_user_settings; + KeyManager m_key_manager; + EmulatorSettingsImpl m_emulator_settings; + + std::unique_ptr m_hle_layer; +}; diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 0648df92281..c90732abd2a 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -13,6 +13,7 @@ #include "core/libraries/videoout/driver.h" #include "core/memory.h" #include "core/platform.h" +#include "shadps4_app.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/amdgpu/pm4_cmds.h" #include "video_core/renderdoc.h" diff --git a/src/video_core/buffer_cache/memory_tracker.h b/src/video_core/buffer_cache/memory_tracker.h index a093be8dd4b..f1b9d4d03cc 100644 --- a/src/video_core/buffer_cache/memory_tracker.h +++ b/src/video_core/buffer_cache/memory_tracker.h @@ -12,6 +12,7 @@ #include "common/debug.h" #include "common/types.h" #include "core/emulator_settings.h" +#include "shadps4_app.h" #include "video_core/buffer_cache/region_manager.h" namespace VideoCore { diff --git a/src/video_core/buffer_cache/region_manager.h b/src/video_core/buffer_cache/region_manager.h index a760dd596df..2e6804edda4 100644 --- a/src/video_core/buffer_cache/region_manager.h +++ b/src/video_core/buffer_cache/region_manager.h @@ -14,6 +14,7 @@ #endif #include "common/debug.h" #include "common/types.h" +#include "shadps4_app.h" #include "video_core/buffer_cache/region_definitions.h" #include "video_core/page_manager.h" diff --git a/src/video_core/cache_storage.cpp b/src/video_core/cache_storage.cpp index 8d6abf9b58f..88363987277 100644 --- a/src/video_core/cache_storage.cpp +++ b/src/video_core/cache_storage.cpp @@ -6,13 +6,12 @@ #include "common/polyfill_thread.h" #include "common/thread.h" #include "core/emulator_settings.h" - +#include "shadps4_app.h" #include "video_core/cache_storage.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_pipeline_cache.h" #include - #include #include #include diff --git a/src/video_core/renderdoc.cpp b/src/video_core/renderdoc.cpp index b0275221299..83ba620824a 100644 --- a/src/video_core/renderdoc.cpp +++ b/src/video_core/renderdoc.cpp @@ -3,6 +3,7 @@ #include "common/assert.h" #include "core/emulator_settings.h" +#include "shadps4_app.h" #include "video_core/renderdoc.h" #include @@ -122,7 +123,7 @@ void SetOutputDir(const std::filesystem::path& path, const std::string& prefix) return; } LOG_WARNING(Common, "RenderDoc capture path: {}", (path / prefix).string()); - rdoc_api->SetCaptureFilePathTemplate(fmt::UTF((path / prefix).u8string()).data.data()); + rdoc_api->SetCaptureFilePathTemplate((path / prefix).string().data()); } } // namespace VideoCore diff --git a/src/video_core/renderer_vulkan/host_passes/fsr_pass.cpp b/src/video_core/renderer_vulkan/host_passes/fsr_pass.cpp index a4ebc859de6..3c9729d348e 100644 --- a/src/video_core/renderer_vulkan/host_passes/fsr_pass.cpp +++ b/src/video_core/renderer_vulkan/host_passes/fsr_pass.cpp @@ -10,6 +10,7 @@ #define A_CPU #include "core/debug_state.h" +#include "shadps4_app.h" #include "video_core/host_shaders/fsr/ffx_a.h" #include "video_core/host_shaders/fsr/ffx_fsr1.h" diff --git a/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp b/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp index 4b073c5feac..bd374a49416 100644 --- a/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp +++ b/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "core/emulator_settings.h" +#include "shadps4_app.h" #include "video_core/host_shaders/fs_tri_vert.h" #include "video_core/host_shaders/post_process_frag.h" #include "video_core/renderer_vulkan/vk_platform.h" diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 6898df97ac4..1b510013864 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -15,6 +15,8 @@ #include +#include "imgui/renderer/imgui_core.h" + namespace Vulkan { namespace { @@ -183,6 +185,7 @@ Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index, } Instance::~Instance() { + ImGui::Core::Shutdown(GetDevice()); vmaDestroyAllocator(allocator); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 2666f05d353..887b742307c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -12,6 +12,7 @@ #include "shader_recompiler/info.h" #include "shader_recompiler/recompiler.h" #include "shader_recompiler/runtime_info.h" +#include "shadps4_app.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/cache_storage.h" #include "video_core/renderer_vulkan/liverpool_to_vk.h" diff --git a/src/video_core/renderer_vulkan/vk_pipeline_serialization.cpp b/src/video_core/renderer_vulkan/vk_pipeline_serialization.cpp index eb31d499485..de4453ff15b 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_serialization.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_serialization.cpp @@ -5,6 +5,7 @@ #include "core/emulator_settings.h" #include "shader_recompiler/frontend/fetch_shader.h" #include "shader_recompiler/info.h" +#include "shadps4_app.h" #include "video_core/cache_storage.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_pipeline_cache.h" diff --git a/src/video_core/renderer_vulkan/vk_platform.cpp b/src/video_core/renderer_vulkan/vk_platform.cpp index c77c8022363..b897a758bc0 100644 --- a/src/video_core/renderer_vulkan/vk_platform.cpp +++ b/src/video_core/renderer_vulkan/vk_platform.cpp @@ -21,6 +21,7 @@ #include "common/path_util.h" #include "core/emulator_settings.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "video_core/renderer_vulkan/vk_platform.h" #ifdef __APPLE__ @@ -36,23 +37,23 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback( vk::DebugUtilsMessageSeverityFlagBitsEXT severity, vk::DebugUtilsMessageTypeFlagsEXT type, const vk::DebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) { - Common::Log::Level level{}; + spdlog::level::level_enum level{}; switch (severity) { case vk::DebugUtilsMessageSeverityFlagBitsEXT::eError: - level = Common::Log::Level::Error; + level = spdlog::level::err; break; case vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning: - level = Common::Log::Level::Info; + level = spdlog::level::info; break; case vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo: case vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose: - level = Common::Log::Level::Debug; + level = spdlog::level::debug; break; default: - level = Common::Log::Level::Info; + level = spdlog::level::info; } - LOG_GENERIC(Common::Log::Class::Render_Vulkan, level, "{}: {}", + LOG_GENERIC(Common::Log::Render_Vulkan, level, "{}: {}", callback_data->pMessageIdName ? callback_data->pMessageIdName : "", callback_data->pMessage ? callback_data->pMessage : ""); diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index c2a2a6621f3..17dc0e2f48d 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -11,6 +11,7 @@ #include "imgui/renderer/imgui_core.h" #include "imgui/renderer/imgui_impl_vulkan.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "video_core/renderer_vulkan/vk_platform.h" #include "video_core/renderer_vulkan/vk_presenter.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" @@ -137,14 +138,34 @@ Presenter::Presenter(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_ Presenter::~Presenter() { ImGui::Layer::RemoveLayer(Common::Singleton::Instance()); + draw_scheduler.Finish(); + present_scheduler.Finish(); + flip_scheduler.Finish(); + Check(draw_scheduler.CommandBuffer().reset()); + Check(present_scheduler.CommandBuffer().reset()); + Check(flip_scheduler.CommandBuffer().reset()); + const vk::Device device = instance.GetDevice(); for (auto& frame : present_frames) { vmaDestroyImage(instance.GetAllocator(), frame.image, frame.allocation); device.destroyImageView(frame.image_view); device.destroyFence(frame.present_done); } - ImGui::Core::Shutdown(device); + /* + while (!free_queue.empty()) { + auto& iv = free_queue.front(); + + if (iv->image_view) { + device.destroyImageView(iv->image_view); + } + + if (iv->image) { + device.destroyImage(iv->image); + } + + free_queue.pop(); + }*/ } bool Presenter::IsVideoOutSurface(const AmdGpu::ColorBuffer& color_buffer) const { diff --git a/src/video_core/renderer_vulkan/vk_presenter.h b/src/video_core/renderer_vulkan/vk_presenter.h index c1748e9dd9b..35fa5f28e3e 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.h +++ b/src/video_core/renderer_vulkan/vk_presenter.h @@ -107,18 +107,18 @@ class Presenter { void SetExpectedGameSize(s32 width, s32 height); -private: +public: float expected_ratio{1920.0 / 1080.0f}; u32 expected_frame_width{1920}; u32 expected_frame_height{1080}; + Frontend::WindowSDL& window; + Instance instance; HostPasses::FsrPass fsr_pass; HostPasses::FsrPass::Settings fsr_settings{}; HostPasses::PostProcessingPass::Settings pp_settings{}; HostPasses::PostProcessingPass pp_pass; - Frontend::WindowSDL& window; AmdGpu::Liverpool* liverpool; - Instance instance; Scheduler draw_scheduler; Scheduler present_scheduler; Scheduler flip_scheduler; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 800941fe387..47815e8d3c8 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -5,6 +5,7 @@ #include "core/emulator_settings.h" #include "core/memory.h" #include "shader_recompiler/runtime_info.h" +#include "shadps4_app.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/renderer_vulkan/liverpool_to_vk.h" #include "video_core/renderer_vulkan/vk_instance.h" diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index fee0b408e6d..b8585a99eca 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -23,6 +23,8 @@ Scheduler::Scheduler(const Instance& instance) } Scheduler::~Scheduler() { + priority_pending_ops_thread.request_stop(); + #if TRACY_GPU_ENABLED std::free(profiler_scope); #endif diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 04f9d85043c..2e91fed263d 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -8,6 +8,7 @@ #include "core/emulator_settings.h" #include "imgui/renderer/imgui_core.h" #include "sdl_window.h" +#include "shadps4_app.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_swapchain.h" @@ -261,6 +262,12 @@ void Swapchain::Destroy() { LOG_WARNING(Render_Vulkan, "Failed to wait for device to become idle: {}", vk::to_string(wait_result)); } + + for (auto& image_view : images_view) { + device.destroyImageView(image_view); + } + images_view.clear(); + if (swapchain) { device.destroySwapchainKHR(swapchain); } diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index 826705d40ba..1e6183e461e 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h @@ -92,7 +92,7 @@ class Swapchain { return needs_hdr; } -private: +public: /// Selects the best available swapchain image format void FindPresentFormat(); diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 16371275692..d6c2993b35b 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -8,6 +8,7 @@ #include "common/scope_exit.h" #include "core/emulator_settings.h" #include "core/memory.h" +#include "shadps4_app.h" #include "video_core/buffer_cache/buffer_cache.h" #include "video_core/page_manager.h" #include "video_core/renderer_vulkan/vk_instance.h" @@ -415,7 +416,7 @@ std::tuple TextureCache::ResolveOverlap(const ImageInfo& imag cache_image.info.size.height, cache_image.info.size.depth, cache_image.info.pitch, cache_image.info.resources.levels, cache_image.info.resources.layers, cache_image.info.num_samples, static_cast(cache_image.info.tile_mode), - cache_image.info.num_bits, cache_image.info.props.is_block, + cache_image.info.num_bits, +cache_image.info.props.is_block, cache_image.info.guest_size, cache_image.tick_accessed_last, safe_to_delete, // New image details