From 48283da2a67c8465f69ca6318fed6132299fc1b5 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Mon, 1 Jun 2026 03:00:24 -0400 Subject: [PATCH] Core: Remove old config code (#4499) * Remove old config backend Trophy key migration now uses the toml library directly, like our config transfer code. * Don't retrieve user_dir in main No longer needed. --- CMakeLists.txt | 2 - src/common/config.cpp | 1553 ------------------------------------ src/common/config.h | 213 ----- src/common/key_manager.cpp | 48 +- src/common/key_manager.h | 1 + src/common/logging/log.cpp | 1 - src/main.cpp | 16 +- 7 files changed, 49 insertions(+), 1785 deletions(-) delete mode 100644 src/common/config.cpp delete mode 100644 src/common/config.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b0b2d99fc..927e102c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -732,8 +732,6 @@ set(COMMON src/common/logging/classes.h src/common/bit_field.h src/common/bounded_threadsafe_queue.h src/common/concepts.h - src/common/config.cpp - src/common/config.h src/common/cstring.h src/common/debug.h src/common/decoder.cpp diff --git a/src/common/config.cpp b/src/common/config.cpp deleted file mode 100644 index c8f5aa4b9..000000000 --- a/src/common/config.cpp +++ /dev/null @@ -1,1553 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include -#include -#include // for wstring support -#include - -#include "common/assert.h" -#include "common/config.h" -#include "common/logging/formatter.h" -#include "common/path_util.h" -#include "common/scm_rev.h" - -#include "input/input_handler.h" - -using std::nullopt; -using std::optional; -using std::string; - -namespace toml { -template -std::filesystem::path find_fs_path_or(const basic_value& v, const K& ky, - std::filesystem::path opt) { - try { - auto str = find(v, ky); - if (str.empty()) { - return opt; - } - std::u8string u8str{(char8_t*)&str.front(), (char8_t*)&str.back() + 1}; - return std::filesystem::path{u8str}; - } catch (...) { - return opt; - } -} - -// why is it so hard to avoid exceptions with this library -template -std::optional get_optional(const toml::value& v, const std::string& key) { - if (!v.is_table()) - return std::nullopt; - const auto& tbl = v.as_table(); - auto it = tbl.find(key); - if (it == tbl.end()) - return std::nullopt; - - 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_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); - } - } else if constexpr (std::is_same_v) { - if (it->second.is_string()) { - return toml::get(it->second); - } - } else if constexpr (std::is_same_v) { - if (it->second.is_boolean()) { - return toml::get(it->second); - } - } else { - static_assert([] { return false; }(), "Unsupported type in get_optional"); - } - - return std::nullopt; -} - -} // namespace toml - -namespace Config { - -ConfigMode config_mode = ConfigMode::Default; - -void setConfigMode(ConfigMode mode) { - config_mode = mode; -} - -template -class ConfigEntry { -public: - const T default_value; - T base_value; - optional game_specific_value; - ConfigEntry(const T& t = T()) : default_value(t), base_value(t), game_specific_value(nullopt) {} - ConfigEntry operator=(const T& t) { - base_value = t; - return *this; - } - const T get() const { - switch (config_mode) { - case ConfigMode::Default: - return game_specific_value.value_or(base_value); - case ConfigMode::Global: - return base_value; - case ConfigMode::Clean: - return default_value; - default: - UNREACHABLE(); - } - } - void setFromToml(const toml::value& v, const std::string& key, bool is_game_specific = false) { - if (is_game_specific) { - game_specific_value = toml::get_optional(v, key); - } else { - base_value = toml::get_optional(v, key).value_or(base_value); - } - } - void set(const T value, bool is_game_specific = false) { - is_game_specific ? game_specific_value = value : base_value = value; - } - void setTomlValue(toml::ordered_value& data, const std::string& header, const std::string& key, - bool is_game_specific = false) { - if (is_game_specific) { - data[header][key] = game_specific_value.value_or(base_value); - game_specific_value = std::nullopt; - } else { - data[header][key] = base_value; - } - } - // operator T() { - // return get(); - // } -}; - -// General -static ConfigEntry volumeSlider(100); -static ConfigEntry isNeo(false); -static ConfigEntry isDevKit(false); -static ConfigEntry extraDmemInMbytes(0); -static ConfigEntry isPSNSignedIn(false); -static ConfigEntry isTrophyPopupDisabled(false); -static ConfigEntry trophyNotificationDuration(6.0); -static ConfigEntry userName("shadPS4"); -static ConfigEntry isShowSplash(false); -static ConfigEntry isSideTrophy("right"); -static ConfigEntry isConnectedToNetwork(false); -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) -static ConfigEntry useSpecialPad(false); -static ConfigEntry specialPadClass(1); -static ConfigEntry isMotionControlsEnabled(true); -static ConfigEntry useUnifiedInputConfig(true); -static ConfigEntry defaultControllerID(""); -static ConfigEntry backgroundControllerInput(false); - -// Audio -static ConfigEntry micDevice("Default Device"); -static ConfigEntry mainOutputDevice("Default Device"); -static ConfigEntry padSpkOutputDevice("Default Device"); - -// GPU -static ConfigEntry windowWidth(1280); -static ConfigEntry windowHeight(720); -static ConfigEntry internalScreenWidth(1280); -static ConfigEntry internalScreenHeight(720); -static ConfigEntry isNullGpu(false); -static ConfigEntry shouldCopyGPUBuffers(false); -static ConfigEntry readbacksMode(GpuReadbacksMode::Disabled); -static ConfigEntry readbackLinearImagesEnabled(false); -static ConfigEntry directMemoryAccessEnabled(false); -static ConfigEntry shouldDumpShaders(false); -static ConfigEntry shouldPatchShaders(false); -static ConfigEntry vblankFrequency(60); -static ConfigEntry isFullscreen(false); -static ConfigEntry fullscreenMode("Windowed"); -static ConfigEntry presentMode("Mailbox"); -static ConfigEntry isHDRAllowed(false); -static ConfigEntry fsrEnabled(false); -static ConfigEntry rcasEnabled(true); -static ConfigEntry rcasAttenuation(250); - -// Vulkan -static ConfigEntry gpuId(-1); -static ConfigEntry vkValidation(false); -static ConfigEntry vkValidationCore(true); -static ConfigEntry vkValidationSync(false); -static ConfigEntry vkValidationGpu(false); -static ConfigEntry vkCrashDiagnostic(false); -static ConfigEntry vkHostMarkers(false); -static ConfigEntry vkGuestMarkers(false); -static ConfigEntry rdocEnable(false); -static ConfigEntry pipelineCacheEnable(false); -static ConfigEntry pipelineCacheArchive(false); - -// Debug -static ConfigEntry isDebugDump(false); -static ConfigEntry isShaderDebug(false); -static ConfigEntry showFpsCounter(false); - -// GUI -static std::vector settings_install_dirs = {}; -std::vector install_dirs_enabled = {}; -std::filesystem::path settings_addon_install_dir = {}; -std::filesystem::path save_data_path = {}; - -// Settings -ConfigEntry m_language(1); // english - -// USB Device -static ConfigEntry usbDeviceBackend(UsbBackendType::Real); - -// Keys -static string trophyKey = ""; - -// Config version, used to determine if a user's config file is outdated. -static string config_version = Common::g_scm_rev; - -// These entries aren't stored in the config -static bool overrideControllerColor = false; -static int controllerCustomColorRGB[3] = {0, 0, 255}; - -std::filesystem::path getSysModulesPath() { - if (sys_modules_path.empty()) { - return Common::FS::GetUserPath(Common::FS::PathType::SysModuleDir); - } - return sys_modules_path; -} - -void setSysModulesPath(const std::filesystem::path& path) { - sys_modules_path = path; -} - -std::filesystem::path getFontsPath() { - if (fonts_path.empty()) { - return Common::FS::GetUserPath(Common::FS::PathType::FontsDir); - } - return fonts_path; -} - -void setFontsPath(const std::filesystem::path& path) { - fonts_path = path; -} - -int getVolumeSlider() { - return volumeSlider.get(); -} -bool allowHDR() { - return isHDRAllowed.get(); -} - -bool GetUseUnifiedInputConfig() { - return useUnifiedInputConfig.get(); -} - -void SetUseUnifiedInputConfig(bool use) { - useUnifiedInputConfig.base_value = use; -} - -bool GetOverrideControllerColor() { - return overrideControllerColor; -} - -void SetOverrideControllerColor(bool enable) { - overrideControllerColor = enable; -} - -int* GetControllerCustomColor() { - return controllerCustomColorRGB; -} - -// Log -bool isLogAppend() { - return logAppend.get(); -} - -bool isLogEnable() { - return logEnable.get(); -} - -void setLogEnable(bool enable, bool is_game_specific) { - logEnable.set(enable, is_game_specific); -} - -bool getLogEnable() { - return logEnable.get(); -} - -string getLogFilter() { - return logFilter.get(); -} - -void setLogFilter(const string& type, bool is_game_specific) { - logFilter.set(type, is_game_specific); -} - -u32 getLogMaxSkipDuration() { - return logMaxSkipDuration.get(); -} - -bool getLogSeparate() { - return logSeparate.get(); -} - -void setLogSeparate(bool enabled, bool is_game_specific) { - logSeparate.set(enabled, is_game_specific); -} - -unsigned long long getLogSizeLimit() { - return logSizeLimit.get(); -} - -bool getLogSkipDuplicate() { - return logSkipDuplicate.get(); -} - -void setLogSkipDuplicate(bool enable, bool is_game_specific) { - logSkipDuplicate.set(enable, is_game_specific); -} - -bool isLogSync() { - return logSync.get(); -} - -#ifdef _WIN32 -string getLogType() { - return logType.get(); -} - -void setLogType(const string& type, bool is_game_specific) { - logType.set(type, is_game_specific); -} -#endif - -void SetControllerCustomColor(int r, int b, int g) { - controllerCustomColorRGB[0] = r; - controllerCustomColorRGB[1] = b; - controllerCustomColorRGB[2] = g; -} - -string getTrophyKey() { - return trophyKey; -} - -void setTrophyKey(string key) { - trophyKey = key; -} - -std::filesystem::path GetSaveDataPath() { - if (save_data_path.empty()) { - return Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "savedata"; - } - return save_data_path; -} - -void setVolumeSlider(int volumeValue, bool is_game_specific) { - volumeSlider.set(volumeValue, is_game_specific); -} - -bool isNeoModeConsole() { - return isNeo.get(); -} - -bool isDevKitConsole() { - return isDevKit.get(); -} - -int getExtraDmemInMbytes() { - return extraDmemInMbytes.get(); -} - -void setExtraDmemInMbytes(int value, bool is_game_specific) { - // Disable setting in global config - is_game_specific ? extraDmemInMbytes.game_specific_value = value - : extraDmemInMbytes.base_value = 0; -} - -bool getIsFullscreen() { - return isFullscreen.get(); -} - -string getFullscreenMode() { - return fullscreenMode.get(); -} - -std::string getPresentMode() { - return presentMode.get(); -} - -bool getisTrophyPopupDisabled() { - return isTrophyPopupDisabled.get(); -} - -bool getEnableDiscordRPC() { - return enableDiscordRPC; -} - -s16 getCursorState() { - return cursorState.get(); -} - -int getCursorHideTimeout() { - return cursorHideTimeout.get(); -} - -string getMicDevice() { - return micDevice.get(); -} - -std::string getMainOutputDevice() { - return mainOutputDevice.get(); -} - -std::string getPadSpkOutputDevice() { - return padSpkOutputDevice.get(); -} - -double getTrophyNotificationDuration() { - return trophyNotificationDuration.get(); -} - -u32 getWindowWidth() { - return windowWidth.get(); -} - -u32 getWindowHeight() { - return windowHeight.get(); -} - -u32 getInternalScreenWidth() { - return internalScreenWidth.get(); -} - -u32 getInternalScreenHeight() { - return internalScreenHeight.get(); -} - -s32 getGpuId() { - return gpuId.get(); -} - -string getUserName() { - return userName.get(); -} - -bool getUseSpecialPad() { - return useSpecialPad.get(); -} - -int getSpecialPadClass() { - return specialPadClass.get(); -} - -bool getIsMotionControlsEnabled() { - return isMotionControlsEnabled.get(); -} - -bool debugDump() { - return isDebugDump.get(); -} - -bool collectShadersForDebug() { - return isShaderDebug.get(); -} - -bool showSplash() { - return isShowSplash.get(); -} - -string sideTrophy() { - return isSideTrophy.get(); -} - -bool nullGpu() { - return isNullGpu.get(); -} - -bool copyGPUCmdBuffers() { - return shouldCopyGPUBuffers.get(); -} - -int getReadbacksMode() { - return readbacksMode.get(); -} - -bool readbackLinearImages() { - return readbackLinearImagesEnabled.get(); -} - -bool directMemoryAccess() { - return directMemoryAccessEnabled.get(); -} - -bool dumpShaders() { - return shouldDumpShaders.get(); -} - -bool patchShaders() { - return shouldPatchShaders.get(); -} - -bool isRdocEnabled() { - return rdocEnable.get(); -} - -bool isPipelineCacheEnabled() { - return pipelineCacheEnable.get(); -} - -bool isPipelineCacheArchived() { - return pipelineCacheArchive.get(); -} - -bool getShowFpsCounter() { - return showFpsCounter.get(); -} - -void setShowFpsCounter(bool enable, bool is_game_specific) { - showFpsCounter.set(enable, is_game_specific); -} - -u32 vblankFreq() { - if (vblankFrequency.get() < 60) { - vblankFrequency = 60; - } - return vblankFrequency.get(); -} - -bool vkValidationEnabled() { - return vkValidation.get(); -} - -bool vkValidationCoreEnabled() { - return vkValidationCore.get(); -} - -bool vkValidationSyncEnabled() { - return vkValidationSync.get(); -} - -bool vkValidationGpuEnabled() { - return vkValidationGpu.get(); -} - -bool getVkCrashDiagnosticEnabled() { - return vkCrashDiagnostic.get(); -} - -bool getVkHostMarkersEnabled() { - return vkHostMarkers.get(); -} - -bool getVkGuestMarkersEnabled() { - return vkGuestMarkers.get(); -} - -void setVkCrashDiagnosticEnabled(bool enable, bool is_game_specific) { - vkCrashDiagnostic.set(enable, is_game_specific); -} - -void setVkHostMarkersEnabled(bool enable, bool is_game_specific) { - vkHostMarkers.set(enable, is_game_specific); -} - -void setVkGuestMarkersEnabled(bool enable, bool is_game_specific) { - vkGuestMarkers.set(enable, is_game_specific); -} - -bool getIsConnectedToNetwork() { - return isConnectedToNetwork.get(); -} - -void setConnectedToNetwork(bool enable, bool is_game_specific) { - isConnectedToNetwork.set(enable, is_game_specific); -} - -void setGpuId(s32 selectedGpuId, bool is_game_specific) { - gpuId.set(selectedGpuId, is_game_specific); -} - -void setWindowWidth(u32 width, bool is_game_specific) { - windowWidth.set(width, is_game_specific); -} - -void setWindowHeight(u32 height, bool is_game_specific) { - windowHeight.set(height, is_game_specific); -} - -void setInternalScreenWidth(u32 width) { - internalScreenWidth.base_value = width; -} - -void setInternalScreenHeight(u32 height) { - internalScreenHeight.base_value = height; -} - -void setDebugDump(bool enable, bool is_game_specific) { - isDebugDump.set(enable, is_game_specific); -} - -void setCollectShaderForDebug(bool enable, bool is_game_specific) { - isShaderDebug.set(enable, is_game_specific); -} - -void setShowSplash(bool enable, bool is_game_specific) { - isShowSplash.set(enable, is_game_specific); -} - -void setSideTrophy(string side, bool is_game_specific) { - isSideTrophy.set(side, is_game_specific); -} - -void setNullGpu(bool enable, bool is_game_specific) { - isNullGpu.set(enable, is_game_specific); -} - -void setAllowHDR(bool enable, bool is_game_specific) { - isHDRAllowed.set(enable, is_game_specific); -} - -void setCopyGPUCmdBuffers(bool enable, bool is_game_specific) { - shouldCopyGPUBuffers.set(enable, is_game_specific); -} - -void setReadbacksMode(int mode, bool is_game_specific) { - readbacksMode.set(mode, is_game_specific); -} - -void setReadbackLinearImages(bool enable, bool is_game_specific) { - readbackLinearImagesEnabled.set(enable, is_game_specific); -} - -void setDirectMemoryAccess(bool enable, bool is_game_specific) { - directMemoryAccessEnabled.set(enable, is_game_specific); -} - -void setDumpShaders(bool enable, bool is_game_specific) { - shouldDumpShaders.set(enable, is_game_specific); -} - -void setVkValidation(bool enable, bool is_game_specific) { - vkValidation.set(enable, is_game_specific); -} - -void setVkSyncValidation(bool enable, bool is_game_specific) { - vkValidationSync.set(enable, is_game_specific); -} - -void setVkCoreValidation(bool enable, bool is_game_specific) { - vkValidationCore.set(enable, is_game_specific); -} - -void setVkGpuValidation(bool enable, bool is_game_specific) { - vkValidationGpu.set(enable, is_game_specific); -} - -void setRdocEnabled(bool enable, bool is_game_specific) { - rdocEnable.set(enable, is_game_specific); -} - -void setPipelineCacheEnabled(bool enable, bool is_game_specific) { - pipelineCacheEnable.set(enable, is_game_specific); -} - -void setPipelineCacheArchived(bool enable, bool is_game_specific) { - pipelineCacheArchive.set(enable, is_game_specific); -} - -void setVblankFreq(u32 value, bool is_game_specific) { - vblankFrequency.set(value, is_game_specific); -} - -void setIsFullscreen(bool enable, bool is_game_specific) { - isFullscreen.set(enable, is_game_specific); -} - -void setFullscreenMode(string mode, bool is_game_specific) { - fullscreenMode.set(mode, is_game_specific); -} - -void setPresentMode(std::string mode, bool is_game_specific) { - presentMode.set(mode, is_game_specific); -} - -void setisTrophyPopupDisabled(bool disable, bool is_game_specific) { - isTrophyPopupDisabled.set(disable, is_game_specific); -} - -void setEnableDiscordRPC(bool enable) { - enableDiscordRPC = enable; -} - -void setCursorState(s16 newCursorState, bool is_game_specific) { - cursorState.set(newCursorState, is_game_specific); -} - -void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific) { - cursorHideTimeout.set(newcursorHideTimeout, is_game_specific); -} - -void setMicDevice(std::string device, bool is_game_specific) { - micDevice.set(device, is_game_specific); -} - -void setMainOutputDevice(std::string device, bool is_game_specific) { - mainOutputDevice.set(device, is_game_specific); -} - -void setPadSpkOutputDevice(std::string device, bool is_game_specific) { - padSpkOutputDevice.set(device, is_game_specific); -} - -void setTrophyNotificationDuration(double newTrophyNotificationDuration, bool is_game_specific) { - trophyNotificationDuration.set(newTrophyNotificationDuration, is_game_specific); -} - -void setLanguage(u32 language, bool is_game_specific) { - m_language.set(language, is_game_specific); -} - -void setNeoMode(bool enable, bool is_game_specific) { - isNeo.set(enable, is_game_specific); -} - -void setDevKitConsole(bool enable, bool is_game_specific) { - isDevKit.set(enable, is_game_specific); -} - -void setUserName(const string& name, bool is_game_specific) { - userName.set(name, is_game_specific); -} - -void setUseSpecialPad(bool use) { - useSpecialPad.base_value = use; -} - -void setSpecialPadClass(int type) { - specialPadClass.base_value = type; -} - -void setIsMotionControlsEnabled(bool use, bool is_game_specific) { - isMotionControlsEnabled.set(use, is_game_specific); -} - -bool addGameInstallDir(const std::filesystem::path& dir, bool enabled) { - for (const auto& install_dir : settings_install_dirs) { - if (install_dir.path == dir) { - return false; - } - } - settings_install_dirs.push_back({dir, enabled}); - return true; -} - -void removeGameInstallDir(const std::filesystem::path& dir) { - auto iterator = - std::find_if(settings_install_dirs.begin(), settings_install_dirs.end(), - [&dir](const GameInstallDir& install_dir) { return install_dir.path == dir; }); - if (iterator != settings_install_dirs.end()) { - settings_install_dirs.erase(iterator); - } -} - -void setGameInstallDirEnabled(const std::filesystem::path& dir, bool enabled) { - auto iterator = - std::find_if(settings_install_dirs.begin(), settings_install_dirs.end(), - [&dir](const GameInstallDir& install_dir) { return install_dir.path == dir; }); - if (iterator != settings_install_dirs.end()) { - iterator->enabled = enabled; - } -} - -void setAddonInstallDir(const std::filesystem::path& dir) { - settings_addon_install_dir = dir; -} - -void setGameInstallDirs(const std::vector& dirs_config) { - settings_install_dirs.clear(); - for (const auto& dir : dirs_config) { - settings_install_dirs.push_back({dir, true}); - } -} - -void setAllGameInstallDirs(const std::vector& dirs_config) { - settings_install_dirs = dirs_config; -} - -void setSaveDataPath(const std::filesystem::path& path) { - save_data_path = path; -} - -const std::vector getGameInstallDirs() { - std::vector enabled_dirs; - for (const auto& dir : settings_install_dirs) { - if (dir.enabled) { - enabled_dirs.push_back(dir.path); - } - } - return enabled_dirs; -} - -const std::vector getGameInstallDirsEnabled() { - std::vector enabled_dirs; - for (const auto& dir : settings_install_dirs) { - enabled_dirs.push_back(dir.enabled); - } - return enabled_dirs; -} - -std::filesystem::path getAddonInstallDir() { - if (settings_addon_install_dir.empty()) { - // Default for users without a config file or a config file from before this option existed - return Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "addcont"; - } - return settings_addon_install_dir; -} - -u32 GetLanguage() { - return m_language.get(); -} - -bool getPSNSignedIn() { - return isPSNSignedIn.get(); -} - -void setPSNSignedIn(bool sign, bool is_game_specific) { - isPSNSignedIn.set(sign, is_game_specific); -} - -string getDefaultControllerID() { - return defaultControllerID.get(); -} - -void setDefaultControllerID(string id) { - defaultControllerID.base_value = id; -} - -bool getBackgroundControllerInput() { - return backgroundControllerInput.get(); -} - -void setBackgroundControllerInput(bool enable, bool is_game_specific) { - backgroundControllerInput.set(enable, is_game_specific); -} - -bool getFsrEnabled() { - return fsrEnabled.get(); -} - -void setFsrEnabled(bool enable, bool is_game_specific) { - fsrEnabled.set(enable, is_game_specific); -} - -bool getRcasEnabled() { - return rcasEnabled.get(); -} - -void setRcasEnabled(bool enable, bool is_game_specific) { - rcasEnabled.set(enable, is_game_specific); -} - -int getRcasAttenuation() { - return rcasAttenuation.get(); -} - -void setRcasAttenuation(int value, bool is_game_specific) { - rcasAttenuation.set(value, is_game_specific); -} - -int getUsbDeviceBackend() { - return usbDeviceBackend.get(); -} - -void setUsbDeviceBackend(int value, bool is_game_specific) { - usbDeviceBackend.set(value, is_game_specific); -} - -void load(const std::filesystem::path& path, bool is_game_specific) { - // If the configuration file does not exist, create it and return, unless it is game specific - std::error_code error; - if (!std::filesystem::exists(path, error)) { - if (!is_game_specific) { - save(path); - } - return; - } - - toml::value data; - - try { - 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}); - } catch (std::exception& ex) { - fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); - return; - } - - if (data.contains("General")) { - const toml::value& general = data.at("General"); - - volumeSlider.setFromToml(general, "volumeSlider", is_game_specific); - isNeo.setFromToml(general, "isPS4Pro", is_game_specific); - isDevKit.setFromToml(general, "isDevKit", is_game_specific); - if (is_game_specific) { // do not get this value from the base config - extraDmemInMbytes.setFromToml(general, "extraDmemInMbytes", is_game_specific); - } - isPSNSignedIn.setFromToml(general, "isPSNSignedIn", is_game_specific); - isTrophyPopupDisabled.setFromToml(general, "isTrophyPopupDisabled", is_game_specific); - trophyNotificationDuration.setFromToml(general, "trophyNotificationDuration", - is_game_specific); - enableDiscordRPC = toml::find_or(general, "enableDiscordRPC", enableDiscordRPC); - userName.setFromToml(general, "userName", is_game_specific); - isShowSplash.setFromToml(general, "showSplash", is_game_specific); - isSideTrophy.setFromToml(general, "sideTrophy", is_game_specific); - - isConnectedToNetwork.setFromToml(general, "isConnectedToNetwork", is_game_specific); - defaultControllerID.setFromToml(general, "defaultControllerID", is_game_specific); - sys_modules_path = toml::find_fs_path_or(general, "sysModulesPath", sys_modules_path); - fonts_path = toml::find_fs_path_or(general, "fontsPath", fonts_path); - } - - if (data.contains("Log")) { - const toml::value& log = data.at("Log"); - - logAppend.setFromToml(log, "append", is_game_specific); - logEnable.setFromToml(log, "enable", is_game_specific); - logFilter.setFromToml(log, "filter", is_game_specific); - logMaxSkipDuration.setFromToml(log, "maxSkipDuration", is_game_specific); - logSeparate.setFromToml(log, "separate", is_game_specific); - logSkipDuplicate.setFromToml(log, "skipDuplicate", is_game_specific); - logSizeLimit.setFromToml(log, "sizeLimit", is_game_specific); - logSync.setFromToml(log, "sync", is_game_specific); -#ifdef _WIN32 - logType.setFromToml(log, "type", is_game_specific); -#endif - } - - if (data.contains("Input")) { - const toml::value& input = data.at("Input"); - - cursorState.setFromToml(input, "cursorState", is_game_specific); - cursorHideTimeout.setFromToml(input, "cursorHideTimeout", is_game_specific); - useSpecialPad.setFromToml(input, "useSpecialPad", is_game_specific); - specialPadClass.setFromToml(input, "specialPadClass", is_game_specific); - isMotionControlsEnabled.setFromToml(input, "isMotionControlsEnabled", is_game_specific); - useUnifiedInputConfig.setFromToml(input, "useUnifiedInputConfig", is_game_specific); - backgroundControllerInput.setFromToml(input, "backgroundControllerInput", is_game_specific); - usbDeviceBackend.setFromToml(input, "usbDeviceBackend", is_game_specific); - } - - if (data.contains("Audio")) { - const toml::value& audio = data.at("Audio"); - - micDevice.setFromToml(audio, "micDevice", is_game_specific); - mainOutputDevice.setFromToml(audio, "mainOutputDevice", is_game_specific); - padSpkOutputDevice.setFromToml(audio, "padSpkOutputDevice", is_game_specific); - } - - if (data.contains("GPU")) { - const toml::value& gpu = data.at("GPU"); - - windowWidth.setFromToml(gpu, "screenWidth", is_game_specific); - windowHeight.setFromToml(gpu, "screenHeight", is_game_specific); - internalScreenWidth.setFromToml(gpu, "internalScreenWidth", is_game_specific); - internalScreenHeight.setFromToml(gpu, "internalScreenHeight", is_game_specific); - isNullGpu.setFromToml(gpu, "nullGpu", is_game_specific); - shouldCopyGPUBuffers.setFromToml(gpu, "copyGPUBuffers", is_game_specific); - readbacksMode.setFromToml(gpu, "readbacksMode", is_game_specific); - readbackLinearImagesEnabled.setFromToml(gpu, "readbackLinearImages", is_game_specific); - directMemoryAccessEnabled.setFromToml(gpu, "directMemoryAccess", is_game_specific); - shouldDumpShaders.setFromToml(gpu, "dumpShaders", is_game_specific); - shouldPatchShaders.setFromToml(gpu, "patchShaders", is_game_specific); - vblankFrequency.setFromToml(gpu, "vblankFrequency", is_game_specific); - isFullscreen.setFromToml(gpu, "Fullscreen", is_game_specific); - fullscreenMode.setFromToml(gpu, "FullscreenMode", is_game_specific); - presentMode.setFromToml(gpu, "presentMode", is_game_specific); - isHDRAllowed.setFromToml(gpu, "allowHDR", is_game_specific); - fsrEnabled.setFromToml(gpu, "fsrEnabled", is_game_specific); - rcasEnabled.setFromToml(gpu, "rcasEnabled", is_game_specific); - rcasAttenuation.setFromToml(gpu, "rcasAttenuation", is_game_specific); - } - - if (data.contains("Vulkan")) { - const toml::value& vk = data.at("Vulkan"); - - gpuId.setFromToml(vk, "gpuId", is_game_specific); - vkValidation.setFromToml(vk, "validation", is_game_specific); - vkValidationCore.setFromToml(vk, "validation_core", is_game_specific); - vkValidationSync.setFromToml(vk, "validation_sync", is_game_specific); - vkValidationGpu.setFromToml(vk, "validation_gpu", is_game_specific); - vkCrashDiagnostic.setFromToml(vk, "crashDiagnostic", is_game_specific); - vkHostMarkers.setFromToml(vk, "hostMarkers", is_game_specific); - vkGuestMarkers.setFromToml(vk, "guestMarkers", is_game_specific); - rdocEnable.setFromToml(vk, "rdocEnable", is_game_specific); - pipelineCacheEnable.setFromToml(vk, "pipelineCacheEnable", is_game_specific); - pipelineCacheArchive.setFromToml(vk, "pipelineCacheArchive", is_game_specific); - } - - string current_version = {}; - if (data.contains("Debug")) { - const toml::value& debug = data.at("Debug"); - - isDebugDump.setFromToml(debug, "DebugDump", is_game_specific); - isShaderDebug.setFromToml(debug, "CollectShader", is_game_specific); - showFpsCounter.setFromToml(debug, "showFpsCounter", is_game_specific); - current_version = toml::find_or(debug, "ConfigVersion", current_version); - } - - if (data.contains("GUI")) { - const toml::value& gui = data.at("GUI"); - - const auto install_dir_array = - toml::find_or>(gui, "installDirs", {}); - - try { - install_dirs_enabled = toml::find>(gui, "installDirsEnabled"); - } catch (...) { - // If it does not exist, assume that all are enabled. - install_dirs_enabled.resize(install_dir_array.size(), true); - } - - if (install_dirs_enabled.size() < install_dir_array.size()) { - install_dirs_enabled.resize(install_dir_array.size(), true); - } - - settings_install_dirs.clear(); - for (size_t i = 0; i < install_dir_array.size(); i++) { - settings_install_dirs.push_back( - {std::filesystem::path{install_dir_array[i]}, install_dirs_enabled[i]}); - } - - save_data_path = toml::find_fs_path_or(gui, "saveDataPath", save_data_path); - - settings_addon_install_dir = - toml::find_fs_path_or(gui, "addonInstallDir", settings_addon_install_dir); - } - - if (data.contains("Settings")) { - const toml::value& settings = data.at("Settings"); - m_language.setFromToml(settings, "consoleLanguage", is_game_specific); - } - - if (data.contains("Keys")) { - const toml::value& keys = data.at("Keys"); - trophyKey = toml::find_or(keys, "TrophyKey", trophyKey); - } - - // Run save after loading to generate any missing fields with default values. - if (config_version != current_version && !is_game_specific) { - save(path); - } -} - -void sortTomlSections(toml::ordered_value& data) { - toml::ordered_value ordered_data; - std::vector section_order = {"General", "Log", "Input", "Audio", "GPU", - "Vulkan", "Debug", "Keys", "GUI", "Settings"}; - - for (const auto& section : section_order) { - if (data.contains(section)) { - std::vector keys; - for (const auto& item : data.at(section).as_table()) { - keys.push_back(item.first); - } - - std::sort(keys.begin(), keys.end(), [](const string& a, const string& b) { - return std::lexicographical_compare( - a.begin(), a.end(), b.begin(), b.end(), [](char a_char, char b_char) { - return std::tolower(a_char) < std::tolower(b_char); - }); - }); - - toml::ordered_value ordered_section; - for (const auto& key : keys) { - ordered_section[key] = data.at(section).at(key); - } - - ordered_data[section] = ordered_section; - } - } - - data = ordered_data; -} - -void save(const std::filesystem::path& path, bool is_game_specific) { - toml::ordered_value data; - - std::error_code error; - if (std::filesystem::exists(path, error)) { - try { - 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}); - } catch (const std::exception& ex) { - fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what()); - return; - } - } else { - if (error) { - fmt::print("Filesystem error: {}\n", error.message()); - } - fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string())); - } - - // Entries saved by the game-specific settings GUI - volumeSlider.setTomlValue(data, "General", "volumeSlider", is_game_specific); - isTrophyPopupDisabled.setTomlValue(data, "General", "isTrophyPopupDisabled", is_game_specific); - trophyNotificationDuration.setTomlValue(data, "General", "trophyNotificationDuration", - 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); - isNeo.setTomlValue(data, "General", "isPS4Pro", is_game_specific); - isDevKit.setTomlValue(data, "General", "isDevKit", is_game_specific); - if (is_game_specific) { - extraDmemInMbytes.setTomlValue(data, "General", "extraDmemInMbytes", 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", - is_game_specific); - backgroundControllerInput.setTomlValue(data, "Input", "backgroundControllerInput", - is_game_specific); - usbDeviceBackend.setTomlValue(data, "Input", "usbDeviceBackend", is_game_specific); - - micDevice.setTomlValue(data, "Audio", "micDevice", is_game_specific); - mainOutputDevice.setTomlValue(data, "Audio", "mainOutputDevice", is_game_specific); - padSpkOutputDevice.setTomlValue(data, "Audio", "padSpkOutputDevice", is_game_specific); - - windowWidth.setTomlValue(data, "GPU", "screenWidth", is_game_specific); - windowHeight.setTomlValue(data, "GPU", "screenHeight", is_game_specific); - isNullGpu.setTomlValue(data, "GPU", "nullGpu", is_game_specific); - shouldCopyGPUBuffers.setTomlValue(data, "GPU", "copyGPUBuffers", is_game_specific); - readbacksMode.setTomlValue(data, "GPU", "readbacksMode", is_game_specific); - readbackLinearImagesEnabled.setTomlValue(data, "GPU", "readbackLinearImages", is_game_specific); - shouldDumpShaders.setTomlValue(data, "GPU", "dumpShaders", is_game_specific); - vblankFrequency.setTomlValue(data, "GPU", "vblankFrequency", is_game_specific); - isFullscreen.setTomlValue(data, "GPU", "Fullscreen", is_game_specific); - fullscreenMode.setTomlValue(data, "GPU", "FullscreenMode", is_game_specific); - presentMode.setTomlValue(data, "GPU", "presentMode", is_game_specific); - isHDRAllowed.setTomlValue(data, "GPU", "allowHDR", is_game_specific); - fsrEnabled.setTomlValue(data, "GPU", "fsrEnabled", is_game_specific); - rcasEnabled.setTomlValue(data, "GPU", "rcasEnabled", is_game_specific); - rcasAttenuation.setTomlValue(data, "GPU", "rcasAttenuation", is_game_specific); - directMemoryAccessEnabled.setTomlValue(data, "GPU", "directMemoryAccess", is_game_specific); - - gpuId.setTomlValue(data, "Vulkan", "gpuId", is_game_specific); - vkValidation.setTomlValue(data, "Vulkan", "validation", is_game_specific); - vkValidationSync.setTomlValue(data, "Vulkan", "validation_sync", is_game_specific); - vkValidationCore.setTomlValue(data, "Vulkan", "validation_core", is_game_specific); - vkValidationGpu.setTomlValue(data, "Vulkan", "validation_gpu", is_game_specific); - vkCrashDiagnostic.setTomlValue(data, "Vulkan", "crashDiagnostic", is_game_specific); - vkHostMarkers.setTomlValue(data, "Vulkan", "hostMarkers", is_game_specific); - vkGuestMarkers.setTomlValue(data, "Vulkan", "guestMarkers", is_game_specific); - rdocEnable.setTomlValue(data, "Vulkan", "rdocEnable", is_game_specific); - pipelineCacheEnable.setTomlValue(data, "Vulkan", "pipelineCacheEnable", is_game_specific); - pipelineCacheArchive.setTomlValue(data, "Vulkan", "pipelineCacheArchive", is_game_specific); - - isDebugDump.setTomlValue(data, "Debug", "DebugDump", is_game_specific); - isShaderDebug.setTomlValue(data, "Debug", "CollectShader", is_game_specific); - - m_language.setTomlValue(data, "Settings", "consoleLanguage", is_game_specific); - - if (!is_game_specific) { - std::vector install_dirs; - std::vector install_dirs_enabled; - - // temporary structure for ordering - struct DirEntry { - string path_str; - bool enabled; - }; - - std::vector sorted_dirs; - for (const auto& dirInfo : settings_install_dirs) { - sorted_dirs.push_back( - {string{fmt::UTF(dirInfo.path.u8string()).data}, dirInfo.enabled}); - } - - // Sort directories alphabetically - std::sort(sorted_dirs.begin(), sorted_dirs.end(), [](const DirEntry& a, const DirEntry& b) { - return std::lexicographical_compare( - a.path_str.begin(), a.path_str.end(), b.path_str.begin(), b.path_str.end(), - [](char a_char, char b_char) { - return std::tolower(a_char) < std::tolower(b_char); - }); - }); - - for (const auto& entry : sorted_dirs) { - install_dirs.push_back(entry.path_str); - install_dirs_enabled.push_back(entry.enabled); - } - - // 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["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["Debug"]["ConfigVersion"] = config_version; - data["Keys"]["TrophyKey"] = trophyKey; - - // Do not save these entries in the game-specific dialog since they are not in the GUI - data["General"]["defaultControllerID"] = defaultControllerID.base_value; - data["Input"]["useSpecialPad"] = useSpecialPad.base_value; - data["Input"]["specialPadClass"] = specialPadClass.base_value; - data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig.base_value; - data["GPU"]["internalScreenWidth"] = internalScreenWidth.base_value; - data["GPU"]["internalScreenHeight"] = internalScreenHeight.base_value; - data["GPU"]["patchShaders"] = shouldPatchShaders.base_value; - data["Debug"]["showFpsCounter"] = showFpsCounter.base_value; - } - - // Sorting of TOML sections - sortTomlSections(data); - - std::ofstream file(path, std::ios::binary); - file << data; - file.close(); -} - -void setDefaultValues(bool is_game_specific) { - - // Entries with game-specific settings that are in the game-specific setings GUI but not in - // the global settings GUI - if (is_game_specific) { - readbacksMode.set(GpuReadbacksMode::Disabled, is_game_specific); - readbackLinearImagesEnabled.set(false, is_game_specific); - isNeo.set(false, is_game_specific); - isDevKit.set(false, is_game_specific); - isPSNSignedIn.set(false, is_game_specific); - isConnectedToNetwork.set(false, is_game_specific); - directMemoryAccessEnabled.set(false, is_game_specific); - extraDmemInMbytes.set(0, is_game_specific); - } - - // Entries with game-specific settings that are in both the game-specific and global GUI - // GS - General - volumeSlider.set(100, is_game_specific); - isTrophyPopupDisabled.set(false, is_game_specific); - trophyNotificationDuration.set(6.0, is_game_specific); - userName.set("shadPS4", is_game_specific); - isShowSplash.set(false, is_game_specific); - isSideTrophy.set("right", is_game_specific); - - // GS - Log - logAppend.set(false, is_game_specific); - logEnable.set(true, is_game_specific); - logFilter.set("", is_game_specific); - logMaxSkipDuration.set(5'000, is_game_specific); - logSeparate.set(false, is_game_specific); - logSkipDuplicate.set(true, is_game_specific); - logSync.set(true, is_game_specific); - logSizeLimit.set(100_MB, is_game_specific); -#ifdef _WIN32 - logType.set("wincolor", is_game_specific); -#endif - - // GS - Input - cursorState.set(HideCursorState::Idle, is_game_specific); - cursorHideTimeout.set(5, is_game_specific); - isMotionControlsEnabled.set(true, is_game_specific); - backgroundControllerInput.set(false, is_game_specific); - usbDeviceBackend.set(UsbBackendType::Real, is_game_specific); - - // GS - Audio - micDevice.set("Default Device", is_game_specific); - - // GS - GPU - windowWidth.set(1280, is_game_specific); - windowHeight.set(720, is_game_specific); - isNullGpu.set(false, is_game_specific); - shouldCopyGPUBuffers.set(false, is_game_specific); - shouldDumpShaders.set(false, is_game_specific); - vblankFrequency.set(60, is_game_specific); - isFullscreen.set(false, is_game_specific); - fullscreenMode.set("Windowed", is_game_specific); - presentMode.set("Mailbox", is_game_specific); - isHDRAllowed.set(false, is_game_specific); - fsrEnabled.set(true, is_game_specific); - rcasEnabled.set(true, is_game_specific); - rcasAttenuation.set(250, is_game_specific); - - // GS - Vulkan - gpuId.set(-1, is_game_specific); - vkValidation.set(false, is_game_specific); - vkValidationCore.set(true, is_game_specific); - vkValidationSync.set(false, is_game_specific); - vkValidationGpu.set(false, is_game_specific); - vkCrashDiagnostic.set(false, is_game_specific); - vkHostMarkers.set(false, is_game_specific); - vkGuestMarkers.set(false, is_game_specific); - rdocEnable.set(false, is_game_specific); - pipelineCacheEnable.set(false, is_game_specific); - pipelineCacheArchive.set(false, is_game_specific); - - // GS - Debug - isDebugDump.set(false, is_game_specific); - isShaderDebug.set(false, is_game_specific); - - // GS - Settings - m_language.set(1, is_game_specific); - - // All other entries - if (!is_game_specific) { - - // General - enableDiscordRPC = false; - - // Input - useSpecialPad.base_value = false; - specialPadClass.base_value = 1; - useUnifiedInputConfig.base_value = true; - controllerCustomColorRGB[0] = 0; - controllerCustomColorRGB[1] = 0; - controllerCustomColorRGB[2] = 255; - - // TODO: Change to be game specific - mainOutputDevice = "Default Device"; - padSpkOutputDevice = "Default Device"; - - // GPU - shouldPatchShaders.base_value = false; - internalScreenWidth.base_value = 1280; - internalScreenHeight.base_value = 720; - - // Debug - showFpsCounter.base_value = false; - } -} - -constexpr std::string_view GetDefaultGlobalConfig() { - return R"(# Anything put here will be loaded for all games, -# alongside the game's config or default.ini depending on your preference. -)"; -} - -constexpr std::string_view GetDefaultInputConfig() { - return R"(#Feeling lost? Check out the Help section! - -# Keyboard bindings - -triangle = kp8 -circle = kp6 -cross = kp2 -square = kp4 -# Alternatives for users without a keypad -triangle = c -circle = b -cross = n -square = v - -l1 = q -r1 = u -l2 = e -r2 = o -l3 = x -r3 = m - -options = enter -touchpad_center = space - -pad_up = up -pad_down = down -pad_left = left -pad_right = right - -axis_left_x_minus = a -axis_left_x_plus = d -axis_left_y_minus = w -axis_left_y_plus = s - -axis_right_x_minus = j -axis_right_x_plus = l -axis_right_y_minus = i -axis_right_y_plus = k - -# Controller bindings - -triangle = triangle -cross = cross -square = square -circle = circle - -l1 = l1 -l2 = l2 -l3 = l3 -r1 = r1 -r2 = r2 -r3 = r3 - -options = options -touchpad_center = back - -pad_up = pad_up -pad_down = pad_down -pad_left = pad_left -pad_right = pad_right - -axis_left_x = axis_left_x -axis_left_y = axis_left_y -axis_right_x = axis_right_x -axis_right_y = axis_right_y - -# Range of deadzones: 1 (almost none) to 127 (max) -analog_deadzone = leftjoystick, 2, 127 -analog_deadzone = rightjoystick, 2, 127 - -override_controller_color = false, 0, 0, 255 -)"; -} -std::filesystem::path GetInputConfigFile(const string& game_id) { - // Read configuration file of the game, and if it doesn't exist, generate it from default - // If that doesn't exist either, generate that from getDefaultConfig() and try again - // If even the folder is missing, we start with that. - - const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "input_config"; - const auto config_file = config_dir / (game_id + ".ini"); - const auto default_config_file = config_dir / "default.ini"; - - // Ensure the config directory exists - if (!std::filesystem::exists(config_dir)) { - std::filesystem::create_directories(config_dir); - } - - // Check if the default config exists - if (!std::filesystem::exists(default_config_file)) { - // If the default config is also missing, create it from getDefaultConfig() - const auto default_config = GetDefaultInputConfig(); - std::ofstream default_config_stream(default_config_file); - if (default_config_stream) { - default_config_stream << default_config; - } - } - - // if empty, we only need to execute the function up until this point - if (game_id.empty()) { - return default_config_file; - } - - // Create global config if it doesn't exist yet - if (game_id == "global" && !std::filesystem::exists(config_file)) { - if (!std::filesystem::exists(config_file)) { - const auto global_config = GetDefaultGlobalConfig(); - std::ofstream global_config_stream(config_file); - if (global_config_stream) { - global_config_stream << global_config; - } - } - } - if (game_id == "global") { - std::map default_bindings_to_add = { - {"hotkey_capture_frame", "f12"}, - {"hotkey_screenshot_with_overlays", "lalt, f12"}, - {"hotkey_fullscreen", "f11"}, - {"hotkey_show_fps", "f10"}, - {"hotkey_pause", "f9"}, - {"hotkey_reload_inputs", "f8"}, - {"hotkey_toggle_mouse_to_joystick", "f7"}, - {"hotkey_toggle_mouse_to_gyro", "f6"}, - {"hotkey_toggle_mouse_to_touchpad", "delete"}, - {"hotkey_quit", "lctrl, lshift, end"}, - {"hotkey_volume_up", "kpplus"}, - {"hotkey_volume_down", "kpminus"}, - }; - string legacy_capture_binding; - bool legacy_capture_binding_found = false; - std::ifstream global_in(config_file); - string line; - while (std::getline(global_in, line)) { - line.erase(std::remove_if(line.begin(), line.end(), - [](unsigned char c) { return std::isspace(c); }), - line.end()); - std::size_t equal_pos = line.find('='); - if (equal_pos == std::string::npos) { - continue; - } - std::string output_string = line.substr(0, equal_pos); - if (output_string == "hotkey_renderdoc_capture") { - legacy_capture_binding = line.substr(equal_pos + 1); - legacy_capture_binding_found = true; - } - default_bindings_to_add.erase(output_string); - } - global_in.close(); - if (legacy_capture_binding_found) { - if (auto it = default_bindings_to_add.find("hotkey_capture_frame"); - it != default_bindings_to_add.end()) { - it->second = legacy_capture_binding; - } - } - std::ofstream global_out(config_file, std::ios::app); - for (auto const& b : default_bindings_to_add) { - global_out << b.first << " = " << b.second << "\n"; - } - } - - // If game-specific config doesn't exist, create it from the default config - if (!std::filesystem::exists(config_file)) { - std::filesystem::copy(default_config_file, config_file); - } - return config_file; -} - -void resetGameSpecificValue(std::string entry) { - if (entry == "volumeSlider") { - volumeSlider.game_specific_value = std::nullopt; - } -} - -} // namespace Config diff --git a/src/common/config.h b/src/common/config.h deleted file mode 100644 index b98b24137..000000000 --- a/src/common/config.h +++ /dev/null @@ -1,213 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2025-2026 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include "types.h" - -namespace Config { - -enum class ConfigMode { - Default, - Global, - Clean, -}; -void setConfigMode(ConfigMode mode); - -struct GameInstallDir { - std::filesystem::path path; - bool enabled; -}; - -enum HideCursorState : int { Never, Idle, Always }; - -enum GpuReadbacksMode : int { - Disabled, - Relaxed, - Precise, -}; - -void load(const std::filesystem::path& path, bool is_game_specific = false); -void save(const std::filesystem::path& path, bool is_game_specific = false); -void resetGameSpecificValue(std::string entry); - -bool getGameRunning(); -void setGameRunning(bool running); -int getVolumeSlider(); -void setVolumeSlider(int volumeValue, bool is_game_specific = false); -std::string getTrophyKey(); -void setTrophyKey(std::string key); -bool getIsFullscreen(); -void setIsFullscreen(bool enable, bool is_game_specific = false); -std::string getFullscreenMode(); -void setFullscreenMode(std::string mode, bool is_game_specific = false); -std::string getPresentMode(); -void setPresentMode(std::string mode, bool is_game_specific = false); -u32 getWindowWidth(); -u32 getWindowHeight(); -void setWindowWidth(u32 width, bool is_game_specific = false); -void setWindowHeight(u32 height, bool is_game_specific = false); -u32 getInternalScreenWidth(); -u32 getInternalScreenHeight(); -void setInternalScreenWidth(u32 width); -void setInternalScreenHeight(u32 height); -bool debugDump(); -void setDebugDump(bool enable, bool is_game_specific = false); -s32 getGpuId(); -void setGpuId(s32 selectedGpuId, bool is_game_specific = false); -bool allowHDR(); -void setAllowHDR(bool enable, bool is_game_specific = false); -bool collectShadersForDebug(); -void setCollectShaderForDebug(bool enable, bool is_game_specific = false); -bool showSplash(); -void setShowSplash(bool enable, bool is_game_specific = false); -std::string sideTrophy(); -void setSideTrophy(std::string side, bool is_game_specific = false); -bool nullGpu(); -void setNullGpu(bool enable, bool is_game_specific = false); -bool copyGPUCmdBuffers(); -void setCopyGPUCmdBuffers(bool enable, bool is_game_specific = false); -int getReadbacksMode(); -void setReadbacksMode(int mode, bool is_game_specific = false); -bool readbackLinearImages(); -void setReadbackLinearImages(bool enable, bool is_game_specific = false); -bool directMemoryAccess(); -void setDirectMemoryAccess(bool enable, bool is_game_specific = false); -bool dumpShaders(); -void setDumpShaders(bool enable, bool is_game_specific = false); -u32 vblankFreq(); -void setVblankFreq(u32 value, bool is_game_specific = false); -bool getisTrophyPopupDisabled(); -void setisTrophyPopupDisabled(bool disable, bool is_game_specific = false); -s16 getCursorState(); -void setCursorState(s16 cursorState, bool is_game_specific = false); -bool vkValidationEnabled(); -void setVkValidation(bool enable, bool is_game_specific = false); -bool vkValidationSyncEnabled(); -void setVkSyncValidation(bool enable, bool is_game_specific = false); -bool vkValidationGpuEnabled(); -void setVkGpuValidation(bool enable, bool is_game_specific = false); -bool vkValidationCoreEnabled(); -void setVkCoreValidation(bool enable, bool is_game_specific = false); -bool getVkCrashDiagnosticEnabled(); -void setVkCrashDiagnosticEnabled(bool enable, bool is_game_specific = false); -bool getVkHostMarkersEnabled(); -void setVkHostMarkersEnabled(bool enable, bool is_game_specific = false); -bool getVkGuestMarkersEnabled(); -void setVkGuestMarkersEnabled(bool enable, bool is_game_specific = false); -bool getEnableDiscordRPC(); -void setEnableDiscordRPC(bool enable); -bool isRdocEnabled(); -bool isPipelineCacheEnabled(); -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); - -// Log -bool isLogAppend(); -void setLogAppend(bool enable, bool is_game_specific = false); -bool getLogEnable(); -void setLogEnable(bool enable, bool is_game_specific = false); -std::string getLogFilter(); -void setLogFilter(const std::string& type, bool is_game_specific = false); -u32 getLogMaxSkipDuration(); -void setLogMaxSkipDuration(u32 duration, bool is_game_specific = false); -bool getLogSeparateLogFilesEnabled(); -void setLogSeparateLogFilesEnabled(bool enabled, bool is_game_specific = false); -unsigned long long getLogSizeLimit(); -void setLogSizeLimit(unsigned long long size, bool is_game_specific = false); -bool getLogSkipDuplicate(); -void setLogSkipDuplicate(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); -#endif - -double getTrophyNotificationDuration(); -void setTrophyNotificationDuration(double newTrophyNotificationDuration, - bool is_game_specific = false); -int getCursorHideTimeout(); -std::string getMainOutputDevice(); -void setMainOutputDevice(std::string device, bool is_game_specific = false); -std::string getPadSpkOutputDevice(); -void setPadSpkOutputDevice(std::string device, bool is_game_specific = false); -std::string getMicDevice(); -void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific = false); -void setMicDevice(std::string device, bool is_game_specific = false); -u32 GetLanguage(); -void setLanguage(u32 language, bool is_game_specific = false); -void setUseSpecialPad(bool use); -bool getUseSpecialPad(); -void setSpecialPadClass(int type); -int getSpecialPadClass(); -bool getPSNSignedIn(); -void setPSNSignedIn(bool sign, bool is_game_specific = false); -bool patchShaders(); // no set -bool getShowFpsCounter(); -void setShowFpsCounter(bool enable, bool is_game_specific = false); -bool isNeoModeConsole(); -void setNeoMode(bool enable, bool is_game_specific = false); -bool isDevKitConsole(); -void setDevKitConsole(bool enable, bool is_game_specific = false); - -int getExtraDmemInMbytes(); -void setExtraDmemInMbytes(int value, bool is_game_specific = false); -bool getIsMotionControlsEnabled(); -void setIsMotionControlsEnabled(bool use, bool is_game_specific = false); -std::string getDefaultControllerID(); -void setDefaultControllerID(std::string id); -bool getBackgroundControllerInput(); -void setBackgroundControllerInput(bool enable, bool is_game_specific = false); -bool getLoggingEnabled(); -void setLoggingEnabled(bool enable, bool is_game_specific = false); -bool getFsrEnabled(); -void setFsrEnabled(bool enable, bool is_game_specific = false); -bool getRcasEnabled(); -void setRcasEnabled(bool enable, bool is_game_specific = false); -int getRcasAttenuation(); -void setRcasAttenuation(int value, bool is_game_specific = false); -bool getIsConnectedToNetwork(); -void setConnectedToNetwork(bool enable, bool is_game_specific = false); -void setUserName(const std::string& name, bool is_game_specific = false); -std::filesystem::path getSysModulesPath(); -void setSysModulesPath(const std::filesystem::path& path); -std::filesystem::path getFontsPath(); -void setFontsPath(const std::filesystem::path& path); - -enum UsbBackendType : int { Real, SkylandersPortal, InfinityBase, DimensionsToypad }; -int getUsbDeviceBackend(); -void setUsbDeviceBackend(int value, bool is_game_specific = false); - -// TODO -std::filesystem::path GetSaveDataPath(); -std::string getUserName(); -bool GetUseUnifiedInputConfig(); -void SetUseUnifiedInputConfig(bool use); -bool GetOverrideControllerColor(); -void SetOverrideControllerColor(bool enable); -int* GetControllerCustomColor(); -void SetControllerCustomColor(int r, int b, int g); -void setGameInstallDirs(const std::vector& dirs_config); -void setAllGameInstallDirs(const std::vector& dirs_config); -void setSaveDataPath(const std::filesystem::path& path); -// Gui -bool addGameInstallDir(const std::filesystem::path& dir, bool enabled = true); -void removeGameInstallDir(const std::filesystem::path& dir); -void setGameInstallDirEnabled(const std::filesystem::path& dir, bool enabled); -void setAddonInstallDir(const std::filesystem::path& dir); - -const std::vector getGameInstallDirs(); -const std::vector getGameInstallDirsEnabled(); -std::filesystem::path getAddonInstallDir(); - -void setDefaultValues(bool is_game_specific = false); - -constexpr std::string_view GetDefaultGlobalConfig(); -std::filesystem::path GetInputConfigFile(const std::string& game_id = ""); - -}; // namespace Config diff --git a/src/common/key_manager.cpp b/src/common/key_manager.cpp index cd0f668bf..f75d8ccc6 100644 --- a/src/common/key_manager.cpp +++ b/src/common/key_manager.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include "common/logging/formatter.h" #include "common/logging/log.h" #include "key_manager.h" #include "path_util.h" @@ -33,6 +35,40 @@ void KeyManager::SetInstance(std::shared_ptr instance) { } // ------------------- Load / Save ------------------- +bool KeyManager::TransferTrophyKey() { + try { + auto path = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"; + if (!std::filesystem::exists(path)) { + return false; + } + + // Parse the old config + std::ifstream ifs; + ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); + ifs.open(path, std::ios_base::binary); + toml::value og_data = + toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data}); + + // Retrieve old trophy key and store it. + if (og_data.contains("Keys")) { + const auto& keys = og_data.at("Keys").as_table(); + auto it = keys.find("TrophyKey"); + if (it == keys.end()) { + return false; + } + + std::string old_key = toml::get(it->second); + if (!old_key.empty()) { + m_keys.TrophyKeySet.ReleaseTrophyKey = KeyManager::HexStringToBytes(old_key); + return true; + } + } + } catch (std::exception& ex) { + fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); + } + return false; +} + bool KeyManager::LoadFromFile() { try { const auto userDir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); @@ -40,6 +76,7 @@ bool KeyManager::LoadFromFile() { if (!std::filesystem::exists(keysPath)) { SetDefaultKeys(); + TransferTrophyKey(); SaveToFile(); LOG_DEBUG(KeyManager, "Created default key file: {}", keysPath.string()); return true; @@ -56,8 +93,17 @@ bool KeyManager::LoadFromFile() { SetDefaultKeys(); // start from defaults - if (j.contains("TrophyKeySet")) + if (j.contains("TrophyKeySet")) { j.at("TrophyKeySet").get_to(m_keys.TrophyKeySet); + } + + if (m_keys.TrophyKeySet.ReleaseTrophyKey.empty()) { + // No key, try to transfer it from the old configs + if (TransferTrophyKey()) { + // If we did transfer something, make sure to save it. + SaveToFile(); + } + } LOG_DEBUG(KeyManager, "Successfully loaded keys from: {}", keysPath.string()); return true; diff --git a/src/common/key_manager.h b/src/common/key_manager.h index 8925ccbd0..f71765f0d 100644 --- a/src/common/key_manager.h +++ b/src/common/key_manager.h @@ -34,6 +34,7 @@ public: static void SetInstance(std::shared_ptr instance); // ------------------- File operations ------------------- + bool TransferTrophyKey(); bool LoadFromFile(); bool SaveToFile(); diff --git a/src/common/logging/log.cpp b/src/common/logging/log.cpp index baa618fc0..6b0456bfd 100644 --- a/src/common/logging/log.cpp +++ b/src/common/logging/log.cpp @@ -7,7 +7,6 @@ #include #include "common/assert.h" -#include "common/config.h" #include "common/logging/log.h" #include "common/logging/thread_name_formatter.h" #include "common/types.h" diff --git a/src/main.cpp b/src/main.cpp index 8576add0e..d30a64260 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,6 @@ #include #include -#include "common/config.h" #include "common/key_manager.h" #include "common/logging/log.h" #include "common/memory_patcher.h" @@ -113,22 +112,9 @@ int main(int argc, char* argv[]) { 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 ---- + // Initialize key manager 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();