Project64: Read cheats from multiple files

This commit is contained in:
zilmar 2020-11-19 17:46:07 +10:30
parent 88ac97c3a7
commit 124b1c9257
12 changed files with 321 additions and 119 deletions

41
.gitignore vendored
View File

@ -20,78 +20,79 @@
Thumbs.db Thumbs.db
/.vs /.vs
/git.properties
/Bin/Debug /Bin/Debug
/Bin/Debug64 /Bin/Debug64
/Bin/Package /Bin/Package
/Bin/Release /Bin/Release
/Bin/Release64 /Bin/Release64
/build /build
/Config/Cheats-User
/Config/Project64.cache3 /Config/Project64.cache3
/Config/Project64.cfg /Config/Project64.cfg
/Config/Project64.cht
/Config/Project64.rdn /Config/Project64.rdn
/Config/Project64.sc3 /Config/Project64.sc3
/Config/Project64.zcache /Config/Project64.zcache
/git.properties
/ipch /ipch
/Package /Package
/Plugin/Audio/AndroidAudio.dll
/Plugin/Audio/AndroidAudio_d.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_d.dll
/Plugin/Audio/Project64-Audio.dll
/Plugin/GFX/lib /Plugin/GFX/lib
/Plugin/GFX/map /Plugin/GFX/map
/Plugin/GFX/pdb /Plugin/GFX/pdb
/Plugin/GFX/Project64-Video.dll
/Plugin/GFX/Project64-Video_d.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/lib
/Plugin/Input/map /Plugin/Input/map
/Plugin/Input/pdb /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/PJ64_NRage_d.dll
/Plugin/Input/Project64-Input.dll /Plugin/Input/PJ64_NRage.dll
/Plugin/Input/Project64-Input_d.dll /Plugin/Input/Project64-Input_d.dll
/Plugin/Input/Project64-Input.dll
/Plugin/RSP/lib /Plugin/RSP/lib
/Plugin/RSP/map /Plugin/RSP/map
/Plugin/RSP/pdb /Plugin/RSP/pdb
/Plugin/RSP/RSP 1.7.dll /Plugin/RSP/RSP 1.7.dll
/Plugin/RSP/RSP_d 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_d.dll
/Plugin/RSP/RSP-HLE.dll
/Plugin64/AndroidAudio /Plugin64/AndroidAudio
/Plugin64/Audio/AndroidAudio.dll
/Plugin64/Audio/AndroidAudio_d.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_d.dll
/Plugin64/Audio/Project64-Audio.dll
/Plugin64/GFX/lib /Plugin64/GFX/lib
/Plugin64/GFX/map /Plugin64/GFX/map
/Plugin64/GFX/pdb /Plugin64/GFX/pdb
/Plugin64/GFX/PJ64Glide64.dll
/Plugin64/GFX/PJ64Glide64_d.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_d.dll
/Plugin64/GFX/Project64-Video.dll
/Plugin64/Input/AndroidInput_d.dll
/Plugin64/Input/AndroidInput.dll
/Plugin64/Input/lib /Plugin64/Input/lib
/Plugin64/Input/map /Plugin64/Input/map
/Plugin64/Input/pdb /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/PJ64_NRage_d.dll
/Plugin64/Input/Project64-Input.dll /Plugin64/Input/PJ64_NRage.dll
/Plugin64/Input/Project64-Input_d.dll /Plugin64/Input/Project64-Input_d.dll
/Plugin64/Input/Project64-Input.dll
/Plugin64/RSP/lib /Plugin64/RSP/lib
/Plugin64/RSP/map /Plugin64/RSP/map
/Plugin64/RSP/pdb /Plugin64/RSP/pdb
/Plugin64/RSP/RSP 1.7.dll /Plugin64/RSP/RSP 1.7.dll
/Plugin64/RSP/RSP_d 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_d.dll
/Plugin64/RSP/RSP-HLE.dll
/Save
/Source/nragev20/Version.h /Source/nragev20/Version.h
/Source/Project64-audio/Version.h /Source/Project64-audio/Version.h
/Source/Project64-core/Version.h /Source/Project64-core/Version.h
/Source/Project64-input/Version.h /Source/Project64-input/Version.h
/Source/Project64-video/Version.h /Source/Project64-video/Version.h
/Source/RSP/Version.h /Source/RSP/Version.h
/Save
/Config/Project64.cht

View File

