Core: Have user rom settings in Project64.rdb.user

This commit is contained in:
zilmar 2023-01-03 13:08:00 +10:30
parent 80aecdc5e3
commit e0373025ef
11 changed files with 460 additions and 26 deletions

View File

@ -3,7 +3,7 @@
#include <Project64-core/N64System/Enhancement/Enhancement.h>
#include <Project64-core/N64System/N64System.h>
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/Settings/SettingType/SettingsType-GameSetting.h>
#include <Project64-core/Settings/SettingType/SettingsType-Application.h>
const char * CEnhancement::CheatIdent = "Cheat";
const char * CEnhancement::EnhancementIdent = "Enhancement";
@ -23,14 +23,13 @@ static std::string GenerateKeyName(const char * Name, const char * Ident, const
}
class CSettingEnhancementActive :
public CSettingTypeGame
public CSettingTypeApplication
{
public:
CSettingEnhancementActive(const char * Name, const char * Ident, bool Default) :
CSettingTypeGame("", false),
CSettingTypeApplication(g_Settings->LoadStringVal(Game_IniKey).c_str(), GenerateKeyName(Name, Ident, "Active").c_str(), ""),
m_Default(Default)
{
m_KeyNameIdex = GenerateKeyName(Name, Ident, "Active");
}
bool Active()
@ -53,6 +52,11 @@ public:
{
return;
}
stdstr GoodName;
if (g_Settings->LoadStringVal(Rdb_GoodName, GoodName))
{
m_SettingsIniFile->SaveString(SectionName(), "Good Name", GoodName.c_str());
}
m_SettingsIniFile->SaveNumber(SectionName(), m_KeyNameIdex.c_str(), Active ? 1 : 0);
Flush();
}
@ -72,13 +76,12 @@ private:
};
class CSettingEnhancementSelectedOption :
public CSettingTypeGame
public CSettingTypeApplication
{
public:
CSettingEnhancementSelectedOption(const char * Name, const char * Ident) :
CSettingTypeGame("", false)
CSettingTypeApplication(g_Settings->LoadStringVal(Game_IniKey).c_str(), GenerateKeyName(Name, Ident, "Option").c_str(), "")
{
m_KeyNameIdex = GenerateKeyName(Name, Ident, "Option");
}
void SetOption(uint16_t Value)
@ -87,6 +90,11 @@ public:
{
return;
}
stdstr GoodName;
if (g_Settings->LoadStringVal(Rdb_GoodName, GoodName))
{
m_SettingsIniFile->SaveString(SectionName(), "Good Name", GoodName.c_str());
}
Save(0, (uint32_t)Value);
Flush();
}
@ -108,7 +116,7 @@ public:
{
return;
}
CSettingTypeGame::Delete(0);
CSettingTypeApplication::Delete(0);
Flush();
}
};

View File

@ -138,6 +138,7 @@
<ClCompile Include="Settings\SettingType\SettingsType-RDBOnOff.cpp" />
<ClCompile Include="Settings\SettingType\SettingsType-RDBRamSize.cpp" />
<ClCompile Include="Settings\SettingType\SettingsType-RDBSaveChip.cpp" />
<ClCompile Include="Settings\SettingType\SettingsType-RDBUser.cpp" />
<ClCompile Include="Settings\SettingType\SettingsType-RDBYesNo.cpp" />
<ClCompile Include="Settings\SettingType\SettingsType-RelativePath.cpp" />
<ClCompile Include="Settings\SettingType\SettingsType-RomDatabase.cpp" />
@ -278,6 +279,7 @@
<ClInclude Include="Settings\SettingType\SettingsType-TempBool.h" />
<ClInclude Include="Settings\SettingType\SettingsType-TempNumber.h" />
<ClInclude Include="Settings\SettingType\SettingsType-TempString.h" />
<ClInclude Include="Settings\SettingType\SettingsType-RDBUser.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="TraceModulesProject64.h" />
</ItemGroup>

View File

