From 540235bb05ecd18b958f9ef2a667d94fedca61af Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 22 Mar 2019 06:08:11 -0400 Subject: [PATCH 1/2] file_sys/cheat_engine: Remove use of global system accessors Instead, pass in the core timing instance and make the dependency explicit in the interface. --- src/core/core.cpp | 4 ++-- src/core/file_sys/cheat_engine.cpp | 34 +++++++++++++---------------- src/core/file_sys/cheat_engine.h | 29 ++++++++++++++---------- src/core/file_sys/patch_manager.cpp | 14 ++++++------ src/core/file_sys/patch_manager.h | 7 +++++- src/core/loader/nso.cpp | 8 +++---- 6 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index a88e332be7..4fe77c25b8 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -460,8 +460,8 @@ Tegra::DebugContext* System::GetGPUDebugContext() const { void System::RegisterCheatList(const std::vector& list, const std::string& build_id, VAddr code_region_start, VAddr code_region_end) { - impl->cheat_engine = - std::make_unique(list, build_id, code_region_start, code_region_end); + impl->cheat_engine = std::make_unique(*this, list, build_id, + code_region_start, code_region_end); } void System::SetFilesystem(std::shared_ptr vfs) { diff --git a/src/core/file_sys/cheat_engine.cpp b/src/core/file_sys/cheat_engine.cpp index 09ca9d7050..1cbdc60204 100644 --- a/src/core/file_sys/cheat_engine.cpp +++ b/src/core/file_sys/cheat_engine.cpp @@ -11,7 +11,6 @@ #include "core/core_timing_util.h" #include "core/file_sys/cheat_engine.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/hid.h" #include "core/hle/service/sm/sm.h" @@ -77,8 +76,8 @@ void CheatList::Execute() { } } -CheatList::CheatList(ProgramSegment master, ProgramSegment standard) - : master_list(master), standard_list(standard) {} +CheatList::CheatList(const Core::System& system_, ProgramSegment master, ProgramSegment standard) + : master_list{std::move(master)}, standard_list{std::move(standard)}, system{&system_} {} bool CheatList::EvaluateConditional(const Cheat& cheat) const { using ComparisonFunction = bool (*)(u64, u64); @@ -89,10 +88,8 @@ bool CheatList::EvaluateConditional(const Cheat& cheat) const { }; if (cheat.type == CodeType::ConditionalInput) { - const auto applet_resource = Core::System::GetInstance() - .ServiceManager() - .GetService("hid") - ->GetAppletResource(); + const auto applet_resource = + system->ServiceManager().GetService("hid")->GetAppletResource(); if (applet_resource == nullptr) { LOG_WARNING( Common_Filesystem, @@ -320,14 +317,14 @@ void CheatList::ExecuteBlock(const Block& block) { CheatParser::~CheatParser() = default; -CheatList CheatParser::MakeCheatList(CheatList::ProgramSegment master, +CheatList CheatParser::MakeCheatList(const Core::System& system, CheatList::ProgramSegment master, CheatList::ProgramSegment standard) const { - return {master, standard}; + return {system, std::move(master), std::move(standard)}; } TextCheatParser::~TextCheatParser() = default; -CheatList TextCheatParser::Parse(const std::vector& data) const { +CheatList TextCheatParser::Parse(const Core::System& system, const std::vector& data) const { std::stringstream ss; ss.write(reinterpret_cast(data.data()), data.size()); @@ -375,7 +372,7 @@ CheatList TextCheatParser::Parse(const std::vector& data) const { } } - return MakeCheatList(master_list, standard_list); + return MakeCheatList(system, master_list, standard_list); } std::array TextCheatParser::ParseSingleLineCheat(const std::string& line) const { @@ -460,16 +457,16 @@ void MemoryWriteImpl(u32 width, VAddr addr, u64 value) { } } -CheatEngine::CheatEngine(std::vector cheats, const std::string& build_id, - VAddr code_region_start, VAddr code_region_end) - : cheats(std::move(cheats)) { - auto& core_timing{Core::System::GetInstance().CoreTiming()}; +CheatEngine::CheatEngine(Core::System& system, std::vector cheats_, + const std::string& build_id, VAddr code_region_start, + VAddr code_region_end) + : cheats{std::move(cheats_)}, core_timing{system.CoreTiming()} { event = core_timing.RegisterEvent( "CheatEngine::FrameCallback::" + build_id, [this](u64 userdata, s64 cycles_late) { FrameCallback(userdata, cycles_late); }); 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) { list.SetMemoryParameters(code_region_start, vm_manager.GetHeapRegionBaseAddress(), code_region_end, vm_manager.GetHeapRegionEndAddress(), @@ -478,15 +475,14 @@ CheatEngine::CheatEngine(std::vector cheats, const std::string& build } CheatEngine::~CheatEngine() { - auto& core_timing{Core::System::GetInstance().CoreTiming()}; core_timing.UnscheduleEvent(event, 0); } void CheatEngine::FrameCallback(u64 userdata, int cycles_late) { - for (auto& list : cheats) + for (auto& list : cheats) { list.Execute(); + } - auto& core_timing{Core::System::GetInstance().CoreTiming()}; core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS - cycles_late, event); } diff --git a/src/core/file_sys/cheat_engine.h b/src/core/file_sys/cheat_engine.h index 7ed69a2c82..c2de3198c3 100644 --- a/src/core/file_sys/cheat_engine.h +++ b/src/core/file_sys/cheat_engine.h @@ -7,14 +7,18 @@ #include #include #include -#include #include "common/bit_field.h" #include "common/common_types.h" -namespace Core::Timing { -struct EventType; +namespace Core { +class System; } +namespace Core::Timing { +class CoreTiming; +struct EventType; +} // namespace Core::Timing + namespace FileSys { enum class CodeType : u32 { @@ -133,7 +137,7 @@ public: void Execute(); private: - CheatList(ProgramSegment master, ProgramSegment standard); + CheatList(const Core::System& system_, ProgramSegment master, ProgramSegment standard); void ProcessBlockPairs(const Block& block); void ExecuteSingleCheat(const Cheat& cheat); @@ -183,6 +187,8 @@ private: std::map block_pairs; std::set encountered_loops; + + const Core::System* system; }; // Intermediary class that parses a text file or other disk format for storing cheats into a @@ -191,10 +197,10 @@ class CheatParser { public: virtual ~CheatParser(); - virtual CheatList Parse(const std::vector& data) const = 0; + virtual CheatList Parse(const Core::System& system, const std::vector& data) const = 0; protected: - CheatList MakeCheatList(CheatList::ProgramSegment master, + CheatList MakeCheatList(const Core::System& system_, CheatList::ProgramSegment master, CheatList::ProgramSegment standard) const; }; @@ -203,7 +209,7 @@ class TextCheatParser final : public CheatParser { public: ~TextCheatParser() override; - CheatList Parse(const std::vector& data) const override; + CheatList Parse(const Core::System& system, const std::vector& data) const override; private: std::array 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 CheatEngine final { public: - CheatEngine(std::vector cheats, const std::string& build_id, VAddr code_region_start, - VAddr code_region_end); + CheatEngine(Core::System& system_, std::vector cheats_, const std::string& build_id, + VAddr code_region_start, VAddr code_region_end); ~CheatEngine(); private: void FrameCallback(u64 userdata, int cycles_late); - Core::Timing::EventType* event; - std::vector cheats; + + Core::Timing::EventType* event; + Core::Timing::CoreTiming& core_timing; }; } // namespace FileSys diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 2b09e5d359..58884b4a02 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -233,7 +233,7 @@ bool PatchManager::HasNSOPatch(const std::array& build_id_) const { return !CollectPatches(patch_dirs, build_id).empty(); } -static std::optional ReadCheatFileFromFolder(u64 title_id, +static std::optional ReadCheatFileFromFolder(const Core::System& system, u64 title_id, const std::array& build_id_, const VirtualDir& base_path, bool upper) { const auto build_id_raw = Common::HexArrayToString(build_id_, upper); @@ -254,28 +254,28 @@ static std::optional ReadCheatFileFromFolder(u64 title_id, } TextCheatParser parser; - return parser.Parse(data); + return parser.Parse(system, data); } -std::vector PatchManager::CreateCheatList(const std::array& build_id_) const { - std::vector out; - +std::vector PatchManager::CreateCheatList(const Core::System& system, + const std::array& build_id_) const { const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); auto patch_dirs = load_dir->GetSubdirectories(); std::sort(patch_dirs.begin(), patch_dirs.end(), [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); + std::vector out; out.reserve(patch_dirs.size()); for (const auto& subdir : patch_dirs) { auto cheats_dir = subdir->GetSubdirectory("cheats"); 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()) { out.push_back(std::move(*res)); continue; } - res = ReadCheatFileFromFolder(title_id, build_id_, cheats_dir, false); + res = ReadCheatFileFromFolder(system, title_id, build_id_, cheats_dir, false); if (res.has_value()) out.push_back(std::move(*res)); } diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 3e3ac6aca0..de2672c76e 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -12,6 +12,10 @@ #include "core/file_sys/nca_metadata.h" #include "core/file_sys/vfs.h" +namespace Core { +class System; +} + namespace FileSys { class NCA; @@ -47,7 +51,8 @@ public: bool HasNSOPatch(const std::array& build_id) const; // Creates a CheatList object with all - std::vector CreateCheatList(const std::array& build_id) const; + std::vector CreateCheatList(const Core::System& system, + const std::array& build_id) const; // Currently tracked RomFS patches: // - Game Updates diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 0eb9fd7f70..7494f8a286 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -169,11 +169,11 @@ std::optional AppLoader_NSO::LoadModule(Kernel::Process& process, // Apply cheats if they exist and the program has a valid title ID 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()) { - Core::System::GetInstance().RegisterCheatList( - cheats, Common::HexArrayToString(nso_header.build_id), load_base, - load_base + program_image.size()); + system.RegisterCheatList(cheats, Common::HexArrayToString(nso_header.build_id), + load_base, load_base + program_image.size()); } } From 733cf179b84a098955f0b7296d90da0aac3ddf7b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 22 Mar 2019 11:08:04 -0400 Subject: [PATCH 2/2] file_sys/cheat_engine: Silence truncation and sign-conversion warnings --- src/core/file_sys/cheat_engine.cpp | 9 +++++---- src/core/file_sys/cheat_engine.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/file_sys/cheat_engine.cpp b/src/core/file_sys/cheat_engine.cpp index 1cbdc60204..247fbc864d 100644 --- a/src/core/file_sys/cheat_engine.cpp +++ b/src/core/file_sys/cheat_engine.cpp @@ -17,7 +17,7 @@ namespace FileSys { -constexpr u64 CHEAT_ENGINE_TICKS = Core::Timing::BASE_CLOCK_RATE / 60; +constexpr s64 CHEAT_ENGINE_TICKS = static_cast(Core::Timing::BASE_CLOCK_RATE / 60); constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF; u64 Cheat::Address() const { @@ -185,8 +185,9 @@ void CheatList::Loop(const Cheat& cheat) { ASSERT(iter != block_pairs.end()); ASSERT(iter->first < iter->second); - for (int i = cheat.Value(4, 4); i >= 0; --i) { - register_3 = i; + const s32 initial_value = static_cast(cheat.Value(4, sizeof(s32))); + for (s32 i = initial_value; i >= 0; --i) { + register_3 = static_cast(i); for (std::size_t c = iter->first + 1; c < iter->second; ++c) { current_index = c; ExecuteSingleCheat( @@ -478,7 +479,7 @@ CheatEngine::~CheatEngine() { 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) { list.Execute(); } diff --git a/src/core/file_sys/cheat_engine.h b/src/core/file_sys/cheat_engine.h index c2de3198c3..ac22a82cb1 100644 --- a/src/core/file_sys/cheat_engine.h +++ b/src/core/file_sys/cheat_engine.h @@ -223,7 +223,7 @@ public: ~CheatEngine(); private: - void FrameCallback(u64 userdata, int cycles_late); + void FrameCallback(u64 userdata, s64 cycles_late); std::vector cheats;