Skip to content
Permalink
Browse files

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.
  • Loading branch information...
turtleli committed Aug 18, 2019
1 parent 476ccf8 commit aef0f94dcfd9eb02f21fbd0707b5768cca4daffe
Showing with 48 additions and 31 deletions.
  1. +45 −24 plugins/GSdx/GSdx.cpp
  2. +3 −7 plugins/GSdx/GSdx.h
@@ -23,6 +23,7 @@
#include "GSdx.h"
#include "GS.h"
#include "PSX/GPU.h"
#include <fstream>

static void* s_hModule;

@@ -117,8 +118,9 @@ bool GSdxApp::LoadResource(int id, std::vector<char>& 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");
#ifdef _WIN32
std::ifstream file(convert_utf8_to_utf16(lpFileName));
#else
std::ifstream file(lpFileName);
#endif
if (!file.is_open())
return;

if (f == NULL) return; // FIXME print a nice message
std::string line;
while (std::getline(file, line)) {
const auto separator = line.find('=');
if (separator == std::string::npos)
continue;

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;
}
std::string key = line.substr(0, separator);
// Trim trailing whitespace
key.erase(key.find_last_not_of(" \r\t") + 1);

fclose(f);
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;
}
}
#endif

void* GSdxApp::GetModuleHandlePtr()
{
@@ -539,29 +560,29 @@ 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};
}

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)
{
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());
}
}

@@ -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 @@ class GSdxApp
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<char>& buff, const char* type = nullptr);

0 comments on commit aef0f94

Please sign in to comment.
You can’t perform that action at this time.