summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-12-11 10:40:03 +0100
committerGitHub <noreply@github.com>2020-12-11 10:40:03 +0100
commit7d9276c3401d99d601bcd6fb1ca1e2c9cd4a3e97 (patch)
treef0d5e8bd197d828a6826ee4ffe800fff9e135463 /Source
parentfd5c69deca4aa988a445b29c6c2292d586c0bf45 (diff)
parent36ecfdd6b597b0264625d06320a5308147bbc55b (diff)
Merge pull request #9317 from JosJuice/default-enabled-codes
GameSettings: Enable compatibility patches by default
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/ActionReplay.cpp45
-rw-r--r--Source/Core/Core/ActionReplay.h5
-rw-r--r--Source/Core/Core/CMakeLists.txt1
-rw-r--r--Source/Core/Core/CheatCodes.h38
-rw-r--r--Source/Core/Core/Core.vcxproj1
-rw-r--r--Source/Core/Core/Core.vcxproj.filters1
-rw-r--r--Source/Core/Core/GeckoCode.h1
-rw-r--r--Source/Core/Core/GeckoCodeConfig.cpp39
-rw-r--r--Source/Core/Core/NetPlayClient.cpp2
-rw-r--r--Source/Core/Core/PatchEngine.cpp29
-rw-r--r--Source/Core/Core/PatchEngine.h3
-rw-r--r--Source/Core/DolphinQt/CheatsManager.cpp2
-rw-r--r--Source/Core/DolphinQt/Config/ARCodeWidget.cpp6
-rw-r--r--Source/Core/DolphinQt/Config/NewPatchDialog.cpp2
-rw-r--r--Source/Core/DolphinQt/Config/PatchesWidget.cpp18
15 files changed, 113 insertions, 80 deletions
diff --git a/Source/Core/Core/ActionReplay.cpp b/Source/Core/Core/ActionReplay.cpp
index 8a432b99ec..f3641f72bc 100644
--- a/Source/Core/Core/ActionReplay.cpp
+++ b/Source/Core/Core/ActionReplay.cpp
@@ -26,7 +26,6 @@
#include <iterator>
#include <mutex>
#include <string>
-#include <unordered_set>
#include <utility>
#include <vector>
@@ -39,6 +38,7 @@
#include "Common/MsgHandler.h"
#include "Core/ARDecrypt.h"
+#include "Core/CheatCodes.h"
#include "Core/ConfigManager.h"
#include "Core/PowerPC/MMU.h"
@@ -120,7 +120,7 @@ void ApplyCodes(const std::vector<ARCode>& codes)
s_disable_logging = false;
s_active_codes.clear();
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes),
- [](const ARCode& code) { return code.active; });
+ [](const ARCode& code) { return code.enabled; });
s_active_codes.shrink_to_fit();
}
@@ -136,7 +136,7 @@ void UpdateSyncedCodes(const std::vector<ARCode>& codes)
s_synced_codes.clear();
s_synced_codes.reserve(codes.size());
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_synced_codes),
- [](const ARCode& code) { return code.active; });
+ [](const ARCode& code) { return code.enabled; });
s_synced_codes.shrink_to_fit();
}
@@ -148,7 +148,7 @@ std::vector<ARCode> ApplyAndReturnCodes(const std::vector<ARCode>& codes)
s_disable_logging = false;
s_active_codes.clear();
std::copy_if(codes.begin(), codes.end(), std::back_inserter(s_active_codes),
- [](const ARCode& code) { return code.active; });
+ [](const ARCode& code) { return code.enabled; });
}
s_active_codes.shrink_to_fit();
@@ -160,7 +160,7 @@ void AddCode(ARCode code)
if (!SConfig::GetInstance().bEnableCheats)
return;
- if (code.active)
+ if (code.enabled)
{
std::lock_guard<std::mutex> guard(s_lock);
s_disable_logging = false;
@@ -178,20 +178,6 @@ std::vector<ARCode> LoadCodes(const IniFile& global_ini, const IniFile& local_in
{
std::vector<ARCode> codes;
- std::unordered_set<std::string> enabled_names;
- {
- std::vector<std::string> enabled_lines;
- local_ini.GetLines("ActionReplay_Enabled", &enabled_lines);
- for (const std::string& line : enabled_lines)
- {
- if (!line.empty() && line[0] == '$')
- {
- std::string name = line.substr(1, line.size() - 1);
- enabled_names.insert(name);
- }
- }
- }
-
const IniFile* inis[2] = {&global_ini, &local_ini};
for (const IniFile* ini : inis)
{
@@ -225,7 +211,6 @@ std::vector<ARCode> LoadCodes(const IniFile& global_ini, const IniFile& local_in
}
current_code.name = line.substr(1, line.size() - 1);
- current_code.active = enabled_names.find(current_code.name) != enabled_names.end();
current_code.user_defined = (ini == &local_ini);
}
else
@@ -279,6 +264,14 @@ std::vector<ARCode> LoadCodes(const IniFile& global_ini, const IniFile& local_in
DecryptARCode(encrypted_lines, &current_code.ops);
codes.push_back(current_code);
}
+
+ ReadEnabledAndDisabled(*ini, "ActionReplay", &codes);
+
+ if (ini == &global_ini)
+ {
+ for (ARCode& code : codes)
+ code.default_enabled = code.enabled;
+ }
}
return codes;
@@ -288,21 +281,27 @@ void SaveCodes(IniFile* local_ini, const std::vector<ARCode>& codes)
{
std::vector<std::string> lines;
std::vector<std::string> enabled_lines;
+ std::vector<std::string> disabled_lines;
+
for (const ActionReplay::ARCode& code : codes)
{
- if (code.active)
- enabled_lines.emplace_back("$" + code.name);
+ if (code.enabled)
+ enabled_lines.emplace_back('$' + code.name);
+ else if (code.default_enabled)
+ disabled_lines.emplace_back('$' + code.name);
if (code.user_defined)
{
- lines.emplace_back("$" + code.name);
+ lines.emplace_back('$' + code.name);
for (const ActionReplay::AREntry& op : code.ops)
{
lines.emplace_back(fmt::format("{:08X} {:08X}", op.cmd_addr, op.value));
}
}
}
+
local_ini->SetLines("ActionReplay_Enabled", enabled_lines);
+ local_ini->SetLines("ActionReplay_Disabled", disabled_lines);
local_ini->SetLines("ActionReplay", lines);
}
diff --git a/Source/Core/Core/ActionReplay.h b/Source/Core/Core/ActionReplay.h
index b42e2f08b0..e79c6d4f38 100644
--- a/Source/Core/Core/ActionReplay.h
+++ b/Source/Core/Core/ActionReplay.h
@@ -28,8 +28,9 @@ struct ARCode
{
std::string name;
std::vector<AREntry> ops;
- bool active;
- bool user_defined;
+ bool enabled = false;
+ bool default_enabled = false;
+ bool user_defined = false;
};
void RunAllActive();
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 6da101c42e..72835324a7 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(core
ARDecrypt.h
BootManager.cpp
BootManager.h
+ CheatCodes.h
CommonTitles.h
ConfigManager.cpp
ConfigManager.h
diff --git a/Source/Core/Core/CheatCodes.h b/Source/Core/Core/CheatCodes.h
new file mode 100644
index 0000000000..a440f9ed6a
--- /dev/null
+++ b/Source/Core/Core/CheatCodes.h
@@ -0,0 +1,38 @@
+// Copyright 2020 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "Common/IniFile.h"
+
+template <typename T>
+void ReadEnabledOrDisabled(const IniFile& ini, const std::string& section, bool enabled,
+ std::vector<T>* codes)
+{
+ std::vector<std::string> lines;
+ ini.GetLines(section, &lines, false);
+
+ for (const std::string& line : lines)
+ {
+ if (line.empty() || line[0] != '$')
+ continue;
+
+ for (T& code : *codes)
+ {
+ // Exclude the initial '$' from the comparison.
+ if (line.compare(1, std::string::npos, code.name) == 0)
+ code.enabled = enabled;
+ }
+ }
+}
+
+template <typename T>
+void ReadEnabledAndDisabled(const IniFile& ini, const std::string& section, std::vector<T>* codes)
+{
+ ReadEnabledOrDisabled(ini, section + "_Enabled", true, codes);
+ ReadEnabledOrDisabled(ini, section + "_Disabled", false, codes);
+}
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 35dd58d202..a7ada5b18e 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -384,6 +384,7 @@
<ClInclude Include="Boot\DolReader.h" />
<ClInclude Include="Boot\ElfReader.h" />
<ClInclude Include="Boot\ElfTypes.h" />
+ <ClInclude Include="CheatCodes.h" />
<ClInclude Include="Config\GraphicsSettings.h" />
<ClInclude Include="Config\MainSettings.h" />
<ClInclude Include="Config\NetplaySettings.h" />
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 73b159219f..749b81b9c2 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -1765,6 +1765,7 @@
<Filter>HW %28Flipper/Hollywood%29\EXI - Expansion Interface\BBA</Filter>
</ClInclude>
<ClInclude Include="SyncIdentifier.h" />
+ <ClInclude Include="CheatCodes.h" />
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
diff --git a/Source/Core/Core/GeckoCode.h b/Source/Core/Core/GeckoCode.h
index 9c6c7c7a14..74d750bcf4 100644
--- a/Source/Core/Core/GeckoCode.h
+++ b/Source/Core/Core/GeckoCode.h
@@ -29,6 +29,7 @@ public:
std::vector<std::string> notes;
bool enabled = false;
+ bool default_enabled = false;
bool user_defined = false;
bool Exist(u32 address, u32 data) const;
diff --git a/Source/Core/Core/GeckoCodeConfig.cpp b/Source/Core/Core/GeckoCodeConfig.cpp
index d11035306f..605fb82533 100644
--- a/Source/Core/Core/GeckoCodeConfig.cpp
+++ b/Source/Core/Core/GeckoCodeConfig.cpp
@@ -13,6 +13,7 @@
#include "Common/IniFile.h"
#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
+#include "Core/CheatCodes.h"
namespace Gecko
{
@@ -190,23 +191,12 @@ std::vector<GeckoCode> LoadCodes(const IniFile& globalIni, const IniFile& localI
gcodes.push_back(gcode);
}
- ini->GetLines("Gecko_Enabled", &lines, false);
+ ReadEnabledAndDisabled(*ini, "Gecko", &gcodes);
- for (const std::string& line : lines)
+ if (ini == &globalIni)
{
- if (line.empty() || line[0] != '$')
- {
- continue;
- }
-
- for (GeckoCode& ogcode : gcodes)
- {
- // Exclude the initial '$' from the comparison.
- if (line.compare(1, std::string::npos, ogcode.name) == 0)
- {
- ogcode.enabled = true;
- }
- }
+ for (GeckoCode& code : gcodes)
+ code.default_enabled = code.enabled;
}
}
@@ -226,12 +216,8 @@ static std::string MakeGeckoCodeTitle(const GeckoCode& code)
}
// used by the SaveGeckoCodes function
-static void SaveGeckoCode(std::vector<std::string>& lines, std::vector<std::string>& enabledLines,
- const GeckoCode& gcode)
+static void SaveGeckoCode(std::vector<std::string>& lines, const GeckoCode& gcode)
{
- if (gcode.enabled)
- enabledLines.push_back('$' + gcode.name);
-
if (!gcode.user_defined)
return;
@@ -251,14 +237,21 @@ static void SaveGeckoCode(std::vector<std::string>& lines, std::vector<std::stri
void SaveCodes(IniFile& inifile, const std::vector<GeckoCode>& gcodes)
{
std::vector<std::string> lines;
- std::vector<std::string> enabledLines;
+ std::vector<std::string> enabled_lines;
+ std::vector<std::string> disabled_lines;
for (const GeckoCode& geckoCode : gcodes)
{
- SaveGeckoCode(lines, enabledLines, geckoCode);
+ if (geckoCode.enabled)
+ enabled_lines.emplace_back('$' + geckoCode.name);
+ else if (geckoCode.default_enabled)
+ disabled_lines.emplace_back('$' + geckoCode.name);
+
+ SaveGeckoCode(lines, geckoCode);
}
inifile.SetLines("Gecko", lines);
- inifile.SetLines("Gecko_Enabled", enabledLines);
+ inifile.SetLines("Gecko_Enabled", enabled_lines);
+ inifile.SetLines("Gecko_Disabled", disabled_lines);
}
} // namespace Gecko
diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp
index 4a2d168173..5dee4b3405 100644
--- a/Source/Core/Core/NetPlayClient.cpp
+++ b/Source/Core/Core/NetPlayClient.cpp
@@ -1158,7 +1158,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
arcode = ActionReplay::ARCode();
// Initialize arcode
arcode.name = "Synced Codes";
- arcode.active = true;
+ arcode.enabled = true;
// Receive code contents from packet
for (int i = 0; i < m_sync_ar_codes_count; i++)
diff --git a/Source/Core/Core/PatchEngine.cpp b/Source/Core/Core/PatchEngine.cpp
index f249d33c7a..4f4daafcd7 100644
--- a/Source/Core/Core/PatchEngine.cpp
+++ b/Source/Core/Core/PatchEngine.cpp
@@ -12,7 +12,6 @@
#include <array>
#include <iterator>
#include <map>
-#include <set>
#include <string>
#include <vector>
@@ -21,6 +20,7 @@
#include "Common/StringUtil.h"
#include "Core/ActionReplay.h"
+#include "Core/CheatCodes.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/GeckoCode.h"
@@ -47,20 +47,6 @@ const char* PatchTypeAsString(PatchType type)
void LoadPatchSection(const std::string& section, std::vector<Patch>& patches, IniFile& globalIni,
IniFile& localIni)
{
- // Load the name of all enabled patches
- std::string enabledSectionName = section + "_Enabled";
- std::vector<std::string> enabledLines;
- std::set<std::string> enabledNames;
- localIni.GetLines(enabledSectionName, &enabledLines);
- for (const std::string& line : enabledLines)
- {
- if (!line.empty() && line[0] == '$')
- {
- std::string name = line.substr(1, line.size() - 1);
- enabledNames.insert(name);
- }
- }
-
const IniFile* inis[2] = {&globalIni, &localIni};
for (const IniFile* ini : inis)
@@ -83,9 +69,8 @@ void LoadPatchSection(const std::string& section, std::vector<Patch>& patches, I
}
currentPatch.entries.clear();
- // Set active and name
+ // Set name and whether the patch is user defined
currentPatch.name = line.substr(1, line.size() - 1);
- currentPatch.active = enabledNames.find(currentPatch.name) != enabledNames.end();
currentPatch.user_defined = (ini == &localIni);
}
else
@@ -123,6 +108,14 @@ void LoadPatchSection(const std::string& section, std::vector<Patch>& patches, I
{
patches.push_back(currentPatch);
}
+
+ ReadEnabledAndDisabled(*ini, section, &patches);
+
+ if (ini == &globalIni)
+ {
+ for (Patch& patch : patches)
+ patch.default_enabled = patch.enabled;
+ }
}
}
@@ -185,7 +178,7 @@ static void ApplyPatches(const std::vector<Patch>& patches)
{
for (const Patch& patch : patches)
{
- if (patch.active)
+ if (patch.enabled)
{
for (const PatchEntry& entry : patch.entries)
{
diff --git a/Source/Core/Core/PatchEngine.h b/Source/Core/Core/PatchEngine.h
index 7e3ae628db..a496f04936 100644
--- a/Source/Core/Core/PatchEngine.h
+++ b/Source/Core/Core/PatchEngine.h
@@ -33,7 +33,8 @@ struct Patch
{
std::string name;
std::vector<PatchEntry> entries;
- bool active = false;
+ bool enabled = false;
+ bool default_enabled = false;
bool user_defined = false; // False if this code is shipped with Dolphin.
};
diff --git a/Source/Core/DolphinQt/CheatsManager.cpp b/Source/Core/DolphinQt/CheatsManager.cpp
index 3c0dc72e76..860f6e6110 100644
--- a/Source/Core/DolphinQt/CheatsManager.cpp
+++ b/Source/Core/DolphinQt/CheatsManager.cpp
@@ -292,7 +292,7 @@ void CheatsManager::GenerateARCode()
int index = item->data(INDEX_ROLE).toInt();
ActionReplay::ARCode ar_code;
- ar_code.active = true;
+ ar_code.enabled = true;
ar_code.user_defined = true;
ar_code.name = tr("Generated by search (Address %1)")
.arg(m_watch[index].address, 8, 16, QLatin1Char('0'))
diff --git a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp
index eca7ccf705..4a1769ff3b 100644
--- a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp
+++ b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp
@@ -89,7 +89,7 @@ void ARCodeWidget::ConnectWidgets()
void ARCodeWidget::OnItemChanged(QListWidgetItem* item)
{
- m_ar_codes[m_code_list->row(item)].active = (item->checkState() == Qt::Checked);
+ m_ar_codes[m_code_list->row(item)].enabled = (item->checkState() == Qt::Checked);
if (!m_restart_required)
ActionReplay::ApplyCodes(m_ar_codes);
@@ -159,7 +159,7 @@ void ARCodeWidget::UpdateList()
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |
Qt::ItemIsDragEnabled);
- item->setCheckState(ar.active ? Qt::Checked : Qt::Unchecked);
+ item->setCheckState(ar.enabled ? Qt::Checked : Qt::Unchecked);
item->setData(Qt::UserRole, static_cast<int>(i));
m_code_list->addItem(item);
@@ -190,7 +190,7 @@ void ARCodeWidget::AddCode(ActionReplay::ARCode code)
void ARCodeWidget::OnCodeAddClicked()
{
ActionReplay::ARCode ar;
- ar.active = true;
+ ar.enabled = true;
CheatCodeEditor ed(this);
ed.SetARCode(&ar);
diff --git a/Source/Core/DolphinQt/Config/NewPatchDialog.cpp b/Source/Core/DolphinQt/Config/NewPatchDialog.cpp
index 9ee9e76218..b72506be49 100644
--- a/Source/Core/DolphinQt/Config/NewPatchDialog.cpp
+++ b/Source/Core/DolphinQt/Config/NewPatchDialog.cpp
@@ -34,7 +34,7 @@ NewPatchDialog::NewPatchDialog(QWidget* parent, PatchEngine::Patch& patch)
if (m_patch.entries.empty())
{
AddEntry();
- m_patch.active = true;
+ m_patch.enabled = true;
}
}
diff --git a/Source/Core/DolphinQt/Config/PatchesWidget.cpp b/Source/Core/DolphinQt/Config/PatchesWidget.cpp
index bb9025008a..1ac7f55154 100644
--- a/Source/Core/DolphinQt/Config/PatchesWidget.cpp
+++ b/Source/Core/DolphinQt/Config/PatchesWidget.cpp
@@ -65,7 +65,7 @@ void PatchesWidget::ConnectWidgets()
void PatchesWidget::OnItemChanged(QListWidgetItem* item)
{
- m_patches[m_list->row(item)].active = (item->checkState() == Qt::Checked);
+ m_patches[m_list->row(item)].enabled = (item->checkState() == Qt::Checked);
SavePatches();
}
@@ -129,21 +129,24 @@ void PatchesWidget::SavePatches()
{
std::vector<std::string> lines;
std::vector<std::string> lines_enabled;
+ std::vector<std::string> lines_disabled;
for (const auto& patch : m_patches)
{
- if (patch.active)
- lines_enabled.push_back("$" + patch.name);
+ if (patch.enabled)
+ lines_enabled.emplace_back('$' + patch.name);
+ else if (patch.default_enabled)
+ lines_disabled.emplace_back('$' + patch.name);
if (!patch.user_defined)
continue;
- lines.push_back("$" + patch.name);
+ lines.emplace_back('$' + patch.name);
for (const auto& entry : patch.entries)
{
- lines.push_back(StringFromFormat("0x%08X:%s:0x%08X", entry.address,
- PatchEngine::PatchTypeAsString(entry.type), entry.value));
+ lines.emplace_back(StringFromFormat("0x%08X:%s:0x%08X", entry.address,
+ PatchEngine::PatchTypeAsString(entry.type), entry.value));
}
}
@@ -151,6 +154,7 @@ void PatchesWidget::SavePatches()
game_ini_local.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini");
game_ini_local.SetLines("OnFrame_Enabled", lines_enabled);
+ game_ini_local.SetLines("OnFrame_Disabled", lines_disabled);
game_ini_local.SetLines("OnFrame", lines);
game_ini_local.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini");
@@ -164,7 +168,7 @@ void PatchesWidget::Update()
{
auto* item = new QListWidgetItem(QString::fromStdString(patch.name));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
- item->setCheckState(patch.active ? Qt::Checked : Qt::Unchecked);
+ item->setCheckState(patch.enabled ? Qt::Checked : Qt::Unchecked);
item->setData(Qt::UserRole, patch.user_defined);
m_list->addItem(item);