mirror of
https://github.com/libretro/Play-.git
synced 2025-01-27 11:41:46 +00:00
git-svn-id: http://svn.purei.org/purei/trunk@191 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
1bdee42be6
commit
a34cafb0c4
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
127
Source/PS2VM.cpp
127
Source/PS2VM.cpp
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user