forked from eden-emu/eden
		
	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.
This commit is contained in:
		
							parent
							
								
									245c751cbf
								
							
						
					
					
						commit
						b59b7084c7
					
				
					 6 changed files with 52 additions and 44 deletions
				
			
		|  | @ -460,8 +460,8 @@ Tegra::DebugContext* System::GetGPUDebugContext() const { | |||
| void System::RegisterCheatList(const std::vector<FileSys::CheatList>& list, | ||||
|                                const std::string& build_id, VAddr code_region_start, | ||||
|                                VAddr code_region_end) { | ||||
|     impl->cheat_engine = | ||||
|         std::make_unique<FileSys::CheatEngine>(list, build_id, code_region_start, code_region_end); | ||||
|     impl->cheat_engine = std::make_unique<FileSys::CheatEngine>(*this, list, build_id, | ||||
|                                                                 code_region_start, code_region_end); | ||||
| } | ||||
| 
 | ||||
| void System::SetFilesystem(std::shared_ptr<FileSys::VfsFilesystem> vfs) { | ||||
|  |  | |||
|  | @ -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<Service::HID::Hid>("hid") | ||||
|                                          ->GetAppletResource(); | ||||
|         const auto applet_resource = | ||||
|             system->ServiceManager().GetService<Service::HID::Hid>("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<u8>& data) const { | ||||
| CheatList TextCheatParser::Parse(const Core::System& system, const std::vector<u8>& data) const { | ||||
|     std::stringstream ss; | ||||
|     ss.write(reinterpret_cast<const char*>(data.data()), data.size()); | ||||
| 
 | ||||
|  | @ -375,7 +372,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 { | ||||
|  | @ -460,16 +457,16 @@ void MemoryWriteImpl(u32 width, VAddr addr, u64 value) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| CheatEngine::CheatEngine(std::vector<CheatList> 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<CheatList> 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<CheatList> 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); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,14 +7,18 @@ | |||
| #include <map> | ||||
| #include <set> | ||||
| #include <vector> | ||||
| #include <queue> | ||||
| #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<u64, u64> block_pairs; | ||||
| 
 | ||||
|     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
 | ||||
|  | @ -191,10 +197,10 @@ class CheatParser { | |||
| public: | ||||
|     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: | ||||
|     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<u8>& data) const override; | ||||
|     CheatList Parse(const Core::System& system, const std::vector<u8>& data) const override; | ||||
| 
 | ||||
| private: | ||||
|     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 CheatEngine final { | ||||
| public: | ||||
|     CheatEngine(std::vector<CheatList> cheats, const std::string& build_id, VAddr code_region_start, | ||||
|                 VAddr code_region_end); | ||||
|     CheatEngine(Core::System& system_, std::vector<CheatList> 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<CheatList> cheats; | ||||
| 
 | ||||
|     Core::Timing::EventType* event; | ||||
|     Core::Timing::CoreTiming& core_timing; | ||||
| }; | ||||
| 
 | ||||
| } // namespace FileSys
 | ||||
|  |  | |||
|  | @ -233,7 +233,7 @@ bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const { | |||
|     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 VirtualDir& base_path, bool 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; | ||||
|     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> out; | ||||
| 
 | ||||
| std::vector<CheatList> PatchManager::CreateCheatList(const Core::System& system, | ||||
|                                                      const std::array<u8, 32>& 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<CheatList> 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)); | ||||
|         } | ||||
|  |  | |||
|  | @ -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<u8, 0x20>& build_id) const; | ||||
| 
 | ||||
|     // 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:
 | ||||
|     // - Game Updates
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|     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()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lioncash
						Lioncash