@ -3,13 +3,14 @@
AudioRDB=..\..\Config\Audio.rdb AudioRDB=..\..\Config\Audio.rdb
Auto Sleep=0 Auto Sleep=0
Basic Mode=0 Basic Mode=0
Cheats=..\..\Config\Project64.cht CheatDir=..\..\Config\Cheats\
Enhancement=..\..\Config\Project64.enh Enhancement=..\..\Config\Project64.enh
ExtInfo=..\..\Config\Project64.rdx ExtInfo=..\..\Config\Project64.rdx
Notes=..\..\Config\Project64.rdn Notes=..\..\Config\Project64.rdn
RomDatabase=..\..\Config\Project64.rdb RomDatabase=..\..\Config\Project64.rdb
RomListCache=..\..\Config\Project64.cache3 RomListCache=..\..\Config\Project64.cache3
ShortCuts=..\..\Config\Project64.sc3 ShortCuts=..\..\Config\Project64.sc3
UserCheatDir=..\..\Config\Cheats-User\
VideoRDB=..\..\Config\Video.rdb VideoRDB=..\..\Config\Video.rdb
[Debugger] [Debugger]

View File

@ -26,7 +26,7 @@ Filename: "{app}\Project64.exe"; Description: "{cm:LaunchProgram,{#StringChange(
Source: "{#BaseDir}\Bin\{#Configuration}\Project64.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#BaseDir}\Bin\{#Configuration}\Project64.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#BaseDir}\Config\Video.rdb"; DestDir: "{app}\Config" Source: "{#BaseDir}\Config\Video.rdb"; DestDir: "{app}\Config"
Source: "{#BaseDir}\Config\Audio.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.enh"; DestDir: "{app}\Config"
Source: "{#BaseDir}\Config\Project64.rdb"; DestDir: "{app}\Config" Source: "{#BaseDir}\Config\Project64.rdb"; DestDir: "{app}\Config"
Source: "{#BaseDir}\Config\Project64.rdx"; DestDir: "{app}\Config" Source: "{#BaseDir}\Config\Project64.rdx"; DestDir: "{app}\Config"

View File

@ -40,9 +40,6 @@
<ClCompile> <ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile> </ClCompile>
<PostBuildEvent>
<Command>"$(OutDir)\JoinSettings.exe" -join "$(SolutionDir)Config\Cheats" "$(SolutionDir)Config\Project64.cht"</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />

View File

@ -234,7 +234,6 @@
<ClInclude Include="Settings\SettingType\SettingsType-TempString.h" /> <ClInclude Include="Settings\SettingType\SettingsType-TempString.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="TraceModulesProject64.h" /> <ClInclude Include="TraceModulesProject64.h" />
<ClInclude Include="Version.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj"> <ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj">

View File

@ -455,9 +455,6 @@
<ClInclude Include="Plugin.h"> <ClInclude Include="Plugin.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Settings\RecompilerSettings.h"> <ClInclude Include="Settings\RecompilerSettings.h">
<Filter>Header Files\Settings</Filter> <Filter>Header Files\Settings</Filter>
</ClInclude> </ClInclude>

View File

@ -101,9 +101,11 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
AddHandler(SupportFile_VideoRDBDefault, new CSettingTypeRelativePath("Config", "Video.rdb")); AddHandler(SupportFile_VideoRDBDefault, new CSettingTypeRelativePath("Config", "Video.rdb"));
AddHandler(SupportFile_AudioRDB, new CSettingTypeApplicationPath("Settings", "AudioRDB", SupportFile_AudioRDBDefault)); AddHandler(SupportFile_AudioRDB, new CSettingTypeApplicationPath("Settings", "AudioRDB", SupportFile_AudioRDBDefault));
AddHandler(SupportFile_AudioRDBDefault, new CSettingTypeRelativePath("Config", "Audio.rdb")); AddHandler(SupportFile_AudioRDBDefault, new CSettingTypeRelativePath("Config", "Audio.rdb"));
AddHandler(SupportFile_Cheats, new CSettingTypeApplicationPath("Settings", "Cheats", SupportFile_CheatsDefault)); AddHandler(SupportFile_CheatDir, new CSettingTypeApplicationPath("Settings", "CheatDir", SupportFile_CheatDirDefault));
AddHandler(SupportFile_CheatsDefault, new CSettingTypeRelativePath("Config", "Project64.cht")); AddHandler(SupportFile_CheatDirDefault, new CSettingTypeRelativePath("Config\\Cheats", ""));
AddHandler(SupportFile_Enhancements, new CSettingTypeApplicationPath("Settings", "Enhancement", SupportFile_EnhancementsDefault)); 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_EnhancementsDefault, new CSettingTypeRelativePath("Config", "Project64.enh"));
AddHandler(SupportFile_Notes, new CSettingTypeApplicationPath("Settings", "Notes", SupportFile_NotesDefault)); AddHandler(SupportFile_Notes, new CSettingTypeApplicationPath("Settings", "Notes", SupportFile_NotesDefault));
AddHandler(SupportFile_NotesDefault, new CSettingTypeRelativePath("Config", "Project64.rdn")); 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)); AddHandler(Logging_LogUnknown, new CSettingTypeApplication("Logging", "Log Rom Header", false));
// cheats // cheats
AddHandler(Cheat_Modified, new CSettingTypeGame("CheatModified",false)); AddHandler(Cheat_Entry, new CSettingTypeCheats(""));
AddHandler(Cheat_Entry, new CSettingTypeCheats("", Cheat_UserEntry)); AddHandler(Cheat_Notes, new CSettingTypeCheats("_N"));
AddHandler(Cheat_Notes, new CSettingTypeCheats("_N", Cheat_UserNotes)); AddHandler(Cheat_Options, new CSettingTypeCheats("_O"));
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_Active, new CSettingTypeGameIndex("Cheat", "Active", false)); AddHandler(Cheat_Active, new CSettingTypeGameIndex("Cheat", "Active", false));
AddHandler(Cheat_Extension, new CSettingTypeGameIndex("Cheat", ".exten", "??? - Not Set")); AddHandler(Cheat_Extension, new CSettingTypeGameIndex("Cheat", ".exten", "??? - Not Set"));

