@@ -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)
{
@@ -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.
};

@@ -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'))
@@ -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);
@@ -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;
}
}

@@ -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,28 +129,32 @@ 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));
}
}

IniFile game_ini_local;
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);