pcsx2/pcsx2/USB/configuration.cpp

280 lines
6.6 KiB
C++

/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "deviceproxy.h"
#include "configuration.h"
#include "shared/inifile_usb.h"
#include "platcompat.h"
#include "Config.h"
#include <map>
#include <vector>
std::map<std::pair<int, std::string>, std::string> changedAPIs;
std::map<std::pair<int, std::string>, int> changedSubtype;
wxString iniFileUSB(L"USB.ini");
static TSTDSTRING usb_path;
TSTDSTRING IniPath; // default path, just in case
TSTDSTRING LogDir;
CIniFile ciniFile;
bool USBpathSet = false;
void USBsetSettingsDir()
{
if(!USBpathSet)
{
#ifdef _WIN32
IniPath = EmuFolders::Settings.Combine( iniFileUSB ).GetFullPath(); // default path, just in case
#else
IniPath = std::string(EmuFolders::Settings.Combine( iniFileUSB ).GetFullPath()); // default path, just in case
#endif
USBpathSet = true;
}
}
void USBsetLogDir(const char* dir)
{
#ifdef _WIN32
LogDir = str_to_wstr(dir);
#else
LogDir = dir;
#endif
}
std::string GetSelectedAPI(const std::pair<int, std::string>& pair)
{
USBsetSettingsDir();
auto it = changedAPIs.find(pair);
if (it != changedAPIs.end())
return it->second;
return std::string();
}
int GetSelectedSubtype(const std::pair<int, std::string>& pair)
{
auto it = changedSubtype.find(pair);
if (it != changedSubtype.end())
return it->second;
return 0;
}
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, TSTDSTRING& value)
{
USBsetSettingsDir();
CIniKey* key;
#ifdef _WIN32
auto sect = ciniFile.GetSection(section);
if (sect && (key = sect->GetKey(param)))
{
value = key->GetValue();
return true;
}
#else
auto sect = ciniFile.GetSection(str_to_wstr(section));
if (sect && (key = sect->GetKey(str_to_wstr(param))))
{
value = wstr_to_str(key->GetValue());
return true;
}
#endif
return false;
}
bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t& value)
{
USBsetSettingsDir();
CIniKey* key;
#ifdef _WIN32
auto sect = ciniFile.GetSection(section);
if (sect && (key = sect->GetKey(param)))
{
try
{
value = std::stoi(key->GetValue());
return true;
}
#else
auto sect = ciniFile.GetSection(str_to_wstr(section));
if (sect && (key = sect->GetKey(str_to_wstr(param))))
{
try
{
value = std::stoi(key->GetValue());
return true;
}
#endif
catch (std::exception& err)
{
DevCon.WriteLn("%s\n", err.what());
}
}
return false;
}
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, const TSTDSTRING& value)
{
USBsetSettingsDir();
#ifdef _WIN32
ciniFile.SetKeyValue(section, param, value);
#else
ciniFile.SetKeyValue(str_to_wstr(section), str_to_wstr(param), str_to_wstr(value));
#endif
return true;
}
bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TCHAR* param, int32_t value)
{
USBsetSettingsDir();
#ifdef _WIN32
ciniFile.SetKeyValue(section, param, TSTDTOSTRING(value));
#else
ciniFile.SetKeyValue(str_to_wstr(section), str_to_wstr(param), str_to_wstr(TSTDTOSTRING(value)));
#endif
return true;
}
void SaveConfig()
{
USBsetSettingsDir();
#ifdef _WIN32
SaveSetting(L"MAIN", L"log", conf.Log);
#else
SaveSetting("MAIN", "log", conf.Log);
#endif
#ifdef _WIN32
SaveSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, str_to_wstr(conf.Port[0]));
SaveSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, str_to_wstr(conf.Port[1]));
#else
SaveSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, conf.Port[0]);
SaveSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, conf.Port[1]);
#endif
for (auto& k : changedAPIs)
{
#ifdef _WIN32
SaveSetting(nullptr, k.first.first, k.first.second, N_DEVICE_API, str_to_wstr(k.second));
#else
SaveSetting(nullptr, k.first.first, k.first.second, N_DEVICE_API, k.second);
#endif
}
for (auto& k : changedSubtype)
{
SaveSetting(nullptr, k.first.first, k.first.second, N_DEV_SUBTYPE, k.second);
}
#ifdef _WIN32
bool ret = ciniFile.Save(IniPath);
#else
[[maybe_unused]]bool ret = ciniFile.Save(str_to_wstr(IniPath));
#endif
}
void LoadConfig()
{
USBsetSettingsDir();
static bool loaded = false;
if (loaded)
return;
loaded = true;
#ifdef _WIN32
ciniFile.Load(IniPath);
LoadSetting(L"MAIN", L"log", conf.Log);
#else
ciniFile.Load(str_to_wstr(IniPath));
LoadSetting("MAIN", "log", conf.Log);
#endif
#ifdef _WIN32
std::wstring tmp;
LoadSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, tmp);
conf.Port[0] = wstr_to_str(tmp);
LoadSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, tmp);
conf.Port[1] = wstr_to_str(tmp);
#else
LoadSetting(nullptr, 0, N_DEVICE_PORT, N_DEVICE, conf.Port[0]);
LoadSetting(nullptr, 1, N_DEVICE_PORT, N_DEVICE, conf.Port[1]);
#endif
auto& instance = RegisterDevice::instance();
for (int i = 0; i < 2; i++)
{
std::string api;
#ifdef _WIN32
LoadSetting(nullptr, i, conf.Port[i], N_DEVICE_API, tmp);
api = wstr_to_str(tmp);
#else
LoadSetting(nullptr, i, conf.Port[i], N_DEVICE_API, api);
#endif
auto dev = instance.Device(conf.Port[i]);
if (dev)
{
if (!dev->IsValidAPI(api))
{
api = "<invalid>";
const auto& apis = dev->ListAPIs();
if (!apis.empty())
api = *apis.begin();
}
}
if (api.size())
changedAPIs[std::make_pair(i, conf.Port[i])] = api;
int subtype = 0;
LoadSetting(nullptr, i, conf.Port[i], N_DEV_SUBTYPE, subtype);
changedSubtype[std::make_pair(i, conf.Port[i])] = subtype;
}
}
void ClearSection(const TCHAR* section)
{
USBsetSettingsDir();
#ifdef _WIN32
auto s = ciniFile.GetSection(section);
#else
auto s = ciniFile.GetSection(str_to_wstr(section));
#endif
if (s)
{
s->RemoveAllKeys();
}
}
void RemoveSection(const char* dev_type, int port, const std::string& key)
{
USBsetSettingsDir();
TSTDSTRING tkey;
tkey.assign(key.begin(), key.end());
TSTDSTRINGSTREAM section;
if (dev_type)
section << dev_type << TEXT(" ");
section << tkey << TEXT(" ") << port;
TSTDSTRING str = section.str();
#ifdef _WIN32
ciniFile.RemoveSection(section.str());
#else
ciniFile.RemoveSection(str_to_wstr(section.str()));
#endif
}