git-svn-id: http://svn.purei.org/purei/trunk@191 b36208d7-6611-0410-8bec-b1987f11c4a2

This commit is contained in:
jpd002 2007-12-09 02:28:28 +00:00
parent 1bdee42be6
commit a34cafb0c4
4 changed files with 150 additions and 56 deletions

View File

@ -1,10 +1,13 @@
#include "MailBox.h"
#ifdef WIN32
#include "win32/Window.h"
#endif
using namespace boost;
CMailBox::CMailBox()
{
m_callDone = false;
}
CMailBox::~CMailBox()
@ -24,20 +27,54 @@ void CMailBox::WaitForCall()
m_waitCondition.wait(waitLock);
}
void CMailBox::SendCall(const FunctionType& function)
void CMailBox::SendCall(const FunctionType& function, bool waitForCompletion)
{
mutex::scoped_lock waitLock(m_waitMutex);
m_calls.push_back(function);
m_waitCondition.notify_all();
// m_callFinished.wait(waitLock);
{
if(waitForCompletion)
{
assert(!m_callDone);
m_callDone = false;
}
mutex::scoped_lock waitLock(m_waitMutex);
m_calls.push_back(function);
m_waitCondition.notify_all();
}
if(waitForCompletion)
{
mutex::scoped_lock doneLock(m_doneNotifyMutex);
#ifdef WIN32
while(!m_callDone)
{
xtime xt;
xtime_get(&xt, boost::TIME_UTC);
xt.nsec += 10 * 1000000;
m_callFinished.timed_wait(doneLock, xt);
MSG wmmsg;
while(PeekMessage(&wmmsg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&wmmsg);
DispatchMessage(&wmmsg);
}
}
m_callDone = false;
#else
m_callFinished.wait(doneLock);
#endif
}
}
void CMailBox::ReceiveCall()
{
mutex::scoped_lock waitLock(m_waitMutex);
if(!IsPending()) return;
FunctionType function = *m_calls.begin();
m_calls.pop_front();
function();
m_callFinished.notify_one();
{
mutex::scoped_lock waitLock(m_waitMutex);
if(!IsPending()) return;
FunctionType function = *m_calls.begin();
m_calls.pop_front();
function();
}
{
mutex::scoped_lock doneLock(m_doneNotifyMutex);
m_callFinished.notify_all();
m_callDone = true;
}
}

View File

@ -13,7 +13,7 @@ public:
typedef std::tr1::function<void ()> FunctionType;
void SendCall(const FunctionType&);
void SendCall(const FunctionType&, bool = false);
bool IsPending() const;
void ReceiveCall();
@ -24,8 +24,10 @@ private:
FunctionCallQueue m_calls;
boost::mutex m_waitMutex;
boost::mutex m_doneNotifyMutex;
boost::condition m_callFinished;
boost::condition m_waitCondition;
bool m_callDone;
};
#endif

View File

