diff --git a/src/common/config.cpp b/src/common/config.cpp index fb6ee120a..51c88bcc7 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -1,529 +1,1013 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include -#include -#include #include "config.h" -namespace Config { +#include +#include -static bool isNeo = false; -static bool isFullscreen = 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 logType = "async"; -static std::string userName = "shadPS4"; -static bool useSpecialPad = false; -static int specialPadClass = 1; -static bool isDebugDump = false; -static bool isShowSplash = false; -static bool isNullGpu = false; -static bool shouldCopyGPUBuffers = false; -static bool shouldDumpShaders = false; -static bool shouldDumpPM4 = false; -static u32 vblankDivider = 1; -static bool vkValidation = false; -static bool vkValidationSync = false; -static bool vkValidationGpu = false; -static bool rdocEnable = false; -static bool vkMarkers = false; -static bool vkCrashDiagnostic = false; +#include "common/singleton.h" -// Gui -std::string settings_install_dir = ""; -u32 main_window_geometry_x = 400; -u32 main_window_geometry_y = 400; -u32 main_window_geometry_w = 1280; -u32 main_window_geometry_h = 720; -u32 mw_themes = 0; -u32 m_icon_size = 36; -u32 m_icon_size_grid = 69; -u32 m_slider_pos = 0; -u32 m_slider_pos_grid = 0; -u32 m_table_mode = 0; -u32 m_window_size_W = 1280; -u32 m_window_size_H = 720; -std::vector m_pkg_viewer; -std::vector m_elf_viewer; -std::vector m_recent_files; -std::string emulator_language = "en"; -// Settings -u32 m_language = 1; // english +using namespace Config; -bool isNeoMode() { - return isNeo; +void Config::ConfigManager::loadConfigurations() { + const auto configs_dir = Common::FS::GetUserPath(Common::FS::PathType::ConfigsDir); + + fmt::print("Iterating configuration files from: {}\n", configs_dir.string()); + + bool configsLoaded = false; + + // Iterate over all files in the directory + for (auto& file : std::filesystem::recursive_directory_iterator(configs_dir)) { + // Skip any files that aren't toml files + if (file.path().extension() != ".toml") + continue; + + fmt::print("Loading configuration file {}\n", file.path().string()); + + auto loadedConfiguration = std::make_shared(file.path()); + if (!loadedConfiguration) + { + fmt::print("Error loading configuration file ({}).", file.path().string()); + continue; + } + + // Validate title id + auto& loadedTitleId = loadedConfiguration->getTitleId(); + if (loadedTitleId.empty()) + { + loadedConfiguration.reset(); + continue; + } + + configurations[loadedTitleId] = loadedConfiguration; + configsLoaded = true; + } + + // If there were no configurations loaded, then create a global one + if (!configsLoaded) + configurations[c_globalTitleId] = + std::make_shared(configs_dir / (c_globalTitleId + c_configExtension)); } -bool isFullscreenMode() { - return isFullscreen; +void Config::ConfigManager::setCurrentConfigId(std::string titleId) { + // Check if the current title id is empty for user error + if (titleId.empty()) { + currentTitleId = c_globalTitleId; + return; + } + + currentTitleId = titleId; } -u32 getScreenWidth() { - return screenWidth; +void Config::ConfigManager::setDefaultConfigId() { + currentTitleId = c_globalTitleId; } -u32 getScreenHeight() { - return screenHeight; +const std::string Config::ConfigManager::getCurrentConfigId() { + return currentTitleId; } -s32 getGpuId() { - return gpuId; +std::shared_ptr Config::ConfigManager::getCurrentConfig() { + if (configurations.empty()) + return nullptr; + + if (currentTitleId.empty()) + return nullptr; + + if (configurations.find(currentTitleId) == configurations.end()) + return nullptr; + + return configurations[currentTitleId]; } -std::string getLogFilter() { - return logFilter; +Config::Configuration::Configuration() { + setDefaultValues(); } -std::string getLogType() { - return logType; +Config::Configuration::Configuration(const std::filesystem::path& path) : Config::Configuration() { + load(path); } -std::string getUserName() { - return userName; -} - -bool getUseSpecialPad() { - return useSpecialPad; -} - -int getSpecialPadClass() { - return specialPadClass; -} - -bool debugDump() { - return isDebugDump; -} - -bool showSplash() { - return isShowSplash; -} - -bool nullGpu() { - return isNullGpu; -} - -bool copyGPUCmdBuffers() { - return shouldCopyGPUBuffers; -} - -bool dumpShaders() { - return shouldDumpShaders; -} - -bool dumpPM4() { - return shouldDumpPM4; -} - -bool isRdocEnabled() { - return rdocEnable; -} - -bool isMarkersEnabled() { - return vkMarkers; -} - -u32 vblankDiv() { - return vblankDivider; -} - -bool vkValidationEnabled() { - return vkValidation; -} - -bool vkValidationSyncEnabled() { - return vkValidationSync; -} - -bool vkValidationGpuEnabled() { - return vkValidationGpu; -} - -bool vkMarkersEnabled() { - return vkMarkers || vkCrashDiagnostic; // Crash diagnostic forces markers on -} - -bool vkCrashDiagnosticEnabled() { - return vkCrashDiagnostic; -} - -void setGpuId(s32 selectedGpuId) { - gpuId = selectedGpuId; -} - -void setScreenWidth(u32 width) { - screenWidth = width; -} - -void setScreenHeight(u32 height) { - screenHeight = height; -} - -void setDebugDump(bool enable) { - isDebugDump = enable; -} - -void setShowSplash(bool enable) { - isShowSplash = enable; -} - -void setNullGpu(bool enable) { - isNullGpu = enable; -} - -void setCopyGPUCmdBuffers(bool enable) { - shouldCopyGPUBuffers = enable; -} - -void setDumpShaders(bool enable) { - shouldDumpShaders = enable; -} - -void setDumpPM4(bool enable) { - shouldDumpPM4 = enable; -} - -void setVkValidation(bool enable) { - vkValidation = enable; -} - -void setVkSyncValidation(bool enable) { - vkValidationSync = enable; -} - -void setRdocEnabled(bool enable) { - rdocEnable = enable; -} - -void setVblankDiv(u32 value) { - vblankDivider = value; -} - -void setFullscreenMode(bool enable) { - isFullscreen = enable; -} - -void setLanguage(u32 language) { - m_language = language; -} - -void setNeoMode(bool enable) { - isNeo = enable; -} - -void setLogType(const std::string& type) { - logType = type; -} - -void setLogFilter(const std::string& type) { - logFilter = type; -} - -void setUserName(const std::string& type) { - userName = type; -} - -void setUseSpecialPad(bool use) { - useSpecialPad = use; -} - -void setSpecialPadClass(int type) { - specialPadClass = type; -} - -void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) { - main_window_geometry_x = x; - main_window_geometry_y = y; - main_window_geometry_w = w; - main_window_geometry_h = h; -} -void setGameInstallDir(const std::string& dir) { - settings_install_dir = dir; -} -void setMainWindowTheme(u32 theme) { - mw_themes = theme; -} -void setIconSize(u32 size) { - m_icon_size = size; -} -void setIconSizeGrid(u32 size) { - m_icon_size_grid = size; -} -void setSliderPosition(u32 pos) { - m_slider_pos = pos; -} -void setSliderPositionGrid(u32 pos) { - m_slider_pos_grid = pos; -} -void setTableMode(u32 mode) { - m_table_mode = mode; -} -void setMainWindowWidth(u32 width) { - m_window_size_W = width; -} -void setMainWindowHeight(u32 height) { - m_window_size_H = height; -} -void setPkgViewer(const std::vector& pkgList) { - m_pkg_viewer.resize(pkgList.size()); - m_pkg_viewer = pkgList; -} -void setElfViewer(const std::vector& elfList) { - m_elf_viewer.resize(elfList.size()); - m_elf_viewer = elfList; -} -void setRecentFiles(const std::vector& recentFiles) { - m_recent_files.resize(recentFiles.size()); - m_recent_files = recentFiles; -} - -void setEmulatorLanguage(std::string language) { - emulator_language = language; -} - -u32 getMainWindowGeometryX() { - return main_window_geometry_x; -} -u32 getMainWindowGeometryY() { - return main_window_geometry_y; -} -u32 getMainWindowGeometryW() { - return main_window_geometry_w; -} -u32 getMainWindowGeometryH() { - return main_window_geometry_h; -} -std::string getGameInstallDir() { - return settings_install_dir; -} -u32 getMainWindowTheme() { - return mw_themes; -} -u32 getIconSize() { - return m_icon_size; -} -u32 getIconSizeGrid() { - return m_icon_size_grid; -} -u32 getSliderPosition() { - return m_slider_pos; -} -u32 getSliderPositionGrid() { - return m_slider_pos_grid; -} -u32 getTableMode() { - return m_table_mode; -} -u32 getMainWindowWidth() { - return m_window_size_W; -} -u32 getMainWindowHeight() { - return m_window_size_H; -} -std::vector getPkgViewer() { - return m_pkg_viewer; -} -std::vector getElfViewer() { - return m_elf_viewer; -} -std::vector getRecentFiles() { - return m_recent_files; -} - -std::string getEmulatorLanguage() { - return emulator_language; -} - -u32 GetLanguage() { - return m_language; -} -void load(const std::filesystem::path& path) { - // If the configuration file does not exist, create it and return +void Config::Configuration::load(const std::filesystem::path& path) { + // Validate that the incoming configuration file exists std::error_code error; if (!std::filesystem::exists(path, error)) { save(path); + fmt::print("err: configuration file path ({}) does not exist.\n", path.string()); return; } - toml::value data; - + // Attempt to parse the configuration data try { data = toml::parse(path); } catch (std::exception& ex) { - fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); + fmt::print("err: could not load configuration (ex: {}).\n", ex.what()); return; } - if (data.contains("General")) { - const toml::value& general = data.at("General"); - - isNeo = toml::find_or(general, "isPS4Pro", false); - isFullscreen = toml::find_or(general, "Fullscreen", false); - 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); - } - - if (data.contains("Input")) { - const toml::value& input = data.at("Input"); - - useSpecialPad = toml::find_or(input, "useSpecialPad", false); - specialPadClass = toml::find_or(input, "specialPadClass", 1); - } - - if (data.contains("GPU")) { - const toml::value& gpu = data.at("GPU"); - - 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); - shouldDumpShaders = toml::find_or(gpu, "dumpShaders", false); - shouldDumpPM4 = toml::find_or(gpu, "dumpPM4", false); - vblankDivider = toml::find_or(gpu, "vblankDivider", 1); - } - - 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); - rdocEnable = toml::find_or(vk, "rdocEnable", false); - vkMarkers = toml::find_or(vk, "rdocMarkersEnable", false); - vkCrashDiagnostic = toml::find_or(vk, "crashDiagnostic", false); - } - - if (data.contains("Debug")) { - const toml::value& debug = data.at("Debug"); - - isDebugDump = toml::find_or(debug, "DebugDump", false); - } - - if (data.contains("GUI")) { - const toml::value& gui = data.at("GUI"); - - m_icon_size = toml::find_or(gui, "iconSize", 0); - m_icon_size_grid = toml::find_or(gui, "iconSizeGrid", 0); - m_slider_pos = toml::find_or(gui, "sliderPos", 0); - m_slider_pos_grid = toml::find_or(gui, "sliderPosGrid", 0); - mw_themes = toml::find_or(gui, "theme", 0); - m_window_size_W = toml::find_or(gui, "mw_width", 0); - m_window_size_H = toml::find_or(gui, "mw_height", 0); - settings_install_dir = toml::find_or(gui, "installDir", ""); - main_window_geometry_x = toml::find_or(gui, "geometry_x", 0); - main_window_geometry_y = toml::find_or(gui, "geometry_y", 0); - main_window_geometry_w = toml::find_or(gui, "geometry_w", 0); - main_window_geometry_h = toml::find_or(gui, "geometry_h", 0); - m_pkg_viewer = toml::find_or>(gui, "pkgDirs", {}); - m_elf_viewer = toml::find_or>(gui, "elfDirs", {}); - m_recent_files = toml::find_or>(gui, "recentFiles", {}); - m_table_mode = toml::find_or(gui, "gameTableMode", 0); - emulator_language = toml::find_or(gui, "emulatorLanguage", "en"); - } - - if (data.contains("Settings")) { - const toml::value& settings = data.at("Settings"); - - m_language = toml::find_or(settings, "consoleLanguage", 1); - } } -void save(const std::filesystem::path& path) { - toml::value data; +void Config::Configuration::save(const std::filesystem::path& path) { std::error_code error; if (std::filesystem::exists(path, error)) { try { data = toml::parse(path); } 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 accessing {} (error: {})\n", path.string(), - error.message().c_str()); } - fmt::print("Saving new configuration file {}\n", path.string()); + + fmt::print("saving new configuration file ({}).\n", path.string()); } - data["General"]["isPS4Pro"] = isNeo; - data["General"]["Fullscreen"] = isFullscreen; - data["General"]["logFilter"] = logFilter; - data["General"]["logType"] = logType; - data["General"]["userName"] = userName; - data["General"]["showSplash"] = isShowSplash; - data["Input"]["useSpecialPad"] = useSpecialPad; - data["Input"]["specialPadClass"] = specialPadClass; - data["GPU"]["screenWidth"] = screenWidth; - data["GPU"]["screenHeight"] = screenHeight; - data["GPU"]["nullGpu"] = isNullGpu; - data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers; - data["GPU"]["dumpShaders"] = shouldDumpShaders; - data["GPU"]["dumpPM4"] = shouldDumpPM4; - data["GPU"]["vblankDivider"] = vblankDivider; - data["Vulkan"]["gpuId"] = gpuId; - data["Vulkan"]["validation"] = vkValidation; - data["Vulkan"]["validation_sync"] = vkValidationSync; - data["Vulkan"]["validation_gpu"] = vkValidationGpu; - data["Vulkan"]["rdocEnable"] = rdocEnable; - data["Vulkan"]["rdocMarkersEnable"] = vkMarkers; - data["Vulkan"]["crashDiagnostic"] = vkCrashDiagnostic; - data["Debug"]["DebugDump"] = isDebugDump; - data["GUI"]["theme"] = mw_themes; - data["GUI"]["iconSize"] = m_icon_size; - data["GUI"]["sliderPos"] = m_slider_pos; - data["GUI"]["iconSizeGrid"] = m_icon_size_grid; - data["GUI"]["sliderPosGrid"] = m_slider_pos_grid; - data["GUI"]["gameTableMode"] = m_table_mode; - data["GUI"]["mw_width"] = m_window_size_W; - data["GUI"]["mw_height"] = m_window_size_H; - data["GUI"]["installDir"] = settings_install_dir; - data["GUI"]["geometry_x"] = main_window_geometry_x; - data["GUI"]["geometry_y"] = main_window_geometry_y; - data["GUI"]["geometry_w"] = main_window_geometry_w; - data["GUI"]["geometry_h"] = main_window_geometry_h; - data["GUI"]["pkgDirs"] = m_pkg_viewer; - data["GUI"]["elfDirs"] = m_elf_viewer; - data["GUI"]["recentFiles"] = m_recent_files; - data["GUI"]["emulatorLanguage"] = emulator_language; - - data["Settings"]["consoleLanguage"] = m_language; - - std::ofstream file(path, std::ios::out); - file << data; - file.close(); + std::ofstream saveFile(path, std::ios::out); + saveFile << data; + saveFile.close(); } -void setDefaultValues() { - isNeo = false; - isFullscreen = false; - screenWidth = 1280; - screenHeight = 720; - logFilter = ""; - logType = "async"; - userName = "shadPS4"; - useSpecialPad = false; - specialPadClass = 1; - isDebugDump = false; - isShowSplash = false; - isNullGpu = false; - shouldDumpShaders = false; - shouldDumpPM4 = false; - vblankDivider = 1; - vkValidation = false; - vkValidationSync = false; - vkValidationGpu = false; - rdocEnable = false; - vkMarkers = false; - vkCrashDiagnostic = false; - emulator_language = "en"; - m_language = 1; - gpuId = -1; +bool Configuration::configVersionDifference(const std::filesystem::path& path) { + // Validate that the incoming configuration file exists + std::error_code error; + if (!std::filesystem::exists(path, error)) { + fmt::print("err: configuration file path ({}) does not exist.\n", path.string()); + return true; + } + + // Attempt to parse the configuration data + toml::value oldConfigData; + try { + oldConfigData = toml::parse(path); + } catch (std::exception& ex) { + fmt::print("err: could not open old configuration file (ex: {}).\n", ex.what()); + return true; + } + + // Iterate checking for new entries that do not exist in the provided config + for (auto& item : c_defaultConfig) { + // Get the key name + auto& defaultFirst = item.first; + auto& defaultSecond = item.second; + + // std::cout << "checking for key (" << defaultFirst << ") in old config." << std::endl; + + // Check to see if the old configuration contains the key provided + if (oldConfigData.contains(defaultFirst)) { + // std::cout << "checking (" << defaultFirst.c_str() << ") type (" << defaultSecond.type() + // << " = " << oldConfigData[defaultFirst].type() << ")" << std::endl; + + // Check to see that the types match for the second + if (oldConfigData[defaultFirst].type() != defaultSecond.type()) { + // std::cout << "mismatch type found!" << std::endl; + return true; + } + } else // If the key does not exist in the old config but exists in the new, mark difference + { + // std::cout << "key (" << defaultFirst << ") is not found in old config." << std::endl; + return true; + } + + auto& oldConfigSecond = oldConfigData[defaultFirst]; + + // If there is a nested table, check the sub-entries + if (defaultSecond.is_table()) { + toml::table secondTable = defaultSecond.as_table(); + + for (auto& tableItemPair : secondTable) { + auto& secondItemFirst = tableItemPair.first; + auto& secondItemSecond = tableItemPair.second; + + // std::cout << "checking for key (" << secondItemFirst << ") in old config." + // << std::endl; + + if (oldConfigSecond.contains(secondItemFirst)) { + // std::cout << "checking (" << secondItemFirst.c_str() << ") type (" + // << secondItemSecond.type() << " = " + // << oldConfigSecond[secondItemFirst].type() << ")" << std::endl; + + // Check for type match + if (oldConfigSecond[secondItemFirst].type() != secondItemSecond.type()) { + // std::cout << "mismatch type found!" << std::endl; + return true; + } + } else { + // std::cout << "key (" << secondItemFirst << ") is not found in old config." + // << std::endl; + return true; + } + } + } + } + return false; } -} // namespace Config +const std::string& Config::Configuration::getTitleId() const { + return titleId; +} + +bool Config::Configuration::isNeoMode() { + return getValue("General", "isPS4Pro"); +} + +void Config::Configuration::setNeoMode(bool enable) { + setValue("General", "isPS4Pro", enable); +} + +bool Config::Configuration::isFullscreenMode() { + return getValue("General", "Fullscreen"); +} + +void Config::Configuration::setFullscreenMode(bool enable) { + setValue("General", "Fullscreen", enable); +} + +std::string Config::Configuration::getLogFilter() { + return getValue("General", "logFilter"); +} + +void Config::Configuration::setLogFilter(const std::string& type) { + setValue("General", "logFilter", type); +} + +std::string Config::Configuration::getLogType() { + return getValue("General", "logType"); +} + +void Config::Configuration::setLogType(const std::string& type) { + setValue("General", "logType", type); +} + +std::string Config::Configuration::getUserName() { + return getValue("General", "userName"); +} + +void Config::Configuration::setUserName(const std::string& type) { + setValue("General", "userName", type); +} + +bool Config::Configuration::showSplash() { + return getValue("General", "showSplash"); +} + +void Config::Configuration::setShowSplash(bool enable) { + return setValue("General", "showSplash", enable); +} + +bool Config::Configuration::getUseSpecialPad() { + return getValue("General", "useSpecialPad"); +} + +void Config::Configuration::setUseSpecialPad(bool use) { + setValue("General", "useSpecialPad", use); +} + +int Config::Configuration::getSpecialPadClass() { + return getValue("General", "specialPadClass"); +} + +void Config::Configuration::setSpecialPadClass(int type) { + setValue("General", "specialPadClass", type); +} + +u32 Config::Configuration::getScreenWidth() { + return getValue("General", "screenWidth"); +} + +void Config::Configuration::setScreenWidth(u32 width) { + setValue("General", "screenWidth", width); +} + +u32 Config::Configuration::getScreenHeight() { + return getValue("General", "screenHeight"); +} + +void Config::Configuration::setScreenHeight(u32 height) { + setValue("General", "screenHeight", height); +} + +bool Config::Configuration::nullGpu() { + return getValue("General", "nullGpu"); +} + +void Config::Configuration::setNullGpu(bool enable) { + setValue("General", "nullGpu", enable); +} + +bool Config::Configuration::copyGPUCmdBuffers() { + return getValue("General", "copyGPUBuffers"); +} + +void Config::Configuration::setCopyGPUCmdBuffers(bool enable) { + setValue("General", "copyGPUBuffers", enable); +} + +bool Config::Configuration::dumpShaders() { + return getValue("General", "dumpShaders"); +} + +void Config::Configuration::setDumpShaders(bool enable) { + setValue("General", "dumpShader", enable); +} + +bool Config::Configuration::dumpPM4() { + return getValue("General", "dumpPM4"); +} + +void Config::Configuration::setDumpPM4(bool enable) { + setValue("General", "dumpPM4", enable); +} + +u32 Config::Configuration::vblankDiv() { + return getValue("General", "vblankDivider"); +} + +void Config::Configuration::setVblankDiv(u32 value) { + setValue("General", "vblankDivider", value); +} + +s32 Config::Configuration::getGpuId() { + return getValue("Vulkan", "gpuId"); +} + +void Config::Configuration::setGpuId(s32 selectedGpuId) { + setValue("Vulkan", "gpuId", selectedGpuId); +} + +bool Config::Configuration::vkValidationEnabled() { + return getValue("Vulkan", "validation"); +} + +void Config::Configuration::setVkValidation(bool enable) { + setValue("Vulkan", "validation", enable); +} + +bool Config::Configuration::vkValidationSyncEnabled() { + return getValue("Vulkan", "validationSync"); +} + +void Config::Configuration::setVkSyncValidation(bool enable) { + setValue("Vulkan", "validationSync", enable); +} + +bool Config::Configuration::vkValidationGpuEnabled() { + return getValue("Vulkan", "validationGpu"); +} + +void Config::Configuration::setVkValidationGpuEnabled(bool enable) { + setValue("Vulkan", "validationGpu", enable); +} + +bool Config::Configuration::isRdocEnabled() { + return getValue("Vulkan", "rdocEnable"); +} + +void Config::Configuration::setRdocEnabled(bool enable) { + setValue("Vulkan", "rdocEnable", enable); +} + +bool Config::Configuration::vkMarkersEnabled() { + return getValue("Vulkan", "vkMarkersEnabled"); +} + +void Config::Configuration::setVkMarkersEnabled(bool enable) { + setValue("Vulkan", "rdocMarkersEnable", enable); +} + +bool Config::Configuration::debugDump() { + return getValue("Vulkan", "debugDump"); +} + +void Config::Configuration::setDebugDump(bool enable) { + setValue("Vulkan", "debugDump", enable); +} + +bool Config::Configuration::vkCrashDiagnostic() { + return getValue("Vulkan", "crashDiagnostic"); +} + +void Config::Configuration::setVkCrashDiagnostic(bool enable) { + setValue("Vulkan", "crashDiagnostic", enable); +} + +u32 Config::Configuration::getMainWindowTheme() { + return getValue("GUI", "theme"); +} + +void Config::Configuration::setMainWindowTheme(u32 theme) { + setValue("GUI", "theme", theme); +} + +u32 Config::Configuration::getIconSize() { + return getValue("GUI", "iconSize"); +} + +void Config::Configuration::setIconSize(u32 size) { + setValue("GUI", "iconSize", size); +} + +u32 Config::Configuration::getIconSizeGrid() { + return getValue("GUI", "iconSizeGrid"); +} + +void Config::Configuration::setIconSizeGrid(u32 size) { + setValue("GUI", "iconSizeGrid", size); +} + +u32 Config::Configuration::getSliderPosition() { + return getValue("GUI", "sliderPos"); +} + +void Config::Configuration::setSliderPosition(u32 pos) { + setValue("GUI", "sliderPos", pos); +} + +u32 Config::Configuration::getSliderPositionGrid() { + return getValue("GUI", "sliderPosGrid"); +} + +void Config::Configuration::setSliderPositionGrid(u32 pos) { + setValue("GUI", "sliderPosGrid", pos); +} + +u32 Config::Configuration::getTableMode() { + return getValue("GUI", "gameTableMode"); +} + +void Config::Configuration::setTableMode(u32 mode) { + setValue("GUI", "gameTableMode", mode); +} + +u32 Config::Configuration::getMainWindowWidth() { + return getValue("GUI", "mwWidth"); +} + +void Config::Configuration::setMainWindowWidth(u32 width) { + setValue("GUI", "mwWidth", width); +} + +u32 Config::Configuration::getMainWindowHeight() { + return getValue("GUI", "mwHeight"); +} + +void Config::Configuration::setMainWindowHeight(u32 height) { + setValue("GUI", "mwHeight", height); +} + +std::string Config::Configuration::getGameInstallDir() { + return getValue("GUI", "installDir"); +} + +void Config::Configuration::setGameInstallDir(const std::string& dir) { + setValue("GUI", "installDir", dir); +} + +u32 Config::Configuration::getMainWindowGeometryX() { + return getValue("GUI", "geometryX"); +} + +u32 Config::Configuration::getMainWindowGeometryY() { + return getValue("GUI", "geometryY"); +} + +u32 Config::Configuration::getMainWindowGeometryW() { + return getValue("GUI", "geometryW"); +} + +u32 Config::Configuration::getMainWindowGeometryH() { + return getValue("GUI", "geometryH"); +} + +void Config::Configuration::setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) { + setValue("GUI", "geometryX", x); + setValue("GUI", "geometryY", y); + setValue("GUI", "geometryW", w); + setValue("GUI", "geometryH", h); +} + +std::vector Config::Configuration::getPkgViewer() { + if (!data.contains("GUI")) + return std::vector(); + + auto& gui = data["GUI"]; + + return toml::find_or>(gui, "pkgDirs", {}); +} + +void Config::Configuration::setPkgViewer(const std::vector& pkgList) { + data["GUI"]["pkgDirs"] = pkgList; +} + +std::vector Config::Configuration::getElfViewer() { + if (!data.contains("GUI")) + return std::vector(); + + auto& gui = data["GUI"]; + + return toml::find_or>(gui, "elfDirs", {}); +} + +void Config::Configuration::setElfViewer(const std::vector& elfList) { + data["GUI"]["elfDirs"] = elfList; +} + +std::vector Config::Configuration::getRecentFiles() { + if (!data.contains("GUI")) + return std::vector(); + + auto& gui = data["GUI"]; + + return toml::find_or>(gui, "recentFiles", {}); +} + +void Config::Configuration::setRecentFiles(const std::vector& recentFiles) { + data["GUI"]["recentFiles"] = recentFiles; +} + +std::string Config::Configuration::getEmulatorLanguage() { + return getValue("GUI", "emulatorLanguage"); +} + +void Config::Configuration::setEmulatorLanguage(std::string language) { + setValue("GUI", "emulatorLanguage", language); +} + +u32 Config::Configuration::getConsoleLanguage() { + return getValue("Settings", "consoleLanauge"); +} + +void Config::Configuration::setLanguage(u32 language) { + setValue("Settings", "consoleLanauge", language); +} + +void Config::Configuration::setDefaultValues() { + data = toml::table(c_defaultConfig); +} + +void Config::load(const std::filesystem::path& path) { + const auto configManager = Common::Singleton::Instance(); + configManager->loadConfigurations(); +} + +void Config::save(const std::filesystem::path& path) { + fmt::print("TODO: IMPLEMENT SAVE IN CONFIG MANAGER\n"); +} + +bool Config::isNeoMode() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->isNeoMode(); +} + +bool Config::isFullscreenMode() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->isFullscreenMode(); +} + +std::string Config::getLogFilter() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::string(); + + return config->getLogFilter(); +} + +std::string Config::getLogType() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::string(); + + return config->getLogType(); +} + +std::string Config::getUserName() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::string(); + + return config->getUserName(); +} + +bool Config::getUseSpecialPad() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->getUseSpecialPad(); +} + +int Config::getSpecialPadClass() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getSpecialPadClass(); +} + +u32 Config::getScreenWidth() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getScreenWidth(); +} + +u32 Config::getScreenHeight() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getScreenHeight(); +} + +s32 Config::getGpuId() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return -1; + + return config->getGpuId(); +} + +bool Config::debugDump() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->debugDump(); +} + +bool Config::showSplash() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->showSplash(); +} + +bool Config::nullGpu() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->nullGpu(); +} + +bool Config::copyGPUCmdBuffers() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->copyGPUCmdBuffers(); +} + +bool Config::dumpShaders() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->dumpShaders(); +} + +bool Config::dumpPM4() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->dumpPM4(); +} + +bool Config::isRdocEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->isRdocEnabled(); +} + +bool Config::vkMarkersEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkMarkersEnabled(); +} + +bool Config::vkCrashDiagnosticEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkCrashDiagnostic(); +} + +u32 Config::vblankDiv() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->vblankDiv(); +} + +void Config::setDebugDump(bool enable) {} + +void Config::setShowSplash(bool enable) {} + +void Config::setNullGpu(bool enable) {} + +void Config::setCopyGPUCmdBuffers(bool enable) {} + +void Config::setDumpShaders(bool enable) {} + +void Config::setDumpPM4(bool enable) {} + +void Config::setVblankDiv(u32 value) {} + +void Config::setGpuId(s32 selectedGpuId) {} + +void Config::setScreenWidth(u32 width) {} + +void Config::setScreenHeight(u32 height) {} + +void Config::setFullscreenMode(bool enable) {} + +void Config::setLanguage(u32 language) {} + +void Config::setNeoMode(bool enable) {} + +void Config::setUserName(const std::string& type) {} + +void Config::setUseSpecialPad(bool use) {} + +void Config::setSpecialPadClass(int type) {} + +void Config::setLogType(const std::string& type) {} + +void Config::setLogFilter(const std::string& type) {} + +void Config::setVkValidation(bool enable) {} + +void Config::setVkSyncValidation(bool enable) {} + +void Config::setRdocEnabled(bool enable) {} + +bool Config::vkValidationEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkValidationEnabled(); +} + +bool Config::vkValidationSyncEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkValidationSyncEnabled(); +} + +bool Config::vkValidationGpuEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkValidationGpuEnabled(); +} + +void Config::setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {} + +void Config::setGameInstallDir(const std::string& dir) {} + +void Config::setMainWindowTheme(u32 theme) {} + +void Config::setIconSize(u32 size) {} + +void Config::setIconSizeGrid(u32 size) {} + +void Config::setSliderPosition(u32 pos) {} + +void Config::setSliderPositionGrid(u32 pos) {} + +void Config::setTableMode(u32 mode) {} + +void Config::setMainWindowWidth(u32 width) {} + +void Config::setMainWindowHeight(u32 height) {} + +void Config::setPkgViewer(const std::vector& pkgList) {} + +void Config::setElfViewer(const std::vector& elfList) {} + +void Config::setRecentFiles(const std::vector& recentFiles) {} + +void Config::setEmulatorLanguage(std::string language) {} + +u32 Config::getMainWindowGeometryX() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getMainWindowGeometryX(); +} + +u32 Config::getMainWindowGeometryY() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getMainWindowGeometryY(); +} + +u32 Config::getMainWindowGeometryW() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getMainWindowGeometryW(); +} + +u32 Config::getMainWindowGeometryH() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getMainWindowGeometryH(); +} + +std::string Config::getGameInstallDir() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::string(); + + return config->getGameInstallDir(); +} + +u32 Config::getMainWindowTheme() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getMainWindowTheme(); +} + +u32 Config::getIconSize() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getIconSize(); +} + +u32 Config::getIconSizeGrid() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getIconSizeGrid(); +} + +u32 Config::getSliderPosition() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getSliderPosition(); +} + +u32 Config::getSliderPositionGrid() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getSliderPositionGrid(); +} + +u32 Config::getTableMode() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getTableMode(); +} + +u32 Config::getMainWindowWidth() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->getMainWindowWidth(); +} + +u32 Config::getMainWindowHeight() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getMainWindowHeight(); +} + +std::vector Config::getPkgViewer() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::vector(); + + return config->getPkgViewer(); +} + +std::vector Config::getElfViewer() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::vector(); + + return config->getElfViewer(); +} + +std::vector Config::getRecentFiles() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::vector(); + + return config->getRecentFiles(); +} + +std::string Config::getEmulatorLanguage() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return std::string(); + + return config->getEmulatorLanguage(); +} + +void Config::setDefaultValues() {} + +u32 Config::GetLanguage() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return 0; + + return config->getConsoleLanguage(); +} + +bool vkMarkersEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkMarkersEnabled() || config->vkCrashDiagnostic(); +} + +bool vkCrashDiagnosticEnabled() { + const auto configManager = Common::Singleton::Instance(); + auto config = configManager->getCurrentConfig(); + if (!config) + return false; + + return config->vkCrashDiagnostic(); +} \ No newline at end of file diff --git a/src/common/config.h b/src/common/config.h index 7e717fe71..9a132bc14 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -2,12 +2,334 @@ // SPDX-License-Identifier: GPL-2.0-or-later #pragma once - +#include +#include #include +#include +#include +#include #include -#include "types.h" + +#include +#include + +#include "common/path_util.h" + +#define u32 uint32_t +#define s32 int32_t namespace Config { +// Name of the global configuration +static std::string c_globalTitleId = "config"; +static std::string c_configExtension = ".toml"; + +class Configuration; + +class ConfigManager { +private: + // This is the map of title id <-> configuraation + std::map> configurations; + std::string currentTitleId = c_globalTitleId; + + // ConfigManager() = default; + // virtual ~ConfigManager() = default; + +public: + void loadConfigurations(); + + void setCurrentConfigId(std::string titleId); + + void setDefaultConfigId(); + + const std::string getCurrentConfigId(); + + std::shared_ptr getCurrentConfig(); +}; + +class Configuration { +private: + const toml::table c_defaultConfig = { + {"titleId", c_globalTitleId}, + {"General", + toml::table{ + {"isPS4Pro", false}, + {"Fullscreen", false}, + {"logFilter", ""}, + {"logType", "async"}, + {"userName", "shadPS4"}, + {"showSplash", false}, + {"useSpecialPad", false}, + {"specialPadClass", 1}, + {"screenWidth", 1280}, + {"screenHeight", 720}, + {"nullGpu", false}, + {"copyGPUBuffers", false}, + {"dumpShaders", false}, + {"dumpPM4", false}, + {"vblankDivider", 1}, + }}, + { + "Vulkan", + toml::table{ + {"gpuId", (-1)}, + {"validation", false}, + {"validationSync", false}, // Breaking change + {"validationGpu", false}, // Breaking change + {"rdocEnable", false}, + {"rdocMarkersEnable", false}, + {"debugDump", false}, // Breaking change + {"crashDiagnostic", false}, + }, + }, + { + "GUI", + toml::table{{"theme", 0}, + {"iconSize", 36}, + {"iconSizeGrid", 69}, + {"sliderPos", 0}, + {"sliderPosGrid", 0}, + {"gameTableMode", 0}, + {"mwWidth", 1280}, // Breaking change + {"mwHeight", 720}, // Breaking change + {"installDir", ""}, + {"geometryX", 400}, // Breaking change + {"geometryY", 400}, // Breaking change + {"geometryW", 1280}, // Breaking change + {"geometryH", 720}, // Breaking change + {"pkgDirs", toml::array{}}, + {"elfDirs", toml::array{}}, + {"recentFiles", toml::array{}}, + {"emulatorLanguage", "en"}}, + }, + { + "Settings", + toml::table{{"consoleLanguage", 1}}, + }, + }; + +protected: + // Title id of the game, or "global" for global settings + std::string titleId; + + // Toml data, do not modify this directly + toml::value data; + +public: + /// + /// Create a new configuration with defaults + /// + Configuration(); + + /// + /// Load configuration from file path + /// + /// Path of configuration file + Configuration(const std::filesystem::path& path); + + /// + /// Loads a configuration from file path + /// + /// Path of configuration file + void load(const std::filesystem::path& path); + + /// + /// Saves a configuration to file path + /// + /// Path of configuration file + void save(const std::filesystem::path& path); + + /// + /// This function will iterate through all of the section and entries in the default + /// configuration + /// + /// It will check to make sure that all of the categories, and keys match in both name and type + /// + /// Path of configuration file to check + /// True if there is a structural difference in config files, false if no + /// difference + bool configVersionDifference(const std::filesystem::path& path); + + template + T getValue(const char* category, const char* key) { + // Debug logging for profiling + fmt::print("DBG: getValue ({}) ({})\n", category, key); + + if (!c_defaultConfig.contains(category)) + return T(); + + const toml::value& defaultGeneral = c_defaultConfig.at(category); + + auto defaultValue = toml::find_or(defaultGeneral, key, T()); + + if (data.contains(category)) { + const toml::value& general = data.at(category); + + return toml::find_or(general, key, defaultValue); + } + + return T(); + } + + template + void setValue(const char* category, const char* key, T value) { + if (!data.contains(category)) + return; + + auto& dataCategory = data[category]; + + if (!dataCategory.contains(key)) + return; + + data[category][key] = value; + } + + /* + * Alright, making some changes here, first is keeping the + * default config and the C++ functions in the same order + */ + + const std::string& getTitleId() const; + +#pragma region General settings + bool isNeoMode(); + void setNeoMode(bool enable); + + bool isFullscreenMode(); + void setFullscreenMode(bool enable); + + std::string getLogFilter(); + void setLogFilter(const std::string& type); + + std::string getLogType(); + void setLogType(const std::string& type); + + std::string getUserName(); + void setUserName(const std::string& type); + + bool showSplash(); + void setShowSplash(bool enable); + + bool getUseSpecialPad(); + void setUseSpecialPad(bool use); + + int getSpecialPadClass(); + void setSpecialPadClass(int type); + + u32 getScreenWidth(); + void setScreenWidth(u32 width); + + u32 getScreenHeight(); + void setScreenHeight(u32 height); + + bool nullGpu(); + void setNullGpu(bool enable); + + bool copyGPUCmdBuffers(); + void setCopyGPUCmdBuffers(bool enable); + + bool dumpShaders(); + void setDumpShaders(bool enable); + + bool dumpPM4(); + void setDumpPM4(bool enable); + + u32 vblankDiv(); + void setVblankDiv(u32 value); + +#pragma endregion + +#pragma region Vulkan settings + s32 getGpuId(); + void setGpuId(s32 selectedGpuId); + + bool vkValidationEnabled(); + void setVkValidation(bool enable); + + bool vkValidationSyncEnabled(); + void setVkSyncValidation(bool enable); + + bool vkValidationGpuEnabled(); + void setVkValidationGpuEnabled(bool enable); + + bool isRdocEnabled(); + void setRdocEnabled(bool enable); + + bool vkMarkersEnabled(); + void setVkMarkersEnabled(bool enable); + + bool debugDump(); + void setDebugDump(bool enable); + + bool vkCrashDiagnostic(); + void setVkCrashDiagnostic(bool enable); +#pragma endregion + +#pragma region GUI settings + u32 getMainWindowTheme(); + void setMainWindowTheme(u32 theme); + + u32 getIconSize(); + void setIconSize(u32 size); + + u32 getIconSizeGrid(); + void setIconSizeGrid(u32 size); + + u32 getSliderPosition(); + void setSliderPosition(u32 pos); + + u32 getSliderPositionGrid(); + void setSliderPositionGrid(u32 pos); + + u32 getTableMode(); + void setTableMode(u32 mode); + + u32 getMainWindowWidth(); + void setMainWindowWidth(u32 width); + + u32 getMainWindowHeight(); + void setMainWindowHeight(u32 height); + + std::string getGameInstallDir(); + void setGameInstallDir(const std::string& dir); + + u32 getMainWindowGeometryX(); + u32 getMainWindowGeometryY(); + u32 getMainWindowGeometryW(); + u32 getMainWindowGeometryH(); + void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h); + + std::vector getPkgViewer(); + void setPkgViewer(const std::vector& pkgList); + + std::vector getElfViewer(); + void setElfViewer(const std::vector& elfList); + + std::vector getRecentFiles(); + void setRecentFiles(const std::vector& recentFiles); + + std::string getEmulatorLanguage(); + void setEmulatorLanguage(std::string language); +#pragma endregion + +#pragma region Console settings + u32 getConsoleLanguage(); + void setLanguage(u32 language); +#pragma endregion + + /// + /// Sets the data to the default values + /// + void setDefaultValues(); +}; + +/* + * ============================================================ + * THIS IS TO TEST FUNCTIONALITY, EVENTUALLY NUKE BELOW + * + * NOTE: For all of these should fall back on defaults in event config + * manager is busted for whatever reason (which should not happen) + * ============================================================ + */ void load(const std::filesystem::path& path); void save(const std::filesystem::path& path); @@ -31,6 +353,8 @@ bool copyGPUCmdBuffers(); bool dumpShaders(); bool dumpPM4(); bool isRdocEnabled(); +bool vkMarkersEnabled(); +bool vkCrashDiagnosticEnabled(); u32 vblankDiv(); void setDebugDump(bool enable); @@ -61,8 +385,6 @@ void setRdocEnabled(bool enable); bool vkValidationEnabled(); bool vkValidationSyncEnabled(); bool vkValidationGpuEnabled(); -bool vkMarkersEnabled(); -bool vkCrashDiagnosticEnabled(); // Gui void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h); @@ -102,4 +424,4 @@ void setDefaultValues(); // settings u32 GetLanguage(); -}; // namespace Config +} // namespace Config \ No newline at end of file diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp index cce12ebcf..5b4fc30e3 100644 --- a/src/common/path_util.cpp +++ b/src/common/path_util.cpp @@ -117,6 +117,7 @@ static auto UserPaths = [] { create_path(PathType::PatchesDir, user_dir / PATCHES_DIR); create_path(PathType::AddonsDir, user_dir / ADDONS_DIR); create_path(PathType::MetaDataDir, user_dir / METADATA_DIR); + create_path(PathType::ConfigsDir, user_dir / CONFIGS_DIR); return paths; }(); diff --git a/src/common/path_util.h b/src/common/path_util.h index 623b285ed..378927a20 100644 --- a/src/common/path_util.h +++ b/src/common/path_util.h @@ -24,6 +24,7 @@ enum class PathType { PatchesDir, // Where patches are stored. AddonsDir, // Where additional content is stored. MetaDataDir, // Where game metadata (e.g. trophies and menu backgrounds) is stored. + ConfigsDir, // Where configuration files are stored. }; constexpr auto PORTABLE_DIR = "user"; @@ -42,7 +43,6 @@ constexpr auto CAPTURES_DIR = "captures"; constexpr auto CHEATS_DIR = "cheats"; constexpr auto PATCHES_DIR = "patches"; constexpr auto ADDONS_DIR = "addcont"; -constexpr auto METADATA_DIR = "game_data"; // Filenames constexpr auto LOG_FILE = "shad_log.txt"; diff --git a/src/emulator.cpp b/src/emulator.cpp index a469a31ce..8e073eb46 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -38,8 +38,8 @@ namespace Core { Emulator::Emulator() { // Read configuration file. - const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); - Config::load(config_dir / "config.toml"); + const auto configs_dir = Common::FS::GetUserPath(Common::FS::PathType::ConfigsDir); + Config::load(configs_dir / "config.toml"); // Initialize NT API functions #ifdef _WIN32 @@ -77,8 +77,8 @@ Emulator::Emulator() { } Emulator::~Emulator() { - const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); - Config::save(config_dir / "config.toml"); + const auto configs_dir = Common::FS::GetUserPath(Common::FS::PathType::ConfigsDir); + Config::save(configs_dir / "config.toml"); } void Emulator::Run(const std::filesystem::path& file) { diff --git a/src/qt_gui/main.cpp b/src/qt_gui/main.cpp index abbf6dcb6..c1af4c126 100644 --- a/src/qt_gui/main.cpp +++ b/src/qt_gui/main.cpp @@ -15,7 +15,9 @@ int main(int argc, char* argv[]) { // Load configurations and initialize Qt application const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); - Config::load(user_dir / "config.toml"); + const auto configs_dir = Common::FS::GetUserPath(Common::FS::PathType::ConfigsDir); + Config::load(configs_dir / "config.toml"); + std::filesystem::create_directory(user_dir / "game_data"); // Check if elf or eboot.bin path was passed as a command line argument bool has_command_line_argument = argc > 1;