diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index bdcd9dee00..44713fec8d 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -530,7 +530,7 @@ namespace ppu_patterns }; } -void ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::basic_string& applied) +bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::basic_string& applied, std::function check_aborted) { // Assume first segment is executable const u32 start = segs[0].addr; @@ -841,6 +841,11 @@ void ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b // Main loop (func_queue may grow) for (usz i = 0; i < func_queue.size(); i++) { + if (check_aborted && check_aborted()) + { + return false; + } + ppu_function& func = func_queue[i]; // Fixup TOCs @@ -1843,6 +1848,7 @@ void ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b } ppu_log.notice("Block analysis: %zu blocks (%zu enqueued)", funcs.size(), block_queue.size()); + return true; } // Temporarily diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 77ca15c509..c82408856e 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -70,15 +70,15 @@ struct ppu_segment // PPU Module Information struct ppu_module { - ppu_module() = default; + ppu_module() noexcept = default; ppu_module(const ppu_module&) = delete; - ppu_module(ppu_module&&) = default; + ppu_module(ppu_module&&) noexcept = default; ppu_module& operator=(const ppu_module&) = delete; - ppu_module& operator=(ppu_module&&) = default; + ppu_module& operator=(ppu_module&&) noexcept = default; uchar sha1[20]{}; std::string name{}; @@ -101,10 +101,17 @@ struct ppu_module secs = info.secs; } - void analyse(u32 lib_toc, u32 entry, u32 end, const std::basic_string& applied); + bool analyse(u32 lib_toc, u32 entry, u32 end, const std::basic_string& applied, std::function check_aborted = {}); void validate(u32 reloc); }; +struct main_ppu_module : public ppu_module +{ + u32 elf_entry; + u32 seg0_code_end; + std::basic_string applied_pathes; +}; + // Aux struct ppu_pattern { diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 98dd4ddda5..e311abee2e 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -961,7 +961,7 @@ static auto ppu_load_imports(std::vector& relocs, ppu_linkage_info* l // For _sys_prx_register_module void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags) { - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get(); auto& link = g_fxo->get(); ppu_load_exports(&link, exports_start, exports_start + exports_size, false, &loaded_flags); @@ -1158,7 +1158,7 @@ static void ppu_check_patch_spu_images(const ppu_segment& seg) void try_spawn_ppu_if_exclusive_program(const ppu_module& m) { // If only PRX/OVL has been loaded at Emu.BootGame(), launch a single PPU thread so its memory can be viewed - if (Emu.IsReady() && g_fxo->get().segs.empty() && !Emu.DeserialManager()) + if (Emu.IsReady() && g_fxo->get().segs.empty() && !Emu.DeserialManager()) { ppu_thread_params p { @@ -1706,7 +1706,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar) init_ppu_functions(ar, false); // Set for delayed initialization in ppu_initialize() - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get(); // Access linkage information object auto& link = g_fxo->get(); @@ -2126,11 +2126,9 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar) _main.name.clear(); _main.path = vfs::get(Emu.argv[0]); - // Analyse executable (TODO) - _main.analyse(0, static_cast(elf.header.e_entry), end, applied); - - // Validate analyser results (not required) - _main.validate(0); + _main.elf_entry = static_cast(elf.header.e_entry); + _main.seg0_code_end = end; + _main.applied_pathes = applied; // Set SDK version g_ps3_process_info.sdk_ver = sdk_version; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index ea98d772d8..9f277d5b6c 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3200,7 +3200,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectoris_init()) + if (!g_fxo->is_init()) { return; } @@ -3210,9 +3210,20 @@ extern void ppu_initialize() return; } - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get(); - scoped_progress_dialog progr = "Scanning PPU modules..."; + scoped_progress_dialog progr = "Analyzing PPU Executable..."; + + // Analyse executable + if (!_main.analyse(0, _main.elf_entry, _main.seg0_code_end, _main.applied_pathes, [](){ return Emu.IsStopped(); })) + { + return; + } + + // Validate analyser results (not required) + _main.validate(0); + + g_progr = "Scanning PPU Modules..."; bool compile_main = false; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 1da9c27549..98a846aa9a 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -185,7 +185,7 @@ void Emulator::BlockingCallFromMainThread(std::function&& func) const // This function ensures constant initialization order between different compilers and builds void init_fxo_for_exec(utils::serial* ar, bool full = false) { - g_fxo->init(); + g_fxo->init(); void init_ppu_functions(utils::serial* ar, bool full); @@ -1352,7 +1352,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool { m_state = system_state::ready; GetCallbacks().on_ready(); - g_fxo->init(); + g_fxo->init(); vm::init(); m_force_boot = false; @@ -1435,7 +1435,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool if (obj == elf_error::ok && ppu_load_exec(obj)) { - g_fxo->get().path = path; + g_fxo->get().path = path; } else { @@ -1455,14 +1455,14 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool } } - if (auto& _main = g_fxo->get(); _main.path.empty()) + if (auto& _main = g_fxo->get(); _main.path.empty()) { init_fxo_for_exec(nullptr, false); } g_fxo->init("SPRX Loader"sv, [this, dir_queue]() mutable { - if (auto& _main = g_fxo->get(); !_main.path.empty()) + if (auto& _main = g_fxo->get(); !_main.path.empty()) { ppu_initialize(_main); } @@ -2020,7 +2020,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool sys_log.error("Booting HG category outside of HDD0!"); } - g_fxo->init(); + g_fxo->init(); if (ppu_load_exec(ppu_exec, DeserialManager())) { @@ -2032,7 +2032,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool } else { - // Preserve emulation state for OVL excutable + // Preserve emulation state for OVL executable Pause(true); } @@ -3026,7 +3026,7 @@ s32 error_code::error_report(s32 result, const logs::message* channel, const cha void Emulator::ConfigurePPUCache() const { - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get(); _main.cache = rpcs3::utils::get_cache_dir(); diff --git a/rpcs3/Emu/cache_utils.cpp b/rpcs3/Emu/cache_utils.cpp index e352d48143..c41897c539 100644 --- a/rpcs3/Emu/cache_utils.cpp +++ b/rpcs3/Emu/cache_utils.cpp @@ -12,9 +12,9 @@ namespace rpcs3::cache { std::string get_ppu_cache() { - auto& _main = g_fxo->get(); + auto& _main = g_fxo->get(); - if (!g_fxo->is_init() || _main.cache.empty()) + if (!g_fxo->is_init() || _main.cache.empty()) { ppu_log.error("PPU Cache location not initialized."); return {}; diff --git a/rpcs3/Emu/system_progress.hpp b/rpcs3/Emu/system_progress.hpp index 9082ec4d8c..2cb6d94fdd 100644 --- a/rpcs3/Emu/system_progress.hpp +++ b/rpcs3/Emu/system_progress.hpp @@ -18,7 +18,7 @@ class scoped_progress_dialog final const char* const m_prev; public: - scoped_progress_dialog(const char* text) + scoped_progress_dialog(const char* text) noexcept : m_prev(g_progr.exchange(text ? text : "")) { } @@ -27,7 +27,7 @@ public: scoped_progress_dialog& operator=(const scoped_progress_dialog&) = delete; - ~scoped_progress_dialog() + ~scoped_progress_dialog() noexcept { g_progr.release(m_prev); } diff --git a/rpcs3/rpcs3qt/cheat_manager.cpp b/rpcs3/rpcs3qt/cheat_manager.cpp index 22edfa07d4..218522be0e 100644 --- a/rpcs3/rpcs3qt/cheat_manager.cpp +++ b/rpcs3/rpcs3qt/cheat_manager.cpp @@ -441,7 +441,7 @@ bool cheat_engine::is_addr_safe(const u32 offset) if (Emu.IsStopped()) return false; - const auto ppum = g_fxo->try_get(); + const auto ppum = g_fxo->try_get(); if (!ppum) {