From d95b1be7c321f366f7becf12b715487f306fa278 Mon Sep 17 00:00:00 2001 From: kiwidoggie Date: Fri, 30 Aug 2024 17:20:07 -0400 Subject: [PATCH] Replace old configuration with new one. TODO: Implement per-game directories TODO: Implement loading multiple configs TODO: Fix build issues --- src/common/config.cpp | 896 ++++++++++++++++++++---------------------- src/common/config.h | 350 +++++++++++++---- 2 files changed, 684 insertions(+), 562 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index 8d87ed3c..64ad3f8d 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -1,513 +1,457 @@ -// 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 rdocMarkersEnable = false; -// 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; +Config::Configuration::Configuration() { + setDefaultValues(); } -bool isFullscreenMode() { - return isFullscreen; +Config::Configuration::Configuration(const std::filesystem::path& path) : Config::Configuration() { + load(path); } -u32 getScreenWidth() { - return screenWidth; -} - -u32 getScreenHeight() { - return screenHeight; -} - -s32 getGpuId() { - return gpuId; -} - -std::string getLogFilter() { - return logFilter; -} - -std::string getLogType() { - return logType; -} - -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 rdocMarkersEnable; -} - -u32 vblankDiv() { - return vblankDivider; -} - -bool vkValidationEnabled() { - return vkValidation; -} - -bool vkValidationSyncEnabled() { - return vkValidationSync; -} - -bool vkValidationGpuEnabled() { - return vkValidationGpu; -} - -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); + std::cerr << "file path (" << path << ") does not exist." << std::endl; 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()); + std::cerr << "got exception: " << ex.what() << std::endl; 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); - rdocMarkersEnable = toml::find_or(vk, "rdocMarkersEnable", 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()); + + std::cout << "saving new configuration file (" << path << ")." << std::endl; } - 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"] = rdocMarkersEnable; - 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; - rdocEnable = 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)) { + std::cerr << "file path (" << path << ") does not exist." << std::endl; + return true; + } + + // Attempt to parse the configuration data + toml::value oldConfigData; + try { + oldConfigData = toml::parse(path); + } catch (std::exception& ex) { + std::cerr << "got exception: " << ex.what() << std::endl; + 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 +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::isMarkersEnabled() { + return getValue("Vulkan", "rdocMarkersEnable"); +} + +void Config::Configuration::setIsMarkersEnabled(bool enable) { + setValue("Vulkan", "rdocMarkersEnable", enable); +} + +bool Config::Configuration::debugDump() { + return getValue("Vulkan", "debugDump"); +} + +void Config::Configuration::setDebugDump(bool enable) { + setValue("Vulkan", "debugDump", 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); +} diff --git a/src/common/config.h b/src/common/config.h index 11e7d882..81f3644b 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -1,104 +1,282 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - #pragma once - +#include +#include #include +#include #include -#include "types.h" + +#include + +#define u32 uint32_t +#define s32 int32_t namespace Config { -void load(const std::filesystem::path& path); -void save(const std::filesystem::path& path); +class Configuration { +private: + const std::string c_globalTitleId = "global"; + const std::string c_configFolderName = "config"; + 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 + }, + }, + { + "GUI", + toml::table{{"theme", 0}, + {"iconSize", 0}, + {"iconSizeGrid", 0}, + {"sliderPos", 0}, + {"sliderPosGrid", 0}, + {"gameTableMode", 0}, + {"mwWidth", 0}, // Breaking change + {"mwHeight", 0}, // Breaking change + {"installDir", ""}, + {"geometryX", 0}, // Breaking change + {"geometryY", 0}, // Breaking change + {"geometryW", 0}, // Breaking change + {"geometryH", 0}, // Breaking change + {"pkgDirs", toml::array{}}, + {"elfDirs", toml::array{}}, + {"recentFiles", toml::array{}}, + {"emulatorLanguage", "en"}}, + }, + { + "Settings", + toml::table{{"consoleLanguage", 1}}, + }, + }; -bool isNeoMode(); -bool isFullscreenMode(); -std::string getLogFilter(); -std::string getLogType(); -std::string getUserName(); +protected: + // Title id of the game, or "global" for global settings + std::string titleId; -bool getUseSpecialPad(); -int getSpecialPadClass(); + // Toml data, do not modify this directly + toml::value data; -u32 getScreenWidth(); -u32 getScreenHeight(); -s32 getGpuId(); +public: + /// + /// Create a new configuration with defaults + /// + Configuration(); -bool debugDump(); -bool showSplash(); -bool nullGpu(); -bool copyGPUCmdBuffers(); -bool dumpShaders(); -bool dumpPM4(); -bool isRdocEnabled(); -bool isMarkersEnabled(); -u32 vblankDiv(); + /// + /// Load configuration from file path + /// + /// Path of configuration file + Configuration(const std::filesystem::path& path); -void setDebugDump(bool enable); -void setShowSplash(bool enable); -void setNullGpu(bool enable); -void setCopyGPUCmdBuffers(bool enable); -void setDumpShaders(bool enable); -void setDumpPM4(bool enable); -void setVblankDiv(u32 value); -void setGpuId(s32 selectedGpuId); -void setScreenWidth(u32 width); -void setScreenHeight(u32 height); -void setFullscreenMode(bool enable); -void setLanguage(u32 language); -void setNeoMode(bool enable); -void setUserName(const std::string& type); + /// + /// Loads a configuration from file path + /// + /// Path of configuration file + void load(const std::filesystem::path& path); -void setUseSpecialPad(bool use); -void setSpecialPadClass(int type); + /// + /// Saves a configuration to file path + /// + /// Path of configuration file + void save(const std::filesystem::path& path); -void setLogType(const std::string& type); -void setLogFilter(const std::string& type); + /// + /// 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); -void setVkValidation(bool enable); -void setVkSyncValidation(bool enable); -void setRdocEnabled(bool enable); + template + T getValue(const char* category, const char* key) { + if (!c_defaultConfig.contains(category)) + return T(); -bool vkValidationEnabled(); -bool vkValidationSyncEnabled(); -bool vkValidationGpuEnabled(); + const toml::value& defaultGeneral = c_defaultConfig.at(category); -// Gui -void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h); -void setGameInstallDir(const std::string& dir); -void setMainWindowTheme(u32 theme); -void setIconSize(u32 size); -void setIconSizeGrid(u32 size); -void setSliderPosition(u32 pos); -void setSliderPositionGrid(u32 pos); -void setTableMode(u32 mode); -void setMainWindowWidth(u32 width); -void setMainWindowHeight(u32 height); -void setPkgViewer(const std::vector& pkgList); -void setElfViewer(const std::vector& elfList); -void setRecentFiles(const std::vector& recentFiles); -void setEmulatorLanguage(std::string language); + auto defaultValue = toml::find_or(defaultGeneral, key, T()); -u32 getMainWindowGeometryX(); -u32 getMainWindowGeometryY(); -u32 getMainWindowGeometryW(); -u32 getMainWindowGeometryH(); -std::string getGameInstallDir(); -u32 getMainWindowTheme(); -u32 getIconSize(); -u32 getIconSizeGrid(); -u32 getSliderPosition(); -u32 getSliderPositionGrid(); -u32 getTableMode(); -u32 getMainWindowWidth(); -u32 getMainWindowHeight(); -std::vector getPkgViewer(); -std::vector getElfViewer(); -std::vector getRecentFiles(); -std::string getEmulatorLanguage(); + if (data.contains(category)) { + const toml::value& general = data.at(category); -void setDefaultValues(); + return toml::find_or(general, key, defaultValue); + } -// settings -u32 GetLanguage(); -}; // namespace Config + 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 + */ + +#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 isMarkersEnabled(); + void setIsMarkersEnabled(bool enable); + + bool debugDump(); + void setDebugDump(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(); +}; +} // namespace Config \ No newline at end of file