@ -56,6 +56,7 @@ m_EE(MEMORYMAP_ENDIAN_LSBF, 0x00000000, 0x20000000),
m_VU1(MEMORYMAP_ENDIAN_LSBF, 0x00000000, 0x00008000),
m_executor(m_EE),
m_nStatus(PAUSED),
m_nEnd(false),
m_pGS(NULL),
m_pPad(NULL),
m_singleStep(false),
@ -79,13 +80,14 @@ CPS2VM::~CPS2VM()
void CPS2VM::CreateGSHandler(GSHANDLERFACTORY pF, void* pParam)
{
CREATEGSHANDLERPARAM Param;
if(m_pGS != NULL) return;
Param.pFactory = pF;
CREATEGSHANDLERPARAM Param;
Param.pFactory = pF;
Param.pParam = pParam;
SendMessage(PS2VM_MSG_CREATEGS, &Param);
// SendMessage(PS2VM_MSG_CREATEGS, &Param);
m_mailBox.SendCall(bind(&CPS2VM::CreateGsImpl, this, &Param), true);
}
CGSHandler* CPS2VM::GetGSHandler()
@ -96,11 +98,13 @@ CGSHandler* CPS2VM::GetGSHandler()
void CPS2VM::DestroyGSHandler()
{
if(m_pGS == NULL) return;
SendMessage(PS2VM_MSG_DESTROYGS);
// SendMessage(PS2VM_MSG_DESTROYGS);
m_mailBox.SendCall(bind(&CPS2VM::DestroyGsImpl, this), true);
}
void CPS2VM::CreatePadHandler(PADHANDLERFACTORY pF, void* pParam)
{
/*
CREATEPADHANDLERPARAM Param;
if(m_pPad != NULL) return;
@ -108,12 +112,15 @@ void CPS2VM::CreatePadHandler(PADHANDLERFACTORY pF, void* pParam)
Param.pParam = pParam;
SendMessage(PS2VM_MSG_CREATEPAD, &Param);
*/
}
void CPS2VM::DestroyPadHandler()
{
/*
if(m_pPad == NULL) return;
SendMessage(PS2VM_MSG_DESTROYPAD);
*/
}
CVirtualMachine::STATUS CPS2VM::GetStatus() const
@ -125,24 +132,33 @@ void CPS2VM::Step()
{
if(GetStatus() == RUNNING) return;
m_singleStep = true;
SendMessage(PS2VM_MSG_RESUME);
// SendMessage(PS2VM_MSG_RESUME);
m_mailBox.SendCall(bind(&CPS2VM::ResumeImpl, this), true);
}
void CPS2VM::Resume()
{
if(m_nStatus == RUNNING) return;
SendMessage(PS2VM_MSG_RESUME);
// SendMessage(PS2VM_MSG_RESUME);
m_mailBox.SendCall(bind(&CPS2VM::ResumeImpl, this), true);
m_OnRunningStateChange();
}
void CPS2VM::Pause()
{
if(m_nStatus == PAUSED) return;
SendMessage(PS2VM_MSG_PAUSE);
// SendMessage(PS2VM_MSG_PAUSE);
m_mailBox.SendCall(bind(&CPS2VM::PauseImpl, this), true);
m_OnMachineStateChange();
m_OnRunningStateChange();
}
void CPS2VM::Reset()
{
SendMessage(PS2VM_MSG_RESET);
assert(m_nStatus == PAUSED);
ResetVM();
// SendMessage(PS2VM_MSG_RESET);
// m_mailBox.SendCall(bind(&CPS2VM::ResetVM, this), true);
}
void CPS2VM::DumpEEThreadSchedule()
@ -174,7 +190,8 @@ void CPS2VM::Initialize()
void CPS2VM::Destroy()
{
SendMessage(PS2VM_MSG_DESTROY);
m_mailBox.SendCall(bind(&CPS2VM::DestroyImpl, this));
// SendMessage(PS2VM_MSG_DESTROY);
m_pThread->join();
DELETEPTR(m_pThread);
DestroyVM();
@ -182,18 +199,20 @@ void CPS2VM::Destroy()
unsigned int CPS2VM::SaveState(const char* sPath)
{
return SendMessage(PS2VM_MSG_SAVESTATE, (void*)sPath);
throw runtime_error("Not implemented.");
// return SendMessage(PS2VM_MSG_SAVESTATE, (void*)sPath);
}
unsigned int CPS2VM::LoadState(const char* sPath)
{
return SendMessage(PS2VM_MSG_LOADSTATE, (void*)sPath);
throw runtime_error("Not implemented.");
// return SendMessage(PS2VM_MSG_LOADSTATE, (void*)sPath);
}
unsigned int CPS2VM::SendMessage(PS2VM_MSG nMsg, void* pParam)
{
return m_MsgBox.SendMessage(nMsg, pParam);
}
//unsigned int CPS2VM::SendMessage(PS2VM_MSG nMsg, void* pParam)
//{
// return m_MsgBox.SendMessage(nMsg, pParam);
//}
//////////////////////////////////////////////////
//Non extern callable methods
@ -397,6 +416,35 @@ unsigned int CPS2VM::LoadVMState(const char* sPath)
return 0;
}
void CPS2VM::PauseImpl()
{
m_nStatus = PAUSED;
// printf("PS2VM: Virtual Machine paused.\r\n");
}
void CPS2VM::ResumeImpl()
{
m_nStatus = RUNNING;
// printf("PS2VM: Virtual Machine started.\r\n");
}
void CPS2VM::DestroyImpl()
{
DELETEPTR(m_pGS);
m_nEnd = true;
}
void CPS2VM::CreateGsImpl(CREATEGSHANDLERPARAM* param)
{
m_pGS = param->pFactory(param->pParam);
m_pGS->Initialize();
}
void CPS2VM::DestroyGsImpl()
{
DELETEPTR(m_pGS);
}
void CPS2VM::CDROM0_Initialize()
{
CConfig::GetInstance()->RegisterPreferenceString("ps2.cdrom0.path", "");
@ -617,7 +665,8 @@ unsigned int CPS2VM::EETickFunction(unsigned int nTicks)
}
//TODO: Check if we can remove this if there's no debugger around
if(m_MsgBox.IsMessagePending())
// if(m_MsgBox.IsMessagePending())
if(m_mailBox.IsPending())
{
return 1;
}
@ -643,8 +692,9 @@ unsigned int CPS2VM::VU1TickFunction(unsigned int nTicks)
}
//TODO: Check if we can remove this if there's no debugger around
if(m_MsgBox.IsMessagePending())
{
// if(m_MsgBox.IsMessagePending())
if(m_mailBox.IsPending())
{
return 1;
}
@ -655,43 +705,29 @@ unsigned int CPS2VM::VU1TickFunction(unsigned int nTicks)
void CPS2VM::EmuThread()
{
bool nEnd;
CThreadMsg::MESSAGE Msg;
unsigned int nRetValue;
// CThreadMsg::MESSAGE Msg;
// unsigned int nRetValue;
nEnd = false;
m_nEnd = false;
while(1)
{
if(m_MsgBox.GetMessage(&Msg))
/*
if(m_MsgBox.GetMessage(&Msg))
{
nRetValue = 0;
switch(Msg.nMsg)
{
case PS2VM_MSG_PAUSE:
m_nStatus = PAUSED;
m_OnMachineStateChange();
m_OnRunningStateChange();
// printf("PS2VM: Virtual Machine paused.\r\n");
break;
case PS2VM_MSG_RESUME:
m_nStatus = RUNNING;
m_OnRunningStateChange();
// printf("PS2VM: Virtual Machine started.\r\n");
break;
case PS2VM_MSG_DESTROY:
DELETEPTR(m_pGS);
nEnd = true;
break;
case PS2VM_MSG_CREATEGS:
CREATEGSHANDLERPARAM* pCreateGSParam;
pCreateGSParam = (CREATEGSHANDLERPARAM*)Msg.pParam;
m_pGS = pCreateGSParam->pFactory(pCreateGSParam->pParam);
m_pGS->Initialize();
break;
case PS2VM_MSG_DESTROYGS:
DELETEPTR(m_pGS);
break;
case PS2VM_MSG_CREATEPAD:
CREATEPADHANDLERPARAM* pCreatePadParam;
@ -715,7 +751,12 @@ void CPS2VM::EmuThread()
m_MsgBox.FlushMessage(nRetValue);
}
if(nEnd) break;
*/
while(m_mailBox.IsPending())
{
m_mailBox.ReceiveCall();
}
if(m_nEnd) break;
if(m_nStatus == PAUSED)
{
//Sleep during 100ms
@ -732,14 +773,20 @@ void CPS2VM::EmuThread()
if(m_nInVBlank)
{
m_nVBlankTicks += VBLANKTICKS;
m_pGS->SetVBlank();
if(m_pGS != NULL)
{
m_pGS->SetVBlank();
}
//Old Flipping Method
//m_pGS->Flip();
m_OnNewFrame();
//////
m_pPad->Update();
if(m_pPad != NULL)
{
m_pPad->Update();
}
}
else
{

View File

@ -8,7 +8,7 @@
#include "DMAC.h"
#include "GIF.h"
#include "MIPS.h"
#include "ThreadMsg.h"
#include "MailBox.h"
#include "GSHandler.h"
#include "PadHandler.h"
#include "LogControl.h"
@ -149,6 +149,12 @@ private:
unsigned int SaveVMState(const char*);
unsigned int LoadVMState(const char*);
void ResumeImpl();
void PauseImpl();
void DestroyImpl();
void CreateGsImpl(CREATEGSHANDLERPARAM*);
void DestroyGsImpl();
unsigned int EETickFunction(unsigned int);
unsigned int VU1TickFunction(unsigned int);
static unsigned int EETickFunctionStub(unsigned int, CMIPS*);
@ -163,11 +169,13 @@ private:
void LoadBIOS();
void RegisterModulesInPadHandler();
unsigned int SendMessage(PS2VM_MSG, void* = NULL);
// unsigned int SendMessage(PS2VM_MSG, void* = NULL);
void EmuThread();
boost::thread* m_pThread;
CThreadMsg m_MsgBox;
// CThreadMsg m_MsgBox;
CMailBox m_mailBox;
STATUS m_nStatus;
bool m_nEnd;
};
#endif