diff --git a/.gitignore b/.gitignore
index 66d4f78b9..ab70479a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,78 +20,79 @@
Thumbs.db
/.vs
-/git.properties
/Bin/Debug
/Bin/Debug64
/Bin/Package
/Bin/Release
/Bin/Release64
/build
+/Config/Cheats-User
/Config/Project64.cache3
/Config/Project64.cfg
+/Config/Project64.cht
/Config/Project64.rdn
/Config/Project64.sc3
/Config/Project64.zcache
+/git.properties
/ipch
/Package
-/Plugin/Audio/AndroidAudio.dll
/Plugin/Audio/AndroidAudio_d.dll
-/Plugin/Audio/Project64-Audio.dll
+/Plugin/Audio/AndroidAudio.dll
/Plugin/Audio/Project64-Audio_d.dll
+/Plugin/Audio/Project64-Audio.dll
/Plugin/GFX/lib
/Plugin/GFX/map
/Plugin/GFX/pdb
-/Plugin/GFX/Project64-Video.dll
/Plugin/GFX/Project64-Video_d.dll
+/Plugin/GFX/Project64-Video.dll
+/Plugin/Input/AndroidInput_d.dll
+/Plugin/Input/AndroidInput.dll
/Plugin/Input/lib
/Plugin/Input/map
/Plugin/Input/pdb
-/Plugin/Input/AndroidInput.dll
-/Plugin/Input/AndroidInput_d.dll
-/Plugin/Input/PJ64_NRage.dll
/Plugin/Input/PJ64_NRage_d.dll
-/Plugin/Input/Project64-Input.dll
+/Plugin/Input/PJ64_NRage.dll
/Plugin/Input/Project64-Input_d.dll
+/Plugin/Input/Project64-Input.dll
/Plugin/RSP/lib
/Plugin/RSP/map
/Plugin/RSP/pdb
/Plugin/RSP/RSP 1.7.dll
/Plugin/RSP/RSP_d 1.7.dll
-/Plugin/RSP/RSP-HLE.dll
/Plugin/RSP/RSP-HLE_d.dll
+/Plugin/RSP/RSP-HLE.dll
/Plugin64/AndroidAudio
-/Plugin64/Audio/AndroidAudio.dll
/Plugin64/Audio/AndroidAudio_d.dll
-/Plugin64/Audio/Project64-Audio.dll
+/Plugin64/Audio/AndroidAudio.dll
/Plugin64/Audio/Project64-Audio_d.dll
+/Plugin64/Audio/Project64-Audio.dll
/Plugin64/GFX/lib
/Plugin64/GFX/map
/Plugin64/GFX/pdb
-/Plugin64/GFX/PJ64Glide64.dll
/Plugin64/GFX/PJ64Glide64_d.dll
-/Plugin64/GFX/Project64-Video.dll
+/Plugin64/GFX/PJ64Glide64.dll
/Plugin64/GFX/Project64-Video_d.dll
+/Plugin64/GFX/Project64-Video.dll
+/Plugin64/Input/AndroidInput_d.dll
+/Plugin64/Input/AndroidInput.dll
/Plugin64/Input/lib
/Plugin64/Input/map
/Plugin64/Input/pdb
-/Plugin64/Input/AndroidInput.dll
-/Plugin64/Input/AndroidInput_d.dll
-/Plugin64/Input/PJ64_NRage.dll
/Plugin64/Input/PJ64_NRage_d.dll
-/Plugin64/Input/Project64-Input.dll
+/Plugin64/Input/PJ64_NRage.dll
/Plugin64/Input/Project64-Input_d.dll
+/Plugin64/Input/Project64-Input.dll
/Plugin64/RSP/lib
/Plugin64/RSP/map
/Plugin64/RSP/pdb
/Plugin64/RSP/RSP 1.7.dll
/Plugin64/RSP/RSP_d 1.7.dll
-/Plugin64/RSP/RSP-HLE.dll
/Plugin64/RSP/RSP-HLE_d.dll
+/Plugin64/RSP/RSP-HLE.dll
+/Save
/Source/nragev20/Version.h
/Source/Project64-audio/Version.h
/Source/Project64-core/Version.h
/Source/Project64-input/Version.h
/Source/Project64-video/Version.h
/Source/RSP/Version.h
-/Save
-/Config/Project64.cht
diff --git a/Config/Project64.cfg.development b/Config/Project64.cfg.development
index e01028535..33078c16d 100644
--- a/Config/Project64.cfg.development
+++ b/Config/Project64.cfg.development
@@ -3,13 +3,14 @@
AudioRDB=..\..\Config\Audio.rdb
Auto Sleep=0
Basic Mode=0
-Cheats=..\..\Config\Project64.cht
+CheatDir=..\..\Config\Cheats\
Enhancement=..\..\Config\Project64.enh
ExtInfo=..\..\Config\Project64.rdx
Notes=..\..\Config\Project64.rdn
RomDatabase=..\..\Config\Project64.rdb
RomListCache=..\..\Config\Project64.cache3
ShortCuts=..\..\Config\Project64.sc3
+UserCheatDir=..\..\Config\Cheats-User\
VideoRDB=..\..\Config\Video.rdb
[Debugger]
diff --git a/Source/Installer/Installer.iss b/Source/Installer/Installer.iss
index 086b166f9..1afac9fab 100644
--- a/Source/Installer/Installer.iss
+++ b/Source/Installer/Installer.iss
@@ -26,7 +26,7 @@ Filename: "{app}\Project64.exe"; Description: "{cm:LaunchProgram,{#StringChange(
Source: "{#BaseDir}\Bin\{#Configuration}\Project64.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#BaseDir}\Config\Video.rdb"; DestDir: "{app}\Config"
Source: "{#BaseDir}\Config\Audio.rdb"; DestDir: "{app}\Config"
-Source: "{#BaseDir}\Config\Project64.cht"; DestDir: "{app}\Config"
+Source: "{#BaseDir}\Config\Cheats\*.cht"; DestDir: "{app}\Config\Cheats"
Source: "{#BaseDir}\Config\Project64.enh"; DestDir: "{app}\Config"
Source: "{#BaseDir}\Config\Project64.rdb"; DestDir: "{app}\Config"
Source: "{#BaseDir}\Config\Project64.rdx"; DestDir: "{app}\Config"
diff --git a/Source/JoinSettings/JoinSettings.vcxproj b/Source/JoinSettings/JoinSettings.vcxproj
index d0554e31e..a67536d0b 100644
--- a/Source/JoinSettings/JoinSettings.vcxproj
+++ b/Source/JoinSettings/JoinSettings.vcxproj
@@ -40,9 +40,6 @@
NotUsing
-
- "$(OutDir)\JoinSettings.exe" -join "$(SolutionDir)Config\Cheats" "$(SolutionDir)Config\Project64.cht"
-
diff --git a/Source/Project64-core/Project64-core.vcxproj b/Source/Project64-core/Project64-core.vcxproj
index 85d6458e4..192eee7fd 100644
--- a/Source/Project64-core/Project64-core.vcxproj
+++ b/Source/Project64-core/Project64-core.vcxproj
@@ -234,7 +234,6 @@
-
diff --git a/Source/Project64-core/Project64-core.vcxproj.filters b/Source/Project64-core/Project64-core.vcxproj.filters
index bc8225f25..c2b18b6ac 100644
--- a/Source/Project64-core/Project64-core.vcxproj.filters
+++ b/Source/Project64-core/Project64-core.vcxproj.filters
@@ -455,9 +455,6 @@
Header Files
-
- Header Files
-
Header Files\Settings
diff --git a/Source/Project64-core/Settings.cpp b/Source/Project64-core/Settings.cpp
index c140969e5..77f211beb 100644
--- a/Source/Project64-core/Settings.cpp
+++ b/Source/Project64-core/Settings.cpp
@@ -101,9 +101,11 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
AddHandler(SupportFile_VideoRDBDefault, new CSettingTypeRelativePath("Config", "Video.rdb"));
AddHandler(SupportFile_AudioRDB, new CSettingTypeApplicationPath("Settings", "AudioRDB", SupportFile_AudioRDBDefault));
AddHandler(SupportFile_AudioRDBDefault, new CSettingTypeRelativePath("Config", "Audio.rdb"));
- AddHandler(SupportFile_Cheats, new CSettingTypeApplicationPath("Settings", "Cheats", SupportFile_CheatsDefault));
- AddHandler(SupportFile_CheatsDefault, new CSettingTypeRelativePath("Config", "Project64.cht"));
- AddHandler(SupportFile_Enhancements, new CSettingTypeApplicationPath("Settings", "Enhancement", SupportFile_EnhancementsDefault));
+ AddHandler(SupportFile_CheatDir, new CSettingTypeApplicationPath("Settings", "CheatDir", SupportFile_CheatDirDefault));
+ AddHandler(SupportFile_CheatDirDefault, new CSettingTypeRelativePath("Config\\Cheats", ""));
+ AddHandler(SupportFile_UserCheatDir, new CSettingTypeApplicationPath("Settings", "UserCheatDir", SupportFile_UserCheatDirDefault));
+ AddHandler(SupportFile_UserCheatDirDefault, new CSettingTypeRelativePath("Config\\Cheats-User", ""));
+ AddHandler(SupportFile_Enhancements, new CSettingTypeApplicationPath("Settings", "Enhancement", SupportFile_EnhancementsDefault));
AddHandler(SupportFile_EnhancementsDefault, new CSettingTypeRelativePath("Config", "Project64.enh"));
AddHandler(SupportFile_Notes, new CSettingTypeApplicationPath("Settings", "Notes", SupportFile_NotesDefault));
AddHandler(SupportFile_NotesDefault, new CSettingTypeRelativePath("Config", "Project64.rdn"));
@@ -435,13 +437,9 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
AddHandler(Logging_LogUnknown, new CSettingTypeApplication("Logging", "Log Rom Header", false));
// cheats
- AddHandler(Cheat_Modified, new CSettingTypeGame("CheatModified",false));
- AddHandler(Cheat_Entry, new CSettingTypeCheats("", Cheat_UserEntry));
- AddHandler(Cheat_Notes, new CSettingTypeCheats("_N", Cheat_UserNotes));
- AddHandler(Cheat_Options, new CSettingTypeCheats("_O", Cheat_UserOptions));
- AddHandler(Cheat_UserEntry, new CSettingTypeGameIndex("Cheat", "", ""));
- AddHandler(Cheat_UserNotes, new CSettingTypeGameIndex("Cheat", "_N", ""));
- AddHandler(Cheat_UserOptions, new CSettingTypeGameIndex("Cheat", "_O", ""));
+ AddHandler(Cheat_Entry, new CSettingTypeCheats(""));
+ AddHandler(Cheat_Notes, new CSettingTypeCheats("_N"));
+ AddHandler(Cheat_Options, new CSettingTypeCheats("_O"));
AddHandler(Cheat_Active, new CSettingTypeGameIndex("Cheat", "Active", false));
AddHandler(Cheat_Extension, new CSettingTypeGameIndex("Cheat", ".exten", "??? - Not Set"));
diff --git a/Source/Project64-core/Settings.h b/Source/Project64-core/Settings.h
index b999b6253..c46dc6f59 100644
--- a/Source/Project64-core/Settings.h
+++ b/Source/Project64-core/Settings.h
@@ -78,8 +78,8 @@ public:
void SaveStringIndex(SettingID Type, uint32_t index, const char * Buffer);
// Delete a setting
- void DeleteSetting(SettingID Type);
- void DeleteSettingIndex(SettingID Type, uint32_t index);
+ void DeleteSetting(SettingID Type);
+ void DeleteSettingIndex(SettingID Type, uint32_t index);
//Register Notification of change
void RegisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func);
diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp
index ecc30246f..215f357a2 100644
--- a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp
+++ b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.cpp
@@ -11,14 +11,45 @@
#include "stdafx.h"
#include "SettingsType-Cheats.h"
#include
+#include
+#include
+#include
-CIniFile * CSettingTypeCheats::m_CheatIniFile = NULL;
-std::string * CSettingTypeCheats::m_SectionIdent = NULL;
-bool CSettingTypeCheats::m_CheatsModified = false;
+class CCheatInfo
+{
+ typedef std::map SectionFiles;
-CSettingTypeCheats::CSettingTypeCheats(const char * PostFix, SettingID UserSetting) :
- m_PostFix(PostFix),
- m_UserSetting(UserSetting)
+public:
+ CCheatInfo();
+ ~CCheatInfo();
+
+ void FlushChanges (void);
+ bool Load(const char * PostFix, uint32_t Index, std::string & Value) const;
+ void Save(const char * PostFix, uint32_t Index, const char * Value);
+ void Delete(const char * PostFix, uint32_t Index);
+
+private:
+ void ScanFileThread(void);
+ void GameChanged(void);
+ void UseUserFile();
+
+ static void CustomSortData(CIniFileBase::KeyValueVector & data);
+ static uint32_t stScanFileThread(void * lpThreadParameter) { ((CCheatInfo *)lpThreadParameter)->ScanFileThread(); return 0; }
+ static void stGameChanged(void * lpData) { ((CCheatInfo *)lpData)->GameChanged(); }
+
+ std::string m_SectionIdent;
+ CThread m_ScanFileThread;
+ SectionFiles m_SectionFiles;
+ CriticalSection m_CS;
+ std::unique_ptr m_CheatIniFile;
+ bool m_Scanned;
+ bool m_UsingUserFile;
+};
+
+CCheatInfo * CheatInfo = nullptr;
+
+CSettingTypeCheats::CSettingTypeCheats(const char * PostFix) :
+ m_PostFix(PostFix)
{
}
@@ -29,43 +60,27 @@ CSettingTypeCheats::~CSettingTypeCheats ( void )
void CSettingTypeCheats::Initialize ( void )
{
WriteTrace(TraceAppInit, TraceDebug, "Start");
- m_CheatIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Cheats).c_str());
- m_CheatIniFile->SetAutoFlush(false);
- g_Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged);
- m_SectionIdent = new stdstr(g_Settings->LoadStringVal(Game_IniKey));
- GameChanged(NULL);
+ CheatInfo = new CCheatInfo();
WriteTrace(TraceAppInit, TraceDebug, "Done");
}
void CSettingTypeCheats::CleanUp ( void )
{
- if (m_CheatIniFile)
+ if (CheatInfo != nullptr)
{
- m_CheatIniFile->SetAutoFlush(true);
- delete m_CheatIniFile;
- m_CheatIniFile = NULL;
- }
- if (m_SectionIdent)
- {
- delete m_SectionIdent;
- m_SectionIdent = NULL;
+ delete CheatInfo;
+ CheatInfo = nullptr;
}
}
void CSettingTypeCheats::FlushChanges( void )
{
- if (m_CheatIniFile)
+ if (CheatInfo != nullptr)
{
- m_CheatIniFile->FlushChanges();
+ CheatInfo->FlushChanges();
}
}
-void CSettingTypeCheats::GameChanged ( void * /*Data */ )
-{
- *m_SectionIdent = g_Settings->LoadStringVal(Game_IniKey);
- m_CheatsModified = g_Settings->LoadBool(Cheat_Modified);
-}
-
bool CSettingTypeCheats::IsSettingSet(void) const
{
g_Notify->BreakPoint(__FILE__, __LINE__);
@@ -86,19 +101,13 @@ bool CSettingTypeCheats::Load (uint32_t /*Index*/, uint32_t & /*Value*/ ) const
bool CSettingTypeCheats::Load (uint32_t Index, std::string & Value ) const
{
- if (m_CheatsModified)
+ if (CheatInfo != nullptr)
{
- return g_Settings->LoadStringIndex(m_UserSetting, Index, Value);
+ return CheatInfo->Load(m_PostFix.c_str(), Index, Value);
}
- if (m_CheatIniFile == NULL)
- {
- return false;
- }
- stdstr_f Key("Cheat%d%s",Index,m_PostFix);
- return m_CheatIniFile->GetString(m_SectionIdent->c_str(),Key.c_str(),"",Value);
+ return false;
}
-//return the default values
void CSettingTypeCheats::LoadDefault (uint32_t /*Index*/, bool & /*Value*/ ) const
{
g_Notify->BreakPoint(__FILE__, __LINE__);
@@ -114,7 +123,6 @@ void CSettingTypeCheats::LoadDefault (uint32_t /*Index*/, std::string & /*Value*
g_Notify->BreakPoint(__FILE__, __LINE__);
}
-//Update the settings
void CSettingTypeCheats::Save (uint32_t /*Index*/, bool /*Value*/ )
{
g_Notify->BreakPoint(__FILE__, __LINE__);
@@ -127,54 +135,259 @@ void CSettingTypeCheats::Save (uint32_t /*Index*/, uint32_t /*Value*/ )
void CSettingTypeCheats::Save (uint32_t Index, const std::string & Value )
{
- if (!m_CheatsModified)
+ if (CheatInfo != nullptr)
{
- CopyCheats();
- m_CheatsModified = true;
- g_Settings->SaveBool(Cheat_Modified, true);
+ CheatInfo->Save(m_PostFix.c_str(), Index, Value.c_str());
}
- g_Settings->SaveStringIndex(m_UserSetting, Index, Value.c_str());
}
void CSettingTypeCheats::Save (uint32_t Index, const char * Value )
{
- if (!m_CheatsModified)
+ if (CheatInfo != nullptr)
{
- CopyCheats();
- m_CheatsModified = true;
- g_Settings->SaveBool(Cheat_Modified, true);
+ CheatInfo->Save(m_PostFix.c_str(), Index, Value);
}
- g_Settings->SaveStringIndex(m_UserSetting, Index, Value);
}
void CSettingTypeCheats::Delete (uint32_t Index )
{
- if (!m_CheatsModified)
+ if (CheatInfo != nullptr)
{
- CopyCheats();
- m_CheatsModified = true;
- g_Settings->SaveBool(Cheat_Modified, true);
+ CheatInfo->Delete(m_PostFix.c_str(), Index);
}
- g_Settings->DeleteSettingIndex(m_UserSetting, Index);
}
-void CSettingTypeCheats::CopyCheats(void)
+CCheatInfo::CCheatInfo() :
+ m_ScanFileThread(stScanFileThread),
+ m_Scanned(false),
+ m_UsingUserFile(false)
{
- for (int i = 0; i < CCheats::MaxCheats; i++)
+ m_ScanFileThread.Start(this);
+ g_Settings->RegisterChangeCB(Game_IniKey, this, stGameChanged);
+}
+
+CCheatInfo::~CCheatInfo()
+{
+ g_Settings->UnregisterChangeCB(Game_IniKey, this, stGameChanged);
+}
+
+void CCheatInfo::GameChanged(void)
+{
+ m_SectionIdent = g_Settings->LoadStringVal(Game_IniKey);
+
+ for (uint32_t i = 0; i < 500; i++)
{
- std::string Value;
- if (!g_Settings->LoadStringIndex(Cheat_Entry, i, Value))
+ bool Scanned = false;
+ {
+ CGuard Guard(m_CS);
+ Scanned = m_Scanned;
+ }
+ if (Scanned)
{
break;
}
- g_Settings->SaveStringIndex(Cheat_UserEntry, i, Value);
- if (g_Settings->LoadStringIndex(Cheat_Notes, i, Value))
+ Sleep(100);
+ }
+
+ CGuard Guard(m_CS);
+ SectionFiles::const_iterator itr = m_SectionFiles.find(m_SectionIdent);
+ if (itr != m_SectionFiles.end())
+ {
+ CPath CheatFile(itr->second);
+ if (CheatFile.Exists())
{
- g_Settings->SaveStringIndex(Cheat_UserNotes, i, Value);
- }
- if (g_Settings->LoadStringIndex(Cheat_Options, i, Value))
- {
- g_Settings->SaveStringIndex(Cheat_UserOptions, i, Value);
+ m_CheatIniFile = std::make_unique(CheatFile);
+ m_CheatIniFile->SetCustomSort(CustomSortData);
}
}
-}
\ No newline at end of file
+}
+
+void CCheatInfo::FlushChanges(void)
+{
+ if (m_CheatIniFile.get() != nullptr)
+ {
+ m_CheatIniFile->FlushChanges();
+ }
+}
+
+bool CCheatInfo::Load(const char * PostFix, uint32_t Index, std::string & Value) const
+{
+ if (m_CheatIniFile.get() == nullptr)
+ {
+ return false;
+ }
+ stdstr_f Key("Cheat%d%s", Index, PostFix);
+ return m_CheatIniFile->GetString(m_SectionIdent.c_str(), Key.c_str(), "", Value);
+}
+
+void CCheatInfo::Save(const char * PostFix, uint32_t Index, const char * Value)
+{
+ UseUserFile();
+ if (m_CheatIniFile.get() == nullptr)
+ {
+ return;
+ }
+ if (strlen(Value) == 0)
+ {
+ if (strcmp(PostFix, "_O") == 0 || strcmp(PostFix, "_N") == 0)
+ {
+ Value = nullptr;
+ }
+ else
+ {
+ g_Notify->BreakPoint(__FILE__, __LINE__);
+ }
+ }
+ stdstr_f Key("Cheat%d%s", Index, PostFix);
+ m_CheatIniFile->SaveString(m_SectionIdent.c_str(), Key.c_str(), Value);
+}
+
+void CCheatInfo::Delete(const char * PostFix, uint32_t Index)
+{
+ UseUserFile();
+ stdstr_f Key("Cheat%d%s", Index, PostFix);
+ m_CheatIniFile->SaveString(m_SectionIdent.c_str(), Key.c_str(), nullptr);
+}
+
+void CCheatInfo::ScanFileThread(void)
+{
+ SectionFiles Files;
+ CPath CheatFile(g_Settings->LoadStringVal(SupportFile_CheatDir), "*.cht");
+#ifdef _WIN32
+ CheatFile.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
+#endif
+ if (CheatFile.FindFirst())
+ {
+ do
+ {
+ CIniFile CheatIniFile(CheatFile);
+ CIniFile::SectionList Sections;
+ CheatIniFile.GetVectorOfSections(Sections);
+ for (CIniFile::SectionList::const_iterator itr = Sections.begin(); itr != Sections.end(); itr++)
+ {
+ Files.insert(SectionFiles::value_type(itr->c_str(), CheatFile));
+ }
+ } while (CheatFile.FindNext());
+ }
+
+ CheatFile = CPath(g_Settings->LoadStringVal(SupportFile_UserCheatDir), "*.cht");
+#ifdef _WIN32
+ CheatFile.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
+#endif
+ if (CheatFile.FindFirst())
+ {
+ do
+ {
+ CIniFile CheatIniFile(CheatFile);
+ CIniFile::SectionList Sections;
+ CheatIniFile.GetVectorOfSections(Sections);
+ for (CIniFile::SectionList::const_iterator itr = Sections.begin(); itr != Sections.end(); itr++)
+ {
+ Files[itr->c_str()] = (const char *)CheatFile;
+ }
+ } while (CheatFile.FindNext());
+ }
+
+ {
+ CGuard Guard(m_CS);
+ m_SectionFiles = Files;
+ m_Scanned = true;
+ }
+}
+
+void CCheatInfo::CustomSortData(CIniFileBase::KeyValueVector & data)
+{
+ 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(), "Name") == 0)
+ {
+ return true;
+ }
+ if (_stricmp(b.c_str(), "Name") == 0)
+ {
+ return false;
+ }
+ if (a.length() > 5 && _strnicmp(a.c_str(), "cheat", 5) == 0 &&
+ b.length() > 5 && _strnicmp(b.c_str(), "cheat", 5) == 0)
+ {
+ int i1 = atoi(&(*struct1.first)[5]);
+ int i2 = atoi(&(*struct2.first)[5]);
+ if (i1 != i2)
+ {
+ return i1 < i2;
+ }
+ char Buffer[40];
+ int number_len = strlen(_itoa(i1, Buffer, 10));
+ if (strlen(&a[5 + number_len]) == 0)
+ {
+ return true;
+ }
+ if (strlen(&b[5 + number_len]) == 0)
+ {
+ return false;
+ }
+ return _stricmp(&a[5 + number_len], &b[5 + number_len]) <= 0;
+ }
+ return _stricmp(a.c_str(), b.c_str()) <= 0;
+ }
+ };
+ std::sort(data.begin(), data.end(), compareKeyValueItem());
+}
+
+void CCheatInfo::UseUserFile()
+{
+ if (m_UsingUserFile)
+ {
+ return;
+ }
+
+ std::string UserCheatDir = g_Settings->LoadStringVal(SupportFile_UserCheatDir);
+ CPath FileName(UserCheatDir.c_str(), ".cht");
+
+ CIniFile::strlist KeyList;
+ if (m_CheatIniFile.get() != nullptr)
+ {
+ CPath CurrentIniFolder(m_CheatIniFile->GetFileName());
+ CurrentIniFolder.SetNameExtension("");
+ CPath UserCheatDirPath(UserCheatDir, "");
+
+#ifdef _WIN32
+ CurrentIniFolder.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
+ UserCheatDirPath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
+#endif
+ if (CurrentIniFolder == UserCheatDirPath)
+ {
+ m_UsingUserFile = true;
+ return;
+ }
+ m_CheatIniFile->GetKeyList(m_SectionIdent.c_str(), KeyList);
+ FileName.SetName(CPath(m_CheatIniFile->GetFileName()).GetName().c_str());
+ }
+
+ if (FileName.GetName().empty())
+ {
+ FileName.SetName(g_Settings->LoadStringVal(Rdb_GoodName).c_str());
+ }
+#ifdef _WIN32
+ FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
+#endif
+ if (!FileName.DirectoryExists())
+ {
+ FileName.DirectoryCreate();
+ }
+
+ std::unique_ptr UserIniFile = std::make_unique(FileName);
+ UserIniFile->SetCustomSort(CustomSortData);
+ for (CIniFile::strlist::const_iterator itr = KeyList.begin(); itr != KeyList.end(); itr++)
+ {
+ std::string Value = m_CheatIniFile->GetString(m_SectionIdent.c_str(), itr->c_str(), "");
+ UserIniFile->SaveString(m_SectionIdent.c_str(), itr->c_str(), Value.c_str());
+ }
+ UserIniFile->FlushChanges();
+ m_CheatIniFile.reset(UserIniFile.release());
+ m_UsingUserFile = true;
+}
diff --git a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h
index c001ef4ca..68c770358 100644
--- a/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h
+++ b/Source/Project64-core/Settings/SettingType/SettingsType-Cheats.h
@@ -17,7 +17,7 @@ class CSettingTypeCheats :
public CSettingType
{
public:
- CSettingTypeCheats(const char * PostFix, SettingID UserSetting);
+ CSettingTypeCheats(const char * PostFix);
~CSettingTypeCheats();
virtual bool IndexBasedSetting ( void ) const { return true; }
@@ -51,11 +51,9 @@ public:
protected:
static void GameChanged(void * /*Data */);
- static CIniFile * m_CheatIniFile;
+ //static CIniFile * m_CheatIniFile;
static std::string * m_SectionIdent;
- static bool m_CheatsModified;
- const char * const m_PostFix;
- SettingID m_UserSetting;
+ std::string m_PostFix;
private:
CSettingTypeCheats(void); // Disable default constructor
diff --git a/Source/Project64-core/Settings/SettingsID.h b/Source/Project64-core/Settings/SettingsID.h
index 5bd26d648..02bdd41c9 100644
--- a/Source/Project64-core/Settings/SettingsID.h
+++ b/Source/Project64-core/Settings/SettingsID.h
@@ -36,9 +36,11 @@ enum SettingID
SupportFile_VideoRDBDefault,
SupportFile_AudioRDB,
SupportFile_AudioRDBDefault,
- SupportFile_Cheats,
- SupportFile_CheatsDefault,
- SupportFile_Enhancements,
+ SupportFile_CheatDir,
+ SupportFile_CheatDirDefault,
+ SupportFile_UserCheatDir,
+ SupportFile_UserCheatDirDefault,
+ SupportFile_Enhancements,
SupportFile_EnhancementsDefault,
SupportFile_Notes,
SupportFile_NotesDefault,
@@ -334,13 +336,9 @@ enum SettingID
Logging_LogUnknown,
//Cheats
- Cheat_Modified,
Cheat_Entry,
Cheat_Notes,
Cheat_Options,
- Cheat_UserEntry,
- Cheat_UserNotes,
- Cheat_UserOptions,
Cheat_Active,
Cheat_Extension,
diff --git a/Source/Script/package_zip.cmd b/Source/Script/package_zip.cmd
index 33c0f1637..5270e4261 100644
--- a/Source/Script/package_zip.cmd
+++ b/Source/Script/package_zip.cmd
@@ -48,7 +48,7 @@ copy "%base_dir%\Plugin%VSPlatform%\GFX\GLideN64\translations\*.Lang" "%base_dir
copy "%base_dir%\Bin\Release%VSPlatform%\Project64.exe" "%base_dir%\Bin\Package"
copy "%base_dir%\Config\Video.rdb" "%base_dir%\Bin\Package\Config"
copy "%base_dir%\Config\Audio.rdb" "%base_dir%\Bin\Package\Config"
-copy "%base_dir%\Config\Project64.cht" "%base_dir%\Bin\Package\Config"
+copy "%base_dir%\Config\Cheats\*.cht" "%base_dir%\Bin\Package\Config\Cheats"
copy "%base_dir%\Config\Project64.enh" "%base_dir%\Bin\Package\Config"
copy "%base_dir%\Config\Project64.rdb" "%base_dir%\Bin\Package\Config"
copy "%base_dir%\Config\Project64.rdx" "%base_dir%\Bin\Package\Config"