Merge pull request #2279 from lioncash/cheat-global

file_sys/cheat_engine: Remove use of global system accessors
This commit is contained in:
bunnei 2019-03-22 18:41:44 -04:00 committed by GitHub
commit 819dd93257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 49 deletions

View File

@ -460,8 +460,8 @@ Tegra::DebugContext* System::GetGPUDebugContext() const {
void System::RegisterCheatList(const std::vector<FileSys::CheatList>& list, void System::RegisterCheatList(const std::vector<FileSys::CheatList>& list,
const std::string& build_id, VAddr code_region_start, const std::string& build_id, VAddr code_region_start,
VAddr code_region_end) { VAddr code_region_end) {
impl->cheat_engine = impl->cheat_engine = std::make_unique<FileSys::CheatEngine>(*this, list, build_id,
std::make_unique<FileSys::CheatEngine>(list, build_id, code_region_start, code_region_end); code_region_start, code_region_end);
} }
void System::SetFilesystem(std::shared_ptr<FileSys::VfsFilesystem> vfs) { void System::SetFilesystem(std::shared_ptr<FileSys::VfsFilesystem> vfs) {

View File

@ -11,14 +11,13 @@
#include "core/core_timing_util.h" #include "core/core_timing_util.h"
#include "core/file_sys/cheat_engine.h" #include "core/file_sys/cheat_engine.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
namespace FileSys { namespace FileSys {
constexpr u64 CHEAT_ENGINE_TICKS = Core::Timing::BASE_CLOCK_RATE / 60; constexpr s64 CHEAT_ENGINE_TICKS = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60);
constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF; constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF;
u64 Cheat::Address() const { u64 Cheat::Address() const {
@ -77,8 +76,8 @@ void CheatList::Execute() {
} }
} }
CheatList::CheatList(ProgramSegment master, ProgramSegment standard) CheatList::CheatList(const Core::System& system_, ProgramSegment master, ProgramSegment standard)
: master_list(master), standard_list(standard) {} : master_list{std::move(master)}, standard_list{std::move(standard)}, system{&system_} {}
bool CheatList::EvaluateConditional(const Cheat& cheat) const { bool CheatList::EvaluateConditional(const Cheat& cheat) const {
using ComparisonFunction = bool (*)(u64, u64); using ComparisonFunction = bool (*)(u64, u64);
@ -89,10 +88,8 @@ bool CheatList::EvaluateConditional(const Cheat& cheat) const {
}; };
if (cheat.type == CodeType::ConditionalInput) { if (cheat.type == CodeType::ConditionalInput) {
const auto applet_resource = Core::System::GetInstance() const auto applet_resource =
.ServiceManager() system->ServiceManager().GetService<Service::HID::Hid>("hid")->GetAppletResource();
.GetService<Service::HID::Hid>("hid")
->GetAppletResource();
if (applet_resource == nullptr) { if (applet_resource == nullptr) {
LOG_WARNING( LOG_WARNING(
Common_Filesystem, Common_Filesystem,
@ -188,8 +185,9 @@ void CheatList::Loop(const Cheat& cheat) {
ASSERT(iter != block_pairs.end()); ASSERT(iter != block_pairs.end());
ASSERT(iter->first < iter->second); ASSERT(iter->first < iter->second);
for (int i = cheat.Value(4, 4); i >= 0; --i) { const s32 initial_value = static_cast<s32>(cheat.Value(4, sizeof(s32)));
register_3 = i; for (s32 i = initial_value; i >= 0; --i) {
register_3 = static_cast<u64>(i);
for (std::size_t c = iter->first + 1; c < iter->second; ++c) { for (std::size_t c = iter->first + 1; c < iter->second; ++c) {
current_index = c; current_index = c;
ExecuteSingleCheat( ExecuteSingleCheat(
@ -320,14 +318,14 @@ void CheatList::ExecuteBlock(const Block& block) {
CheatParser::~CheatParser() = default; CheatParser::~CheatParser() = default;
CheatList CheatParser::MakeCheatList(CheatList::ProgramSegment master, CheatList CheatParser::MakeCheatList(const Core::System& system, CheatList::ProgramSegment master,
CheatList::ProgramSegment standard) const { CheatList::ProgramSegment standard) const {
return {master, standard}; return {system, std::move(master), std::move(standard)};
} }
TextCheatParser::~TextCheatParser() = default; TextCheatParser::~TextCheatParser() = default;
CheatList TextCheatParser::Parse(const std::vector<u8>& data) const { CheatList TextCheatParser::Parse(const Core::System& system, const std::vector<u8>& data) const {
std::stringstream ss; std::stringstream ss;
ss.write(reinterpret_cast<const char*>(data.data()), data.size()); ss.write(reinterpret_cast<const char*>(data.data()), data.size());
@ -375,7 +373,7 @@ CheatList TextCheatParser::Parse(const std::vector<u8>& data) const {
} }
} }
return MakeCheatList(master_list, standard_list); return MakeCheatList(system, master_list, standard_list);
} }
std::array<u8, 16> TextCheatParser::ParseSingleLineCheat(const std::string& line) const { std::array<u8, 16> TextCheatParser::ParseSingleLineCheat(const std::string& line) const {
@ -460,16 +458,16 @@ void MemoryWriteImpl(u32 width, VAddr addr, u64 value) {
} }
} }
CheatEngine::CheatEngine(std::vector<CheatList> cheats, const std::string& build_id, CheatEngine::CheatEngine(Core::System& system, std::vector<CheatList> cheats_,
VAddr code_region_start, VAddr code_region_end) const std::string& build_id, VAddr code_region_start,
: cheats(std::move(cheats)) { VAddr code_region_end)
auto& core_timing{Core::System::GetInstance().CoreTiming()}; : cheats{std::move(cheats_)}, core_timing{system.CoreTiming()} {
event = core_timing.RegisterEvent( event = core_timing.RegisterEvent(
"CheatEngine::FrameCallback::" + build_id, "CheatEngine::FrameCallback::" + build_id,
[this](u64 userdata, s64 cycles_late) { FrameCallback(userdata, cycles_late); }); [this](u64 userdata, s64 cycles_late) { FrameCallback(userdata, cycles_late); });
core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS, event); core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS, event);
const auto& vm_manager = Core::System::GetInstance().CurrentProcess()->VMManager(); const auto& vm_manager = system.CurrentProcess()->VMManager();
for (auto& list : this->cheats) { for (auto& list : this->cheats) {
list.SetMemoryParameters(code_region_start, vm_manager.GetHeapRegionBaseAddress(), list.SetMemoryParameters(code_region_start, vm_manager.GetHeapRegionBaseAddress(),
code_region_end, vm_manager.GetHeapRegionEndAddress(), code_region_end, vm_manager.GetHeapRegionEndAddress(),
@ -478,15 +476,14 @@ CheatEngine::CheatEngine(std::vector<CheatList> cheats, const std::string& build
} }
CheatEngine::~CheatEngine() { CheatEngine::~CheatEngine() {
auto& core_timing{Core::System::GetInstance().CoreTiming()};
core_timing.UnscheduleEvent(event, 0); core_timing.UnscheduleEvent(event, 0);
} }
void CheatEngine::FrameCallback(u64 userdata, int cycles_late) { void CheatEngine::FrameCallback(u64 userdata, s64 cycles_late) {
for (auto& list : cheats) for (auto& list : cheats) {
list.Execute(); list.Execute();
}
auto& core_timing{Core::System::GetInstance().CoreTiming()};
core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS - cycles_late, event); core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS - cycles_late, event);
} }

View File

@ -7,14 +7,18 @@
#include <map> #include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include <queue>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_types.h" #include "common/common_types.h"
namespace Core::Timing { namespace Core {
struct EventType; class System;
} }
namespace Core::Timing {
class CoreTiming;
struct EventType;
} // namespace Core::Timing
namespace FileSys { namespace FileSys {
enum class CodeType : u32 { enum class CodeType : u32 {
@ -133,7 +137,7 @@ public:
void Execute(); void Execute();
private: private:
CheatList(ProgramSegment master, ProgramSegment standard); CheatList(const Core::System& system_, ProgramSegment master, ProgramSegment standard);
void ProcessBlockPairs(const Block& block); void ProcessBlockPairs(const Block& block);
void ExecuteSingleCheat(const Cheat& cheat); void ExecuteSingleCheat(const Cheat& cheat);
@ -183,6 +187,8 @@ private:
std::map<u64, u64> block_pairs; std::map<u64, u64> block_pairs;
std::set<u64> encountered_loops; std::set<u64> encountered_loops;
const Core::System* system;
}; };
// Intermediary class that parses a text file or other disk format for storing cheats into a // Intermediary class that parses a text file or other disk format for storing cheats into a
@ -191,10 +197,10 @@ class CheatParser {
public: public:
virtual ~CheatParser(); virtual ~CheatParser();
virtual CheatList Parse(const std::vector<u8>& data) const = 0; virtual CheatList Parse(const Core::System& system, const std::vector<u8>& data) const = 0;
protected: protected:
CheatList MakeCheatList(CheatList::ProgramSegment master, CheatList MakeCheatList(const Core::System& system_, CheatList::ProgramSegment master,
CheatList::ProgramSegment standard) const; CheatList::ProgramSegment standard) const;
}; };
@ -203,7 +209,7 @@ class TextCheatParser final : public CheatParser {
public: public:
~TextCheatParser() override; ~TextCheatParser() override;
CheatList Parse(const std::vector<u8>& data) const override; CheatList Parse(const Core::System& system, const std::vector<u8>& data) const override;
private: private:
std::array<u8, 16> ParseSingleLineCheat(const std::string& line) const; std::array<u8, 16> ParseSingleLineCheat(const std::string& line) const;
@ -212,16 +218,17 @@ private:
// Class that encapsulates a CheatList and manages its interaction with memory and CoreTiming // Class that encapsulates a CheatList and manages its interaction with memory and CoreTiming
class CheatEngine final { class CheatEngine final {
public: public:
CheatEngine(std::vector<CheatList> cheats, const std::string& build_id, VAddr code_region_start, CheatEngine(Core::System& system_, std::vector<CheatList> cheats_, const std::string& build_id,
VAddr code_region_end); VAddr code_region_start, VAddr code_region_end);
~CheatEngine(); ~CheatEngine();
private: private:
void FrameCallback(u64 userdata, int cycles_late); void FrameCallback(u64 userdata, s64 cycles_late);
Core::Timing::EventType* event;
std::vector<CheatList> cheats; std::vector<CheatList> cheats;
Core::Timing::EventType* event;
Core::Timing::CoreTiming& core_timing;
}; };
} // namespace FileSys } // namespace FileSys

View File

@ -233,7 +233,7 @@ bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const {
return !CollectPatches(patch_dirs, build_id).empty(); return !CollectPatches(patch_dirs, build_id).empty();
} }
static std::optional<CheatList> ReadCheatFileFromFolder(u64 title_id, static std::optional<CheatList> ReadCheatFileFromFolder(const Core::System& system, u64 title_id,
const std::array<u8, 0x20>& build_id_, const std::array<u8, 0x20>& build_id_,
const VirtualDir& base_path, bool upper) { const VirtualDir& base_path, bool upper) {
const auto build_id_raw = Common::HexArrayToString(build_id_, upper); const auto build_id_raw = Common::HexArrayToString(build_id_, upper);
@ -254,28 +254,28 @@ static std::optional<CheatList> ReadCheatFileFromFolder(u64 title_id,
} }
TextCheatParser parser; TextCheatParser parser;
return parser.Parse(data); return parser.Parse(system, data);
} }
std::vector<CheatList> PatchManager::CreateCheatList(const std::array<u8, 32>& build_id_) const { std::vector<CheatList> PatchManager::CreateCheatList(const Core::System& system,
std::vector<CheatList> out; const std::array<u8, 32>& build_id_) const {
const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id);
auto patch_dirs = load_dir->GetSubdirectories(); auto patch_dirs = load_dir->GetSubdirectories();
std::sort(patch_dirs.begin(), patch_dirs.end(), std::sort(patch_dirs.begin(), patch_dirs.end(),
[](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
std::vector<CheatList> out;
out.reserve(patch_dirs.size()); out.reserve(patch_dirs.size());
for (const auto& subdir : patch_dirs) { for (const auto& subdir : patch_dirs) {
auto cheats_dir = subdir->GetSubdirectory("cheats"); auto cheats_dir = subdir->GetSubdirectory("cheats");
if (cheats_dir != nullptr) { if (cheats_dir != nullptr) {
auto res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, true); auto res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, true);
if (res.has_value()) { if (res.has_value()) {
out.push_back(std::move(*res)); out.push_back(std::move(*res));
continue; continue;
} }
res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, false); res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, false);
if (res.has_value()) if (res.has_value())
out.push_back(std::move(*res)); out.push_back(std::move(*res));
} }

View File

@ -12,6 +12,10 @@
#include "core/file_sys/nca_metadata.h" #include "core/file_sys/nca_metadata.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
namespace Core {
class System;
}
namespace FileSys { namespace FileSys {
class NCA; class NCA;
@ -47,7 +51,8 @@ public:
bool HasNSOPatch(const std::array<u8, 0x20>& build_id) const; bool HasNSOPatch(const std::array<u8, 0x20>& build_id) const;
// Creates a CheatList object with all // Creates a CheatList object with all
std::vector<CheatList> CreateCheatList(const std::array<u8, 0x20>& build_id) const; std::vector<CheatList> CreateCheatList(const Core::System& system,
const std::array<u8, 0x20>& build_id) const;
// Currently tracked RomFS patches: // Currently tracked RomFS patches:
// - Game Updates // - Game Updates

View File

@ -169,11 +169,11 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
// Apply cheats if they exist and the program has a valid title ID // Apply cheats if they exist and the program has a valid title ID
if (pm) { if (pm) {
const auto cheats = pm->CreateCheatList(nso_header.build_id); auto& system = Core::System::GetInstance();
const auto cheats = pm->CreateCheatList(system, nso_header.build_id);
if (!cheats.empty()) { if (!cheats.empty()) {
Core::System::GetInstance().RegisterCheatList( system.RegisterCheatList(cheats, Common::HexArrayToString(nso_header.build_id),
cheats, Common::HexArrayToString(nso_header.build_id), load_base, load_base, load_base + program_image.size());
load_base + program_image.size());
} }
} }