2012-11-15 00:39:56 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Ini.h"
|
|
|
|
|
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Utilities/StrFmt.h"
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cctype>
|
2014-07-08 22:33:57 +02:00
|
|
|
#include <regex>
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
#define DEF_CONFIG_NAME "./rpcs3.ini"
|
|
|
|
|
|
|
|
|
|
CSimpleIniCaseA *getIniFile()
|
|
|
|
|
{
|
|
|
|
|
static bool inited = false;
|
|
|
|
|
static CSimpleIniCaseA ini;
|
|
|
|
|
if (inited == false)
|
|
|
|
|
{
|
|
|
|
|
ini.SetUnicode(true);
|
|
|
|
|
ini.LoadFile(DEF_CONFIG_NAME);
|
|
|
|
|
inited = true;
|
|
|
|
|
}
|
|
|
|
|
return &ini;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void saveIniFile()
|
|
|
|
|
{
|
|
|
|
|
getIniFile()->SaveFile(DEF_CONFIG_NAME);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<int, int> rDefaultSize = { -1, -1 };
|
2014-07-08 22:33:57 +02:00
|
|
|
std::pair<long, long> rDefaultPosition = { -1, -1 };
|
2012-11-15 00:39:56 +01:00
|
|
|
Inis Ini;
|
|
|
|
|
|
2014-07-08 22:33:57 +02:00
|
|
|
static bool StringToBool(const std::string& str)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-07-08 22:33:57 +02:00
|
|
|
return std::regex_match(str.begin(), str.end(),
|
|
|
|
|
std::regex("1|e|t|enable|true", std::regex_constants::icase));
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-08 22:33:57 +02:00
|
|
|
static inline std::string BoolToString(const bool b)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-07-08 22:33:57 +02:00
|
|
|
return b ? "true" : "false";
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
//takes a string of format "[number]x[number]" and returns a pair of ints
|
|
|
|
|
//example input would be "123x456" and the returned value would be {123,456}
|
|
|
|
|
static std::pair<int, int> StringToSize(const std::string& str)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
std::pair<int, int> ret;
|
2014-07-09 21:16:17 +02:00
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
std::string s[2] = { "", "" };
|
|
|
|
|
|
|
|
|
|
for (uint i = 0, a = 0; i<str.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!fmt::CmpNoCase(str.substr(i, 1), "x"))
|
|
|
|
|
{
|
|
|
|
|
if (++a >= 2) return rDefaultSize;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s[a] += str.substr(i, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s[0].empty() || s[1].empty())
|
|
|
|
|
#else
|
|
|
|
|
// Requires GCC 4.9 or new stdlib for Clang
|
2014-07-08 22:33:57 +02:00
|
|
|
std::sregex_token_iterator first(str.begin(), str.end(), std::regex("x"), -1), last;
|
2014-07-09 21:16:17 +02:00
|
|
|
std::vector<std::string> s(first, last);
|
2014-07-08 22:33:57 +02:00
|
|
|
if (vec.size() < 2)
|
2014-07-09 21:16:17 +02:00
|
|
|
#endif
|
2014-06-01 22:57:50 +02:00
|
|
|
return rDefaultSize;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-07-08 22:33:57 +02:00
|
|
|
try {
|
2014-07-09 21:16:17 +02:00
|
|
|
ret.first = std::stoi(s[0]);
|
|
|
|
|
ret.second = std::stoi(s[1]);
|
2014-06-01 22:57:50 +02:00
|
|
|
}
|
2014-07-08 22:33:57 +02:00
|
|
|
catch (const std::invalid_argument& e) {
|
2014-06-01 22:57:50 +02:00
|
|
|
return rDefaultSize;
|
|
|
|
|
}
|
2014-07-08 22:33:57 +02:00
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
if (ret.first < 0 || ret.second < 0)
|
|
|
|
|
return rDefaultSize;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
static std::string SizeToString(const std::pair<int, int>& size)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
return fmt::Format("%dx%d", size.first, size.second);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-09 21:16:17 +02:00
|
|
|
// Unused?
|
|
|
|
|
/*static std::pair<long, long> StringToPosition(const std::string& str)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-07-08 22:33:57 +02:00
|
|
|
std::pair<long, long> ret;
|
|
|
|
|
std::sregex_token_iterator first(str.begin(), str.end(), std::regex("x"), -1), last;
|
|
|
|
|
std::vector<std::string> vec(first, last);
|
|
|
|
|
if (vec.size() < 2)
|
|
|
|
|
return rDefaultPosition;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-07-08 22:33:57 +02:00
|
|
|
ret.first = std::strtol(vec.at(0).c_str(), nullptr, 10);
|
|
|
|
|
ret.second = std::strtol(vec.at(1).c_str(), nullptr, 10);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-07-08 22:33:57 +02:00
|
|
|
if (ret.first <= 0 || ret.second <= 0)
|
|
|
|
|
return rDefaultPosition;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
|
|
|
|
return ret;
|
2014-07-09 21:16:17 +02:00
|
|
|
}*/
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
static WindowInfo StringToWindowInfo(const std::string& str)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
WindowInfo ret = WindowInfo(rDefaultSize, rDefaultSize);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-07-09 21:16:17 +02:00
|
|
|
#if 1
|
|
|
|
|
std::string s[4] = { "", "", "", "" };
|
|
|
|
|
|
|
|
|
|
for (uint i = 0, a = 0; i<str.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!fmt::CmpNoCase(str.substr(i, 1), "x") || !fmt::CmpNoCase(str.substr(i, 1), ":"))
|
|
|
|
|
{
|
|
|
|
|
if (++a >= 4) return WindowInfo::GetDefault();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s[a] += str.substr(i, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s[0].empty() || s[1].empty() || s[2].empty() || s[3].empty())
|
|
|
|
|
#else
|
|
|
|
|
// Requires GCC 4.9 or new stdlib for Clang
|
2014-07-08 22:33:57 +02:00
|
|
|
std::sregex_token_iterator first(str.begin(), str.end(), std::regex("x|:"), -1), last;
|
2014-07-09 21:16:17 +02:00
|
|
|
std::vector<std::string> s(first, last);
|
2014-07-08 22:33:57 +02:00
|
|
|
if (vec.size() < 4)
|
2014-07-09 21:16:17 +02:00
|
|
|
#endif
|
2012-11-15 00:39:56 +01:00
|
|
|
return WindowInfo::GetDefault();
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
try{
|
2014-07-09 21:16:17 +02:00
|
|
|
ret.size.first = std::stoi(s[0]);
|
|
|
|
|
ret.size.second = std::stoi(s[1]);
|
|
|
|
|
ret.position.first = std::stoi(s[2]);
|
|
|
|
|
ret.position.second = std::stoi(s[3]);
|
2014-06-01 22:57:50 +02:00
|
|
|
}
|
|
|
|
|
catch (const std::invalid_argument &e)
|
|
|
|
|
{
|
|
|
|
|
return WindowInfo::GetDefault();
|
|
|
|
|
}
|
|
|
|
|
if (ret.size.first <= 0 || ret.size.second <= 0)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
|
|
|
|
return WindowInfo::GetDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
static std::string WindowInfoToString(const WindowInfo& wind)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
const int px = wind.position.first < -wind.size.first ? -1 : wind.position.first;
|
|
|
|
|
const int py = wind.position.second < -wind.size.second ? -1 : wind.position.second;
|
|
|
|
|
return fmt::Format("%dx%d:%dx%d", wind.size.first, wind.size.second, px, py);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Ini
|
|
|
|
|
Ini::Ini()
|
|
|
|
|
{
|
2014-05-02 08:30:32 +02:00
|
|
|
m_Config = getIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-04-15 16:12:15 +02:00
|
|
|
Ini::~Ini()
|
|
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
//TODO: saving the file after each change seems like overkill but that's how wx did it
|
|
|
|
|
void Ini::Save(const std::string& section, const std::string& key, int value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
m_Config->SetLongValue(section.c_str(), key.c_str(), value);
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
void Ini::Save(const std::string& section, const std::string& key, bool value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
m_Config->SetBoolValue(section.c_str(), key.c_str(), value);
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
void Ini::Save(const std::string& section, const std::string& key, std::pair<int, int> value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
m_Config->SetValue(section.c_str(), key.c_str(), SizeToString(value).c_str());
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
void Ini::Save(const std::string& section, const std::string& key, const std::string& value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
m_Config->SetValue(section.c_str(), key.c_str(), value.c_str());
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
void Ini::Save(const std::string& section, const std::string& key, WindowInfo value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
m_Config->SetValue(section.c_str(), key.c_str(), WindowInfoToString(value).c_str());
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
int Ini::Load(const std::string& section, const std::string& key, const int def_value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
return m_Config->GetLongValue(section.c_str(), key.c_str(), def_value);
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
bool Ini::Load(const std::string& section, const std::string& key, const bool def_value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
return StringToBool(m_Config->GetValue(section.c_str(), key.c_str(), BoolToString(def_value).c_str()));
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
std::pair<int, int> Ini::Load(const std::string& section, const std::string& key, const std::pair<int, int> def_value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
return StringToSize(m_Config->GetValue(section.c_str(), key.c_str(), SizeToString(def_value).c_str()));
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
std::string Ini::Load(const std::string& section, const std::string& key, const std::string& def_value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
return std::string(m_Config->GetValue(section.c_str(), key.c_str(), def_value.c_str()));
|
|
|
|
|
saveIniFile();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 22:57:50 +02:00
|
|
|
WindowInfo Ini::Load(const std::string& section, const std::string& key, const WindowInfo& def_value)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-06-01 22:57:50 +02:00
|
|
|
return StringToWindowInfo(m_Config->GetValue(section.c_str(), key.c_str(), WindowInfoToString(def_value).c_str()));
|
|
|
|
|
saveIniFile();
|
2014-07-08 22:33:57 +02:00
|
|
|
}
|