diff --git a/src/common/config.cpp b/src/common/config.cpp index 4a764a4c6..d3a5fa6a1 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -31,31 +31,50 @@ std::filesystem::path find_fs_path_or(const basic_value& v, const K& ky, namespace Config { +// General static bool isNeo = false; static bool isDevKit = false; +static bool isPSNSignedIn = false; static bool isTrophyPopupDisabled = false; +static double trophyNotificationDuration = 6.0; static bool enableDiscordRPC = false; -static u32 screenWidth = 1280; -static u32 screenHeight = 720; -static s32 gpuId = -1; // Vulkan physical device index. Set to negative for auto select -static std::string logFilter; +static std::string logFilter = ""; static std::string logType = "sync"; static std::string userName = "shadPS4"; -static std::string chooseHomeTab; +static std::string chooseHomeTab = "General"; +static bool isShowSplash = false; +static std::string isSideTrophy = "right"; +static bool compatibilityData = false; +static bool checkCompatibilityOnStartup = false; + +// Input +static int cursorState = HideCursorState::Idle; +static int cursorHideTimeout = 5; // 5 seconds (default) static bool useSpecialPad = false; static int specialPadClass = 1; static bool isMotionControlsEnabled = true; -static bool isDebugDump = false; -static bool isShaderDebug = false; -static bool isShowSplash = false; -static std::string isSideTrophy = "right"; +static bool useUnifiedInputConfig = true; + +// These two entries aren't stored in the config +static bool overrideControllerColor = false; +static int controllerCustomColorRGB[3] = {0, 0, 255}; + +// GPU +static u32 screenWidth = 1280; +static u32 screenHeight = 720; static bool isNullGpu = false; static bool shouldCopyGPUBuffers = false; static bool readbacksEnabled = false; static bool directMemoryAccessEnabled = false; static bool shouldDumpShaders = false; -static bool shouldPatchShaders = true; +static bool shouldPatchShaders = false; static u32 vblankDivider = 1; +static bool isFullscreen = false; +static std::string fullscreenMode = "Windowed"; +static bool isHDRAllowed = false; + +// Vulkan +static s32 gpuId = -1; static bool vkValidation = false; static bool vkValidationSync = false; static bool vkValidationGpu = false; @@ -63,32 +82,29 @@ static bool vkCrashDiagnostic = false; static bool vkHostMarkers = false; static bool vkGuestMarkers = false; static bool rdocEnable = false; -static bool isFpsColor = true; -static bool isSeparateLogFilesEnabled = false; -static int cursorState = HideCursorState::Idle; -static int cursorHideTimeout = 5; // 5 seconds (default) -static double trophyNotificationDuration = 6.0; -static bool useUnifiedInputConfig = true; -static bool overrideControllerColor = false; -static int controllerCustomColorRGB[3] = {0, 0, 255}; -static bool compatibilityData = false; -static bool checkCompatibilityOnStartup = false; -static std::string trophyKey; -static bool isPSNSignedIn = false; -// Gui +// Debug +static bool isDebugDump = false; +static bool isShaderDebug = false; +static bool isSeparateLogFilesEnabled = false; +static bool isFpsColor = true; + +// GUI static bool load_game_size = true; static std::vector settings_install_dirs = {}; std::vector install_dirs_enabled = {}; std::filesystem::path settings_addon_install_dir = {}; std::filesystem::path save_data_path = {}; -static bool isFullscreen = false; -static std::string fullscreenMode = "Windowed"; -static bool isHDRAllowed = false; -// Language +// Settings u32 m_language = 1; // english +// Keys +static std::string trophyKey = ""; + +// Expected number of items in the config file +static constexpr u64 total_entries = 51; + bool allowHDR() { return isHDRAllowed; } @@ -565,36 +581,46 @@ void load(const std::filesystem::path& path) { fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); return; } + + u64 entry_count = 0; + if (data.contains("General")) { const toml::value& general = data.at("General"); - isNeo = toml::find_or(general, "isPS4Pro", false); - isDevKit = toml::find_or(general, "isDevKit", false); - isPSNSignedIn = toml::find_or(general, "isPSNSignedIn", false); - isTrophyPopupDisabled = toml::find_or(general, "isTrophyPopupDisabled", false); - trophyNotificationDuration = - toml::find_or(general, "trophyNotificationDuration", 5.0); - enableDiscordRPC = toml::find_or(general, "enableDiscordRPC", true); - logFilter = toml::find_or(general, "logFilter", ""); - logType = toml::find_or(general, "logType", "sync"); - userName = toml::find_or(general, "userName", "shadPS4"); - isShowSplash = toml::find_or(general, "showSplash", true); - isSideTrophy = toml::find_or(general, "sideTrophy", "right"); - compatibilityData = toml::find_or(general, "compatibilityEnabled", false); - checkCompatibilityOnStartup = - toml::find_or(general, "checkCompatibilityOnStartup", false); - chooseHomeTab = toml::find_or(general, "chooseHomeTab", "Release"); + isNeo = toml::find_or(general, "isPS4Pro", isNeo); + isDevKit = toml::find_or(general, "isDevKit", isDevKit); + isPSNSignedIn = toml::find_or(general, "isPSNSignedIn", isPSNSignedIn); + isTrophyPopupDisabled = + toml::find_or(general, "isTrophyPopupDisabled", isTrophyPopupDisabled); + trophyNotificationDuration = toml::find_or(general, "trophyNotificationDuration", + trophyNotificationDuration); + enableDiscordRPC = toml::find_or(general, "enableDiscordRPC", enableDiscordRPC); + logFilter = toml::find_or(general, "logFilter", logFilter); + logType = toml::find_or(general, "logType", logType); + userName = toml::find_or(general, "userName", userName); + isShowSplash = toml::find_or(general, "showSplash", isShowSplash); + isSideTrophy = toml::find_or(general, "sideTrophy", isSideTrophy); + compatibilityData = toml::find_or(general, "compatibilityEnabled", compatibilityData); + checkCompatibilityOnStartup = toml::find_or(general, "checkCompatibilityOnStartup", + checkCompatibilityOnStartup); + chooseHomeTab = toml::find_or(general, "chooseHomeTab", chooseHomeTab); + + entry_count += general.size(); } if (data.contains("Input")) { const toml::value& input = data.at("Input"); - cursorState = toml::find_or(input, "cursorState", HideCursorState::Idle); - cursorHideTimeout = toml::find_or(input, "cursorHideTimeout", 5); - useSpecialPad = toml::find_or(input, "useSpecialPad", false); - specialPadClass = toml::find_or(input, "specialPadClass", 1); - isMotionControlsEnabled = toml::find_or(input, "isMotionControlsEnabled", true); - useUnifiedInputConfig = toml::find_or(input, "useUnifiedInputConfig", true); + cursorState = toml::find_or(input, "cursorState", cursorState); + cursorHideTimeout = toml::find_or(input, "cursorHideTimeout", cursorHideTimeout); + useSpecialPad = toml::find_or(input, "useSpecialPad", useSpecialPad); + specialPadClass = toml::find_or(input, "specialPadClass", specialPadClass); + isMotionControlsEnabled = + toml::find_or(input, "isMotionControlsEnabled", isMotionControlsEnabled); + useUnifiedInputConfig = + toml::find_or(input, "useUnifiedInputConfig", useUnifiedInputConfig); + + entry_count += input.size(); } if (data.contains("GPU")) { @@ -602,44 +628,52 @@ void load(const std::filesystem::path& path) { screenWidth = toml::find_or(gpu, "screenWidth", screenWidth); screenHeight = toml::find_or(gpu, "screenHeight", screenHeight); - isNullGpu = toml::find_or(gpu, "nullGpu", false); - shouldCopyGPUBuffers = toml::find_or(gpu, "copyGPUBuffers", false); - readbacksEnabled = toml::find_or(gpu, "readbacks", false); - directMemoryAccessEnabled = toml::find_or(gpu, "directMemoryAccess", false); - shouldDumpShaders = toml::find_or(gpu, "dumpShaders", false); - shouldPatchShaders = toml::find_or(gpu, "patchShaders", true); - vblankDivider = toml::find_or(gpu, "vblankDivider", 1); - isFullscreen = toml::find_or(gpu, "Fullscreen", false); - fullscreenMode = toml::find_or(gpu, "FullscreenMode", "Windowed"); - isHDRAllowed = toml::find_or(gpu, "allowHDR", false); + isNullGpu = toml::find_or(gpu, "nullGpu", isNullGpu); + shouldCopyGPUBuffers = toml::find_or(gpu, "copyGPUBuffers", shouldCopyGPUBuffers); + readbacksEnabled = toml::find_or(gpu, "readbacks", readbacksEnabled); + directMemoryAccessEnabled = + toml::find_or(gpu, "directMemoryAccess", directMemoryAccessEnabled); + shouldDumpShaders = toml::find_or(gpu, "dumpShaders", shouldDumpShaders); + shouldPatchShaders = toml::find_or(gpu, "patchShaders", shouldPatchShaders); + vblankDivider = toml::find_or(gpu, "vblankDivider", vblankDivider); + isFullscreen = toml::find_or(gpu, "Fullscreen", isFullscreen); + fullscreenMode = toml::find_or(gpu, "FullscreenMode", fullscreenMode); + isHDRAllowed = toml::find_or(gpu, "allowHDR", isHDRAllowed); + + entry_count += gpu.size(); } if (data.contains("Vulkan")) { const toml::value& vk = data.at("Vulkan"); - gpuId = toml::find_or(vk, "gpuId", -1); - vkValidation = toml::find_or(vk, "validation", false); - vkValidationSync = toml::find_or(vk, "validation_sync", false); - vkValidationGpu = toml::find_or(vk, "validation_gpu", true); - vkCrashDiagnostic = toml::find_or(vk, "crashDiagnostic", false); - vkHostMarkers = toml::find_or(vk, "hostMarkers", false); - vkGuestMarkers = toml::find_or(vk, "guestMarkers", false); - rdocEnable = toml::find_or(vk, "rdocEnable", false); + gpuId = toml::find_or(vk, "gpuId", gpuId); + vkValidation = toml::find_or(vk, "validation", vkValidation); + vkValidationSync = toml::find_or(vk, "validation_sync", vkValidationSync); + vkValidationGpu = toml::find_or(vk, "validation_gpu", vkValidationGpu); + vkCrashDiagnostic = toml::find_or(vk, "crashDiagnostic", vkCrashDiagnostic); + vkHostMarkers = toml::find_or(vk, "hostMarkers", vkHostMarkers); + vkGuestMarkers = toml::find_or(vk, "guestMarkers", vkGuestMarkers); + rdocEnable = toml::find_or(vk, "rdocEnable", rdocEnable); + + entry_count += vk.size(); } if (data.contains("Debug")) { const toml::value& debug = data.at("Debug"); - isDebugDump = toml::find_or(debug, "DebugDump", false); - isSeparateLogFilesEnabled = toml::find_or(debug, "isSeparateLogFilesEnabled", false); - isShaderDebug = toml::find_or(debug, "CollectShader", false); - isFpsColor = toml::find_or(debug, "FPSColor", true); + isDebugDump = toml::find_or(debug, "DebugDump", isDebugDump); + isSeparateLogFilesEnabled = + toml::find_or(debug, "isSeparateLogFilesEnabled", isSeparateLogFilesEnabled); + isShaderDebug = toml::find_or(debug, "CollectShader", isShaderDebug); + isFpsColor = toml::find_or(debug, "FPSColor", isFpsColor); + + entry_count += debug.size(); } if (data.contains("GUI")) { const toml::value& gui = data.at("GUI"); - load_game_size = toml::find_or(gui, "loadGameSizeEnabled", true); + load_game_size = toml::find_or(gui, "loadGameSizeEnabled", load_game_size); const auto install_dir_array = toml::find_or>(gui, "installDirs", {}); @@ -661,20 +695,32 @@ void load(const std::filesystem::path& path) { {std::filesystem::path{install_dir_array[i]}, install_dirs_enabled[i]}); } - save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {}); + 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 = + toml::find_fs_path_or(gui, "addonInstallDir", settings_addon_install_dir); + + entry_count += gui.size(); } if (data.contains("Settings")) { const toml::value& settings = data.at("Settings"); + m_language = toml::find_or(settings, "consoleLanguage", m_language); - m_language = toml::find_or(settings, "consoleLanguage", 1); + entry_count += settings.size(); } if (data.contains("Keys")) { const toml::value& keys = data.at("Keys"); - trophyKey = toml::find_or(keys, "TrophyKey", ""); + trophyKey = toml::find_or(keys, "TrophyKey", trophyKey); + + entry_count += keys.size(); + } + + // Run save after loading to generate any missing fields with default values. + if (entry_count != total_entries) { + fmt::print("Outdated config detected, updating config file.\n"); + save(path); } } @@ -822,32 +868,50 @@ void save(const std::filesystem::path& path) { } void setDefaultValues() { - isHDRAllowed = false; + // General isNeo = false; isDevKit = false; isPSNSignedIn = false; - isFullscreen = false; isTrophyPopupDisabled = false; - enableDiscordRPC = true; - screenWidth = 1280; - screenHeight = 720; + trophyNotificationDuration = 6.0; + enableDiscordRPC = false; logFilter = ""; logType = "sync"; userName = "shadPS4"; - chooseHomeTab = "General"; - cursorState = HideCursorState::Idle; - cursorHideTimeout = 5; - trophyNotificationDuration = 6.0; - useSpecialPad = false; - specialPadClass = 1; - isDebugDump = false; - isShaderDebug = false; isShowSplash = false; isSideTrophy = "right"; + compatibilityData = false; + checkCompatibilityOnStartup = false; + + // Input + cursorState = HideCursorState::Idle; + cursorHideTimeout = 5; + useSpecialPad = false; + specialPadClass = 1; + isMotionControlsEnabled = true; + useUnifiedInputConfig = true; + overrideControllerColor = false; + controllerCustomColorRGB[0] = 0; + controllerCustomColorRGB[1] = 0; + controllerCustomColorRGB[2] = 255; + + // GPU + screenWidth = 1280; + screenHeight = 720; isNullGpu = false; + shouldCopyGPUBuffers = false; + readbacksEnabled = false; + directMemoryAccessEnabled = false; shouldDumpShaders = false; + shouldPatchShaders = false; vblankDivider = 1; + isFullscreen = false; + fullscreenMode = "Windowed"; + isHDRAllowed = false; + + // Vulkan + gpuId = -1; vkValidation = false; vkValidationSync = false; vkValidationGpu = false; @@ -855,10 +919,18 @@ void setDefaultValues() { vkHostMarkers = false; vkGuestMarkers = false; rdocEnable = false; + + // Debug + isDebugDump = false; + isShaderDebug = false; + isSeparateLogFilesEnabled = false; + isFpsColor = true; + + // GUI + load_game_size = true; + + // Settings m_language = 1; - gpuId = -1; - compatibilityData = false; - checkCompatibilityOnStartup = false; } constexpr std::string_view GetDefaultKeyboardConfig() {