View File

@ -78,8 +78,8 @@ public:
void SaveStringIndex(SettingID Type, uint32_t index, const char * Buffer); void SaveStringIndex(SettingID Type, uint32_t index, const char * Buffer);
// Delete a setting // Delete a setting
void DeleteSetting(SettingID Type); void DeleteSetting(SettingID Type);
void DeleteSettingIndex(SettingID Type, uint32_t index); void DeleteSettingIndex(SettingID Type, uint32_t index);
//Register Notification of change //Register Notification of change
void RegisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func); void RegisterChangeCB(SettingID Type, void * Data, SettingChangedFunc Func);

View File

@ -11,14 +11,45 @@
#include "stdafx.h" #include "stdafx.h"
#include "SettingsType-Cheats.h" #include "SettingsType-Cheats.h"
#include <Project64-core\N64System\CheatClass.h> #include <Project64-core\N64System\CheatClass.h>
#include <Common\path.h>
#include <Common\Thread.h>
#include <algorithm>
CIniFile * CSettingTypeCheats::m_CheatIniFile = NULL; class CCheatInfo
std::string * CSettingTypeCheats::m_SectionIdent = NULL; {
bool CSettingTypeCheats::m_CheatsModified = false; typedef std::map<std::string, std::string> SectionFiles;
CSettingTypeCheats::CSettingTypeCheats(const char * PostFix, SettingID UserSetting) : public:
m_PostFix(PostFix), CCheatInfo();
m_UserSetting(UserSetting) ~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<CIniFile> 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 ) void CSettingTypeCheats::Initialize ( void )
{ {
WriteTrace(TraceAppInit, TraceDebug, "Start"); WriteTrace(TraceAppInit, TraceDebug, "Start");
m_CheatIniFile = new CIniFile(g_Settings->LoadStringVal(SupportFile_Cheats).c_str()); CheatInfo = new CCheatInfo();
m_CheatIniFile->SetAutoFlush(false);
g_Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged);
m_SectionIdent = new stdstr(g_Settings->LoadStringVal(Game_IniKey));
GameChanged(NULL);
WriteTrace(TraceAppInit, TraceDebug, "Done"); WriteTrace(TraceAppInit, TraceDebug, "Done");
} }
void CSettingTypeCheats::CleanUp ( void ) void CSettingTypeCheats::CleanUp ( void )
{ {
if (m_CheatIniFile) if (CheatInfo != nullptr)
{ {
m_CheatIniFile->SetAutoFlush(true); delete CheatInfo;
delete m_CheatIniFile; CheatInfo = nullptr;
m_CheatIniFile = NULL;
}
if (m_SectionIdent)
{
delete m_SectionIdent;
m_SectionIdent = NULL;
} }
} }
void CSettingTypeCheats::FlushChanges( void ) 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 bool CSettingTypeCheats::IsSettingSet(void) const
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); 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 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;
{
return false;
}
stdstr_f Key("Cheat%d%s",Index,m_PostFix);
return m_CheatIniFile->GetString(m_SectionIdent->c_str(),Key.c_str(),"",Value);
} }
//return the default values
void CSettingTypeCheats::LoadDefault (uint32_t /*Index*/, bool & /*Value*/ ) const void CSettingTypeCheats::LoadDefault (uint32_t /*Index*/, bool & /*Value*/ ) const
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
@ -114,7 +123,6 @@ void CSettingTypeCheats::LoadDefault (uint32_t /*Index*/, std::string & /*Value*
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
//Update the settings
void CSettingTypeCheats::Save (uint32_t /*Index*/, bool /*Value*/ ) void CSettingTypeCheats::Save (uint32_t /*Index*/, bool /*Value*/ )
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); 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 ) void CSettingTypeCheats::Save (uint32_t Index, const std::string & Value )
{ {
if (!m_CheatsModified) if (CheatInfo != nullptr)
{ {
CopyCheats(); CheatInfo->Save(m_PostFix.c_str(), Index, Value.c_str());
m_CheatsModified = true;
g_Settings->SaveBool(Cheat_Modified, true);
} }
g_Settings->SaveStringIndex(m_UserSetting, Index, Value.c_str());
} }
void CSettingTypeCheats::Save (uint32_t Index, const char * Value ) void CSettingTypeCheats::Save (uint32_t Index, const char * Value )
{ {
if (!m_CheatsModified) if (CheatInfo != nullptr)
{ {
CopyCheats(); CheatInfo->Save(m_PostFix.c_str(), Index, Value);
m_CheatsModified = true;
g_Settings->SaveBool(Cheat_Modified, true);
} }
g_Settings->SaveStringIndex(m_UserSetting, Index, Value);
} }
void CSettingTypeCheats::Delete (uint32_t Index ) void CSettingTypeCheats::Delete (uint32_t Index )
{ {
if (!m_CheatsModified) if (CheatInfo != nullptr)
{ {
CopyCheats(); CheatInfo->Delete(m_PostFix.c_str(), Index);
m_CheatsModified = true;
g_Settings->SaveBool(Cheat_Modified, true);
} }
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; bool Scanned = false;
if (!g_Settings->LoadStringIndex(Cheat_Entry, i, Value)) {
CGuard Guard(m_CS);
Scanned = m_Scanned;
}
if (Scanned)
{ {
break; break;
} }
g_Settings->SaveStringIndex(Cheat_UserEntry, i, Value); Sleep(100);
if (g_Settings->LoadStringIndex(Cheat_Notes, i, Value)) }
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); m_CheatIniFile = std::make_unique<CIniFile>(CheatFile);
} m_CheatIniFile->SetCustomSort(CustomSortData);
if (g_Settings->LoadStringIndex(Cheat_Options, i, Value))
{
g_Settings->SaveStringIndex(Cheat_UserOptions, i, Value);
} }
} }
} }
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<CIniFile> UserIniFile = std::make_unique<CIniFile>(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;
}

