2014-08-13 12:54:27 +00:00
|
|
|
#include "stdafx.h"
|
2014-08-23 00:16:54 +00:00
|
|
|
#include "rpcs3/Ini.h"
|
2014-08-13 12:54:27 +00:00
|
|
|
#include "AutoPause.h"
|
2014-08-22 14:21:55 +00:00
|
|
|
#include "Utilities/Log.h"
|
2015-04-24 21:38:11 +00:00
|
|
|
#include "Utilities/File.h"
|
2014-08-22 14:21:55 +00:00
|
|
|
#include "Emu/System.h"
|
2014-08-13 12:54:27 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-08-17 07:53:09 +00:00
|
|
|
//Still use binary format. Default Setting should be "disable all auto pause".
|
2014-08-13 12:54:27 +00:00
|
|
|
AutoPause::AutoPause(void)
|
|
|
|
{
|
|
|
|
m_pause_function.reserve(16);
|
|
|
|
m_pause_syscall.reserve(16);
|
|
|
|
initialized = false;
|
|
|
|
//Reload(false, false);
|
2014-08-14 15:22:13 +00:00
|
|
|
Reload();
|
2014-08-13 12:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//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;
|
|
|
|
}
|
|
|
|
|
2014-08-17 07:53:09 +00:00
|
|
|
//Load Auto Pause Configuration from file "pause.bin"
|
2014-08-13 12:54:27 +00:00
|
|
|
//This would be able to create in a GUI window.
|
|
|
|
void AutoPause::Reload(void)
|
|
|
|
{
|
2015-04-24 21:38:11 +00:00
|
|
|
if (fs::is_file("pause.bin"))
|
2014-08-13 12:54:27 +00:00
|
|
|
{
|
|
|
|
m_pause_function.clear();
|
|
|
|
m_pause_function.reserve(16);
|
|
|
|
m_pause_syscall.clear();
|
|
|
|
m_pause_syscall.reserve(16);
|
|
|
|
|
2015-04-24 21:38:11 +00:00
|
|
|
fs::file list("pause.bin");
|
2014-08-13 12:54:27 +00:00
|
|
|
//System calls ID and Function calls ID are all u32 iirc.
|
|
|
|
u32 num;
|
2015-04-19 13:19:24 +00:00
|
|
|
size_t fmax = list.size();
|
2014-08-13 12:54:27 +00:00
|
|
|
size_t fcur = 0;
|
2015-04-19 13:19:24 +00:00
|
|
|
list.seek(0);
|
2014-08-13 12:54:27 +00:00
|
|
|
while (fcur <= fmax - sizeof(u32))
|
|
|
|
{
|
2015-04-19 13:19:24 +00:00
|
|
|
list.read(&num, sizeof(u32));
|
2014-08-13 12:54:27 +00:00
|
|
|
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);
|
2014-09-29 15:38:04 +00:00
|
|
|
LOG_WARNING(HLE, "Auto Pause: Find System Call ID 0x%x", num);
|
2014-08-13 12:54:27 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_pause_function.emplace_back(num);
|
2014-09-29 15:38:04 +00:00
|
|
|
LOG_WARNING(HLE, "Auto Pause: Find Function Call ID 0x%x", num);
|
2014-08-13 12:54:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-19 17:14:16 +00:00
|
|
|
|
2014-08-14 15:22:13 +00:00
|
|
|
m_pause_syscall_enable = Ini.DBGAutoPauseSystemCall.GetValue();
|
|
|
|
m_pause_function_enable = Ini.DBGAutoPauseFunctionCall.GetValue();
|
2014-08-13 12:54:27 +00:00
|
|
|
initialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2014-09-29 15:38:04 +00:00
|
|
|
LOG_ERROR(HLE, "Auto Pause Triggered: System call 0x%x", code); // Used Error
|
2014-08-13 12:54:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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();
|
2014-09-29 15:38:04 +00:00
|
|
|
LOG_ERROR(HLE, "Auto Pause Triggered: Function call 0x%x", code); // Used Error
|
2014-08-13 12:54:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-19 17:14:16 +00:00
|
|
|
}
|