Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #9886 from AdmiralCurtiss/cheat-search
Reimplement Cheat Search.
  • Loading branch information
JMC47 committed Sep 15, 2021
2 parents 94cfbfc + 55397b6 commit 57a8ee0
Show file tree
Hide file tree
Showing 16 changed files with 1,918 additions and 704 deletions.
4 changes: 4 additions & 0 deletions Source/Core/Core/CMakeLists.txt
Expand Up @@ -15,6 +15,10 @@ add_library(core
BootManager.cpp
BootManager.h
CheatCodes.h
CheatGeneration.cpp
CheatGeneration.h
CheatSearch.cpp
CheatSearch.h
CommonTitles.h
Config/DefaultLocale.cpp
Config/DefaultLocale.h
Expand Down
77 changes: 77 additions & 0 deletions Source/Core/Core/CheatGeneration.cpp
@@ -0,0 +1,77 @@
// Copyright 2021 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <vector>

#include <fmt/format.h>

#include "Core/CheatGeneration.h"

#include "Common/Align.h"
#include "Common/CommonTypes.h"
#include "Common/Result.h"
#include "Common/Swap.h"

#include "Core/ActionReplay.h"
#include "Core/CheatSearch.h"

constexpr int AR_SET_BYTE_CMD = 0x00;
constexpr int AR_SET_SHORT_CMD = 0x02;
constexpr int AR_SET_INT_CMD = 0x04;

static std::vector<ActionReplay::AREntry> ResultToAREntries(u32 addr, const Cheats::SearchValue& sv)
{
std::vector<ActionReplay::AREntry> codes;
std::vector<u8> data = Cheats::GetValueAsByteVector(sv);

for (size_t i = 0; i < data.size(); ++i)
{
const u32 address = (addr + i) & 0x01ff'ffffu;
if (Common::AlignUp(address, 4) == address && i + 3 < data.size())
{
const u8 cmd = AR_SET_INT_CMD;
const u32 val = Common::swap32(&data[i]);
codes.emplace_back((cmd << 24) | address, val);
i += 3;
}
else if (Common::AlignUp(address, 2) == address && i + 1 < data.size())
{
const u8 cmd = AR_SET_SHORT_CMD;
const u32 val = Common::swap16(&data[i]);
codes.emplace_back((cmd << 24) | address, val);
++i;
}
else
{
const u8 cmd = AR_SET_BYTE_CMD;
const u32 val = data[i];
codes.emplace_back((cmd << 24) | address, val);
}
}

return codes;
}

Common::Result<Cheats::GenerateActionReplayCodeErrorCode, ActionReplay::ARCode>
Cheats::GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index)
{
if (index >= session.GetResultCount())
return Cheats::GenerateActionReplayCodeErrorCode::IndexOutOfRange;

if (session.GetResultValueState(index) != Cheats::SearchResultValueState::ValueFromVirtualMemory)
return Cheats::GenerateActionReplayCodeErrorCode::NotVirtualMemory;

u32 address = session.GetResultAddress(index);

// check if the address is actually addressable by the ActionReplay system
if (((address & 0x01ff'ffffu) | 0x8000'0000u) != address)
return Cheats::GenerateActionReplayCodeErrorCode::InvalidAddress;

ActionReplay::ARCode ar_code;
ar_code.enabled = true;
ar_code.user_defined = true;
ar_code.name = fmt::format("Generated by Cheat Search (Address 0x{:08x})", address);
ar_code.ops = ResultToAREntries(address, session.GetResultValueAsSearchValue(index));

return ar_code;
}
23 changes: 23 additions & 0 deletions Source/Core/Core/CheatGeneration.h
@@ -0,0 +1,23 @@
// Copyright 2021 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "Common/Result.h"

#include "Core/ActionReplay.h"

namespace Cheats
{
class CheatSearchSessionBase;

enum class GenerateActionReplayCodeErrorCode
{
IndexOutOfRange,
NotVirtualMemory,
InvalidAddress,
};

Common::Result<GenerateActionReplayCodeErrorCode, ActionReplay::ARCode>
GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index);
} // namespace Cheats

0 comments on commit 57a8ee0

Please sign in to comment.