View File

@ -17,7 +17,7 @@ class CSettingTypeCheats :
public CSettingType public CSettingType
{ {
public: public:
CSettingTypeCheats(const char * PostFix, SettingID UserSetting); CSettingTypeCheats(const char * PostFix);
~CSettingTypeCheats(); ~CSettingTypeCheats();
virtual bool IndexBasedSetting ( void ) const { return true; } virtual bool IndexBasedSetting ( void ) const { return true; }
@ -51,11 +51,9 @@ public:
protected: protected:
static void GameChanged(void * /*Data */); static void GameChanged(void * /*Data */);
static CIniFile * m_CheatIniFile; //static CIniFile * m_CheatIniFile;
static std::string * m_SectionIdent; static std::string * m_SectionIdent;
static bool m_CheatsModified; std::string m_PostFix;
const char * const m_PostFix;
SettingID m_UserSetting;
private: private:
CSettingTypeCheats(void); // Disable default constructor CSettingTypeCheats(void); // Disable default constructor

View File

@ -36,9 +36,11 @@ enum SettingID
SupportFile_VideoRDBDefault, SupportFile_VideoRDBDefault,
SupportFile_AudioRDB, SupportFile_AudioRDB,
SupportFile_AudioRDBDefault, SupportFile_AudioRDBDefault,
SupportFile_Cheats, SupportFile_CheatDir,
SupportFile_CheatsDefault, SupportFile_CheatDirDefault,
SupportFile_Enhancements, SupportFile_UserCheatDir,
SupportFile_UserCheatDirDefault,
SupportFile_Enhancements,
SupportFile_EnhancementsDefault, SupportFile_EnhancementsDefault,
SupportFile_Notes, SupportFile_Notes,
SupportFile_NotesDefault, SupportFile_NotesDefault,
@ -334,13 +336,9 @@ enum SettingID
Logging_LogUnknown, Logging_LogUnknown,
//Cheats //Cheats
Cheat_Modified,
Cheat_Entry, Cheat_Entry,
Cheat_Notes, Cheat_Notes,
Cheat_Options, Cheat_Options,
Cheat_UserEntry,
Cheat_UserNotes,
Cheat_UserOptions,
Cheat_Active, Cheat_Active,
Cheat_Extension, Cheat_Extension,

View File

@ -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%\Bin\Release%VSPlatform%\Project64.exe" "%base_dir%\Bin\Package"
copy "%base_dir%\Config\Video.rdb" "%base_dir%\Bin\Package\Config" 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\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.enh" "%base_dir%\Bin\Package\Config"
copy "%base_dir%\Config\Project64.rdb" "%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" copy "%base_dir%\Config\Project64.rdx" "%base_dir%\Bin\Package\Config"