mirror of https://github.com/RPCS3/rpcs3.git
Fixed conflicts
This commit is contained in:
commit
6553909dc5
|
@ -1,97 +1,149 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
ThreadBase* GetCurrentNamedThread()
|
static DWORD g_tls_this_thread = 0xFFFFFFFF;
|
||||||
{
|
|
||||||
ThreadExec* thr = (ThreadExec*)::wxThread::This();
|
|
||||||
return thr ? thr->m_parent : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadBase::ThreadBase(bool detached, const std::string& name)
|
struct __init_tls
|
||||||
: m_detached(detached)
|
|
||||||
, m_name(name)
|
|
||||||
, m_executor(nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
//NamedThreadBase m_main_thr;
|
||||||
|
|
||||||
void ThreadBase::Start()
|
__init_tls()
|
||||||
{
|
|
||||||
if(m_executor) return;
|
|
||||||
|
|
||||||
m_executor = new ThreadExec(m_detached, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadBase::Resume()
|
|
||||||
{
|
|
||||||
if(m_executor)
|
|
||||||
{
|
{
|
||||||
m_executor->Resume();
|
g_tls_this_thread = ::TlsAlloc();
|
||||||
|
//m_main_thr.SetThreadName("Main Thread");
|
||||||
|
//::TlsSetValue(g_tls_this_thread, &m_main_thr);
|
||||||
|
::TlsSetValue(g_tls_this_thread, nullptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadBase::Pause()
|
~__init_tls()
|
||||||
{
|
|
||||||
if(m_executor)
|
|
||||||
{
|
{
|
||||||
m_executor->Pause();
|
::TlsFree(g_tls_this_thread);
|
||||||
}
|
}
|
||||||
}
|
} _init_tls;
|
||||||
|
|
||||||
void ThreadBase::Stop(bool wait)
|
NamedThreadBase* GetCurrentNamedThread()
|
||||||
{
|
{
|
||||||
if(!m_executor) return;
|
return (NamedThreadBase*)::TlsGetValue(g_tls_this_thread);
|
||||||
ThreadExec* exec = m_executor;
|
|
||||||
m_executor = nullptr;
|
|
||||||
|
|
||||||
if(!m_detached)
|
|
||||||
{
|
|
||||||
if(wait)
|
|
||||||
{
|
|
||||||
exec->Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
exec->Stop(false);
|
|
||||||
delete exec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
exec->Stop(wait);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThreadBase::Wait() const
|
std::string NamedThreadBase::GetThreadName() const
|
||||||
{
|
|
||||||
return m_executor != nullptr && m_executor->Wait() != (wxThread::ExitCode)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadBase::IsRunning() const
|
|
||||||
{
|
|
||||||
return m_executor != nullptr && m_executor->IsRunning();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadBase::IsPaused() const
|
|
||||||
{
|
|
||||||
return m_executor != nullptr && m_executor->IsPaused();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadBase::IsAlive() const
|
|
||||||
{
|
|
||||||
return m_executor != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadBase::TestDestroy() const
|
|
||||||
{
|
|
||||||
if(!m_executor || !m_executor->m_parent) return true;
|
|
||||||
|
|
||||||
return m_executor->TestDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ThreadBase::GetThreadName() const
|
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadBase::SetThreadName(const std::string& name)
|
void NamedThreadBase::SetThreadName(const std::string& name)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBase::ThreadBase(const std::string& name)
|
||||||
|
: NamedThreadBase(name)
|
||||||
|
, m_executor(nullptr)
|
||||||
|
, m_destroy(false)
|
||||||
|
, m_alive(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadBase::~ThreadBase()
|
||||||
|
{
|
||||||
|
if(IsAlive())
|
||||||
|
Stop(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadBase::Start()
|
||||||
|
{
|
||||||
|
if(m_executor) Stop();
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||||
|
|
||||||
|
m_destroy = false;
|
||||||
|
m_alive = true;
|
||||||
|
|
||||||
|
m_executor = new std::thread(
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
::TlsSetValue(g_tls_this_thread, this);
|
||||||
|
|
||||||
|
Task();
|
||||||
|
|
||||||
|
m_alive = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadBase::Stop(bool wait)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||||
|
|
||||||
|
m_destroy = true;
|
||||||
|
|
||||||
|
if(!m_executor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(wait && m_executor->joinable() && m_alive)
|
||||||
|
{
|
||||||
|
m_executor->join();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_executor->detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_executor;
|
||||||
|
m_executor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadBase::Join() const
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||||
|
if(m_executor->joinable() && m_alive && m_executor != nullptr)
|
||||||
|
{
|
||||||
|
m_executor->join();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadBase::IsAlive() const
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
||||||
|
return m_alive;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadBase::TestDestroy() const
|
||||||
|
{
|
||||||
|
return m_destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread::thread(const std::string& name, std::function<void()> func) : m_name(name)
|
||||||
|
{
|
||||||
|
start(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
thread::thread(const std::string& name) : m_name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
thread::thread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread::start(std::function<void()> func)
|
||||||
|
{
|
||||||
|
m_thr = std::thread([this, func]() { NamedThreadBase info(m_name); ::TlsSetValue(g_tls_this_thread, &info); func(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread::detach()
|
||||||
|
{
|
||||||
|
m_thr.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread::join()
|
||||||
|
{
|
||||||
|
m_thr.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thread::joinable() const
|
||||||
|
{
|
||||||
|
return m_thr.joinable();
|
||||||
}
|
}
|
|
@ -3,84 +3,68 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
class ThreadExec;
|
class ThreadExec;
|
||||||
|
|
||||||
class ThreadBase
|
class NamedThreadBase
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
bool m_detached;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::mutex m_main_mutex;
|
NamedThreadBase(const std::string& name) : m_name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
NamedThreadBase()
|
||||||
ThreadBase(bool detached = true, const std::string& name = "Unknown ThreadBase");
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadExec* m_executor;
|
|
||||||
|
|
||||||
virtual void Task()=0;
|
|
||||||
|
|
||||||
virtual void Start();
|
|
||||||
virtual void Resume();
|
|
||||||
virtual void Pause();
|
|
||||||
virtual void Stop(bool wait = true);
|
|
||||||
|
|
||||||
virtual bool Wait() const;
|
|
||||||
virtual bool IsRunning() const;
|
|
||||||
virtual bool IsPaused() const;
|
|
||||||
virtual bool IsAlive() const;
|
|
||||||
virtual bool TestDestroy() const;
|
|
||||||
virtual std::string GetThreadName() const;
|
virtual std::string GetThreadName() const;
|
||||||
virtual void SetThreadName(const std::string& name);
|
virtual void SetThreadName(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
ThreadBase* GetCurrentNamedThread();
|
NamedThreadBase* GetCurrentNamedThread();
|
||||||
|
|
||||||
class ThreadExec : public wxThread
|
class ThreadBase : public NamedThreadBase
|
||||||
{
|
{
|
||||||
std::mutex m_wait_for_exit;
|
protected:
|
||||||
volatile bool m_alive;
|
std::atomic<bool> m_destroy;
|
||||||
|
std::atomic<bool> m_alive;
|
||||||
|
std::thread* m_executor;
|
||||||
|
|
||||||
|
mutable std::mutex m_main_mutex;
|
||||||
|
|
||||||
|
ThreadBase(const std::string& name);
|
||||||
|
~ThreadBase();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ThreadBase* m_parent;
|
void Start();
|
||||||
|
void Stop(bool wait = true);
|
||||||
|
|
||||||
ThreadExec(bool detached, ThreadBase* parent)
|
bool Join() const;
|
||||||
: wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE)
|
bool IsAlive() const;
|
||||||
, m_parent(parent)
|
bool TestDestroy() const;
|
||||||
, m_alive(true)
|
|
||||||
{
|
|
||||||
Create();
|
|
||||||
Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop(bool wait = true)
|
virtual void Task() = 0;
|
||||||
{
|
|
||||||
if(!m_alive) return;
|
|
||||||
|
|
||||||
m_parent = nullptr;
|
|
||||||
|
|
||||||
if(wait)
|
|
||||||
{
|
|
||||||
Delete();
|
|
||||||
//std::lock_guard<std::mutex> lock(m_wait_for_exit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitCode Entry()
|
|
||||||
{
|
|
||||||
//std::lock_guard<std::mutex> lock(m_wait_for_exit);
|
|
||||||
m_parent->Task();
|
|
||||||
m_alive = false;
|
|
||||||
if(m_parent) m_parent->m_executor = nullptr;
|
|
||||||
return (ExitCode)0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//ThreadBase* GetCurrentThread();
|
class thread
|
||||||
|
{
|
||||||
|
std::string m_name;
|
||||||
|
std::thread m_thr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
thread(const std::string& name, std::function<void()> func);
|
||||||
|
thread(const std::string& name);
|
||||||
|
thread();
|
||||||
|
|
||||||
|
void start(std::function<void()> func);
|
||||||
|
void detach();
|
||||||
|
void join();
|
||||||
|
bool joinable() const;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T> class MTPacketBuffer
|
template<typename T> class MTPacketBuffer
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ CPUThread* GetCurrentCPUThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUThread::CPUThread(CPUThreadType type)
|
CPUThread::CPUThread(CPUThreadType type)
|
||||||
: ThreadBase(true, "CPUThread")
|
: ThreadBase("CPUThread")
|
||||||
, m_type(type)
|
, m_type(type)
|
||||||
, m_stack_size(0)
|
, m_stack_size(0)
|
||||||
, m_stack_addr(0)
|
, m_stack_addr(0)
|
||||||
|
@ -15,30 +15,24 @@ CPUThread::CPUThread(CPUThreadType type)
|
||||||
, m_prio(0)
|
, m_prio(0)
|
||||||
, m_sync_wait(false)
|
, m_sync_wait(false)
|
||||||
, m_wait_thread_id(-1)
|
, m_wait_thread_id(-1)
|
||||||
, m_free_data(false)
|
|
||||||
, m_dec(nullptr)
|
, m_dec(nullptr)
|
||||||
, m_is_step(false)
|
, m_is_step(false)
|
||||||
, m_is_branch(false)
|
, m_is_branch(false)
|
||||||
|
, m_status(Stopped)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUThread::~CPUThread()
|
CPUThread::~CPUThread()
|
||||||
{
|
{
|
||||||
Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUThread::Close()
|
void CPUThread::Close()
|
||||||
{
|
{
|
||||||
if(IsAlive())
|
ThreadBase::Stop();
|
||||||
{
|
DoStop();
|
||||||
m_free_data = true;
|
|
||||||
ThreadBase::Stop(false);
|
delete m_dec;
|
||||||
}
|
m_dec = nullptr;
|
||||||
else
|
|
||||||
{
|
|
||||||
delete m_dec;
|
|
||||||
m_dec = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUThread::Reset()
|
void CPUThread::Reset()
|
||||||
|
@ -77,7 +71,7 @@ void CPUThread::SetId(const u32 id)
|
||||||
|
|
||||||
void CPUThread::SetName(const std::string& name)
|
void CPUThread::SetName(const std::string& name)
|
||||||
{
|
{
|
||||||
m_name = name;
|
NamedThreadBase::SetThreadName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUThread::Wait(bool wait)
|
void CPUThread::Wait(bool wait)
|
||||||
|
@ -189,12 +183,10 @@ wxArrayString CPUThread::ErrorToString(const u32 error)
|
||||||
|
|
||||||
void CPUThread::Run()
|
void CPUThread::Run()
|
||||||
{
|
{
|
||||||
if(IsRunning()) Stop();
|
if(!IsStopped())
|
||||||
if(IsPaused())
|
Stop();
|
||||||
{
|
|
||||||
Resume();
|
Reset();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef QT_UI
|
#ifndef QT_UI
|
||||||
wxGetApp().SendDbgCommand(DID_START_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_START_THREAD, this);
|
||||||
|
@ -244,7 +236,7 @@ void CPUThread::Pause()
|
||||||
DoPause();
|
DoPause();
|
||||||
Emu.CheckStatus();
|
Emu.CheckStatus();
|
||||||
|
|
||||||
ThreadBase::Stop(false);
|
ThreadBase::Stop();
|
||||||
#ifndef QT_UI
|
#ifndef QT_UI
|
||||||
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
|
||||||
#endif
|
#endif
|
||||||
|
@ -259,9 +251,15 @@ void CPUThread::Stop()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_status = Stopped;
|
m_status = Stopped;
|
||||||
ThreadBase::Stop(false);
|
|
||||||
Reset();
|
if(CPUThread* thr = GetCurrentCPUThread())
|
||||||
DoStop();
|
{
|
||||||
|
if(thr->GetId() != GetId())
|
||||||
|
ThreadBase::Stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ThreadBase::Stop();
|
||||||
|
|
||||||
Emu.CheckStatus();
|
Emu.CheckStatus();
|
||||||
|
|
||||||
#ifndef QT_UI
|
#ifndef QT_UI
|
||||||
|
@ -275,7 +273,9 @@ void CPUThread::Exec()
|
||||||
#ifndef QT_UI
|
#ifndef QT_UI
|
||||||
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
||||||
#endif
|
#endif
|
||||||
ThreadBase::Start();
|
|
||||||
|
if(IsRunning())
|
||||||
|
ThreadBase::Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUThread::ExecOnce()
|
void CPUThread::ExecOnce()
|
||||||
|
@ -285,7 +285,7 @@ void CPUThread::ExecOnce()
|
||||||
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
||||||
#endif
|
#endif
|
||||||
ThreadBase::Start();
|
ThreadBase::Start();
|
||||||
if(!ThreadBase::Wait()) while(m_is_step) Sleep(1);
|
ThreadBase::Stop();
|
||||||
#ifndef QT_UI
|
#ifndef QT_UI
|
||||||
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this);
|
||||||
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_PAUSED_THREAD, this);
|
||||||
|
@ -294,7 +294,7 @@ void CPUThread::ExecOnce()
|
||||||
|
|
||||||
void CPUThread::Task()
|
void CPUThread::Task()
|
||||||
{
|
{
|
||||||
//ConLog.Write("%s enter", CPUThread::GetFName());
|
ConLog.Write("%s enter", CPUThread::GetFName());
|
||||||
|
|
||||||
const Array<u64>& bp = Emu.GetBreakPoints();
|
const Array<u64>& bp = Emu.GetBreakPoints();
|
||||||
|
|
||||||
|
@ -354,15 +354,7 @@ void CPUThread::Task()
|
||||||
catch(int exitcode)
|
catch(int exitcode)
|
||||||
{
|
{
|
||||||
ConLog.Success("Exit Code: %d", exitcode);
|
ConLog.Success("Exit Code: %d", exitcode);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//ConLog.Write("%s leave", CPUThread::GetFName());
|
ConLog.Write("%s leave", CPUThread::GetFName());
|
||||||
|
|
||||||
if(m_free_data)
|
|
||||||
{
|
|
||||||
delete m_dec;
|
|
||||||
m_dec = nullptr;
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ protected:
|
||||||
CPUThreadType m_type;
|
CPUThreadType m_type;
|
||||||
bool m_joinable;
|
bool m_joinable;
|
||||||
bool m_joining;
|
bool m_joining;
|
||||||
bool m_free_data;
|
|
||||||
bool m_is_step;
|
bool m_is_step;
|
||||||
|
|
||||||
u64 m_stack_addr;
|
u64 m_stack_addr;
|
||||||
|
@ -68,7 +67,7 @@ public:
|
||||||
u32 GetExitStatus() const { return m_exit_status; }
|
u32 GetExitStatus() const { return m_exit_status; }
|
||||||
u64 GetPrio() const { return m_prio; }
|
u64 GetPrio() const { return m_prio; }
|
||||||
|
|
||||||
std::string GetName() const { return m_name; }
|
std::string GetName() const { return NamedThreadBase::GetThreadName(); }
|
||||||
wxString GetFName() const
|
wxString GetFName() const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
|
@ -64,16 +64,7 @@ void CPUThreadManager::RemoveThread(const u32 id)
|
||||||
#ifndef QT_UI
|
#ifndef QT_UI
|
||||||
wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, thr);
|
wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, thr);
|
||||||
#endif
|
#endif
|
||||||
if(thr->IsAlive())
|
thr->Close();
|
||||||
{
|
|
||||||
//thr->Close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//thr->Close();
|
|
||||||
//delete thr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m_threads.RemoveFAt(i);
|
m_threads.RemoveFAt(i);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -21,7 +21,7 @@ RawSPUThread::~RawSPUThread()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Close();
|
//Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawSPUThread::Read8(const u64 addr, u8* value)
|
bool RawSPUThread::Read8(const u64 addr, u8* value)
|
||||||
|
|
|
@ -78,7 +78,7 @@ void SPUThread::DoRun()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pause();
|
//Pause();
|
||||||
//Emu.Pause();
|
//Emu.Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ BEGIN_EVENT_TABLE(DbgConsole, FrameBase)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
DbgConsole::DbgConsole()
|
DbgConsole::DbgConsole()
|
||||||
: FrameBase(NULL, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true)
|
: FrameBase(nullptr, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true)
|
||||||
, ThreadBase(false, "DbgConsole thread")
|
, ThreadBase("DbgConsole thread")
|
||||||
{
|
{
|
||||||
m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||||
wxSize(500, 500), wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
|
wxSize(500, 500), wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
|
||||||
|
@ -39,8 +39,14 @@ void DbgConsole::Clear()
|
||||||
|
|
||||||
void DbgConsole::Task()
|
void DbgConsole::Task()
|
||||||
{
|
{
|
||||||
while(m_dbg_buffer.HasNewPacket() && !TestDestroy())
|
while(!TestDestroy())
|
||||||
{
|
{
|
||||||
|
if(!m_dbg_buffer.HasNewPacket())
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
DbgPacket packet = m_dbg_buffer.Pop();
|
DbgPacket packet = m_dbg_buffer.Pop();
|
||||||
m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white);
|
m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white);
|
||||||
m_console->SetInsertionPointEnd();
|
m_console->SetInsertionPointEnd();
|
||||||
|
@ -52,7 +58,7 @@ void DbgConsole::Task()
|
||||||
|
|
||||||
void DbgConsole::OnQuit(wxCloseEvent& event)
|
void DbgConsole::OnQuit(wxCloseEvent& event)
|
||||||
{
|
{
|
||||||
ThreadBase::Stop();
|
ThreadBase::Stop(false);
|
||||||
Hide();
|
Hide();
|
||||||
//event.Skip();
|
//event.Skip();
|
||||||
}
|
}
|
|
@ -54,7 +54,7 @@ bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode)
|
||||||
bool vfsLocalFile::Create(const wxString& path)
|
bool vfsLocalFile::Create(const wxString& path)
|
||||||
{
|
{
|
||||||
ConLog.Warning("vfsLocalFile::Create('%s')", path.c_str());
|
ConLog.Warning("vfsLocalFile::Create('%s')", path.c_str());
|
||||||
for(uint p=1;p<path.Length();p++)
|
for(uint p=1; path[p] != '\0'; p++)
|
||||||
{
|
{
|
||||||
for(; path[p] != '\0'; p++)
|
for(; path[p] != '\0'; p++)
|
||||||
if(path[p] == '\\') break;
|
if(path[p] == '\\') break;
|
||||||
|
|
|
@ -6,17 +6,18 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
|
||||||
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
|
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;
|
||||||
|
|
||||||
const std::string mask = GetMask().c_str();
|
const std::string mask = GetMask().c_str();
|
||||||
std::string cond = "";
|
std::string cond;
|
||||||
|
|
||||||
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
|
if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
|
||||||
{
|
{
|
||||||
static const char f[4] = {'x', 'y', 'z', 'w'};
|
static const char f[4] = {'x', 'y', 'z', 'w'};
|
||||||
|
|
||||||
std::string swizzle = "";
|
std::string swizzle;
|
||||||
swizzle += f[src0.cond_swizzle_x];
|
swizzle += f[src0.cond_swizzle_x];
|
||||||
swizzle += f[src0.cond_swizzle_y];
|
swizzle += f[src0.cond_swizzle_y];
|
||||||
swizzle += f[src0.cond_swizzle_z];
|
swizzle += f[src0.cond_swizzle_z];
|
||||||
swizzle += f[src0.cond_swizzle_w];
|
swizzle += f[src0.cond_swizzle_w];
|
||||||
|
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||||
|
|
||||||
if(src0.exec_if_gr && src0.exec_if_eq)
|
if(src0.exec_if_gr && src0.exec_if_eq)
|
||||||
{
|
{
|
||||||
|
@ -43,10 +44,7 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
|
||||||
cond = "equal";
|
cond = "equal";
|
||||||
}
|
}
|
||||||
|
|
||||||
cond = std::string("if(all(" + cond + "(" + AddCond(dst.no_dest) + "." + swizzle +", vec4(0, 0, 0, 0)))) ");
|
cond = "if(all(" + cond + "(" + AddCond(dst.no_dest) + swizzle + ", vec4(0.0)))) ";
|
||||||
//ConLog.Error("cond! [eq: %d gr: %d lt: %d] (%s)", src0.exec_if_eq, src0.exec_if_gr, src0.exec_if_lt, cond);
|
|
||||||
//Emu.Pause();
|
|
||||||
//return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(src1.scale)
|
if(src1.scale)
|
||||||
|
@ -72,16 +70,28 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
|
||||||
code = "clamp(" + code + ", 0.0, 1.0)";
|
code = "clamp(" + code + ", 0.0, 1.0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
code = cond + (dst.set_cond ? m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index))
|
std::string dest;
|
||||||
: AddReg(dst.dest_reg, dst.fp16)) + mask
|
|
||||||
+ " = " + code + (append_mask ? mask : "");
|
if(dst.no_dest)
|
||||||
|
{
|
||||||
|
if(dst.set_cond)
|
||||||
|
{
|
||||||
|
dest = m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest = AddReg(dst.dest_reg, dst.fp16);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = cond + (dest.length() ? dest + mask + " = " : "") + code + (append_mask ? mask : "");
|
||||||
|
|
||||||
main += "\t" + code + ";\n";
|
main += "\t" + code + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLFragmentDecompilerThread::GetMask()
|
std::string GLFragmentDecompilerThread::GetMask()
|
||||||
{
|
{
|
||||||
std::string ret = "";
|
std::string ret;
|
||||||
|
|
||||||
static const char dst_mask[4] =
|
static const char dst_mask[4] =
|
||||||
{
|
{
|
||||||
|
@ -98,17 +108,16 @@ std::string GLFragmentDecompilerThread::GetMask()
|
||||||
|
|
||||||
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
|
std::string GLFragmentDecompilerThread::AddReg(u32 index, int fp16)
|
||||||
{
|
{
|
||||||
/*
|
if(index >= 2 && index <= 4)
|
||||||
if(HasReg(index, fp16))
|
|
||||||
{
|
{
|
||||||
return wxString::Format((fp16 ? "h%u" : "r%u"), index);
|
return m_parr.AddParam(PARAM_OUT, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index),
|
||||||
|
(fp16) ? -1 : (index - 1));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
//ConLog.Warning("%c%d: %d %d", (fp16 ? 'h' : 'r'), index, dst.tex_num, src2.use_index_reg);
|
return m_parr.AddParam(PARAM_NONE, "vec4", std::string(fp16 ? "h" : "r") + std::to_string(index), "vec4(0.0, 0.0, 0.0, 0.0)");
|
||||||
|
|
||||||
return m_parr.AddParam((index >= 2 && index <= 4) ? PARAM_OUT : PARAM_NONE, "vec4",
|
//return m_parr.AddParam((index >= 2 && index <= 4) ? PARAM_OUT : PARAM_NONE, "vec4",
|
||||||
std::string(fp16 ? "h" : "r") + std::to_string(index), (fp16 || !index) ? -1 : ((index >= 2 && index <= 4) ? (index - 1) : -1));
|
// std::string(fp16 ? "h" : "r") + std::to_string(index), (fp16 || !index) ? -1 : ((index >= 2 && index <= 4) ? (index - 1) : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
|
bool GLFragmentDecompilerThread::HasReg(u32 index, int fp16)
|
||||||
|
@ -219,6 +228,15 @@ std::string GLFragmentDecompilerThread::BuildCode()
|
||||||
p += m_parr.params[i].Format();
|
p += m_parr.params[i].Format();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return "#version 330\n\
|
||||||
|
\n\
|
||||||
|
out vec3 color;\n\
|
||||||
|
in vec4 tc1;\n\
|
||||||
|
\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
color = tc1.rgb;\n\
|
||||||
|
}";
|
||||||
return std::string("#version 330\n"
|
return std::string("#version 330\n"
|
||||||
"\n"
|
"\n"
|
||||||
+ p + "\n"
|
+ p + "\n"
|
||||||
|
|
|
@ -109,7 +109,7 @@ struct GLFragmentDecompilerThread : public ThreadBase
|
||||||
u32 m_ctrl;
|
u32 m_ctrl;
|
||||||
|
|
||||||
GLFragmentDecompilerThread(std::string& shader, GLParamArray& parr, u32 addr, u32& size, u32 ctrl)
|
GLFragmentDecompilerThread(std::string& shader, GLParamArray& parr, u32 addr, u32& size, u32 ctrl)
|
||||||
: ThreadBase(false, "Fragment Shader Decompiler Thread")
|
: ThreadBase("Fragment Shader Decompiler Thread")
|
||||||
, m_shader(shader)
|
, m_shader(shader)
|
||||||
, m_parr(parr)
|
, m_parr(parr)
|
||||||
, m_addr(addr)
|
, m_addr(addr)
|
||||||
|
@ -155,7 +155,7 @@ struct GLShaderProgram
|
||||||
{
|
{
|
||||||
if(m_decompiler_thread && m_decompiler_thread->IsAlive())
|
if(m_decompiler_thread && m_decompiler_thread->IsAlive())
|
||||||
{
|
{
|
||||||
m_decompiler_thread->Wait();
|
m_decompiler_thread->Join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Decompile(RSXShaderProgram& prog);
|
void Decompile(RSXShaderProgram& prog);
|
||||||
|
|
|
@ -109,7 +109,7 @@ extern CellGcmContextData current_context;
|
||||||
|
|
||||||
void GLGSRender::Close()
|
void GLGSRender::Close()
|
||||||
{
|
{
|
||||||
if(IsAlive()) Stop();
|
Stop();
|
||||||
|
|
||||||
if(m_frame->IsShown()) m_frame->Hide();
|
if(m_frame->IsShown()) m_frame->Hide();
|
||||||
m_ctrl = nullptr;
|
m_ctrl = nullptr;
|
||||||
|
|
|
@ -151,7 +151,7 @@ wxString GLVertexDecompilerThread::GetSRC(const u32 n, bool isSca)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst)
|
void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask, bool set_dst, bool set_cond)
|
||||||
{
|
{
|
||||||
if(d0.cond == 0) return;
|
if(d0.cond == 0) return;
|
||||||
enum
|
enum
|
||||||
|
@ -161,28 +161,42 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||||
gt = 0x4,
|
gt = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* cond_string_table[(lt | gt | eq) + 1] =
|
||||||
|
{
|
||||||
|
"error",
|
||||||
|
"lessThan",
|
||||||
|
"equal",
|
||||||
|
"lessThanEqual",
|
||||||
|
"greaterThan",
|
||||||
|
"notEqual",
|
||||||
|
"greaterThanEqual",
|
||||||
|
"error"
|
||||||
|
};
|
||||||
|
|
||||||
wxString cond;
|
wxString cond;
|
||||||
|
|
||||||
if(d0.cond != (lt | gt | eq))
|
if((set_cond || d0.cond_test_enable) && d0.cond != (lt | gt | eq))
|
||||||
{
|
{
|
||||||
if((d0.cond & (lt | gt)) == (lt | gt))
|
static const char f[4] = {'x', 'y', 'z', 'w'};
|
||||||
{
|
|
||||||
cond = "!=";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(d0.cond & lt) cond = "<";
|
|
||||||
else if(d0.cond & gt) cond = ">";
|
|
||||||
else if(d0.cond & eq) cond = "=";
|
|
||||||
|
|
||||||
if(d0.cond & eq) cond += "=";
|
std::string swizzle;
|
||||||
}
|
swizzle += f[d0.mask_x];
|
||||||
|
swizzle += f[d0.mask_y];
|
||||||
|
swizzle += f[d0.mask_z];
|
||||||
|
swizzle += f[d0.mask_w];
|
||||||
|
|
||||||
//ConLog.Error("cond! %d (%d %s %d %d)", d0.cond, d0.dst_tmp, cond, d1.input_src, d1.const_src);
|
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
||||||
cond = wxString::Format("if(rc %s 0) ", cond.mb_str());
|
|
||||||
|
cond = wxString::Format("if(all(%s(rc%s, vec4(0.0)%s))) ", cond_string_table[d0.cond], swizzle.c_str(), swizzle.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString value = src_mask ? code + GetMask(is_sca) : code;
|
wxString mask = GetMask(is_sca);
|
||||||
|
wxString value = src_mask ? code + mask : code;
|
||||||
|
|
||||||
|
if(is_sca && d0.vec_result)
|
||||||
|
{
|
||||||
|
value = "vec4(" + value + ")" + mask;
|
||||||
|
}
|
||||||
|
|
||||||
if(d0.staturate)
|
if(d0.staturate)
|
||||||
{
|
{
|
||||||
|
@ -194,26 +208,28 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||||
wxString dest;
|
wxString dest;
|
||||||
if(d0.cond_update_enable_0)
|
if(d0.cond_update_enable_0)
|
||||||
{
|
{
|
||||||
dest = m_parr.AddParam(PARAM_NONE, "float", "rc");
|
dest = m_parr.AddParam(PARAM_NONE, "vec4", "rc", "vec4(0.0)") + mask;
|
||||||
}
|
}
|
||||||
else if(d3.dst == 5 || d3.dst == 6)
|
else if(d3.dst == 5 || d3.dst == 6)
|
||||||
{
|
{
|
||||||
int num = d3.dst == 5 ? 0 : 3;
|
|
||||||
|
|
||||||
if(d3.vec_writemask_x)
|
if(d3.vec_writemask_x)
|
||||||
{
|
{
|
||||||
ConLog.Error("Bad clip mask.");
|
dest = m_parr.AddParam(PARAM_OUT, "vec4", "fogc") + mask;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int num = d3.dst == 5 ? 0 : 3;
|
||||||
|
|
||||||
//if(d3.vec_writemask_y) num += 0;
|
//if(d3.vec_writemask_y) num += 0;
|
||||||
if(d3.vec_writemask_z) num += 1;
|
if(d3.vec_writemask_z) num += 1;
|
||||||
else if(d3.vec_writemask_w) num += 2;
|
else if(d3.vec_writemask_w) num += 2;
|
||||||
|
|
||||||
dest = wxString::Format(GetDST(is_sca), num);
|
dest = wxString::Format(GetDST(is_sca) + "/*" + mask + "*/", num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dest = GetDST(is_sca) + GetMask(is_sca);
|
dest = GetDST(is_sca) + mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = cond + dest + " = " + value;
|
code = cond + dest + " = " + value;
|
||||||
|
@ -223,7 +239,7 @@ void GLVertexDecompilerThread::AddCode(bool is_sca, wxString code, bool src_mask
|
||||||
code = cond + value;
|
code = cond + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_body.Add(code + wxString::Format(";//%d %d %d %d", d0.cond_reg_sel_1, d0.cond_test_enable, d0.cond_update_enable_0, d0.cond_update_enable_1));
|
m_body.Add(code + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GLVertexDecompilerThread::GetFunc()
|
wxString GLVertexDecompilerThread::GetFunc()
|
||||||
|
@ -249,9 +265,9 @@ void GLVertexDecompilerThread::AddVecCode(const wxString& code, bool src_mask, b
|
||||||
AddCode(false, code, src_mask, set_dst);
|
AddCode(false, code, src_mask, set_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst)
|
void GLVertexDecompilerThread::AddScaCode(const wxString& code, bool set_dst, bool set_cond)
|
||||||
{
|
{
|
||||||
AddCode(true, code, false, set_dst);
|
AddCode(true, code, false, set_dst, set_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GLVertexDecompilerThread::BuildFuncBody(const FuncInfo& func)
|
wxString GLVertexDecompilerThread::BuildFuncBody(const FuncInfo& func)
|
||||||
|
@ -296,7 +312,7 @@ wxString GLVertexDecompilerThread::BuildCode()
|
||||||
|
|
||||||
wxString fp = wxEmptyString;
|
wxString fp = wxEmptyString;
|
||||||
|
|
||||||
for(int i=m_funcs.GetCount() - 1; i>=0; --i)
|
for(int i=m_funcs.GetCount() - 1; i>0; --i)
|
||||||
{
|
{
|
||||||
fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str());
|
fp += wxString::Format("void %s();\n", m_funcs[i].name.mb_str());
|
||||||
}
|
}
|
||||||
|
@ -322,6 +338,8 @@ wxString GLVertexDecompilerThread::BuildCode()
|
||||||
|
|
||||||
void GLVertexDecompilerThread::Task()
|
void GLVertexDecompilerThread::Task()
|
||||||
{
|
{
|
||||||
|
m_parr.params.Clear();
|
||||||
|
|
||||||
for(u32 i=0;;)
|
for(u32 i=0;;)
|
||||||
{
|
{
|
||||||
d0.HEX = m_data[i++];
|
d0.HEX = m_data[i++];
|
||||||
|
@ -339,17 +357,17 @@ void GLVertexDecompilerThread::Task()
|
||||||
{
|
{
|
||||||
case 0x00: break; // NOP
|
case 0x00: break; // NOP
|
||||||
case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV
|
case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV
|
||||||
case 0x02: AddScaCode("1 / (" + GetSRC(2, true) + ")"); break; // RCP
|
case 0x02: AddScaCode("1.0 / " + GetSRC(2, true)); break; // RCP
|
||||||
case 0x03: AddScaCode("clamp(1 / (" + GetSRC(2, true) + "), 5.42101e-20, 1.884467e19)"); break; // RCC
|
case 0x03: AddScaCode("clamp(1.0 / " + GetSRC(2, true) + ", 5.42101e-20, 1.884467e19)"); break; // RCC
|
||||||
case 0x04: AddScaCode("inversesqrt(" + GetSRC(2, true) + ")"); break; // RSQ
|
case 0x04: AddScaCode("inversesqrt(" + GetSRC(2, true) + ")"); break; // RSQ
|
||||||
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
|
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
|
||||||
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
|
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
|
||||||
//case 0x07: break; // LIT
|
//case 0x07: break; // LIT
|
||||||
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false); break; // BRA
|
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false, true); break; // BRA
|
||||||
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false); break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
|
||||||
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false); break; // CAL : works same as BRI
|
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false, true); break; // CAL : works same as BRI
|
||||||
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false); break; // CLI : works same as BRI
|
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false, true); break; // CLI : works same as BRI
|
||||||
case 0x0c: AddScaCode("return", false); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
case 0x0c: AddScaCode("return", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
|
||||||
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
|
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
|
||||||
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
|
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
|
||||||
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
|
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
|
||||||
|
|
|
@ -143,7 +143,7 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||||
GLParamArray& m_parr;
|
GLParamArray& m_parr;
|
||||||
|
|
||||||
GLVertexDecompilerThread(Array<u32>& data, wxString& shader, GLParamArray& parr)
|
GLVertexDecompilerThread(Array<u32>& data, wxString& shader, GLParamArray& parr)
|
||||||
: ThreadBase(false, "Vertex Shader Decompiler Thread")
|
: ThreadBase("Vertex Shader Decompiler Thread")
|
||||||
, m_data(data)
|
, m_data(data)
|
||||||
, m_shader(shader)
|
, m_shader(shader)
|
||||||
, m_parr(parr)
|
, m_parr(parr)
|
||||||
|
@ -160,9 +160,9 @@ struct GLVertexDecompilerThread : public ThreadBase
|
||||||
wxString GetDST(bool is_sca = false);
|
wxString GetDST(bool is_sca = false);
|
||||||
wxString GetSRC(const u32 n, bool is_sca = false);
|
wxString GetSRC(const u32 n, bool is_sca = false);
|
||||||
wxString GetFunc();
|
wxString GetFunc();
|
||||||
void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true);
|
void AddCode(bool is_sca, wxString code, bool src_mask = true, bool set_dst = true, bool set_cond = true);
|
||||||
void AddVecCode(const wxString& code, bool src_mask = true, bool set_dst = true);
|
void AddVecCode(const wxString& code, bool src_mask = true, bool set_dst = true);
|
||||||
void AddScaCode(const wxString& code, bool set_dst = true);
|
void AddScaCode(const wxString& code, bool set_dst = true, bool set_cond = true);
|
||||||
wxString BuildFuncBody(const FuncInfo& func);
|
wxString BuildFuncBody(const FuncInfo& func);
|
||||||
wxString BuildCode();
|
wxString BuildCode();
|
||||||
|
|
||||||
|
@ -182,9 +182,9 @@ struct GLVertexProgram
|
||||||
|
|
||||||
void Wait()
|
void Wait()
|
||||||
{
|
{
|
||||||
if(m_decompiler_thread && m_decompiler_thread->IsRunning())
|
if(m_decompiler_thread && m_decompiler_thread->IsAlive())
|
||||||
{
|
{
|
||||||
m_decompiler_thread->Wait();
|
m_decompiler_thread->Join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,17 @@ struct NullGSFrame : public GSFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw()
|
void Draw()
|
||||||
{
|
{
|
||||||
wxClientDC dc(this);
|
wxClientDC dc(this);
|
||||||
Draw(&dc);
|
Draw(&dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void OnPaint(wxPaintEvent& event)
|
virtual void OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
Draw(&dc);
|
Draw(&dc);
|
||||||
}
|
}
|
||||||
virtual void OnSize(wxSizeEvent& event)
|
virtual void OnSize(wxSizeEvent& event)
|
||||||
{
|
{
|
||||||
GSFrame::OnSize(event);
|
GSFrame::OnSize(event);
|
||||||
|
@ -77,7 +77,7 @@ private:
|
||||||
|
|
||||||
virtual void Close()
|
virtual void Close()
|
||||||
{
|
{
|
||||||
if(IsAlive()) Stop();
|
Stop();
|
||||||
|
|
||||||
if(m_frame->IsShown()) m_frame->Hide();
|
if(m_frame->IsShown()) m_frame->Hide();
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,6 @@ public:
|
||||||
u32 m_report_main_addr;
|
u32 m_report_main_addr;
|
||||||
|
|
||||||
u32 m_local_mem_addr, m_main_mem_addr;
|
u32 m_local_mem_addr, m_main_mem_addr;
|
||||||
Array<MemInfo> m_main_mem_info;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint m_draw_mode;
|
uint m_draw_mode;
|
||||||
|
@ -520,7 +519,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RSXThread()
|
RSXThread()
|
||||||
: ThreadBase(false, "RSXThread")
|
: ThreadBase("RSXThread")
|
||||||
, m_ctrl(nullptr)
|
, m_ctrl(nullptr)
|
||||||
, m_flip_status(0)
|
, m_flip_status(0)
|
||||||
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
|
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
|
||||||
|
@ -637,7 +636,7 @@ protected:
|
||||||
switch(location)
|
switch(location)
|
||||||
{
|
{
|
||||||
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
|
case CELL_GCM_LOCATION_LOCAL: return m_local_mem_addr + offset;
|
||||||
case CELL_GCM_LOCATION_MAIN: return m_main_mem_addr + offset;
|
case CELL_GCM_LOCATION_MAIN: return Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location);
|
ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location);
|
||||||
|
|
|
@ -691,12 +691,17 @@ struct _func_arg
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _func_arg<mem_base_t<T>>
|
struct _func_arg<mem_base_t<T>>
|
||||||
{
|
{
|
||||||
__forceinline static u64 get_value(const mem_base_t<T>& arg)
|
__forceinline static u64 get_value(const mem_base_t<T> arg)
|
||||||
{
|
{
|
||||||
return arg.GetAddr();
|
return arg.GetAddr();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T> struct _func_arg<mem_ptr_t<T>> : public _func_arg<mem_base_t<T>> {};
|
||||||
|
template<> struct _func_arg<mem_ptr_t<void>> : public _func_arg<mem_base_t<u8>> {};
|
||||||
|
template<typename T> struct _func_arg<mem_list_ptr_t<T>> : public _func_arg<mem_base_t<T>> {};
|
||||||
|
template<typename T> struct _func_arg<mem_t<T>> : public _func_arg<mem_base_t<T>> {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _func_arg<be_t<T>>
|
struct _func_arg<be_t<T>>
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,23 +53,29 @@ void Callback::Branch(bool wait)
|
||||||
{
|
{
|
||||||
m_has_data = false;
|
m_has_data = false;
|
||||||
|
|
||||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
CPUThread& thr = Emu.GetCallbackThread();
|
||||||
|
|
||||||
new_thread.SetEntry(m_addr);
|
while(Emu.IsRunning() && thr.IsAlive())
|
||||||
new_thread.SetPrio(1001);
|
Sleep(1);
|
||||||
new_thread.SetStackSize(0x10000);
|
|
||||||
new_thread.SetName(m_name);
|
|
||||||
|
|
||||||
new_thread.SetArg(0, a1);
|
thr.Stop();
|
||||||
new_thread.SetArg(1, a2);
|
thr.Reset();
|
||||||
new_thread.SetArg(2, a3);
|
|
||||||
new_thread.SetArg(3, a4);
|
|
||||||
new_thread.Run();
|
|
||||||
|
|
||||||
new_thread.Exec();
|
thr.SetEntry(m_addr);
|
||||||
|
thr.SetPrio(1001);
|
||||||
|
thr.SetStackSize(0x10000);
|
||||||
|
thr.SetName(m_name);
|
||||||
|
|
||||||
|
thr.SetArg(0, a1);
|
||||||
|
thr.SetArg(1, a2);
|
||||||
|
thr.SetArg(2, a3);
|
||||||
|
thr.SetArg(3, a4);
|
||||||
|
thr.Run();
|
||||||
|
|
||||||
|
thr.Exec();
|
||||||
|
|
||||||
if(wait)
|
if(wait)
|
||||||
GetCurrentPPCThread()->Wait(new_thread);
|
GetCurrentPPCThread()->Wait(thr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Callback::SetName(const std::string& name)
|
void Callback::SetName(const std::string& name)
|
||||||
|
|
|
@ -107,7 +107,6 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
||||||
render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo));
|
render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo));
|
||||||
render.m_gcm_buffers_count = 0;
|
render.m_gcm_buffers_count = 0;
|
||||||
render.m_gcm_current_buffer = 0;
|
render.m_gcm_current_buffer = 0;
|
||||||
render.m_main_mem_info.Clear();
|
|
||||||
render.m_main_mem_addr = 0;
|
render.m_main_mem_addr = 0;
|
||||||
render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr);
|
render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr);
|
||||||
|
|
||||||
|
@ -725,7 +724,6 @@ int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
|
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
|
||||||
Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(ea, size));
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,11 +193,8 @@ int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void
|
||||||
//get a unique id for the callback (may be used by cellFsAioCancel)
|
//get a unique id for the callback (may be used by cellFsAioCancel)
|
||||||
const u32 xid = g_FsAioReadID++;
|
const u32 xid = g_FsAioReadID++;
|
||||||
|
|
||||||
//read data in another thread (doesn't work correctly):
|
thread t("fsAioRead", std::bind(fsAioRead, fd, aio, xid, func));
|
||||||
//std::thread t(fsAioRead, fd, aio, xid, func);
|
t.detach();
|
||||||
//t.detach();
|
|
||||||
//read data immediately (actually it should be read in special thread):
|
|
||||||
fsAioRead(fd, aio, xid, func);
|
|
||||||
|
|
||||||
aio_id = xid;
|
aio_id = xid;
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,11 @@ void sys_ppu_thread_exit(int errorcode)
|
||||||
|
|
||||||
PPUThread& thr = GetCurrentPPUThread();
|
PPUThread& thr = GetCurrentPPUThread();
|
||||||
thr.SetExitStatus(errorcode);
|
thr.SetExitStatus(errorcode);
|
||||||
Emu.GetCPU().RemoveThread(thr.GetId());
|
thr.Stop();
|
||||||
|
|
||||||
throw errorcode;
|
//Emu.GetCPU().RemoveThread(thr.GetId());
|
||||||
|
|
||||||
|
//throw errorcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_yield()
|
int sys_ppu_thread_yield()
|
||||||
|
|
|
@ -27,6 +27,7 @@ Emulator::Emulator()
|
||||||
, m_mode(DisAsm)
|
, m_mode(DisAsm)
|
||||||
, m_dbg_console(nullptr)
|
, m_dbg_console(nullptr)
|
||||||
, m_rsx_callback(0)
|
, m_rsx_callback(0)
|
||||||
|
, m_ppu_callback_thr(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +311,8 @@ void Emulator::Load()
|
||||||
|
|
||||||
case MACHINE_PPC64:
|
case MACHINE_PPC64:
|
||||||
{
|
{
|
||||||
|
m_ppu_callback_thr = &GetCPU().AddThread(CPU_THREAD_PPU);
|
||||||
|
|
||||||
thread.SetEntry(l.GetEntry());
|
thread.SetEntry(l.GetEntry());
|
||||||
Memory.StackMem.Alloc(0x1000);
|
Memory.StackMem.Alloc(0x1000);
|
||||||
thread.InitStack();
|
thread.InitStack();
|
||||||
|
|
|
@ -88,6 +88,8 @@ class Emulator
|
||||||
GSManager m_gs_manager;
|
GSManager m_gs_manager;
|
||||||
AudioManager m_audio_manager;
|
AudioManager m_audio_manager;
|
||||||
CallbackManager m_callback_manager;
|
CallbackManager m_callback_manager;
|
||||||
|
CPUThread* m_ppu_callback_thr;
|
||||||
|
|
||||||
VFS m_vfs;
|
VFS m_vfs;
|
||||||
|
|
||||||
EmuInfo m_info;
|
EmuInfo m_info;
|
||||||
|
@ -125,6 +127,7 @@ public:
|
||||||
VFS& GetVFS() { return m_vfs; }
|
VFS& GetVFS() { return m_vfs; }
|
||||||
Array<u64>& GetBreakPoints() { return m_break_points; }
|
Array<u64>& GetBreakPoints() { return m_break_points; }
|
||||||
Array<u64>& GetMarkedPoints() { return m_marked_points; }
|
Array<u64>& GetMarkedPoints() { return m_marked_points; }
|
||||||
|
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
|
||||||
|
|
||||||
void AddModuleInit(ModuleInitializer* m)
|
void AddModuleInit(ModuleInitializer* m)
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,13 +114,16 @@ LogWriter::LogWriter()
|
||||||
|
|
||||||
void LogWriter::WriteToLog(std::string prefix, std::string value, std::string colour/*, wxColour bgcolour*/)
|
void LogWriter::WriteToLog(std::string prefix, std::string value, std::string colour/*, wxColour bgcolour*/)
|
||||||
{
|
{
|
||||||
if(ThreadBase* thr = GetCurrentNamedThread())
|
if(!prefix.empty())
|
||||||
{
|
{
|
||||||
prefix = (prefix.empty() ? "" : prefix + " : ") + thr->GetThreadName();
|
if(NamedThreadBase* thr = GetCurrentNamedThread())
|
||||||
|
{
|
||||||
|
prefix += " : " + thr->GetThreadName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_logfile.IsOpened())
|
if(m_logfile.IsOpened())
|
||||||
m_logfile.Write((prefix.empty() ? wxString(wxEmptyString) : std::string("[" + prefix + "]: ") + value + "\n").c_str());
|
m_logfile.Write((prefix.empty() ? "" : std::string("[" + prefix + "]: ") + value + "\n").c_str());
|
||||||
|
|
||||||
if(!ConLogFrame) return;
|
if(!ConLogFrame) return;
|
||||||
|
|
||||||
|
@ -221,7 +224,7 @@ END_EVENT_TABLE()
|
||||||
|
|
||||||
LogFrame::LogFrame(wxWindow* parent)
|
LogFrame::LogFrame(wxWindow* parent)
|
||||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500))
|
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500))
|
||||||
, ThreadBase(false, "LogThread")
|
, ThreadBase("LogThread")
|
||||||
, m_log(*new wxListView(this))
|
, m_log(*new wxListView(this))
|
||||||
{
|
{
|
||||||
m_log.InsertColumn(0, wxEmptyString);
|
m_log.InsertColumn(0, wxEmptyString);
|
||||||
|
@ -243,8 +246,8 @@ LogFrame::~LogFrame()
|
||||||
|
|
||||||
bool LogFrame::Close(bool force)
|
bool LogFrame::Close(bool force)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop(false);
|
||||||
ConLogFrame = NULL;
|
ConLogFrame = nullptr;
|
||||||
return wxWindowBase::Close(force);
|
return wxWindowBase::Close(force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +289,7 @@ void LogFrame::Task()
|
||||||
|
|
||||||
void LogFrame::OnQuit(wxCloseEvent& event)
|
void LogFrame::OnQuit(wxCloseEvent& event)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop(false);
|
||||||
ConLogFrame = NULL;
|
ConLogFrame = nullptr;
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ class DumperThread : public ThreadBase
|
||||||
wxArrayString** arr;
|
wxArrayString** arr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DumperThread() : ThreadBase(true, "DumperThread")
|
DumperThread() : ThreadBase("DumperThread")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ struct WaitDumperThread : public ThreadBase
|
||||||
wxArrayString** arr;
|
wxArrayString** arr;
|
||||||
|
|
||||||
WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr)
|
WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr)
|
||||||
: ThreadBase()
|
: ThreadBase("WaitDumperThread")
|
||||||
, done(_done)
|
, done(_done)
|
||||||
, cores(_cores)
|
, cores(_cores)
|
||||||
, patch(_patch)
|
, patch(_patch)
|
||||||
|
|
Loading…
Reference in New Issue