From ea00c3a07f0b66b19a56a49e970db168cdfa89d8 Mon Sep 17 00:00:00 2001 From: luxsie <877033040@qq.com> Date: Wed, 13 Aug 2014 20:54:27 +0800 Subject: [PATCH] Auto-Pause At Function Call and System Call. Would have a configuration window (with create the list, and enable/disable, being something similar to VFSManger and etc). Move the code to Debug::AutoPause in AutoPause.cpp and AutoPause.h It triggers currently in GameViewer, and would finally change to somewhere else. Well and now it is all enabled (Function call + System call) by default. --- Utilities/AutoPause.cpp | 130 +++++++++++++++++++++++++++ Utilities/AutoPause.h | 29 ++++++ rpcs3/Emu/SysCalls/ModuleManager.cpp | 47 ---------- rpcs3/Emu/SysCalls/ModuleManager.h | 2 - rpcs3/Emu/SysCalls/SysCalls.cpp | 4 + rpcs3/Gui/GameViewer.cpp | 4 + rpcs3/emucore.vcxproj | 2 + rpcs3/emucore.vcxproj.filters | 6 ++ 8 files changed, 175 insertions(+), 49 deletions(-) create mode 100644 Utilities/AutoPause.cpp create mode 100644 Utilities/AutoPause.h diff --git a/Utilities/AutoPause.cpp b/Utilities/AutoPause.cpp new file mode 100644 index 0000000000..ad7e3ddd80 --- /dev/null +++ b/Utilities/AutoPause.cpp @@ -0,0 +1,130 @@ +#include "stdafx.h" +#include "AutoPause.h" + +using namespace Debug; + +//Even different from those tutorials on webpages, i use the method similiar from Log.h +//TODO:: Question: Does such a Singleton struct get fully deallocated after its pointer? +AutoPause* gAutoPause = nullptr; + +AutoPause& AutoPause::getInstance(void) +{ + if (!gAutoPause) + { + gAutoPause = new AutoPause(); + } + return *gAutoPause; +} + +//Still use binary format. Default Setting should be "disable all auto-pause". +AutoPause::AutoPause(void) +{ + m_pause_function.reserve(16); + m_pause_syscall.reserve(16); + initialized = false; + //Reload(false, false); + Reload(true, true); //Temporarily use auto enable +} + +//Notice: I would not allow to write the binary to file in this command. +AutoPause::~AutoPause(void) +{ + initialized = false; + m_pause_function.clear(); + m_pause_syscall.clear(); + m_pause_function_enable = false; + m_pause_syscall_enable = false; +} + +//Load Auto-Pause Configuration from file "pause.bin" +//This would be able to create in a GUI window. +void AutoPause::Reload(void) +{ + if (rExists("pause.bin")) + { + m_pause_function.clear(); + m_pause_function.reserve(16); + m_pause_syscall.clear(); + m_pause_syscall.reserve(16); + + rFile list; + list.Open("pause.bin", rFile::read); + //System calls ID and Function calls ID are all u32 iirc. + u32 num; + size_t fmax = list.Length(); + size_t fcur = 0; + list.Seek(0); + while (fcur <= fmax - sizeof(u32)) + { + list.Read(&num, sizeof(u32)); + fcur += sizeof(u32); + if (num == 0xFFFFFFFF) break; + + if (num < 1024) + { + //Less than 1024 - be regarded as a system call. + //emplace_back may not cause reductant move/copy operation. + m_pause_syscall.emplace_back(num); + LOG_WARNING(HLE, "Auto-Pause: Find System Call ID %x", num); + } + else + { + m_pause_function.emplace_back(num); + LOG_WARNING(HLE, "Auto-Pause: Find Function Call ID %x", num); + } + } + list.Close(); + } + else + { + LOG_WARNING(HLE, "No Pause ID specified in pause.bin, Auto-Pause would not act."); + } + + initialized = true; +} + +void AutoPause::Reload(bool enable_pause_syscall, bool enable_pause_function) +{ + Reload(); + m_pause_syscall_enable = enable_pause_syscall; + m_pause_function_enable = enable_pause_function; +} + +void AutoPause::TryPause(u32 code) { + if (code < 1024) + { + //Would first check Enable setting. Then the list length. + if ((!m_pause_syscall_enable) + || (m_pause_syscall.size() <= 0)) + { + return; + } + + for (u32 i = 0; i < m_pause_syscall.size(); ++i) + { + if (code == m_pause_syscall[i]) + { + Emu.Pause(); + LOG_ERROR(HLE, "Auto-Pause Triggered: System call %x", code); //Used Error + } + } + } + else + { + //Well similiar.. Seperate the list caused by possible setting difference. + if ((!m_pause_function_enable) + || (m_pause_function.size() <= 0)) + { + return; + } + + for (u32 i = 0; i < m_pause_function.size(); ++i) + { + if (code == m_pause_function[i]) + { + Emu.Pause(); + LOG_ERROR(HLE, "Auto-Pause Triggered: Function call %x", code); //Used Error + } + } + } +} \ No newline at end of file diff --git a/Utilities/AutoPause.h b/Utilities/AutoPause.h new file mode 100644 index 0000000000..b62ed47eb9 --- /dev/null +++ b/Utilities/AutoPause.h @@ -0,0 +1,29 @@ +#pragma once +#include "Utilities/Log.h" +#include "Utilities/rFile.h" +#include "Emu/System.h" + +//Regarded as a Debugger Enchantment +namespace Debug { + //To store the pause function/call id, and let those pause there. + //Would be with a GUI to configure those. + struct AutoPause + { + std::vector m_pause_syscall; + std::vector m_pause_function; + bool initialized; + bool m_pause_syscall_enable; + bool m_pause_function_enable; + + AutoPause(); + ~AutoPause(); + public: + static AutoPause& getInstance(void); + + void Reload(bool enable_pause_syscall, bool enable_pause_function); + + void Reload(void); + + void TryPause(u32 code); + }; +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp index 57f8085848..5e1d472032 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ b/rpcs3/Emu/SysCalls/ModuleManager.cpp @@ -263,7 +263,6 @@ void ModuleManager::init() m_mod_init.emplace_back(0x000e, sys_fs_init); initialized = true; } - LoadFuncPauses(); //Load the list of pause functions } ModuleManager::ModuleManager() : @@ -294,17 +293,6 @@ bool ModuleManager::IsLoadedFunc(u32 id) bool ModuleManager::CallFunc(u32 num) { - //Pause at specified function calls - for (u32 i = 0; i < m_funcs_pause_funcs.size(); ++i) - { - //Add Call Pause Here. This call is from BLJS10157 - if (num == m_funcs_pause_funcs[i]) - { - Emu.Pause(); //So it is now pause, yep. - LOG_ERROR(HLE, "AUTO PAUSE AT %x", num); //Used Error - } - } - func_caller* func = nullptr; { std::lock_guard lock(m_funcs_lock); @@ -375,9 +363,6 @@ void ModuleManager::UnloadModules() std::lock_guard lock(m_funcs_lock); m_modules_funcs_list.clear(); - - //unload pause list - m_funcs_pause_funcs.clear(); } Module* ModuleManager::GetModuleByName(const std::string& name) @@ -477,36 +462,4 @@ void ModuleManager::AddFunc(ModuleFunc *func) { m_modules_funcs_list.push_back(func); } -} - -//read pause.bin to get some function id that should auto-pause at call. -//you can make this file with Hex Editors, such as MadEdit.. -//you can find the function ids in \rpcs3\rpcs3\Emu\SysCalls\FuncList.cpp -//or just by searching the function name with grep within repo. -//Example if i want it to pause at 0x1051d134, i create the file with 34D15110(Hex, start from 00). -void ModuleManager::LoadFuncPauses(void) -{ - if (rExists("pause.bin")) - { - m_funcs_pause_funcs.reserve(16); - rFile list; - list.Open("pause.bin", rFile::read); - u32 num; - size_t fmax = list.Length(); - size_t fcur = 0; - list.Seek(0); - while (fcur <= fmax - sizeof(u32)) - { - list.Read(&num, sizeof(u32)); - fcur += sizeof(u32); - if (num == 0xFFFFFFFF) break; - m_funcs_pause_funcs.push_back(num); - LOG_WARNING(HLE, "Read Pause Function ID: %x", num); - } - list.Close(); - } - else - { - LOG_WARNING(HLE, "No Pause Function ID specified in pause.bin"); - } } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/ModuleManager.h b/rpcs3/Emu/SysCalls/ModuleManager.h index 8b10ec24c7..4ff1c96f40 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.h +++ b/rpcs3/Emu/SysCalls/ModuleManager.h @@ -10,7 +10,6 @@ class ModuleManager std::vector m_modules_funcs_list; std::vector m_mod_init; bool initialized; - std::vector m_funcs_pause_funcs; public: ModuleManager(); ~ModuleManager(); @@ -25,5 +24,4 @@ public: u32 GetFuncNumById(u32 id); Module* GetModuleByName(const std::string& name); Module* GetModuleById(u16 id); - void LoadFuncPauses(void); }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index d908755f74..da13269249 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" +#include "Utilities/AutoPause.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/PPUThread.h" @@ -919,6 +920,9 @@ void default_syscall() void SysCalls::DoSyscall(u32 code) { + //Auto-Pause using simple singleton. + Debug::AutoPause::getInstance().TryPause(code); + if(code < 1024) { (*sc_table[code])(); diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index f709031bb8..77d1b017c5 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/AutoPause.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -204,6 +205,9 @@ void GameViewer::DClick(wxListEvent& event) const std::string& path = m_path + m_game_data[i].root; Emu.Stop(); + + Debug::AutoPause::getInstance().Reload(); + Emu.GetVFS().Init(path); std::string local_path; if (Emu.GetVFS().GetDevice(path, local_path) && !Emu.BootGame(local_path)) { diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 37ce298aca..81ff0fdffb 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -27,6 +27,7 @@ + @@ -211,6 +212,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index b5828b0a70..034c7a7020 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -590,6 +590,9 @@ Emu\SysCalls\lv2 + + Utilities + @@ -1123,5 +1126,8 @@ Emu\SysCalls\lv2 + + Utilities + \ No newline at end of file