@ -432,6 +432,9 @@
<ClCompile Include="N64System\Recompiler\Aarch64\Aarch64RegInfo.cpp">
<Filter>Source Files\N64 System\Recompiler\Aarch64</Filter>
</ClCompile>
<ClCompile Include="Settings\SettingType\SettingsType-RDBUser.cpp">
<Filter>Source Files\Settings\SettingType</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -818,6 +821,9 @@
<ClInclude Include="N64System\Recompiler\asmjit.h">
<Filter>Header Files\N64 System\Recompiler</Filter>
</ClInclude>
<ClInclude Include="Settings\SettingType\SettingsType-RDBUser.h">
<Filter>Header Files\Settings\SettingType</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Version.h.in">

View File

@ -34,6 +34,7 @@ CSettings::~CSettings()
{
CSettingTypeApplication::CleanUp();
CSettingTypeRomDatabase::CleanUp();
CSettingTypeRDBUser::CleanUp();
CSettingTypeGame::CleanUp();
for (SETTING_MAP::iterator iter = m_SettingInfo.begin(); iter != m_SettingInfo.end(); iter++)
@ -79,6 +80,7 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
AddHandler(Cmd_ComboDiskFile, new CSettingTypeTempString(""));
// Support files
AddHandler(SupportFile_SettingsDirectory, new CSettingTypeTempString(""));
AddHandler(SupportFile_Settings, new CSettingTypeApplicationPath("Settings", "ConfigFile", SupportFile_SettingsDefault));
AddHandler(SupportFile_SettingsDefault, new CSettingTypeRelativePath("Config", "Project64.cfg"));
AddHandler(SupportFile_RomDatabase, new CSettingTypeApplicationPath("Settings", "RomDatabase", SupportFile_RomDatabaseDefault));
@ -676,6 +678,7 @@ bool CSettings::Initialize(const char * BaseDirectory, const char * AppName)
AddHowToHandleSetting(BaseDirectory);
CSettingTypeApplication::Initialize();
CSettingTypeRomDatabase::Initialize();
CSettingTypeRDBUser::Initialize();
CSettingTypeGame::Initialize();
g_Settings->SaveString(Setting_ApplicationName, AppName);

View File

@ -2,6 +2,7 @@
#include "SettingsType-Application.h"
#include <Common/path.h>
#include <algorithm>
CIniFile * CSettingTypeApplication::m_SettingsIniFile = nullptr;
@ -88,8 +89,11 @@ void CSettingTypeApplication::Initialize(void)
{
SettingPath.DirectoryCreate();
}
CPath SettingDir(SettingPath);
SettingDir.SetNameExtension("");
g_Settings->SaveString(SupportFile_SettingsDirectory, (const char *)SettingDir);
m_SettingsIniFile = new CIniFile(SettingPath);
m_SettingsIniFile->SetCustomSort(CustomSortData);
}
m_SettingsIniFile->SetAutoFlush(false);
@ -283,6 +287,29 @@ std::string CSettingTypeApplication::FixSectionName(const char * Section)
return SectionName;
}
struct compareKeyValueItem
{
inline bool operator()(CIniFileBase::KeyValueItem & struct1, const CIniFileBase::KeyValueItem & struct2)
{
std::string a = *struct1.first;
std::string b = *struct2.first;
if (_stricmp(a.c_str(), "Good Name") == 0)
{
return true;
}
if (_stricmp(b.c_str(), "Good Name") == 0)
{
return false;
}
return _stricmp(a.c_str(), b.c_str()) <= 0;
}
};
void CSettingTypeApplication::CustomSortData(CIniFileBase::KeyValueVector & data)
{
std::sort(data.begin(), data.end(), compareKeyValueItem());
}
void CSettingTypeApplication::Delete(uint32_t /*Index*/)
{
m_SettingsIniFile->SaveString(SectionName(), m_KeyNameIdex.c_str(), nullptr);

View File

@ -59,6 +59,7 @@ protected:
const SettingID m_DefaultSetting;
std::string FixSectionName(const char * Section);
static void CustomSortData(CIniFileBase::KeyValueVector & data);
static CIniFile * m_SettingsIniFile;
const std::string m_Section;

View File

@ -1,29 +1,29 @@
#include "stdafx.h"
#include "SettingsType-Application.h"
#include "SettingsType-GameSetting.h"
#include "SettingsType-RDBUser.h"
bool CSettingTypeGame::m_RdbEditor = false;
bool CSettingTypeGame::m_EraseDefaults = true;
std::string * CSettingTypeGame::m_SectionIdent = nullptr;
CSettingTypeGame::CSettingTypeGame(const char * Name, bool DefaultValue) :
CSettingTypeApplication("", Name, DefaultValue)
CSettingTypeRDBUser("", Name, DefaultValue)
{
}
CSettingTypeGame::CSettingTypeGame(const char * Name, const char * DefaultValue) :
CSettingTypeApplication("", Name, DefaultValue)
CSettingTypeRDBUser("", Name, DefaultValue)
{
}
CSettingTypeGame::CSettingTypeGame(const char * Name, uint32_t DefaultValue) :
CSettingTypeApplication("", Name, DefaultValue)
CSettingTypeRDBUser("", Name, DefaultValue)
{
}
CSettingTypeGame::CSettingTypeGame(const char * Name, SettingID DefaultSetting) :
CSettingTypeApplication("", Name, DefaultSetting)
CSettingTypeRDBUser("", Name, DefaultSetting)
{
}
@ -85,7 +85,7 @@ bool CSettingTypeGame::Load(uint32_t Index, bool & Value) const
return g_Settings->LoadBool(m_DefaultSetting, Value);
}
}
return CSettingTypeApplication::Load(Index, Value);
return CSettingTypeRDBUser::Load(Index, Value);
}
bool CSettingTypeGame::Load(uint32_t Index, uint32_t & Value) const
@ -101,7 +101,7 @@ bool CSettingTypeGame::Load(uint32_t Index, uint32_t & Value) const
return g_Settings->LoadDword(m_DefaultSetting, Value);
}
}
return CSettingTypeApplication::Load(Index, Value);
return CSettingTypeRDBUser::Load(Index, Value);
}
bool CSettingTypeGame::Load(uint32_t Index, std::string & Value) const
@ -117,7 +117,7 @@ bool CSettingTypeGame::Load(uint32_t Index, std::string & Value) const
return g_Settings->LoadStringVal(m_DefaultSetting, Value);
}
}
return CSettingTypeApplication::Load(Index, Value);
return CSettingTypeRDBUser::Load(Index, Value);
}
// Return the default values
@ -136,7 +136,7 @@ void CSettingTypeGame::LoadDefault(uint32_t Index, bool & Value) const
}
else
{
CSettingTypeApplication::LoadDefault(Index, Value);
CSettingTypeRDBUser::LoadDefault(Index, Value);
}
}
@ -155,7 +155,7 @@ void CSettingTypeGame::LoadDefault(uint32_t Index, uint32_t & Value) const
}
else
{
CSettingTypeApplication::LoadDefault(Index, Value);
CSettingTypeRDBUser::LoadDefault(Index, Value);
}
}
@ -174,7 +174,7 @@ void CSettingTypeGame::LoadDefault(uint32_t Index, std::string & Value) const
}
else
{
CSettingTypeApplication::LoadDefault(Index, Value);
CSettingTypeRDBUser::LoadDefault(Index, Value);
}
}
@ -204,7 +204,7 @@ void CSettingTypeGame::Save(uint32_t Index, bool Value)
}
else
{
CSettingTypeApplication::Save(Index, Value);
CSettingTypeRDBUser::Save(Index, Value);
}
}
@ -233,7 +233,7 @@ void CSettingTypeGame::Save(uint32_t Index, uint32_t Value)
}
else
{
CSettingTypeApplication::Save(Index, Value);
CSettingTypeRDBUser::Save(Index, Value);
}
}
@ -267,7 +267,7 @@ void CSettingTypeGame::Save(uint32_t Index, const char * Value)
}
else
{
CSettingTypeApplication::Save(Index, Value);
CSettingTypeRDBUser::Save(Index, Value);
}
}
@ -286,6 +286,6 @@ void CSettingTypeGame::Delete(uint32_t Index)
}
else
{
CSettingTypeApplication::Delete(Index);
CSettingTypeRDBUser::Delete(Index);
}
}

