From aef0f94dcfd9eb02f21fbd0707b5768cca4daffe Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Sun, 18 Aug 2019 09:35:21 +0100 Subject: [PATCH] gsdx: Use the same ini code on both Windows and Linux Partially replace the Linux ini code so that it: - works on both Windows and Linux - is backwards compatible with older GSdx inis - properly handles UTF-8 ini pathnames Fix an issue with GSdx on Windows not being able to handle non-ASCII ini pathnames. --- plugins/GSdx/GSdx.cpp | 75 +++++++++++++++++++++++++++---------------- plugins/GSdx/GSdx.h | 10 ++---- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/plugins/GSdx/GSdx.cpp b/plugins/GSdx/GSdx.cpp index 46b37bf76c..434e7be355 100644 --- a/plugins/GSdx/GSdx.cpp +++ b/plugins/GSdx/GSdx.cpp @@ -23,6 +23,7 @@ #include "GSdx.h" #include "GS.h" #include "PSX/GPU.h" +#include static void* s_hModule; @@ -117,8 +118,9 @@ bool GSdxApp::LoadResource(int id, std::vector& buff, const char* type) return true; } +#endif -size_t GSdxApp::GetPrivateProfileString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName) +size_t GSdxApp::GetIniString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName) { BuildConfigurationMap(lpFileName); @@ -134,7 +136,7 @@ size_t GSdxApp::GetPrivateProfileString(const char* lpAppName, const char* lpKey return 0; } -bool GSdxApp::WritePrivateProfileString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName) +bool GSdxApp::WriteIniString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName) { BuildConfigurationMap(lpFileName); @@ -143,10 +145,15 @@ bool GSdxApp::WritePrivateProfileString(const char* lpAppName, const char* lpKey m_configuration_map[key] = value; // Save config to a file - FILE* f = fopen(lpFileName, "w"); + FILE* f = px_fopen(lpFileName, "w"); if (f == NULL) return false; // FIXME print a nice message + // Maintain compatibility with GSDumpGUI/old Windows ini. +#ifdef _WIN32 + fprintf(f, "[Settings]\n"); +#endif + for (const auto& entry : m_configuration_map) { // Do not save the inifile key which is not an option if (entry.first.compare("inifile") == 0) continue; @@ -160,7 +167,7 @@ bool GSdxApp::WritePrivateProfileString(const char* lpAppName, const char* lpKey return false; } -int GSdxApp::GetPrivateProfileInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName) +int GSdxApp::GetIniInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName) { BuildConfigurationMap(lpFileName); @@ -172,7 +179,6 @@ int GSdxApp::GetPrivateProfileInt(const char* lpAppName, const char* lpKeyName, } else return atoi(value.c_str()); } -#endif GSdxApp theApp; @@ -469,7 +475,6 @@ void GSdxApp::Init() m_default_configuration["disable_ts_half_bottom"] = "0"; } -#if defined(__unix__) void GSdxApp::ReloadConfig() { if (m_configuration_map.empty()) return; @@ -491,23 +496,39 @@ void GSdxApp::BuildConfigurationMap(const char* lpFileName) m_configuration_map["inifile"] = inifile_value; // Load config from file - char value[256]; - char key[256]; - FILE* f = fopen(lpFileName, "r"); - - if (f == NULL) return; // FIXME print a nice message - - while( fscanf(f, "%255s = %255s\n", key, value) != EOF ) { - std::string key_s(key); - std::string value_s(value); - // Only keep option that have a default value (allow to purge old option of the GSdx.ini) - if (m_default_configuration.find(key_s) != m_default_configuration.end()) - m_configuration_map[key_s] = value_s; - } - - fclose(f); -} +#ifdef _WIN32 + std::ifstream file(convert_utf8_to_utf16(lpFileName)); +#else + std::ifstream file(lpFileName); #endif + if (!file.is_open()) + return; + + std::string line; + while (std::getline(file, line)) { + const auto separator = line.find('='); + if (separator == std::string::npos) + continue; + + std::string key = line.substr(0, separator); + // Trim trailing whitespace + key.erase(key.find_last_not_of(" \r\t") + 1); + + if (key.empty()) + continue; + + // Only keep options that have a default value so older, no longer used + // ini options can be purged. + if (m_default_configuration.find(key) == m_default_configuration.end()) + continue; + + std::string value = line.substr(separator + 1); + // Trim leading whitespace + value.erase(0, value.find_first_not_of(" \r\t")); + + m_configuration_map[key] = value; + } +} void* GSdxApp::GetModuleHandlePtr() { @@ -539,10 +560,10 @@ std::string GSdxApp::GetConfigS(const char* entry) auto def = m_default_configuration.find(entry); if (def != m_default_configuration.end()) { - GetPrivateProfileString(m_section.c_str(), entry, def->second.c_str(), buff, countof(buff), m_ini.c_str()); + GetIniString(m_section.c_str(), entry, def->second.c_str(), buff, countof(buff), m_ini.c_str()); } else { fprintf(stderr, "Option %s doesn't have a default value\n", entry); - GetPrivateProfileString(m_section.c_str(), entry, "", buff, countof(buff), m_ini.c_str()); + GetIniString(m_section.c_str(), entry, "", buff, countof(buff), m_ini.c_str()); } return {buff}; @@ -550,7 +571,7 @@ std::string GSdxApp::GetConfigS(const char* entry) void GSdxApp::SetConfig(const char* entry, const char* value) { - WritePrivateProfileString(m_section.c_str(), entry, value, m_ini.c_str()); + WriteIniString(m_section.c_str(), entry, value, m_ini.c_str()); } int GSdxApp::GetConfigI(const char* entry) @@ -558,10 +579,10 @@ int GSdxApp::GetConfigI(const char* entry) auto def = m_default_configuration.find(entry); if (def != m_default_configuration.end()) { - return GetPrivateProfileInt(m_section.c_str(), entry, std::stoi(def->second), m_ini.c_str()); + return GetIniInt(m_section.c_str(), entry, std::stoi(def->second), m_ini.c_str()); } else { fprintf(stderr, "Option %s doesn't have a default value\n", entry); - return GetPrivateProfileInt(m_section.c_str(), entry, 0, m_ini.c_str()); + return GetIniInt(m_section.c_str(), entry, 0, m_ini.c_str()); } } diff --git a/plugins/GSdx/GSdx.h b/plugins/GSdx/GSdx.h index 93bf10535c..1a1ffc40e9 100644 --- a/plugins/GSdx/GSdx.h +++ b/plugins/GSdx/GSdx.h @@ -29,9 +29,7 @@ class GSdxApp std::string m_ini; std::string m_section; std::map< std::string, std::string > m_default_configuration; -#if defined(__unix__) std::map< std::string, std::string > m_configuration_map; -#endif GSRendererType m_current_renderer_type; public: @@ -44,14 +42,12 @@ public: HMODULE GetModuleHandle() {return (HMODULE)GetModuleHandlePtr();} #endif -#if defined(__unix__) void BuildConfigurationMap(const char* lpFileName); void ReloadConfig(); - size_t GetPrivateProfileString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName); - bool WritePrivateProfileString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName); - int GetPrivateProfileInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName); -#endif + size_t GetIniString(const char* lpAppName, const char* lpKeyName, const char* lpDefault, char* lpReturnedString, size_t nSize, const char* lpFileName); + bool WriteIniString(const char* lpAppName, const char* lpKeyName, const char* pString, const char* lpFileName); + int GetIniInt(const char* lpAppName, const char* lpKeyName, int nDefault, const char* lpFileName); bool LoadResource(int id, std::vector& buff, const char* type = nullptr);