View File

@ -1,8 +1,8 @@
#pragma once
#include <Project64-core/Settings/SettingType/SettingsType-Application.h>
#include <Project64-core/Settings/SettingType/SettingsType-RDBUser.h>
class CSettingTypeGame :
public CSettingTypeApplication
public CSettingTypeRDBUser
{
public:
CSettingTypeGame(const char * Name, bool DefaultValue);

View File

@ -0,0 +1,308 @@
#include "stdafx.h"
#include "SettingsType-RDBUser.h"
#include <Common/path.h>
#include <algorithm>
CPath CSettingTypeRDBUser::m_IniFilePath;
CIniFile * CSettingTypeRDBUser::m_IniFile = nullptr;
CSettingTypeRDBUser::CSettingTypeRDBUser(const char * Section, const char * Name, uint32_t DefaultValue) :
m_DefaultStr(""),
m_DefaultValue(DefaultValue),
m_DefaultSetting(Default_Constant),
m_Section(FixSectionName(Section)),
m_KeyName(Name),
m_KeyNameIdex(m_KeyName)
{
}
CSettingTypeRDBUser::CSettingTypeRDBUser(const char * Section, const char * Name, bool DefaultValue) :
m_DefaultStr(""),
m_DefaultValue(DefaultValue),
m_DefaultSetting(Default_Constant),
m_Section(FixSectionName(Section)),
m_KeyName(Name),
m_KeyNameIdex(m_KeyName)
{
}
CSettingTypeRDBUser::CSettingTypeRDBUser(const char * Section, const char * Name, const char * DefaultValue) :
m_DefaultStr(DefaultValue),
m_DefaultValue(0),
m_DefaultSetting(Default_Constant),
m_Section(FixSectionName(Section)),
m_KeyName(Name),
m_KeyNameIdex(m_KeyName)
{
}
CSettingTypeRDBUser::CSettingTypeRDBUser(const char * Section, const char * Name, SettingID DefaultSetting) :
m_DefaultStr(""),
m_DefaultValue(0),
m_DefaultSetting(DefaultSetting),
m_Section(FixSectionName(Section)),
m_KeyName(Name),
m_KeyNameIdex(m_KeyName)
{
}
CSettingTypeRDBUser::~CSettingTypeRDBUser()
{
}
bool CSettingTypeRDBUser::IsSettingSet(void) const
{
return m_IniFile != nullptr ? m_IniFile->EntryExists(SectionName(), m_KeyNameIdex.c_str()) : false;
}
void CSettingTypeRDBUser::Initialize(void)
{
WriteTrace(TraceAppInit, TraceDebug, "Start");
m_IniFilePath = CPath(g_Settings->LoadStringVal(SupportFile_SettingsDirectory).c_str(), "Project64.rdb.user");
if (m_IniFilePath.Exists())
{
CreateIniFile();
}
WriteTrace(TraceAppInit, TraceDebug, "Done");
}
void CSettingTypeRDBUser::Flush()
{
if (m_IniFile != nullptr)
{
m_IniFile->FlushChanges();
}
}
void CSettingTypeRDBUser::ResetAll()
{
if (m_IniFile == nullptr)
{
return;
}
CIniFile::SectionList sections;
m_IniFile->GetVectorOfSections(sections);
for (CIniFile::SectionList::const_iterator itr = sections.begin(); itr != sections.end(); itr++)
{
m_IniFile->DeleteSection(itr->c_str());
}
}
void CSettingTypeRDBUser::CleanUp()
{
if (m_IniFile)
{
m_IniFile->SetAutoFlush(true);
delete m_IniFile;
m_IniFile = nullptr;
}
}
bool CSettingTypeRDBUser::Load(uint32_t Index, bool & Value) const
{
bool bRes = false;
uint32_t dwValue = 0;
bRes = m_IniFile ? m_IniFile->GetNumber(SectionName(), m_KeyNameIdex.c_str(), Value, dwValue) : false;
if (bRes)
{
Value = dwValue != 0;
}
if (!bRes && m_DefaultSetting != Default_None)
{
if (m_DefaultSetting == Default_Constant)
{
Value = m_DefaultValue != 0;
}
else
{
if (g_Settings->IndexBasedSetting(m_DefaultSetting))
{
g_Settings->LoadBoolIndex(m_DefaultSetting, Index, Value);
}
else
{
g_Settings->LoadBool(m_DefaultSetting, Value);
}
}
}
return bRes;
}
bool CSettingTypeRDBUser::Load(uint32_t /*Index*/, uint32_t & Value) const
{
bool bRes = m_IniFile != nullptr ? m_IniFile->GetNumber(SectionName(), m_KeyNameIdex.c_str(), Value, Value) : false;
if (!bRes && m_DefaultSetting != Default_None)
{
Value = m_DefaultSetting == Default_Constant ? m_DefaultValue : g_Settings->LoadDword(m_DefaultSetting);
}
return bRes;
}
const char * CSettingTypeRDBUser::SectionName(void) const
{
return m_Section.c_str();
}
bool CSettingTypeRDBUser::Load(uint32_t Index, std::string & Value) const
{
bool bRes = m_IniFile != nullptr ? m_IniFile->GetString(SectionName(), m_KeyNameIdex.c_str(), m_DefaultStr, Value) : false;
if (!bRes)
{
CSettingTypeRDBUser::LoadDefault(Index, Value);
}
return bRes;
}
// Return the default values
void CSettingTypeRDBUser::LoadDefault(uint32_t Index, bool & Value) const
{
if (m_DefaultSetting != Default_None)
{
if (m_DefaultSetting == Default_Constant)
{
Value = m_DefaultValue != 0;
}
else if (g_Settings->IndexBasedSetting(m_DefaultSetting))
{
g_Settings->LoadBoolIndex(m_DefaultSetting, Index, Value);
}
else
{
g_Settings->LoadBool(m_DefaultSetting, Value);
}
}
}
void CSettingTypeRDBUser::LoadDefault(uint32_t /*Index*/, uint32_t & Value) const
{
if (m_DefaultSetting != Default_None)
{
Value = m_DefaultSetting == Default_Constant ? m_DefaultValue : g_Settings->LoadDword(m_DefaultSetting);
}
}
void CSettingTypeRDBUser::LoadDefault(uint32_t /*Index*/, std::string & Value) const
{
if (m_DefaultSetting != Default_None)
{
Value = m_DefaultSetting == Default_Constant ? m_DefaultStr : g_Settings->LoadStringVal(m_DefaultSetting);
}
}
// Update the settings
void CSettingTypeRDBUser::Save(uint32_t Index, bool Value)
{
bool indexed = g_Settings->IndexBasedSetting(m_DefaultSetting);
if (m_DefaultSetting != Default_None &&
((m_DefaultSetting == Default_Constant && m_DefaultValue == (uint32_t)Value) ||
(m_DefaultSetting != Default_Constant && (indexed ? g_Settings->LoadBoolIndex(m_DefaultSetting, Index) : g_Settings->LoadBool(m_DefaultSetting)) == Value)))
{
if (m_IniFile != nullptr)
{
m_IniFile->SaveString(SectionName(), m_KeyNameIdex.c_str(), nullptr);
}
}
else
{
CreateIniFile();
m_IniFile->SaveNumber(SectionName(), m_KeyNameIdex.c_str(), Value);
}
}
void CSettingTypeRDBUser::Save(uint32_t /*Index*/, uint32_t Value)
{
if (m_DefaultSetting != Default_None &&
((m_DefaultSetting == Default_Constant && m_DefaultValue == Value) ||
(m_DefaultSetting != Default_Constant && g_Settings->LoadDword(m_DefaultSetting) == Value)))
{
if (m_IniFile != nullptr)
{
m_IniFile->SaveString(SectionName(), m_KeyNameIdex.c_str(), nullptr);
}
}
else
{
CreateIniFile();
m_IniFile->SaveNumber(SectionName(), m_KeyNameIdex.c_str(), Value);
}
}
void CSettingTypeRDBUser::Save(uint32_t Index, const std::string & Value)
{
Save(Index, Value.c_str());
}
void CSettingTypeRDBUser::Save(uint32_t /*Index*/, const char * Value)
{
if (m_DefaultSetting != Default_None && Value != nullptr &&
((m_DefaultSetting == Default_Constant && strcmp(m_DefaultStr, Value) == 0) ||
(m_DefaultSetting != Default_Constant && strcmp(g_Settings->LoadStringVal(m_DefaultSetting).c_str(), Value) == 0)))
{
if (m_IniFile != nullptr)
{
m_IniFile->SaveString(SectionName(), m_KeyNameIdex.c_str(), nullptr);
}
}
else
{
CreateIniFile();
m_IniFile->SaveString(SectionName(), m_KeyNameIdex.c_str(), Value);
}
}
std::string CSettingTypeRDBUser::FixSectionName(const char * Section)
{
stdstr SectionName(Section);
if (SectionName.empty())
{
SectionName = "default";
}
SectionName.Replace("\\", "-");
return SectionName;
}
void CSettingTypeRDBUser::CreateIniFile(void)
{
if (m_IniFile != nullptr)
{
return;
}
m_IniFile = new CIniFile(m_IniFilePath);
m_IniFile->SetCustomSort(CustomSortData);
}
struct compareKeyValueItem
{
inline bool operator()(CIniFileBase::KeyValueItem & struct1, const CIniFileBase::KeyValueItem & struct2)
{
std::string a = *struct1.first;
std::string b = *struct2.first;
if (_stricmp(a.c_str(), "Good Name") == 0)
{
return true;
}
if (_stricmp(b.c_str(), "Good Name") == 0)
{
return false;
}
return _stricmp(a.c_str(), b.c_str()) <= 0;
}
};
void CSettingTypeRDBUser::CustomSortData(CIniFileBase::KeyValueVector & data)
{
std::sort(data.begin(), data.end(), compareKeyValueItem());
}
void CSettingTypeRDBUser::Delete(uint32_t /*Index*/)
{
if (m_IniFile != nullptr)
{
m_IniFile->SaveString(SectionName(), m_KeyNameIdex.c_str(), nullptr);
}
}

View File

@ -0,0 +1,78 @@
#pragma once
#include <Common/IniFile.h>
#include <Common/path.h>
#include <Project64-core/Settings/SettingType/SettingsType-Base.h>
class CSettingTypeRDBUser :
public CSettingType
{
public:
CSettingTypeRDBUser(const char * Section, const char * Name, const char * DefaultValue);
CSettingTypeRDBUser(const char * Section, const char * Name, bool DefaultValue);
CSettingTypeRDBUser(const char * Section, const char * Name, uint32_t DefaultValue);
CSettingTypeRDBUser(const char * Section, const char * Name, SettingID DefaultSetting);
virtual ~CSettingTypeRDBUser();
virtual bool IndexBasedSetting(void) const
{
return false;
}
virtual SettingType GetSettingType(void) const
{
return SettingType_CfgFile;
}
virtual bool IsSettingSet(void) const;
// Return the values
virtual bool Load(uint32_t Index, bool & Value) const;
virtual bool Load(uint32_t Index, uint32_t & Value) const;
virtual bool Load(uint32_t Index, std::string & Value) const;
// Return the default values
virtual void LoadDefault(uint32_t Index, bool & Value) const;
virtual void LoadDefault(uint32_t Index, uint32_t & Value) const;
virtual void LoadDefault(uint32_t Index, std::string & Value) const;
// Update the settings
virtual void Save(uint32_t Index, bool Value);
virtual void Save(uint32_t Index, uint32_t Value);
virtual void Save(uint32_t Index, const std::string & Value);
virtual void Save(uint32_t Index, const char * Value);
// Delete the setting
virtual void Delete(uint32_t Index);
// Initialize this class to use the INI file or registry
static void Initialize(void);
static void CleanUp(void);
static void Flush(void);
static void ResetAll(void);
const char * GetKeyName(void) const
{
return m_KeyName.c_str();
}
protected:
const char * m_DefaultStr;
const uint32_t m_DefaultValue;
const SettingID m_DefaultSetting;
std::string FixSectionName(const char * Section);
static void CreateIniFile(void);
static void CustomSortData(CIniFileBase::KeyValueVector & data);
static CPath m_IniFilePath;
static CIniFile * m_IniFile;
const std::string m_Section;
const std::string m_KeyName;
mutable std::string m_KeyNameIdex;
virtual const char * SectionName(void) const;
private:
CSettingTypeRDBUser(const CSettingTypeRDBUser &);
CSettingTypeRDBUser & operator=(const CSettingTypeRDBUser &);
};

View File

@ -18,6 +18,7 @@ enum SettingID
Cmd_ShowHelp,
// Support files
SupportFile_SettingsDirectory,
SupportFile_Settings,
SupportFile_SettingsDefault,
SupportFile_RomDatabase,